Loading gfx/gl/ScopedGLHelpers.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -124,7 +124,6 @@ ScopedBindTexture::Init(GLenum aTarget) GLenum bindingTarget = (aTarget == LOCAL_GL_TEXTURE_2D) ? LOCAL_GL_TEXTURE_BINDING_2D : (aTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) ? LOCAL_GL_TEXTURE_BINDING_RECTANGLE_ARB : (aTarget == LOCAL_GL_TEXTURE_CUBE_MAP) ? LOCAL_GL_TEXTURE_BINDING_CUBE_MAP : (aTarget == LOCAL_GL_TEXTURE_EXTERNAL) ? LOCAL_GL_TEXTURE_EXTERNAL : LOCAL_GL_NONE; MOZ_ASSERT(bindingTarget != LOCAL_GL_NONE); mGL->GetUIntegerv(bindingTarget, &mOldTex); Loading gfx/gl/SharedSurfaceEGL.cpp +119 −27 Original line number Diff line number Diff line Loading @@ -27,30 +27,18 @@ SharedSurface_EGLImage::Create(GLContext* prodGL, { GLLibraryEGL* egl = &sEGLLibrary; MOZ_ASSERT(egl); MOZ_ASSERT(context); if (!HasExtensions(egl, prodGL)) { if (!HasExtensions(egl, prodGL)) return nullptr; } MOZ_ALWAYS_TRUE(prodGL->MakeCurrent()); GLuint prodTex = CreateTextureForOffscreen(prodGL, formats, size); if (!prodTex) { return nullptr; } EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(prodTex); EGLImage image = egl->fCreateImage(egl->Display(), context, LOCAL_EGL_GL_TEXTURE_2D, buffer, nullptr); if (!image) { prodGL->fDeleteTextures(1, &prodTex); if (!prodTex) return nullptr; } return new SharedSurface_EGLImage(prodGL, egl, size, hasAlpha, formats, prodTex, image); formats, prodTex); } Loading @@ -59,7 +47,7 @@ SharedSurface_EGLImage::HasExtensions(GLLibraryEGL* egl, GLContext* gl) { return egl->HasKHRImageBase() && egl->IsExtensionSupported(GLLibraryEGL::KHR_gl_texture_2D_image) && gl->IsExtensionSupported(GLContext::OES_EGL_image_external); gl->IsExtensionSupported(GLContext::OES_EGL_image); } SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl, Loading @@ -67,8 +55,7 @@ SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl, const gfx::IntSize& size, bool hasAlpha, const GLFormats& formats, GLuint prodTex, EGLImage image) GLuint prodTex) : SharedSurface_GL(SharedSurfaceType::EGLImageShare, AttachmentType::GLTexture, gl, Loading @@ -78,10 +65,14 @@ SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl, , mEGL(egl) , mFormats(formats) , mProdTex(prodTex) , mImage(image) , mProdTexForPipe(0) , mImage(0) , mCurConsGL(nullptr) , mConsTex(0) , mSync(0) , mPipeFailed(false) , mPipeComplete(false) , mPipeActive(false) {} SharedSurface_EGLImage::~SharedSurface_EGLImage() Loading @@ -93,6 +84,11 @@ SharedSurface_EGLImage::~SharedSurface_EGLImage() mGL->fDeleteTextures(1, &mProdTex); mProdTex = 0; if (mProdTexForPipe) { mGL->fDeleteTextures(1, &mProdTexForPipe); mProdTexForPipe = 0; } if (mConsTex) { MOZ_ASSERT(mGarbageBin); mGarbageBin->Trash(mConsTex); Loading @@ -107,12 +103,94 @@ SharedSurface_EGLImage::~SharedSurface_EGLImage() } } void SharedSurface_EGLImage::LockProdImpl() { MutexAutoLock lock(mMutex); if (!mPipeComplete) return; if (mPipeActive) return; mGL->BlitHelper()->BlitTextureToTexture(mProdTex, mProdTexForPipe, Size(), Size()); mGL->fDeleteTextures(1, &mProdTex); mProdTex = mProdTexForPipe; mProdTexForPipe = 0; mPipeActive = true; } static bool CreateTexturePipe(GLLibraryEGL* const egl, GLContext* const gl, const GLFormats& formats, const gfx::IntSize& size, GLuint* const out_tex, EGLImage* const out_image) { MOZ_ASSERT(out_tex && out_image); *out_tex = 0; *out_image = 0; GLuint tex = CreateTextureForOffscreen(gl, formats, size); if (!tex) return false; EGLContext context = GLContextEGL::Cast(gl)->GetEGLContext(); MOZ_ASSERT(context); EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(tex); EGLImage image = egl->fCreateImage(egl->Display(), context, LOCAL_EGL_GL_TEXTURE_2D, buffer, nullptr); if (!image) { gl->fDeleteTextures(1, &tex); return false; } // Success. *out_tex = tex; *out_image = image; return true; } void SharedSurface_EGLImage::Fence() { MutexAutoLock lock(mMutex); mGL->MakeCurrent(); if (!mPipeActive) { MOZ_ASSERT(!mSync); MOZ_ASSERT(!mPipeComplete); if (!mPipeFailed) { if (!CreateTexturePipe(mEGL, mGL, mFormats, Size(), &mProdTexForPipe, &mImage)) { mPipeFailed = true; } } if (!mPixels) { SurfaceFormat format = HasAlpha() ? SurfaceFormat::B8G8R8A8 : SurfaceFormat::B8G8R8X8; mPixels = Factory::CreateDataSourceSurface(Size(), format); } DataSourceSurface::MappedSurface map; mPixels->Map(DataSourceSurface::MapType::WRITE, &map); nsRefPtr<gfxImageSurface> wrappedData = new gfxImageSurface(map.mData, ThebesIntSize(mPixels->GetSize()), map.mStride, SurfaceFormatToImageFormat(mPixels->GetFormat())); ReadScreenIntoImageSurface(mGL, wrappedData); mPixels->Unmap(); return; } MOZ_ASSERT(mPipeActive); MOZ_ASSERT(mCurConsGL); if (mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync) && mGL->IsExtensionSupported(GLContext::OES_EGL_sync)) { Loading Loading @@ -171,28 +249,42 @@ SharedSurface_EGLImage::Display() const return mEGL->Display(); } void SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target) GLuint SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL) { MutexAutoLock lock(mMutex); MOZ_ASSERT(!mCurConsGL || consGL == mCurConsGL); if (mPipeFailed) return 0; if (!mConsTex) { consGL->fGenTextures(1, &mConsTex); if (mPipeActive) { MOZ_ASSERT(mConsTex); ScopedBindTexture autoTex(consGL, mConsTex, LOCAL_GL_TEXTURE_EXTERNAL); consGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_EXTERNAL, mImage); return mConsTex; } if (!mConsTex) { consGL->fGenTextures(1, &mConsTex); ScopedBindTexture autoTex(consGL, mConsTex); consGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, mImage); mPipeComplete = true; mCurConsGL = consGL; mGarbageBin = consGL->TexGarbageBin(); } MOZ_ASSERT(consGL == mCurConsGL); *out_texture = mConsTex; *out_target = LOCAL_GL_TEXTURE_EXTERNAL; return 0; } DataSourceSurface* SharedSurface_EGLImage::GetPixels() const { MutexAutoLock lock(mMutex); return mPixels; } SurfaceFactory_EGLImage* SurfaceFactory_EGLImage::Create(GLContext* prodGL, Loading gfx/gl/SharedSurfaceEGL.h +12 −5 Original line number Diff line number Diff line Loading @@ -40,19 +40,23 @@ protected: GLLibraryEGL* const mEGL; const GLFormats mFormats; GLuint mProdTex; RefPtr<gfx::DataSourceSurface> mPixels; GLuint mProdTexForPipe; // Moves to mProdTex when mPipeActive becomes true. EGLImage mImage; GLContext* mCurConsGL; GLuint mConsTex; nsRefPtr<TextureGarbageBin> mGarbageBin; EGLSync mSync; bool mPipeFailed; // Pipe creation failed, and has been abandoned. bool mPipeComplete; // Pipe connects (mPipeActive ? mProdTex : mProdTexForPipe) to mConsTex. bool mPipeActive; // Pipe is complete and in use for production. SharedSurface_EGLImage(GLContext* gl, GLLibraryEGL* egl, const gfx::IntSize& size, bool hasAlpha, const GLFormats& formats, GLuint prodTex, EGLImage image); GLuint prodTex); EGLDisplay Display() const; Loading @@ -61,7 +65,7 @@ protected: public: virtual ~SharedSurface_EGLImage(); virtual void LockProdImpl() {} virtual void LockProdImpl(); virtual void UnlockProdImpl() {} Loading @@ -74,8 +78,11 @@ public: } // Implementation-specific functions below: // Returns texture and target void AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target); // Returns 0 if the pipe isn't ready. If 0, use GetPixels below. GLuint AcquireConsumerTexture(GLContext* consGL); // Will be void if AcquireConsumerTexture returns non-zero. gfx::DataSourceSurface* GetPixels() const; }; Loading gfx/layers/opengl/TextureHostOGL.cpp +9 −4 Original line number Diff line number Diff line Loading @@ -515,10 +515,15 @@ StreamTextureSourceOGL::RetrieveTextureFromStream() SharedSurface_EGLImage* eglImageSurf = SharedSurface_EGLImage::Cast(sharedSurf); eglImageSurf->AcquireConsumerTexture(gl(), &mTextureHandle, &mTextureTarget); MOZ_ASSERT(mTextureHandle); mTextureHandle = eglImageSurf->AcquireConsumerTexture(gl()); mTextureTarget = eglImageSurf->TextureTarget(); if (!mTextureHandle) { toUpload = eglImageSurf->GetPixels(); MOZ_ASSERT(toUpload); } else { mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8; } break; } #ifdef XP_MACOSX Loading Loading
gfx/gl/ScopedGLHelpers.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -124,7 +124,6 @@ ScopedBindTexture::Init(GLenum aTarget) GLenum bindingTarget = (aTarget == LOCAL_GL_TEXTURE_2D) ? LOCAL_GL_TEXTURE_BINDING_2D : (aTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) ? LOCAL_GL_TEXTURE_BINDING_RECTANGLE_ARB : (aTarget == LOCAL_GL_TEXTURE_CUBE_MAP) ? LOCAL_GL_TEXTURE_BINDING_CUBE_MAP : (aTarget == LOCAL_GL_TEXTURE_EXTERNAL) ? LOCAL_GL_TEXTURE_EXTERNAL : LOCAL_GL_NONE; MOZ_ASSERT(bindingTarget != LOCAL_GL_NONE); mGL->GetUIntegerv(bindingTarget, &mOldTex); Loading
gfx/gl/SharedSurfaceEGL.cpp +119 −27 Original line number Diff line number Diff line Loading @@ -27,30 +27,18 @@ SharedSurface_EGLImage::Create(GLContext* prodGL, { GLLibraryEGL* egl = &sEGLLibrary; MOZ_ASSERT(egl); MOZ_ASSERT(context); if (!HasExtensions(egl, prodGL)) { if (!HasExtensions(egl, prodGL)) return nullptr; } MOZ_ALWAYS_TRUE(prodGL->MakeCurrent()); GLuint prodTex = CreateTextureForOffscreen(prodGL, formats, size); if (!prodTex) { return nullptr; } EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(prodTex); EGLImage image = egl->fCreateImage(egl->Display(), context, LOCAL_EGL_GL_TEXTURE_2D, buffer, nullptr); if (!image) { prodGL->fDeleteTextures(1, &prodTex); if (!prodTex) return nullptr; } return new SharedSurface_EGLImage(prodGL, egl, size, hasAlpha, formats, prodTex, image); formats, prodTex); } Loading @@ -59,7 +47,7 @@ SharedSurface_EGLImage::HasExtensions(GLLibraryEGL* egl, GLContext* gl) { return egl->HasKHRImageBase() && egl->IsExtensionSupported(GLLibraryEGL::KHR_gl_texture_2D_image) && gl->IsExtensionSupported(GLContext::OES_EGL_image_external); gl->IsExtensionSupported(GLContext::OES_EGL_image); } SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl, Loading @@ -67,8 +55,7 @@ SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl, const gfx::IntSize& size, bool hasAlpha, const GLFormats& formats, GLuint prodTex, EGLImage image) GLuint prodTex) : SharedSurface_GL(SharedSurfaceType::EGLImageShare, AttachmentType::GLTexture, gl, Loading @@ -78,10 +65,14 @@ SharedSurface_EGLImage::SharedSurface_EGLImage(GLContext* gl, , mEGL(egl) , mFormats(formats) , mProdTex(prodTex) , mImage(image) , mProdTexForPipe(0) , mImage(0) , mCurConsGL(nullptr) , mConsTex(0) , mSync(0) , mPipeFailed(false) , mPipeComplete(false) , mPipeActive(false) {} SharedSurface_EGLImage::~SharedSurface_EGLImage() Loading @@ -93,6 +84,11 @@ SharedSurface_EGLImage::~SharedSurface_EGLImage() mGL->fDeleteTextures(1, &mProdTex); mProdTex = 0; if (mProdTexForPipe) { mGL->fDeleteTextures(1, &mProdTexForPipe); mProdTexForPipe = 0; } if (mConsTex) { MOZ_ASSERT(mGarbageBin); mGarbageBin->Trash(mConsTex); Loading @@ -107,12 +103,94 @@ SharedSurface_EGLImage::~SharedSurface_EGLImage() } } void SharedSurface_EGLImage::LockProdImpl() { MutexAutoLock lock(mMutex); if (!mPipeComplete) return; if (mPipeActive) return; mGL->BlitHelper()->BlitTextureToTexture(mProdTex, mProdTexForPipe, Size(), Size()); mGL->fDeleteTextures(1, &mProdTex); mProdTex = mProdTexForPipe; mProdTexForPipe = 0; mPipeActive = true; } static bool CreateTexturePipe(GLLibraryEGL* const egl, GLContext* const gl, const GLFormats& formats, const gfx::IntSize& size, GLuint* const out_tex, EGLImage* const out_image) { MOZ_ASSERT(out_tex && out_image); *out_tex = 0; *out_image = 0; GLuint tex = CreateTextureForOffscreen(gl, formats, size); if (!tex) return false; EGLContext context = GLContextEGL::Cast(gl)->GetEGLContext(); MOZ_ASSERT(context); EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(tex); EGLImage image = egl->fCreateImage(egl->Display(), context, LOCAL_EGL_GL_TEXTURE_2D, buffer, nullptr); if (!image) { gl->fDeleteTextures(1, &tex); return false; } // Success. *out_tex = tex; *out_image = image; return true; } void SharedSurface_EGLImage::Fence() { MutexAutoLock lock(mMutex); mGL->MakeCurrent(); if (!mPipeActive) { MOZ_ASSERT(!mSync); MOZ_ASSERT(!mPipeComplete); if (!mPipeFailed) { if (!CreateTexturePipe(mEGL, mGL, mFormats, Size(), &mProdTexForPipe, &mImage)) { mPipeFailed = true; } } if (!mPixels) { SurfaceFormat format = HasAlpha() ? SurfaceFormat::B8G8R8A8 : SurfaceFormat::B8G8R8X8; mPixels = Factory::CreateDataSourceSurface(Size(), format); } DataSourceSurface::MappedSurface map; mPixels->Map(DataSourceSurface::MapType::WRITE, &map); nsRefPtr<gfxImageSurface> wrappedData = new gfxImageSurface(map.mData, ThebesIntSize(mPixels->GetSize()), map.mStride, SurfaceFormatToImageFormat(mPixels->GetFormat())); ReadScreenIntoImageSurface(mGL, wrappedData); mPixels->Unmap(); return; } MOZ_ASSERT(mPipeActive); MOZ_ASSERT(mCurConsGL); if (mEGL->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync) && mGL->IsExtensionSupported(GLContext::OES_EGL_sync)) { Loading Loading @@ -171,28 +249,42 @@ SharedSurface_EGLImage::Display() const return mEGL->Display(); } void SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target) GLuint SharedSurface_EGLImage::AcquireConsumerTexture(GLContext* consGL) { MutexAutoLock lock(mMutex); MOZ_ASSERT(!mCurConsGL || consGL == mCurConsGL); if (mPipeFailed) return 0; if (!mConsTex) { consGL->fGenTextures(1, &mConsTex); if (mPipeActive) { MOZ_ASSERT(mConsTex); ScopedBindTexture autoTex(consGL, mConsTex, LOCAL_GL_TEXTURE_EXTERNAL); consGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_EXTERNAL, mImage); return mConsTex; } if (!mConsTex) { consGL->fGenTextures(1, &mConsTex); ScopedBindTexture autoTex(consGL, mConsTex); consGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, mImage); mPipeComplete = true; mCurConsGL = consGL; mGarbageBin = consGL->TexGarbageBin(); } MOZ_ASSERT(consGL == mCurConsGL); *out_texture = mConsTex; *out_target = LOCAL_GL_TEXTURE_EXTERNAL; return 0; } DataSourceSurface* SharedSurface_EGLImage::GetPixels() const { MutexAutoLock lock(mMutex); return mPixels; } SurfaceFactory_EGLImage* SurfaceFactory_EGLImage::Create(GLContext* prodGL, Loading
gfx/gl/SharedSurfaceEGL.h +12 −5 Original line number Diff line number Diff line Loading @@ -40,19 +40,23 @@ protected: GLLibraryEGL* const mEGL; const GLFormats mFormats; GLuint mProdTex; RefPtr<gfx::DataSourceSurface> mPixels; GLuint mProdTexForPipe; // Moves to mProdTex when mPipeActive becomes true. EGLImage mImage; GLContext* mCurConsGL; GLuint mConsTex; nsRefPtr<TextureGarbageBin> mGarbageBin; EGLSync mSync; bool mPipeFailed; // Pipe creation failed, and has been abandoned. bool mPipeComplete; // Pipe connects (mPipeActive ? mProdTex : mProdTexForPipe) to mConsTex. bool mPipeActive; // Pipe is complete and in use for production. SharedSurface_EGLImage(GLContext* gl, GLLibraryEGL* egl, const gfx::IntSize& size, bool hasAlpha, const GLFormats& formats, GLuint prodTex, EGLImage image); GLuint prodTex); EGLDisplay Display() const; Loading @@ -61,7 +65,7 @@ protected: public: virtual ~SharedSurface_EGLImage(); virtual void LockProdImpl() {} virtual void LockProdImpl(); virtual void UnlockProdImpl() {} Loading @@ -74,8 +78,11 @@ public: } // Implementation-specific functions below: // Returns texture and target void AcquireConsumerTexture(GLContext* consGL, GLuint* out_texture, GLuint* out_target); // Returns 0 if the pipe isn't ready. If 0, use GetPixels below. GLuint AcquireConsumerTexture(GLContext* consGL); // Will be void if AcquireConsumerTexture returns non-zero. gfx::DataSourceSurface* GetPixels() const; }; Loading
gfx/layers/opengl/TextureHostOGL.cpp +9 −4 Original line number Diff line number Diff line Loading @@ -515,10 +515,15 @@ StreamTextureSourceOGL::RetrieveTextureFromStream() SharedSurface_EGLImage* eglImageSurf = SharedSurface_EGLImage::Cast(sharedSurf); eglImageSurf->AcquireConsumerTexture(gl(), &mTextureHandle, &mTextureTarget); MOZ_ASSERT(mTextureHandle); mTextureHandle = eglImageSurf->AcquireConsumerTexture(gl()); mTextureTarget = eglImageSurf->TextureTarget(); if (!mTextureHandle) { toUpload = eglImageSurf->GetPixels(); MOZ_ASSERT(toUpload); } else { mFormat = sharedSurf->HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8; } break; } #ifdef XP_MACOSX Loading