gfx/gl/TextureImageEGL.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: 4 -*- */
     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 "TextureImageEGL.h"
     7 #include "GLLibraryEGL.h"
     8 #include "GLContext.h"
     9 #include "GLUploadHelpers.h"
    10 #include "gfxPlatform.h"
    11 #include "gfx2DGlue.h"
    12 #include "mozilla/gfx/Types.h"
    14 namespace mozilla {
    15 namespace gl {
    17 static GLenum
    18 GLFormatForImage(gfx::SurfaceFormat aFormat)
    19 {
    20     switch (aFormat) {
    21     case gfx::SurfaceFormat::B8G8R8A8:
    22     case gfx::SurfaceFormat::B8G8R8X8:
    23         return LOCAL_GL_RGBA;
    24     case gfx::SurfaceFormat::R5G6B5:
    25         return LOCAL_GL_RGB;
    26     case gfx::SurfaceFormat::A8:
    27         return LOCAL_GL_LUMINANCE;
    28     default:
    29         NS_WARNING("Unknown GL format for Surface format");
    30     }
    31     return 0;
    32 }
    34 static GLenum
    35 GLTypeForImage(gfx::SurfaceFormat aFormat)
    36 {
    37     switch (aFormat) {
    38     case gfx::SurfaceFormat::B8G8R8A8:
    39     case gfx::SurfaceFormat::B8G8R8X8:
    40     case gfx::SurfaceFormat::A8:
    41         return LOCAL_GL_UNSIGNED_BYTE;
    42     case gfx::SurfaceFormat::R5G6B5:
    43         return LOCAL_GL_UNSIGNED_SHORT_5_6_5;
    44     default:
    45         NS_WARNING("Unknown GL format for Surface format");
    46     }
    47     return 0;
    48 }
    50 TextureImageEGL::TextureImageEGL(GLuint aTexture,
    51                                  const nsIntSize& aSize,
    52                                  GLenum aWrapMode,
    53                                  ContentType aContentType,
    54                                  GLContext* aContext,
    55                                  Flags aFlags,
    56                                  TextureState aTextureState,
    57                                  TextureImage::ImageFormat aImageFormat)
    58     : TextureImage(aSize, aWrapMode, aContentType, aFlags)
    59     , mGLContext(aContext)
    60     , mUpdateFormat(gfx::ImageFormatToSurfaceFormat(aImageFormat))
    61     , mEGLImage(nullptr)
    62     , mTexture(aTexture)
    63     , mSurface(nullptr)
    64     , mConfig(nullptr)
    65     , mTextureState(aTextureState)
    66     , mBound(false)
    67 {
    68     if (mUpdateFormat == gfx::SurfaceFormat::UNKNOWN) {
    69         mUpdateFormat = gfx::ImageFormatToSurfaceFormat(
    70                 gfxPlatform::GetPlatform()->OptimalFormatForContent(GetContentType()));
    71     }
    73     if (mUpdateFormat == gfx::SurfaceFormat::R5G6B5) {
    74         mTextureFormat = gfx::SurfaceFormat::R8G8B8X8;
    75     } else if (mUpdateFormat == gfx::SurfaceFormat::B8G8R8X8) {
    76         mTextureFormat = gfx::SurfaceFormat::B8G8R8X8;
    77     } else {
    78         mTextureFormat = gfx::SurfaceFormat::B8G8R8A8;
    79     }
    80 }
    82 TextureImageEGL::~TextureImageEGL()
    83 {
    84     if (mGLContext->IsDestroyed() || !mGLContext->IsOwningThreadCurrent()) {
    85         return;
    86     }
    88     // If we have a context, then we need to delete the texture;
    89     // if we don't have a context (either real or shared),
    90     // then they went away when the contex was deleted, because it
    91     // was the only one that had access to it.
    92     mGLContext->MakeCurrent();
    93     mGLContext->fDeleteTextures(1, &mTexture);
    94     ReleaseTexImage();
    95     DestroyEGLSurface();
    96 }
    98 void
    99 TextureImageEGL::GetUpdateRegion(nsIntRegion& aForRegion)
   100 {
   101     if (mTextureState != Valid) {
   102         // if the texture hasn't been initialized yet, force the
   103         // client to paint everything
   104         aForRegion = nsIntRect(nsIntPoint(0, 0), gfx::ThebesIntSize(mSize));
   105     }
   107     // We can only draw a rectangle, not subregions due to
   108     // the way that our texture upload functions work.  If
   109     // needed, we /could/ do multiple texture uploads if we have
   110     // non-overlapping rects, but that's a tradeoff.
   111     aForRegion = nsIntRegion(aForRegion.GetBounds());
   112 }
   114 gfx::DrawTarget*
   115 TextureImageEGL::BeginUpdate(nsIntRegion& aRegion)
   116 {
   117     NS_ASSERTION(!mUpdateDrawTarget, "BeginUpdate() without EndUpdate()?");
   119     // determine the region the client will need to repaint
   120     GetUpdateRegion(aRegion);
   121     mUpdateRect = aRegion.GetBounds();
   123     //printf_stderr("BeginUpdate with updateRect [%d %d %d %d]\n", mUpdateRect.x, mUpdateRect.y, mUpdateRect.width, mUpdateRect.height);
   124     if (!nsIntRect(nsIntPoint(0, 0), gfx::ThebesIntSize(mSize)).Contains(mUpdateRect)) {
   125         NS_ERROR("update outside of image");
   126         return nullptr;
   127     }
   129     //printf_stderr("creating image surface %dx%d format %d\n", mUpdateRect.width, mUpdateRect.height, mUpdateFormat);
   131     mUpdateDrawTarget = gfx::Factory::CreateDrawTarget(gfx::BackendType::CAIRO,
   132                                                        gfx::IntSize(mUpdateRect.width, mUpdateRect.height),
   133                                                        mUpdateFormat);
   135     return mUpdateDrawTarget;
   136 }
   138 void
   139 TextureImageEGL::EndUpdate()
   140 {
   141     NS_ASSERTION(!!mUpdateDrawTarget, "EndUpdate() without BeginUpdate()?");
   143     //printf_stderr("EndUpdate: slow path");
   145     // This is the slower path -- we didn't have any way to set up
   146     // a fast mapping between our cairo target surface and the GL
   147     // texture, so we have to upload data.
   149     RefPtr<gfx::SourceSurface> updateSurface = nullptr;
   150     RefPtr<gfx::DataSourceSurface> uploadImage = nullptr;
   151     gfx::IntSize updateSize(mUpdateRect.width, mUpdateRect.height);
   153     NS_ASSERTION(mUpdateDrawTarget->GetSize() == updateSize,
   154                   "Upload image is the wrong size!");
   156     updateSurface = mUpdateDrawTarget->Snapshot();
   157     uploadImage = updateSurface->GetDataSurface();
   159     if (!uploadImage) {
   160         return;
   161     }
   163     mGLContext->MakeCurrent();
   164     mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
   166     if (mTextureState != Valid) {
   167         NS_ASSERTION(mUpdateRect.x == 0 && mUpdateRect.y == 0 &&
   168                       mUpdateRect.Size() == gfx::ThebesIntSize(mSize),
   169                       "Bad initial update on non-created texture!");
   171         mGLContext->fTexImage2D(LOCAL_GL_TEXTURE_2D,
   172                                 0,
   173                                 GLFormatForImage(mUpdateFormat),
   174                                 mUpdateRect.width,
   175                                 mUpdateRect.height,
   176                                 0,
   177                                 GLFormatForImage(uploadImage->GetFormat()),
   178                                 GLTypeForImage(uploadImage->GetFormat()),
   179                                 uploadImage->GetData());
   180     } else {
   181         mGLContext->fTexSubImage2D(LOCAL_GL_TEXTURE_2D,
   182                                     0,
   183                                     mUpdateRect.x,
   184                                     mUpdateRect.y,
   185                                     mUpdateRect.width,
   186                                     mUpdateRect.height,
   187                                     GLFormatForImage(uploadImage->GetFormat()),
   188                                     GLTypeForImage(uploadImage->GetFormat()),
   189                                     uploadImage->GetData());
   190     }
   192     mUpdateDrawTarget = nullptr;
   193     mTextureState = Valid;
   194     return;         // mTexture is bound
   195 }
   197 bool
   198 TextureImageEGL::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom /* = gfx::IntPoint(0,0) */)
   199 {
   200     nsIntRect bounds = aRegion.GetBounds();
   202     nsIntRegion region;
   203     if (mTextureState != Valid) {
   204         bounds = nsIntRect(0, 0, mSize.width, mSize.height);
   205         region = nsIntRegion(bounds);
   206     } else {
   207         region = aRegion;
   208     }
   210     mTextureFormat =
   211       UploadSurfaceToTexture(mGLContext,
   212                              aSurf,
   213                              region,
   214                              mTexture,
   215                              mTextureState == Created,
   216                              bounds.TopLeft() + nsIntPoint(aFrom.x, aFrom.y),
   217                              false);
   219     mTextureState = Valid;
   220     return true;
   221 }
   223 void
   224 TextureImageEGL::BindTexture(GLenum aTextureUnit)
   225 {
   226     // Ensure the texture is allocated before it is used.
   227     if (mTextureState == Created) {
   228         Resize(mSize);
   229     }
   231     mGLContext->fActiveTexture(aTextureUnit);
   232     mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
   233     mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
   234 }
   236 void
   237 TextureImageEGL::Resize(const gfx::IntSize& aSize)
   238 {
   239     NS_ASSERTION(!mUpdateDrawTarget, "Resize() while in update?");
   241     if (mSize == aSize && mTextureState != Created)
   242         return;
   244     mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
   246     mGLContext->fTexImage2D(LOCAL_GL_TEXTURE_2D,
   247                             0,
   248                             GLFormatForImage(mUpdateFormat),
   249                             aSize.width,
   250                             aSize.height,
   251                             0,
   252                             GLFormatForImage(mUpdateFormat),
   253                             GLTypeForImage(mUpdateFormat),
   254                             nullptr);
   256     mTextureState = Allocated;
   257     mSize = aSize;
   258 }
   260 bool
   261 TextureImageEGL::BindTexImage()
   262 {
   263     if (mBound && !ReleaseTexImage())
   264         return false;
   266     EGLBoolean success =
   267         sEGLLibrary.fBindTexImage(EGL_DISPLAY(),
   268                                   (EGLSurface)mSurface,
   269                                   LOCAL_EGL_BACK_BUFFER);
   271     if (success == LOCAL_EGL_FALSE)
   272         return false;
   274     mBound = true;
   275     return true;
   276 }
   278 bool
   279 TextureImageEGL::ReleaseTexImage()
   280 {
   281     if (!mBound)
   282         return true;
   284     EGLBoolean success =
   285         sEGLLibrary.fReleaseTexImage(EGL_DISPLAY(),
   286                                       (EGLSurface)mSurface,
   287                                       LOCAL_EGL_BACK_BUFFER);
   289     if (success == LOCAL_EGL_FALSE)
   290         return false;
   292     mBound = false;
   293     return true;
   294 }
   296 void
   297 TextureImageEGL::DestroyEGLSurface(void)
   298 {
   299     if (!mSurface)
   300         return;
   302     sEGLLibrary.fDestroySurface(EGL_DISPLAY(), mSurface);
   303     mSurface = nullptr;
   304 }
   306 already_AddRefed<TextureImage>
   307 CreateTextureImageEGL(GLContext *gl,
   308                       const gfx::IntSize& aSize,
   309                       TextureImage::ContentType aContentType,
   310                       GLenum aWrapMode,
   311                       TextureImage::Flags aFlags,
   312                       TextureImage::ImageFormat aImageFormat)
   313 {
   314     nsRefPtr<TextureImage> t = new gl::TiledTextureImage(gl, aSize, aContentType, aFlags, aImageFormat);
   315     return t.forget();
   316 }
   318 already_AddRefed<TextureImage>
   319 TileGenFuncEGL(GLContext *gl,
   320                const nsIntSize& aSize,
   321                TextureImage::ContentType aContentType,
   322                TextureImage::Flags aFlags,
   323                TextureImage::ImageFormat aImageFormat)
   324 {
   325   gl->MakeCurrent();
   327   GLuint texture;
   328   gl->fGenTextures(1, &texture);
   330   nsRefPtr<TextureImageEGL> teximage =
   331       new TextureImageEGL(texture, aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType,
   332                           gl, aFlags, TextureImage::Created, aImageFormat);
   334   teximage->BindTexture(LOCAL_GL_TEXTURE0);
   336   GLint texfilter = aFlags & TextureImage::UseNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
   337   gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
   338   gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
   339   gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
   340   gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
   342   return teximage.forget();
   343 }
   345 }
   346 }

mercurial