Bug 1066280 - Implement GLScreenBuffer simplification. - r=kamidphish
authorjdashg <jdashg+github@gmail.com>
Tue, 07 Oct 2014 21:01:07 -0700
changeset 209889 642bfa833485d0012405126f2d190b63762b762c
parent 209888 ec0db54f1033b7cd2d065f9ee43a8797a0dfd898
child 209890 a957533009dfbc03ede8e09f87de8007f410e871
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerskamidphish
bugs1066280
milestone35.0a1
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(-)
gfx/gl/GLScreenBuffer.cpp
gfx/gl/GLScreenBuffer.h
--- 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);