diff --git a/gfx/gl/GLScreenBuffer.cpp b/gfx/gl/GLScreenBuffer.cpp index 3a4e53a6c0c..a4f6bba46f9 100755 --- a/gfx/gl/GLScreenBuffer.cpp +++ b/gfx/gl/GLScreenBuffer.cpp @@ -61,12 +61,7 @@ GLScreenBuffer::Create(GLContext* gl, factory = MakeUnique(gl, caps); } - auto streamType = SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread, - caps.preserve); - RefPtr stream; - stream = SurfaceStream::CreateForType(streamType, gl, nullptr); - - ret.reset( new GLScreenBuffer(gl, caps, Move(factory), stream) ); + ret.reset( new GLScreenBuffer(gl, caps, Move(factory)) ); return Move(ret); } @@ -375,20 +370,10 @@ GLScreenBuffer::AssureBlitted() } void -GLScreenBuffer::Morph(UniquePtr newFactory, - SurfaceStreamType streamType) +GLScreenBuffer::Morph(UniquePtr newFactory) { - MOZ_ASSERT(mStream); - - if (newFactory) { - mFactory = Move(newFactory); - } - - if (mStream->mType == streamType) - return; - - mStream = SurfaceStream::CreateForType(streamType, mGL, mStream); - MOZ_ASSERT(mStream); + MOZ_ASSERT(newFactory); + mFactory = Move(newFactory); } bool @@ -428,28 +413,38 @@ GLScreenBuffer::Attach(SharedSurface* surf, const gfx::IntSize& size) // Check that we're all set up. MOZ_ASSERT(SharedSurf() == surf); - if (!PreserveBuffer()) { - // DiscardFramebuffer here could help perf on some mobile platforms. - } - return true; } bool GLScreenBuffer::Swap(const gfx::IntSize& size) { - SharedSurface* nextSurf = mStream->SwapProducer(mFactory.get(), size); - if (!nextSurf) { - SurfaceFactory_Basic basicFactory(mGL, mFactory->mCaps); - nextSurf = mStream->SwapProducer(&basicFactory, size); - if (!nextSurf) - return false; + RefPtr newBack = mFactory->NewShSurfHandle(size); + if (!newBack) + return false; - NS_WARNING("SwapProd failed for sophisticated Factory type, fell back to Basic."); + if (!Attach(newBack->Surf(), size)) + return false; + // Attach was successful. + + mFront = mBack; + mBack = newBack; + + // Fence before copying. + if (mFront) { + mFront->Surf()->Fence(); } - MOZ_ASSERT(nextSurf); - return Attach(nextSurf, size); + if (ShouldPreserveBuffer() && + mFront && + mBack) + { + auto src = mFront->Surf(); + auto dest = mBack->Surf(); + SharedSurface::ProdCopy(src, dest, mFactory.get()); + } + + return true; } bool @@ -464,11 +459,15 @@ GLScreenBuffer::PublishFrame(const gfx::IntSize& size) bool GLScreenBuffer::Resize(const gfx::IntSize& size) { - SharedSurface* surf = mStream->Resize(mFactory.get(), size); - if (!surf) + RefPtr newBack = mFactory->NewShSurfHandle(size); + if (!newBack) return false; - return Attach(surf, size); + if (!Attach(newBack->Surf(), size)) + return false; + + mBack = newBack; + return true; } bool @@ -508,7 +507,6 @@ GLScreenBuffer::Readback(SharedSurface* src, gfx::DataSourceSurface* dest) src->LockProd(); } - { UniquePtr buffer = CreateRead(src); MOZ_ASSERT(buffer); diff --git a/gfx/gl/GLScreenBuffer.h b/gfx/gl/GLScreenBuffer.h index 9eab5fb020a..679ea74e9b1 100644 --- a/gfx/gl/GLScreenBuffer.h +++ b/gfx/gl/GLScreenBuffer.h @@ -129,7 +129,9 @@ public: const SurfaceCaps mCaps; protected: UniquePtr mFactory; - RefPtr mStream; + + RefPtr mBack; + RefPtr mFront; UniquePtr mDraw; UniquePtr mRead; @@ -149,14 +151,10 @@ protected: GLScreenBuffer(GLContext* gl, const SurfaceCaps& caps, - UniquePtr factory, - const RefPtr& stream) + UniquePtr factory) : mGL(gl) , mCaps(caps) , mFactory(Move(factory)) - , mStream(stream) - , mDraw(nullptr) - , mRead(nullptr) , mNeedsBlit(true) , mUserDrawFB(0) , mUserReadFB(0) @@ -171,20 +169,20 @@ protected: public: virtual ~GLScreenBuffer(); - SurfaceStream* Stream() const { - return mStream; - } - SurfaceFactory* Factory() const { return mFactory.get(); } + SharedSurface* Front() const { + return mFront->Surf(); + } + SharedSurface* SharedSurf() const { MOZ_ASSERT(mRead); return mRead->SharedSurf(); } - bool PreserveBuffer() const { + bool ShouldPreserveBuffer() const { return mCaps.preserve; } @@ -224,20 +222,8 @@ public: bool ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); - /* Morph swaps out our SurfaceStream mechanism and replaces it with - * one best suited to our platform and compositor configuration. - * - * Must be called on the producing thread. - * We haven't made any guarantee that rendering is actually - * done when Morph is run, just that it can't run concurrently - * with rendering. This means that we can't just drop the contents - * of the buffer, since we may only be partially done rendering. - * - * Once you pass newFactory into Morph, newFactory will be owned by - * GLScreenBuffer, so `forget` any references to it that still exist. - */ - void Morph(UniquePtr newFactory, - SurfaceStreamType streamType); + // Morph changes the factory used to create surfaces. + void Morph(UniquePtr newFactory); protected: // Returns false on error or inability to resize.