gfx/layers/opengl/GrallocTextureHost.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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

mercurial