Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "GLContext.h"
7 #include "gfx2DGlue.h"
8 #include <ui/GraphicBuffer.h>
9 #include "GrallocImages.h" // for GrallocImage
10 #include "mozilla/layers/GrallocTextureHost.h"
11 #include "mozilla/layers/CompositorOGL.h"
12 #include "EGLImageHelpers.h"
13 #include "GLReadTexImageHelper.h"
15 namespace mozilla {
16 namespace layers {
18 using namespace android;
20 static gfx::SurfaceFormat
21 SurfaceFormatForAndroidPixelFormat(android::PixelFormat aFormat,
22 bool swapRB = false)
23 {
24 switch (aFormat) {
25 case android::PIXEL_FORMAT_BGRA_8888:
26 return swapRB ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::B8G8R8A8;
27 case android::PIXEL_FORMAT_RGBA_8888:
28 return swapRB ? gfx::SurfaceFormat::B8G8R8A8 : gfx::SurfaceFormat::R8G8B8A8;
29 case android::PIXEL_FORMAT_RGBX_8888:
30 return swapRB ? gfx::SurfaceFormat::B8G8R8X8 : gfx::SurfaceFormat::R8G8B8X8;
31 case android::PIXEL_FORMAT_RGB_565:
32 return gfx::SurfaceFormat::R5G6B5;
33 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
34 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
35 case HAL_PIXEL_FORMAT_YCbCr_422_I:
36 case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
37 case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
38 case HAL_PIXEL_FORMAT_YV12:
39 return gfx::SurfaceFormat::R8G8B8A8; // yup, use SurfaceFormat::R8G8B8A8 even though it's a YUV texture. This is an external texture.
40 default:
41 if (aFormat >= 0x100 && aFormat <= 0x1FF) {
42 // Reserved range for HAL specific formats.
43 return gfx::SurfaceFormat::R8G8B8A8;
44 } else {
45 // This is not super-unreachable, there's a bunch of hypothetical pixel
46 // formats we don't deal with.
47 // We only want to abort in debug builds here, since if we crash here
48 // we'll take down the compositor process and thus the phone. This seems
49 // like undesirable behaviour. We'd rather have a subtle artifact.
50 printf_stderr(" xxxxx unknow android format %i\n", (int)aFormat);
51 MOZ_ASSERT(false, "Unknown Android pixel format.");
52 return gfx::SurfaceFormat::UNKNOWN;
53 }
54 }
55 }
57 static GLenum
58 TextureTargetForAndroidPixelFormat(android::PixelFormat aFormat)
59 {
60 switch (aFormat) {
61 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
62 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
63 case HAL_PIXEL_FORMAT_YCbCr_422_I:
64 case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
65 case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
66 case HAL_PIXEL_FORMAT_YV12:
67 return LOCAL_GL_TEXTURE_EXTERNAL;
68 case android::PIXEL_FORMAT_BGRA_8888:
69 case android::PIXEL_FORMAT_RGBA_8888:
70 case android::PIXEL_FORMAT_RGBX_8888:
71 case android::PIXEL_FORMAT_RGB_565:
72 return LOCAL_GL_TEXTURE_2D;
73 default:
74 if (aFormat >= 0x100 && aFormat <= 0x1FF) {
75 // Reserved range for HAL specific formats.
76 return LOCAL_GL_TEXTURE_EXTERNAL;
77 } else {
78 // This is not super-unreachable, there's a bunch of hypothetical pixel
79 // formats we don't deal with.
80 // We only want to abort in debug builds here, since if we crash here
81 // we'll take down the compositor process and thus the phone. This seems
82 // like undesirable behaviour. We'd rather have a subtle artifact.
83 MOZ_ASSERT(false, "Unknown Android pixel format.");
84 return LOCAL_GL_TEXTURE_EXTERNAL;
85 }
86 }
87 }
89 GrallocTextureSourceOGL::GrallocTextureSourceOGL(CompositorOGL* aCompositor,
90 android::GraphicBuffer* aGraphicBuffer,
91 gfx::SurfaceFormat aFormat)
92 : mCompositor(aCompositor)
93 , mGraphicBuffer(aGraphicBuffer)
94 , mEGLImage(0)
95 , mFormat(aFormat)
96 , mNeedsReset(true)
97 {
98 MOZ_ASSERT(mGraphicBuffer.get());
99 }
101 GrallocTextureSourceOGL::~GrallocTextureSourceOGL()
102 {
103 DeallocateDeviceData();
104 mCompositor = nullptr;
105 }
107 void
108 GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
109 {
110 /*
111 * The job of this function is to ensure that the texture is tied to the
112 * android::GraphicBuffer, so that texturing will source the GraphicBuffer.
113 *
114 * To this effect we create an EGLImage wrapping this GraphicBuffer,
115 * using EGLImageCreateFromNativeBuffer, and then we tie this EGLImage to our
116 * texture using fEGLImageTargetTexture2D.
117 */
118 MOZ_ASSERT(gl());
119 if (!IsValid()) {
120 return;
121 }
122 gl()->MakeCurrent();
124 GLuint tex = GetGLTexture();
125 GLuint textureTarget = GetTextureTarget();
127 gl()->fActiveTexture(aTextureUnit);
128 gl()->fBindTexture(textureTarget, tex);
130 if (mCompositableBackendData) {
131 // There are two paths for locking/unlocking - if mCompositableBackendData is
132 // set, we use the texture on there, otherwise we use
133 // CompositorBackendSpecificData from the compositor and bind the EGLImage
134 // only in Lock().
135 if (!mEGLImage) {
136 mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
137 }
138 gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
139 }
141 ApplyFilterToBoundTexture(gl(), aFilter, textureTarget);
142 }
144 void GrallocTextureSourceOGL::Lock()
145 {
146 if (mCompositableBackendData) return;
148 MOZ_ASSERT(IsValid());
150 mTexture = mCompositor->GetTemporaryTexture(GetTextureTarget(), LOCAL_GL_TEXTURE0);
152 GLuint textureTarget = GetTextureTarget();
154 gl()->MakeCurrent();
155 gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
156 gl()->fBindTexture(textureTarget, mTexture);
157 if (!mEGLImage) {
158 mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
159 }
160 gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
161 }
163 bool
164 GrallocTextureSourceOGL::IsValid() const
165 {
166 return !!gl() && !!mGraphicBuffer.get() && (!!mCompositor || !!mCompositableBackendData);
167 }
169 gl::GLContext*
170 GrallocTextureSourceOGL::gl() const
171 {
172 return mCompositor ? mCompositor->gl() : nullptr;
173 }
175 void
176 GrallocTextureSourceOGL::SetCompositor(Compositor* aCompositor)
177 {
178 if (mCompositor && !aCompositor) {
179 DeallocateDeviceData();
180 }
181 mCompositor = static_cast<CompositorOGL*>(aCompositor);
182 }
185 GLenum
186 GrallocTextureSourceOGL::GetTextureTarget() const
187 {
188 MOZ_ASSERT(gl());
189 MOZ_ASSERT(mGraphicBuffer.get());
191 if (!gl() || !mGraphicBuffer.get()) {
192 return LOCAL_GL_TEXTURE_EXTERNAL;
193 }
195 // SGX has a quirk that only TEXTURE_EXTERNAL works and any other value will
196 // result in black pixels when trying to draw from bound textures.
197 // Unfortunately, using TEXTURE_EXTERNAL on Adreno has a terrible effect on
198 // performance.
199 // See Bug 950050.
200 if (gl()->Renderer() == gl::GLRenderer::SGX530 ||
201 gl()->Renderer() == gl::GLRenderer::SGX540) {
202 return LOCAL_GL_TEXTURE_EXTERNAL;
203 }
205 return TextureTargetForAndroidPixelFormat(mGraphicBuffer->getPixelFormat());
206 }
208 void
209 GrallocTextureSourceOGL::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
210 {
211 if (!aBackendData) {
212 mCompositableBackendData = nullptr;
213 DeallocateDeviceData();
214 return;
215 }
217 if (mCompositableBackendData != aBackendData) {
218 mNeedsReset = true;
219 }
221 if (!mNeedsReset) {
222 // Update binding to the EGLImage
223 gl()->MakeCurrent();
224 GLuint tex = GetGLTexture();
225 GLuint textureTarget = GetTextureTarget();
226 gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
227 gl()->fBindTexture(textureTarget, tex);
228 gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
229 return;
230 }
232 mCompositableBackendData = aBackendData;
234 if (!mCompositor) {
235 return;
236 }
238 // delete old EGLImage
239 DeallocateDeviceData();
241 gl()->MakeCurrent();
242 GLuint tex = GetGLTexture();
243 GLuint textureTarget = GetTextureTarget();
245 gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
246 gl()->fBindTexture(textureTarget, tex);
247 // create new EGLImage
248 mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
249 gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
250 mNeedsReset = false;
251 }
253 gfx::IntSize
254 GrallocTextureSourceOGL::GetSize() const
255 {
256 if (!IsValid()) {
257 NS_WARNING("Trying to access the size of an invalid GrallocTextureSourceOGL");
258 return gfx::IntSize(0, 0);
259 }
260 return gfx::IntSize(mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight());
261 }
263 void
264 GrallocTextureSourceOGL::DeallocateDeviceData()
265 {
266 if (mEGLImage) {
267 MOZ_ASSERT(gl());
268 gl()->MakeCurrent();
269 EGLImageDestroy(gl(), mEGLImage);
270 mEGLImage = EGL_NO_IMAGE;
271 }
272 }
274 GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags,
275 const NewSurfaceDescriptorGralloc& aDescriptor)
276 : TextureHost(aFlags)
277 {
278 android::GraphicBuffer* graphicBuffer = nullptr;
279 gfx::SurfaceFormat format = gfx::SurfaceFormat::UNKNOWN;
281 mSize = aDescriptor.size();
282 mGrallocActor =
283 static_cast<GrallocBufferActor*>(aDescriptor.bufferParent());
285 if (mGrallocActor) {
286 mGrallocActor->AddTextureHost(this);
287 graphicBuffer = mGrallocActor->GetGraphicBuffer();
288 }
290 if (graphicBuffer) {
291 format =
292 SurfaceFormatForAndroidPixelFormat(graphicBuffer->getPixelFormat(),
293 aFlags & TEXTURE_RB_SWAPPED);
294 }
295 mTextureSource = new GrallocTextureSourceOGL(nullptr,
296 graphicBuffer,
297 format);
298 }
300 GrallocTextureHostOGL::~GrallocTextureHostOGL()
301 {
302 mTextureSource = nullptr;
303 if (mGrallocActor) {
304 mGrallocActor->RemoveTextureHost();
305 mGrallocActor = nullptr;
306 }
307 }
309 void
310 GrallocTextureHostOGL::SetCompositor(Compositor* aCompositor)
311 {
312 mTextureSource->SetCompositor(static_cast<CompositorOGL*>(aCompositor));
313 }
315 bool
316 GrallocTextureHostOGL::Lock()
317 {
318 if (IsValid()) {
319 mTextureSource->Lock();
320 return true;
321 }
322 return false;
323 }
325 void
326 GrallocTextureHostOGL::Unlock()
327 {
328 // Unlock is done internally by binding the texture to another gralloc buffer
329 }
331 bool
332 GrallocTextureHostOGL::IsValid() const
333 {
334 return mTextureSource->IsValid();
335 }
337 gfx::SurfaceFormat
338 GrallocTextureHostOGL::GetFormat() const
339 {
340 return mTextureSource->GetFormat();
341 }
343 void
344 GrallocTextureHostOGL::DeallocateSharedData()
345 {
346 if (mTextureSource) {
347 mTextureSource->ForgetBuffer();
348 }
349 if (mGrallocActor) {
350 PGrallocBufferParent::Send__delete__(mGrallocActor);
351 }
352 }
354 void
355 GrallocTextureHostOGL::ForgetSharedData()
356 {
357 if (mTextureSource) {
358 mTextureSource->ForgetBuffer();
359 }
360 }
362 void
363 GrallocTextureHostOGL::DeallocateDeviceData()
364 {
365 mTextureSource->DeallocateDeviceData();
366 }
368 LayerRenderState
369 GrallocTextureHostOGL::GetRenderState()
370 {
371 if (IsValid()) {
372 uint32_t flags = 0;
373 if (mFlags & TEXTURE_NEEDS_Y_FLIP) {
374 flags |= LAYER_RENDER_STATE_Y_FLIPPED;
375 }
376 if (mFlags & TEXTURE_RB_SWAPPED) {
377 flags |= LAYER_RENDER_STATE_FORMAT_RB_SWAP;
378 }
379 return LayerRenderState(mTextureSource->mGraphicBuffer.get(),
380 gfx::ThebesIntSize(mSize),
381 flags,
382 this);
383 }
385 return LayerRenderState();
386 }
388 TemporaryRef<gfx::DataSourceSurface>
389 GrallocTextureHostOGL::GetAsSurface() {
390 return mTextureSource ? mTextureSource->GetAsSurface()
391 : nullptr;
392 }
394 TemporaryRef<gfx::DataSourceSurface>
395 GrallocTextureSourceOGL::GetAsSurface() {
396 if (!IsValid()) {
397 return nullptr;
398 }
399 gl()->MakeCurrent();
401 GLuint tex = GetGLTexture();
402 gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
403 gl()->fBindTexture(GetTextureTarget(), tex);
404 if (!mEGLImage) {
405 mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
406 }
407 gl()->fEGLImageTargetTexture2D(GetTextureTarget(), mEGLImage);
409 RefPtr<gfx::DataSourceSurface> surf =
410 IsValid() ? ReadBackSurface(gl(), tex, false, GetFormat())
411 : nullptr;
413 gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
414 return surf.forget();
415 }
417 GLuint
418 GrallocTextureSourceOGL::GetGLTexture()
419 {
420 if (mCompositableBackendData) {
421 mCompositableBackendData->SetCompositor(mCompositor);
422 return static_cast<CompositableDataGonkOGL*>(mCompositableBackendData.get())->GetTexture();
423 }
425 return mTexture;
426 }
428 void
429 GrallocTextureHostOGL::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
430 {
431 mCompositableBackendData = aBackendData;
432 if (mTextureSource) {
433 mTextureSource->SetCompositableBackendSpecificData(aBackendData);
434 }
435 // Register this object to CompositableBackendSpecificData
436 // as current TextureHost.
437 if (aBackendData) {
438 aBackendData->SetCurrentReleaseFenceTexture(this);
439 }
440 }
442 } // namepsace layers
443 } // namepsace mozilla