gfx/gl/SharedSurfaceIO.cpp

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++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
     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 "SharedSurfaceIO.h"
     7 #include "GLContextCGL.h"
     8 #include "mozilla/gfx/MacIOSurface.h"
     9 #include "mozilla/DebugOnly.h"
    10 #include "ScopedGLHelpers.h"
    12 namespace mozilla {
    13 namespace gl {
    15 using namespace gfx;
    17 /* static */ SharedSurface_IOSurface*
    18 SharedSurface_IOSurface::Create(MacIOSurface* surface, GLContext *gl, bool hasAlpha)
    19 {
    20     MOZ_ASSERT(surface);
    21     MOZ_ASSERT(gl);
    23     gfx::IntSize size(surface->GetWidth(), surface->GetHeight());
    24     return new SharedSurface_IOSurface(surface, gl, size, hasAlpha);
    25 }
    27 void
    28 SharedSurface_IOSurface::Fence()
    29 {
    30     mGL->MakeCurrent();
    31     mGL->fFlush();
    32 }
    34 bool
    35 SharedSurface_IOSurface::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
    36                                     GLenum format, GLenum type, GLvoid *pixels)
    37 {
    38     // Calling glReadPixels when an IOSurface is bound to the current framebuffer
    39     // can cause corruption in following glReadPixel calls (even if they aren't
    40     // reading from an IOSurface).
    41     // We workaround this by copying to a temporary texture, and doing the readback
    42     // from that.
    43     MOZ_ASSERT(mGL->IsCurrent());
    46     ScopedTexture destTex(mGL);
    47     {
    48         ScopedFramebufferForTexture srcFB(mGL, ProdTexture(), ProdTextureTarget());
    50         ScopedBindFramebuffer bindFB(mGL, srcFB.FB());
    51         ScopedBindTexture bindTex(mGL, destTex.Texture());
    52         mGL->fCopyTexImage2D(LOCAL_GL_TEXTURE_2D, 0,
    53                              HasAlpha() ? LOCAL_GL_RGBA : LOCAL_GL_RGB,
    54                              x, y,
    55                              width, height, 0);
    56     }
    58     ScopedFramebufferForTexture destFB(mGL, destTex.Texture());
    60     ScopedBindFramebuffer bindFB(mGL, destFB.FB());
    61     mGL->fReadPixels(0, 0, width, height, format, type, pixels);
    62     return true;
    63 }
    65 static void
    66 BackTextureWithIOSurf(GLContext* gl, GLuint tex, MacIOSurface* ioSurf)
    67 {
    68     MOZ_ASSERT(gl->IsCurrent());
    70     ScopedBindTexture texture(gl, tex, LOCAL_GL_TEXTURE_RECTANGLE_ARB);
    72     gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
    73                         LOCAL_GL_TEXTURE_MIN_FILTER,
    74                         LOCAL_GL_LINEAR);
    75     gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
    76                         LOCAL_GL_TEXTURE_MAG_FILTER,
    77                         LOCAL_GL_LINEAR);
    78     gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
    79                         LOCAL_GL_TEXTURE_WRAP_S,
    80                         LOCAL_GL_CLAMP_TO_EDGE);
    81     gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
    82                         LOCAL_GL_TEXTURE_WRAP_T,
    83                         LOCAL_GL_CLAMP_TO_EDGE);
    85     CGLContextObj cgl = GLContextCGL::Cast(gl)->GetCGLContext();
    86     MOZ_ASSERT(cgl);
    88     ioSurf->CGLTexImageIOSurface2D(cgl);
    89 }
    91 SharedSurface_IOSurface::SharedSurface_IOSurface(MacIOSurface* surface,
    92                                                  GLContext* gl,
    93                                                  const gfx::IntSize& size,
    94                                                  bool hasAlpha)
    95   : SharedSurface_GL(SharedSurfaceType::IOSurface, AttachmentType::GLTexture, gl, size, hasAlpha)
    96   , mSurface(surface)
    97   , mCurConsGL(nullptr)
    98   , mConsTex(0)
    99 {
   100     gl->MakeCurrent();
   101     mProdTex = 0;
   102     gl->fGenTextures(1, &mProdTex);
   103     BackTextureWithIOSurf(gl, mProdTex, surface);
   104 }
   106 GLuint
   107 SharedSurface_IOSurface::ConsTexture(GLContext* consGL)
   108 {
   109     if (!mCurConsGL) {
   110         mCurConsGL = consGL;
   111     }
   112     MOZ_ASSERT(consGL == mCurConsGL);
   114     if (!mConsTex) {
   115         consGL->MakeCurrent();
   116         mConsTex = 0;
   117         consGL->fGenTextures(1, &mConsTex);
   118         BackTextureWithIOSurf(consGL, mConsTex, mSurface);
   119     }
   121     return mConsTex;
   122 }
   124 SharedSurface_IOSurface::~SharedSurface_IOSurface()
   125 {
   126     if (mProdTex) {
   127         DebugOnly<bool> success = mGL->MakeCurrent();
   128         MOZ_ASSERT(success);
   129         mGL->fDeleteTextures(1, &mProdTex);
   130         mGL->fDeleteTextures(1, &mConsTex); // This will work if we're shared.
   131     }
   132 }
   134 SharedSurface*
   135 SurfaceFactory_IOSurface::CreateShared(const gfx::IntSize& size)
   136 {
   137     bool hasAlpha = mReadCaps.alpha;
   138     RefPtr<MacIOSurface> surf =
   139         MacIOSurface::CreateIOSurface(size.width, size.height, 1.0, hasAlpha);
   141     if (!surf) {
   142         NS_WARNING("Failed to create MacIOSurface.");
   143         return nullptr;
   144     }
   146     return SharedSurface_IOSurface::Create(surf, mGL, hasAlpha);
   147 }
   149 }
   150 }

mercurial