gfx/gl/TextureImageCGL.mm

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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 "TextureImageCGL.h"
     7 #include "GLContext.h"
     8 #include "gfx2DGlue.h"
     9 #include "gfxQuartzSurface.h"
    10 #include "gfxPlatform.h"
    11 #include "gfxFailure.h"
    13 namespace mozilla {
    15 using namespace gfx;
    17 namespace gl {
    19 TextureImageCGL::TextureImageCGL(GLuint aTexture,
    20                 const nsIntSize& aSize,
    21                 GLenum aWrapMode,
    22                 ContentType aContentType,
    23                 GLContext* aContext,
    24                 TextureImage::Flags aFlags,
    25                 TextureImage::ImageFormat aImageFormat)
    26     : BasicTextureImage(aTexture, aSize, aWrapMode, aContentType,
    27                         aContext, aFlags, aImageFormat)
    28     , mPixelBuffer(0)
    29     , mPixelBufferSize(0)
    30     , mBoundPixelBuffer(false)
    31 {}
    33 TextureImageCGL::~TextureImageCGL()
    34 {
    35     if (mPixelBuffer) {
    36         mGLContext->MakeCurrent();
    37         mGLContext->fDeleteBuffers(1, &mPixelBuffer);
    38     }
    39 }
    41 already_AddRefed<gfxASurface>
    42 TextureImageCGL::GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt)
    43 {
    44     IntSize size(aSize.width + 1, aSize.height + 1);
    45     mGLContext->MakeCurrent();
    46     if (!mGLContext->
    47         IsExtensionSupported(GLContext::ARB_pixel_buffer_object))
    48     {
    49         return gfxPlatform::GetPlatform()->
    50             CreateOffscreenSurface(size,
    51                                     gfxASurface::ContentFromFormat(aFmt));
    52     }
    54     if (!mPixelBuffer) {
    55         mGLContext->fGenBuffers(1, &mPixelBuffer);
    56     }
    57     mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mPixelBuffer);
    58     int32_t length = size.width * 4 * size.height;
    60     if (length > mPixelBufferSize) {
    61         mGLContext->fBufferData(LOCAL_GL_PIXEL_UNPACK_BUFFER, length,
    62                                 NULL, LOCAL_GL_STREAM_DRAW);
    63         mPixelBufferSize = length;
    64     }
    65     unsigned char* data =
    66         (unsigned char*)mGLContext->
    67             fMapBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER,
    68                         LOCAL_GL_WRITE_ONLY);
    70     mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
    72     if (!data) {
    73         nsAutoCString failure;
    74         failure += "Pixel buffer binding failed: ";
    75         failure.AppendPrintf("%dx%d\n", size.width, size.height);
    76         gfx::LogFailure(failure);
    78         mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
    79         return gfxPlatform::GetPlatform()->
    80             CreateOffscreenSurface(size,
    81                                     gfxASurface::ContentFromFormat(aFmt));
    82     }
    84     nsRefPtr<gfxQuartzSurface> surf =
    85         new gfxQuartzSurface(data, ThebesIntSize(size), size.width * 4, aFmt);
    87     mBoundPixelBuffer = true;
    88     return surf.forget();
    89 }
    91 bool
    92 TextureImageCGL::FinishedSurfaceUpdate()
    93 {
    94     if (mBoundPixelBuffer) {
    95         mGLContext->MakeCurrent();
    96         mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mPixelBuffer);
    97         mGLContext->fUnmapBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER);
    98         return true;
    99     }
   100     return false;
   101 }
   103 void
   104 TextureImageCGL::FinishedSurfaceUpload()
   105 {
   106     if (mBoundPixelBuffer) {
   107         mGLContext->MakeCurrent();
   108         mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
   109         mBoundPixelBuffer = false;
   110     }
   111 }
   113 already_AddRefed<TextureImage>
   114 CreateTextureImageCGL(GLContext* gl,
   115                       const gfx::IntSize& aSize,
   116                       TextureImage::ContentType aContentType,
   117                       GLenum aWrapMode,
   118                       TextureImage::Flags aFlags,
   119                       TextureImage::ImageFormat aImageFormat)
   120 {
   121     if (!gl->IsOffscreenSizeAllowed(aSize) &&
   122         gfxPlatform::OffMainThreadCompositingEnabled()) {
   123       NS_ASSERTION(aWrapMode == LOCAL_GL_CLAMP_TO_EDGE, "Can't support wrapping with tiles!");
   124       nsRefPtr<TextureImage> t = new gl::TiledTextureImage(gl, aSize, aContentType,
   125                                                            aFlags, aImageFormat);
   126       return t.forget();
   127     }
   129     return CreateBasicTextureImage(gl, aSize, aContentType, aWrapMode,
   130                                    aFlags, aImageFormat);
   131 }
   133 already_AddRefed<TextureImage>
   134 TileGenFuncCGL(GLContext *gl,
   135                const nsIntSize& aSize,
   136                TextureImage::ContentType aContentType,
   137                TextureImage::Flags aFlags,
   138                TextureImage::ImageFormat aImageFormat)
   139 {
   140     bool useNearestFilter = aFlags & TextureImage::UseNearestFilter;
   141     gl->MakeCurrent();
   143     GLuint texture;
   144     gl->fGenTextures(1, &texture);
   146     gl->fActiveTexture(LOCAL_GL_TEXTURE0);
   147     gl->fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
   149     GLint texfilter = useNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
   150     gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
   151     gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
   152     gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
   153     gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
   155     nsRefPtr<TextureImageCGL> teximage
   156         (new TextureImageCGL(texture, aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType,
   157                              gl, aFlags, aImageFormat));
   158     return teximage.forget();
   159 }
   161 }
   162 }

mercurial