gfx/gl/SharedSurfaceEGL.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 "SharedSurfaceEGL.h"
     7 #include "GLContextEGL.h"
     8 #include "GLBlitHelper.h"
     9 #include "ScopedGLHelpers.h"
    10 #include "SharedSurfaceGL.h"
    11 #include "SurfaceFactory.h"
    12 #include "GLLibraryEGL.h"
    13 #include "TextureGarbageBin.h"
    14 #include "GLReadTexImageHelper.h"
    16 using namespace mozilla::gfx;
    18 namespace mozilla {
    19 namespace gl {
    21 SharedSurface_EGLImage*
    22 SharedSurface_EGLImage::Create(GLContext* prodGL,
    23                                const GLFormats& formats,
    24                                const gfx::IntSize& size,
    25                                bool hasAlpha,
    26                                EGLContext context)
    27 {
    28     GLLibraryEGL* egl = &sEGLLibrary;
    29     MOZ_ASSERT(egl);
    30     MOZ_ASSERT(context);
    32     if (!HasExtensions(egl, prodGL)) {
    33         return nullptr;
    34     }
    36     MOZ_ALWAYS_TRUE(prodGL->MakeCurrent());
    37     GLuint prodTex = CreateTextureForOffscreen(prodGL, formats, size);
    38     if (!prodTex) {
    39         return nullptr;
    40     }
    42     EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(prodTex);
    43     EGLImage image = egl->fCreateImage(egl->Display(), context,
    44                                        LOCAL_EGL_GL_TEXTURE_2D, buffer,
    45                                        nullptr);
    46     if (!image) {
    47         prodGL->fDeleteTextures(1, &prodTex);
    48         return nullptr;
    49     }
    51     return new SharedSurface_EGLImage(prodGL, egl,
    52                                       size, hasAlpha,
    53                                       formats, prodTex, image);
    54 }
    57 bool
    58 SharedSurface_EGLImage::HasExtensions(GLLibraryEGL* egl, GLContext* gl)
    59 {
    60     return egl->HasKHRImageBase() &&
    61            egl->IsExtensionSupported(GLLibraryEGL::KHR_gl_texture_2D_image) &&
    62            gl->IsExtensionSupported(GLContext::OES_EGL_image_external);
    63 }
    65 SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl,
    66                                                GLLibraryEGL* egl,
    67                                                const gfx::IntSize& size,
    68                                                bool hasAlpha,
    69                                                const GLFormats& formats,
    70                                                GLuint prodTex,
    71                                                EGLImage image)
    72     : SharedSurface_GL(SharedSurfaceType::EGLImageShare,
    73                         AttachmentType::GLTexture,
    74                         gl,
    75                         size,
    76                         hasAlpha)
    77     , mMutex("SharedSurface_EGLImage mutex")
    78     , mEGL(egl)
    79     , mFormats(formats)
    80     , mProdTex(prodTex)
    81     , mImage(image)
    82     , mCurConsGL(nullptr)
    83     , mConsTex(0)
    84     , mSync(0)
    85 {}
    87 SharedSurface_EGLImage::~SharedSurface_EGLImage()
    88 {
    89     mEGL->fDestroyImage(Display(), mImage);
    90     mImage = 0;
    92     mGL->MakeCurrent();
    93     mGL->fDeleteTextures(1, &mProdTex);
    94     mProdTex = 0;
    96     if (mConsTex) {
    97         MOZ_ASSERT(mGarbageBin);
    98         mGarbageBin->Trash(mConsTex);
    99         mConsTex = 0;
   100     }
   102     if (mSync) {
   103         // We can't call this unless we have the ext, but we will always have
   104         // the ext if we have something to destroy.
   105         mEGL->fDestroySync(Display(), mSync);
   106         mSync = 0;
   107     }
   108 }
   110 void
   111 SharedSurface_EGLImage::Fence()
   112 {
   113     MutexAutoLock lock(mMutex);
   114     mGL->MakeCurrent();
   116     if (mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync) &&
   117         mGL->IsExtensionSupported(GLContext::OES_EGL_sync))
   118     {
   119         if (mSync) {
   120             MOZ_ALWAYS_TRUE( mEGL->fDestroySync(Display(), mSync) );
   121             mSync = 0;
   122         }
   124         mSync = mEGL->fCreateSync(Display(),
   125                                   LOCAL_EGL_SYNC_FENCE,
   126                                   nullptr);
   127         if (mSync) {
   128             mGL->fFlush();
   129             return;
   130         }
   131     }
   133     MOZ_ASSERT(!mSync);
   134     mGL->fFinish();
   135 }
   137 bool
   138 SharedSurface_EGLImage::WaitSync()
   139 {
   140     MutexAutoLock lock(mMutex);
   141     if (!mSync) {
   142         // We must not be needed.
   143         return true;
   144     }
   145     MOZ_ASSERT(mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync));
   147     // Wait FOREVER, primarily because some NVIDIA (at least Tegra) drivers
   148     // have ClientWaitSync returning immediately if the timeout delay is anything
   149     // else than FOREVER.
   150     //
   151     // FIXME: should we try to use a finite timeout delay where possible?
   152     EGLint status = mEGL->fClientWaitSync(Display(),
   153                                           mSync,
   154                                           0,
   155                                           LOCAL_EGL_FOREVER);
   157     if (status != LOCAL_EGL_CONDITION_SATISFIED) {
   158         return false;
   159     }
   161     MOZ_ALWAYS_TRUE( mEGL->fDestroySync(Display(), mSync) );
   162     mSync = 0;
   164     return true;
   165 }
   168 EGLDisplay
   169 SharedSurface_EGLImage::Display() const
   170 {
   171     return mEGL->Display();
   172 }
   174 void
   175 SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target)
   176 {
   177     MutexAutoLock lock(mMutex);
   178     MOZ_ASSERT(!mCurConsGL || consGL == mCurConsGL);
   180     if (!mConsTex) {
   181         consGL->fGenTextures(1, &mConsTex);
   182         MOZ_ASSERT(mConsTex);
   184         ScopedBindTexture autoTex(consGL, mConsTex, LOCAL_GL_TEXTURE_EXTERNAL);
   185         consGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_EXTERNAL, mImage);
   187         mCurConsGL = consGL;
   188         mGarbageBin = consGL->TexGarbageBin();
   189     }
   191     MOZ_ASSERT(consGL == mCurConsGL);
   192     *out_texture = mConsTex;
   193     *out_target = LOCAL_GL_TEXTURE_EXTERNAL;
   194 }
   197 SurfaceFactory_EGLImage*
   198 SurfaceFactory_EGLImage::Create(GLContext* prodGL,
   199                                         const SurfaceCaps& caps)
   200 {
   201     EGLContext context = GLContextEGL::Cast(prodGL)->GetEGLContext();
   203     GLLibraryEGL* egl = &sEGLLibrary;
   204     if (!SharedSurface_EGLImage::HasExtensions(egl, prodGL)) {
   205         return nullptr;
   206     }
   208     return new SurfaceFactory_EGLImage(prodGL, context, caps);
   209 }
   211 } /* namespace gfx */
   212 } /* namespace mozilla */

mercurial