Bug 1066280 - Implement GLScreenBuffer simplification. - r=kamidphish
From 2aa5dfd3c1e0ef8d8033ad1daf864455fb01f87b Mon Sep 17 00:00:00 2001
---
gfx/gl/GLScreenBuffer.cpp | 70 +++++++++++++++++++++++------------------------
gfx/gl/GLScreenBuffer.h | 36 ++++++++----------------
2 files changed, 45 insertions(+), 61 deletions(-)
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -56,22 +56,17 @@ GLScreenBuffer::Create(GLContext* gl,
factory = SurfaceFactory_IOSurface::Create(gl, caps);
}
#endif
if (!factory) {
factory = MakeUnique<SurfaceFactory_Basic>(gl, caps);
}
- auto streamType = SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread,
- caps.preserve);
- RefPtr<SurfaceStream> 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);
}
GLScreenBuffer::~GLScreenBuffer()
{
mDraw = nullptr;
mRead = nullptr;
@@ -370,30 +365,20 @@ GLScreenBuffer::AssureBlitted()
LOCAL_GL_NEAREST);
// Done!
}
mNeedsBlit = false;
}
void
-GLScreenBuffer::Morph(UniquePtr<SurfaceFactory> newFactory,
- SurfaceStreamType streamType)
+GLScreenBuffer::Morph(UniquePtr<SurfaceFactory> 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
GLScreenBuffer::Attach(SharedSurface* surf, const gfx::IntSize& size)
{
ScopedBindFramebuffer autoFB(mGL);
if (mRead && SharedSurf())
@@ -423,57 +408,71 @@ GLScreenBuffer::Attach(SharedSurface* su
mDraw = Move(draw);
mRead = Move(read);
}
// 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<ShSurfHandle> newBack = mFactory->NewShSurfHandle(size);
+ if (!newBack)
+ return false;
+
+ if (!Attach(newBack->Surf(), size))
+ return false;
+ // Attach was successful.
+
+ mFront = mBack;
+ mBack = newBack;
- NS_WARNING("SwapProd failed for sophisticated Factory type, fell back to Basic.");
+ // 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
GLScreenBuffer::PublishFrame(const gfx::IntSize& size)
{
AssureBlitted();
bool good = Swap(size);
return good;
}
bool
GLScreenBuffer::Resize(const gfx::IntSize& size)
{
- SharedSurface* surf = mStream->Resize(mFactory.get(), size);
- if (!surf)
+ RefPtr<ShSurfHandle> newBack = mFactory->NewShSurfHandle(size);
+ if (!newBack)
return false;
- return Attach(surf, size);
+ if (!Attach(newBack->Surf(), size))
+ return false;
+
+ mBack = newBack;
+ return true;
}
bool
GLScreenBuffer::CreateDraw(const gfx::IntSize& size,
UniquePtr<DrawBuffer>* out_buffer)
{
GLContext* gl = mFactory->mGL;
const GLFormats& formats = mFactory->mFormats;
@@ -503,17 +502,16 @@ GLScreenBuffer::Readback(SharedSurface*
mGL->MakeCurrent();
bool needsSwap = src != SharedSurf();
if (needsSwap) {
SharedSurf()->UnlockProd();
src->LockProd();
}
-
{
UniquePtr<ReadBuffer> buffer = CreateRead(src);
MOZ_ASSERT(buffer);
ScopedBindFramebuffer autoFB(mGL, buffer->mFB);
ReadPixelsIntoDataSurface(mGL, dest);
}
--- a/gfx/gl/GLScreenBuffer.h
+++ b/gfx/gl/GLScreenBuffer.h
@@ -124,17 +124,19 @@ public:
const SurfaceCaps& caps);
protected:
GLContext* const mGL; // Owns us.
public:
const SurfaceCaps mCaps;
protected:
UniquePtr<SurfaceFactory> mFactory;
- RefPtr<SurfaceStream> mStream;
+
+ RefPtr<ShSurfHandle> mBack;
+ RefPtr<ShSurfHandle> mFront;
UniquePtr<DrawBuffer> mDraw;
UniquePtr<ReadBuffer> mRead;
bool mNeedsBlit;
// Below are the parts that help us pretend to be framebuffer 0:
GLuint mUserDrawFB;
@@ -144,52 +146,48 @@ protected:
#ifdef DEBUG
bool mInInternalMode_DrawFB;
bool mInInternalMode_ReadFB;
#endif
GLScreenBuffer(GLContext* gl,
const SurfaceCaps& caps,
- UniquePtr<SurfaceFactory> factory,
- const RefPtr<SurfaceStream>& stream)
+ UniquePtr<SurfaceFactory> factory)
: mGL(gl)
, mCaps(caps)
, mFactory(Move(factory))
- , mStream(stream)
- , mDraw(nullptr)
- , mRead(nullptr)
, mNeedsBlit(true)
, mUserDrawFB(0)
, mUserReadFB(0)
, mInternalDrawFB(0)
, mInternalReadFB(0)
#ifdef DEBUG
, mInInternalMode_DrawFB(true)
, mInInternalMode_ReadFB(true)
#endif
{}
public:
virtual ~GLScreenBuffer();
- SurfaceStream* Stream() const {
- return mStream;
+ SurfaceFactory* Factory() const {
+ return mFactory.get();
}
- 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;
}
GLuint DrawFB() const {
if (!mDraw)
return ReadFB();
return mDraw->mFB;
@@ -219,30 +217,18 @@ public:
* it is backed by a SharedSurface.
*
* Returns true if the pixel data has been read back, false
* otherwise.
*/
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<SurfaceFactory> newFactory,
- SurfaceStreamType streamType);
+ // Morph changes the factory used to create surfaces.
+ void Morph(UniquePtr<SurfaceFactory> newFactory);
protected:
// Returns false on error or inability to resize.
bool Swap(const gfx::IntSize& size);
public:
bool PublishFrame(const gfx::IntSize& size);