LCOV - code coverage report
Current view: top level - gfx/gl - SharedSurfaceEGL.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 72 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       5             : 
       6             : #include "SharedSurfaceEGL.h"
       7             : 
       8             : #include "GLBlitHelper.h"
       9             : #include "GLContextEGL.h"
      10             : #include "GLContextProvider.h"
      11             : #include "GLLibraryEGL.h"
      12             : #include "GLReadTexImageHelper.h"
      13             : #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
      14             : #include "SharedSurface.h"
      15             : 
      16             : namespace mozilla {
      17             : namespace gl {
      18             : 
      19             : /*static*/ UniquePtr<SharedSurface_EGLImage>
      20           0 : SharedSurface_EGLImage::Create(GLContext* prodGL,
      21             :                                const GLFormats& formats,
      22             :                                const gfx::IntSize& size,
      23             :                                bool hasAlpha,
      24             :                                EGLContext context)
      25             : {
      26           0 :     GLLibraryEGL* egl = &sEGLLibrary;
      27           0 :     MOZ_ASSERT(egl);
      28           0 :     MOZ_ASSERT(context);
      29             : 
      30           0 :     UniquePtr<SharedSurface_EGLImage> ret;
      31             : 
      32           0 :     if (!HasExtensions(egl, prodGL)) {
      33           0 :         return Move(ret);
      34             :     }
      35             : 
      36           0 :     MOZ_ALWAYS_TRUE(prodGL->MakeCurrent());
      37           0 :     GLuint prodTex = CreateTextureForOffscreen(prodGL, formats, size);
      38           0 :     if (!prodTex) {
      39           0 :         return Move(ret);
      40             :     }
      41             : 
      42           0 :     EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(uintptr_t(prodTex));
      43           0 :     EGLImage image = egl->fCreateImage(egl->Display(), context,
      44             :                                        LOCAL_EGL_GL_TEXTURE_2D, buffer,
      45           0 :                                        nullptr);
      46           0 :     if (!image) {
      47           0 :         prodGL->fDeleteTextures(1, &prodTex);
      48           0 :         return Move(ret);
      49             :     }
      50             : 
      51             :     ret.reset( new SharedSurface_EGLImage(prodGL, egl, size, hasAlpha,
      52           0 :                                           formats, prodTex, image) );
      53           0 :     return Move(ret);
      54             : }
      55             : 
      56             : bool
      57           0 : SharedSurface_EGLImage::HasExtensions(GLLibraryEGL* egl, GLContext* gl)
      58             : {
      59           0 :     return egl->HasKHRImageBase() &&
      60           0 :            egl->IsExtensionSupported(GLLibraryEGL::KHR_gl_texture_2D_image) &&
      61           0 :            (gl->IsExtensionSupported(GLContext::OES_EGL_image_external) ||
      62           0 :             gl->IsExtensionSupported(GLContext::OES_EGL_image));
      63             : }
      64             : 
      65           0 : 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           0 :                                                EGLImage image)
      72             :     : SharedSurface(SharedSurfaceType::EGLImageShare,
      73             :                     AttachmentType::GLTexture,
      74             :                     gl,
      75             :                     size,
      76             :                     hasAlpha,
      77             :                     false) // Can't recycle, as mSync changes never update TextureHost.
      78             :     , mMutex("SharedSurface_EGLImage mutex")
      79             :     , mEGL(egl)
      80             :     , mFormats(formats)
      81             :     , mProdTex(prodTex)
      82             :     , mImage(image)
      83           0 :     , mSync(0)
      84           0 : {}
      85             : 
      86           0 : SharedSurface_EGLImage::~SharedSurface_EGLImage()
      87             : {
      88           0 :     mEGL->fDestroyImage(Display(), mImage);
      89             : 
      90           0 :     if (mSync) {
      91             :         // We can't call this unless we have the ext, but we will always have
      92             :         // the ext if we have something to destroy.
      93           0 :         mEGL->fDestroySync(Display(), mSync);
      94           0 :         mSync = 0;
      95             :     }
      96             : 
      97           0 :     if (!mGL || !mGL->MakeCurrent())
      98           0 :         return;
      99             : 
     100           0 :     mGL->fDeleteTextures(1, &mProdTex);
     101           0 :     mProdTex = 0;
     102           0 : }
     103             : 
     104             : void
     105           0 : SharedSurface_EGLImage::ProducerReleaseImpl()
     106             : {
     107           0 :     MutexAutoLock lock(mMutex);
     108           0 :     mGL->MakeCurrent();
     109             : 
     110           0 :     if (mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync) &&
     111           0 :         mGL->IsExtensionSupported(GLContext::OES_EGL_sync))
     112             :     {
     113           0 :         if (mSync) {
     114           0 :             MOZ_RELEASE_ASSERT(false, "GFX: Non-recycleable should not Fence twice.");
     115             :             MOZ_ALWAYS_TRUE( mEGL->fDestroySync(Display(), mSync) );
     116             :             mSync = 0;
     117             :         }
     118             : 
     119           0 :         mSync = mEGL->fCreateSync(Display(),
     120             :                                   LOCAL_EGL_SYNC_FENCE,
     121             :                                   nullptr);
     122           0 :         if (mSync) {
     123           0 :             mGL->fFlush();
     124           0 :             return;
     125             :         }
     126             :     }
     127             : 
     128           0 :     MOZ_ASSERT(!mSync);
     129           0 :     mGL->fFinish();
     130             : }
     131             : 
     132             : void
     133           0 : SharedSurface_EGLImage::ProducerReadAcquireImpl()
     134             : {
     135             :     // Wait on the fence, because presumably we're going to want to read this surface
     136           0 :     if (mSync) {
     137           0 :         mEGL->fClientWaitSync(Display(), mSync, 0, LOCAL_EGL_FOREVER);
     138             :     }
     139           0 : }
     140             : 
     141             : EGLDisplay
     142           0 : SharedSurface_EGLImage::Display() const
     143             : {
     144           0 :     return mEGL->Display();
     145             : }
     146             : 
     147             : bool
     148           0 : SharedSurface_EGLImage::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
     149             : {
     150           0 :     *out_descriptor = layers::EGLImageDescriptor((uintptr_t)mImage, (uintptr_t)mSync,
     151           0 :                                                  mSize, mHasAlpha);
     152           0 :     return true;
     153             : }
     154             : 
     155             : bool
     156           0 : SharedSurface_EGLImage::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface)
     157             : {
     158           0 :     MOZ_ASSERT(out_surface);
     159           0 :     MOZ_ASSERT(NS_IsMainThread());
     160           0 :     return sEGLLibrary.ReadbackEGLImage(mImage, out_surface);
     161             : }
     162             : 
     163             : ////////////////////////////////////////////////////////////////////////
     164             : 
     165             : /*static*/ UniquePtr<SurfaceFactory_EGLImage>
     166           0 : SurfaceFactory_EGLImage::Create(GLContext* prodGL, const SurfaceCaps& caps,
     167             :                                 const RefPtr<layers::LayersIPCChannel>& allocator,
     168             :                                 const layers::TextureFlags& flags)
     169             : {
     170           0 :     EGLContext context = GLContextEGL::Cast(prodGL)->mContext;
     171             : 
     172             :     typedef SurfaceFactory_EGLImage ptrT;
     173           0 :     UniquePtr<ptrT> ret;
     174             : 
     175           0 :     GLLibraryEGL* egl = &sEGLLibrary;
     176           0 :     if (SharedSurface_EGLImage::HasExtensions(egl, prodGL)) {
     177           0 :         ret.reset( new ptrT(prodGL, caps, allocator, flags, context) );
     178             :     }
     179             : 
     180           0 :     return Move(ret);
     181             : }
     182             : 
     183             : ////////////////////////////////////////////////////////////////////////
     184             : 
     185             : #ifdef MOZ_WIDGET_ANDROID
     186             : 
     187             : /*static*/ UniquePtr<SharedSurface_SurfaceTexture>
     188             : SharedSurface_SurfaceTexture::Create(GLContext* prodGL,
     189             :                                      const GLFormats& formats,
     190             :                                      const gfx::IntSize& size,
     191             :                                      bool hasAlpha,
     192             :                                      java::GeckoSurface::Param surface)
     193             : {
     194             :     MOZ_ASSERT(surface);
     195             : 
     196             :     UniquePtr<SharedSurface_SurfaceTexture> ret;
     197             : 
     198             :     AndroidNativeWindow window(surface);
     199             :     EGLSurface eglSurface = GLContextProviderEGL::CreateEGLSurface(window.NativeWindow());
     200             :     if (!eglSurface) {
     201             :         return Move(ret);
     202             :     }
     203             : 
     204             :     ret.reset(new SharedSurface_SurfaceTexture(prodGL, size, hasAlpha,
     205             :                                                formats, surface, eglSurface));
     206             :     return Move(ret);
     207             : }
     208             : 
     209             : SharedSurface_SurfaceTexture::SharedSurface_SurfaceTexture(GLContext* gl,
     210             :                                                            const gfx::IntSize& size,
     211             :                                                            bool hasAlpha,
     212             :                                                            const GLFormats& formats,
     213             :                                                            java::GeckoSurface::Param surface,
     214             :                                                            EGLSurface eglSurface)
     215             :     : SharedSurface(SharedSurfaceType::AndroidSurfaceTexture,
     216             :                     AttachmentType::Screen,
     217             :                     gl,
     218             :                     size,
     219             :                     hasAlpha,
     220             :                     true)
     221             :     , mSurface(surface)
     222             :     , mEglSurface(eglSurface)
     223             : {
     224             : }
     225             : 
     226             : SharedSurface_SurfaceTexture::~SharedSurface_SurfaceTexture()
     227             : {
     228             :     GLContextProviderEGL::DestroyEGLSurface(mEglSurface);
     229             :     java::SurfaceAllocator::DisposeSurface(mSurface);
     230             : }
     231             : 
     232             : void
     233             : SharedSurface_SurfaceTexture::LockProdImpl()
     234             : {
     235             :     MOZ_RELEASE_ASSERT(mSurface->GetAvailable());
     236             : 
     237             :     GLContextEGL *gl = GLContextEGL::Cast(mGL);
     238             :     mOrigEglSurface = gl->GetEGLSurfaceOverride();
     239             :     gl->SetEGLSurfaceOverride(mEglSurface);
     240             : }
     241             : 
     242             : void
     243             : SharedSurface_SurfaceTexture::UnlockProdImpl()
     244             : {
     245             :     MOZ_RELEASE_ASSERT(mSurface->GetAvailable());
     246             : 
     247             :     GLContextEGL *gl = GLContextEGL::Cast(mGL);
     248             :     MOZ_ASSERT(gl->GetEGLSurfaceOverride() == mEglSurface);
     249             : 
     250             :     gl->SetEGLSurfaceOverride(mOrigEglSurface);
     251             :     mOrigEglSurface = nullptr;
     252             : }
     253             : 
     254             : void
     255             : SharedSurface_SurfaceTexture::Commit()
     256             : {
     257             :     MOZ_RELEASE_ASSERT(mSurface->GetAvailable());
     258             : 
     259             :     LockProdImpl();
     260             :     mGL->SwapBuffers();
     261             :     UnlockProdImpl();
     262             :     mSurface->SetAvailable(false);
     263             : }
     264             : 
     265             : void
     266             : SharedSurface_SurfaceTexture::WaitForBufferOwnership()
     267             : {
     268             :     MOZ_RELEASE_ASSERT(!mSurface->GetAvailable());
     269             :     mSurface->SetAvailable(true);
     270             : }
     271             : 
     272             : bool
     273             : SharedSurface_SurfaceTexture::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
     274             : {
     275             :     *out_descriptor = layers::SurfaceTextureDescriptor(mSurface->GetHandle(), mSize, false /* NOT continuous */);
     276             :     return true;
     277             : }
     278             : 
     279             : ////////////////////////////////////////////////////////////////////////
     280             : 
     281             : /*static*/ UniquePtr<SurfaceFactory_SurfaceTexture>
     282             : SurfaceFactory_SurfaceTexture::Create(GLContext* prodGL, const SurfaceCaps& caps,
     283             :                                       const RefPtr<layers::LayersIPCChannel>& allocator,
     284             :                                       const layers::TextureFlags& flags)
     285             : {
     286             :     UniquePtr<SurfaceFactory_SurfaceTexture> ret(
     287             :         new SurfaceFactory_SurfaceTexture(prodGL, caps, allocator, flags));
     288             :     return Move(ret);
     289             : }
     290             : 
     291             : UniquePtr<SharedSurface>
     292             : SurfaceFactory_SurfaceTexture::CreateShared(const gfx::IntSize& size)
     293             : {
     294             :     bool hasAlpha = mReadCaps.alpha;
     295             : 
     296             :     jni::Object::LocalRef surface = java::SurfaceAllocator::AcquireSurface(size.width, size.height, true);
     297             :     if (!surface) {
     298             :         // Try multi-buffer mode
     299             :         surface = java::SurfaceAllocator::AcquireSurface(size.width, size.height, false);
     300             :         if (!surface) {
     301             :             // Give up
     302             :             NS_WARNING("Failed to allocate SurfaceTexture!");
     303             :             return nullptr;
     304             :         }
     305             :     }
     306             : 
     307             :     return SharedSurface_SurfaceTexture::Create(mGL, mFormats, size, hasAlpha,
     308             :                                                 java::GeckoSurface::Ref::From(surface));
     309             : }
     310             : 
     311             : #endif // MOZ_WIDGET_ANDROID
     312             : 
     313             : } // namespace gl
     314             : 
     315             : } /* namespace mozilla */

Generated by: LCOV version 1.13