gfx/gl/SharedSurfaceIO.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/gl/SharedSurfaceIO.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,150 @@
     1.4 +/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "SharedSurfaceIO.h"
    1.10 +#include "GLContextCGL.h"
    1.11 +#include "mozilla/gfx/MacIOSurface.h"
    1.12 +#include "mozilla/DebugOnly.h"
    1.13 +#include "ScopedGLHelpers.h"
    1.14 +
    1.15 +namespace mozilla {
    1.16 +namespace gl {
    1.17 +
    1.18 +using namespace gfx;
    1.19 +
    1.20 +/* static */ SharedSurface_IOSurface*
    1.21 +SharedSurface_IOSurface::Create(MacIOSurface* surface, GLContext *gl, bool hasAlpha)
    1.22 +{
    1.23 +    MOZ_ASSERT(surface);
    1.24 +    MOZ_ASSERT(gl);
    1.25 +
    1.26 +    gfx::IntSize size(surface->GetWidth(), surface->GetHeight());
    1.27 +    return new SharedSurface_IOSurface(surface, gl, size, hasAlpha);
    1.28 +}
    1.29 +
    1.30 +void
    1.31 +SharedSurface_IOSurface::Fence()
    1.32 +{
    1.33 +    mGL->MakeCurrent();
    1.34 +    mGL->fFlush();
    1.35 +}
    1.36 +
    1.37 +bool
    1.38 +SharedSurface_IOSurface::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
    1.39 +                                    GLenum format, GLenum type, GLvoid *pixels)
    1.40 +{
    1.41 +    // Calling glReadPixels when an IOSurface is bound to the current framebuffer
    1.42 +    // can cause corruption in following glReadPixel calls (even if they aren't
    1.43 +    // reading from an IOSurface).
    1.44 +    // We workaround this by copying to a temporary texture, and doing the readback
    1.45 +    // from that.
    1.46 +    MOZ_ASSERT(mGL->IsCurrent());
    1.47 +
    1.48 +
    1.49 +    ScopedTexture destTex(mGL);
    1.50 +    {
    1.51 +        ScopedFramebufferForTexture srcFB(mGL, ProdTexture(), ProdTextureTarget());
    1.52 +
    1.53 +        ScopedBindFramebuffer bindFB(mGL, srcFB.FB());
    1.54 +        ScopedBindTexture bindTex(mGL, destTex.Texture());
    1.55 +        mGL->fCopyTexImage2D(LOCAL_GL_TEXTURE_2D, 0,
    1.56 +                             HasAlpha() ? LOCAL_GL_RGBA : LOCAL_GL_RGB,
    1.57 +                             x, y,
    1.58 +                             width, height, 0);
    1.59 +    }
    1.60 +
    1.61 +    ScopedFramebufferForTexture destFB(mGL, destTex.Texture());
    1.62 +
    1.63 +    ScopedBindFramebuffer bindFB(mGL, destFB.FB());
    1.64 +    mGL->fReadPixels(0, 0, width, height, format, type, pixels);
    1.65 +    return true;
    1.66 +}
    1.67 +
    1.68 +static void
    1.69 +BackTextureWithIOSurf(GLContext* gl, GLuint tex, MacIOSurface* ioSurf)
    1.70 +{
    1.71 +    MOZ_ASSERT(gl->IsCurrent());
    1.72 +
    1.73 +    ScopedBindTexture texture(gl, tex, LOCAL_GL_TEXTURE_RECTANGLE_ARB);
    1.74 +
    1.75 +    gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
    1.76 +                        LOCAL_GL_TEXTURE_MIN_FILTER,
    1.77 +                        LOCAL_GL_LINEAR);
    1.78 +    gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
    1.79 +                        LOCAL_GL_TEXTURE_MAG_FILTER,
    1.80 +                        LOCAL_GL_LINEAR);
    1.81 +    gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
    1.82 +                        LOCAL_GL_TEXTURE_WRAP_S,
    1.83 +                        LOCAL_GL_CLAMP_TO_EDGE);
    1.84 +    gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
    1.85 +                        LOCAL_GL_TEXTURE_WRAP_T,
    1.86 +                        LOCAL_GL_CLAMP_TO_EDGE);
    1.87 +
    1.88 +    CGLContextObj cgl = GLContextCGL::Cast(gl)->GetCGLContext();
    1.89 +    MOZ_ASSERT(cgl);
    1.90 +
    1.91 +    ioSurf->CGLTexImageIOSurface2D(cgl);
    1.92 +}
    1.93 +
    1.94 +SharedSurface_IOSurface::SharedSurface_IOSurface(MacIOSurface* surface,
    1.95 +                                                 GLContext* gl,
    1.96 +                                                 const gfx::IntSize& size,
    1.97 +                                                 bool hasAlpha)
    1.98 +  : SharedSurface_GL(SharedSurfaceType::IOSurface, AttachmentType::GLTexture, gl, size, hasAlpha)
    1.99 +  , mSurface(surface)
   1.100 +  , mCurConsGL(nullptr)
   1.101 +  , mConsTex(0)
   1.102 +{
   1.103 +    gl->MakeCurrent();
   1.104 +    mProdTex = 0;
   1.105 +    gl->fGenTextures(1, &mProdTex);
   1.106 +    BackTextureWithIOSurf(gl, mProdTex, surface);
   1.107 +}
   1.108 +
   1.109 +GLuint
   1.110 +SharedSurface_IOSurface::ConsTexture(GLContext* consGL)
   1.111 +{
   1.112 +    if (!mCurConsGL) {
   1.113 +        mCurConsGL = consGL;
   1.114 +    }
   1.115 +    MOZ_ASSERT(consGL == mCurConsGL);
   1.116 +
   1.117 +    if (!mConsTex) {
   1.118 +        consGL->MakeCurrent();
   1.119 +        mConsTex = 0;
   1.120 +        consGL->fGenTextures(1, &mConsTex);
   1.121 +        BackTextureWithIOSurf(consGL, mConsTex, mSurface);
   1.122 +    }
   1.123 +
   1.124 +    return mConsTex;
   1.125 +}
   1.126 +
   1.127 +SharedSurface_IOSurface::~SharedSurface_IOSurface()
   1.128 +{
   1.129 +    if (mProdTex) {
   1.130 +        DebugOnly<bool> success = mGL->MakeCurrent();
   1.131 +        MOZ_ASSERT(success);
   1.132 +        mGL->fDeleteTextures(1, &mProdTex);
   1.133 +        mGL->fDeleteTextures(1, &mConsTex); // This will work if we're shared.
   1.134 +    }
   1.135 +}
   1.136 +
   1.137 +SharedSurface*
   1.138 +SurfaceFactory_IOSurface::CreateShared(const gfx::IntSize& size)
   1.139 +{
   1.140 +    bool hasAlpha = mReadCaps.alpha;
   1.141 +    RefPtr<MacIOSurface> surf =
   1.142 +        MacIOSurface::CreateIOSurface(size.width, size.height, 1.0, hasAlpha);
   1.143 +
   1.144 +    if (!surf) {
   1.145 +        NS_WARNING("Failed to create MacIOSurface.");
   1.146 +        return nullptr;
   1.147 +    }
   1.148 +
   1.149 +    return SharedSurface_IOSurface::Create(surf, mGL, hasAlpha);
   1.150 +}
   1.151 +
   1.152 +}
   1.153 +}

mercurial