diff --git a/gfx/gl/SurfaceStream.cpp b/gfx/gl/SurfaceStream.cpp index bf105160e4a8..a0c12f706c85 100644 --- a/gfx/gl/SurfaceStream.cpp +++ b/gfx/gl/SurfaceStream.cpp @@ -22,7 +22,7 @@ SurfaceStream::ChooseGLStreamType(SurfaceStream::OMTC omtc, if (preserveBuffer) return SurfaceStreamType::TripleBuffer_Copy; else - return SurfaceStreamType::TripleBuffer; + return SurfaceStreamType::TripleBuffer_Async; } else { if (preserveBuffer) return SurfaceStreamType::SingleBuffer; @@ -43,6 +43,9 @@ SurfaceStream::CreateForType(SurfaceStreamType type, mozilla::gl::GLContext* glC case SurfaceStreamType::TripleBuffer_Copy: result = new SurfaceStream_TripleBuffer_Copy(prevStream); break; + case SurfaceStreamType::TripleBuffer_Async: + result = new SurfaceStream_TripleBuffer_Async(prevStream); + break; case SurfaceStreamType::TripleBuffer: result = new SurfaceStream_TripleBuffer(prevStream); break; @@ -429,7 +432,9 @@ SurfaceStream_TripleBuffer::SwapProducer(SurfaceFactory* factory, if (mProducer) { RecycleScraps(factory); - if (mStaging) + // If WaitForCompositor succeeds, mStaging has moved to mConsumer. + // If it failed, we might have to scrap it. + if (mStaging && !WaitForCompositor()) Scrap(mStaging); MOZ_ASSERT(!mStaging); @@ -456,5 +461,26 @@ SurfaceStream_TripleBuffer::SwapConsumer_NoWait() return mConsumer; } +SurfaceStream_TripleBuffer_Async::SurfaceStream_TripleBuffer_Async(SurfaceStream* prevStream) + : SurfaceStream_TripleBuffer(SurfaceStreamType::TripleBuffer_Async, prevStream) +{ +} + +SurfaceStream_TripleBuffer_Async::~SurfaceStream_TripleBuffer_Async() +{ +} + +bool +SurfaceStream_TripleBuffer_Async::WaitForCompositor() +{ + PROFILER_LABEL("SurfaceStream_TripleBuffer_Async", "WaitForCompositor"); + + // We are assumed to be locked + while (mStaging) + mMonitor.Wait(); + + return true; +} + } /* namespace gfx */ } /* namespace mozilla */ diff --git a/gfx/gl/SurfaceStream.h b/gfx/gl/SurfaceStream.h index e9d372319176..2de34fbe266d 100644 --- a/gfx/gl/SurfaceStream.h +++ b/gfx/gl/SurfaceStream.h @@ -191,6 +191,9 @@ protected: SharedSurface* mStaging; SharedSurface* mConsumer; + // Returns true if we were able to wait, false if not + virtual bool WaitForCompositor() { return false; } + // To support subclasses initializing the mType. SurfaceStream_TripleBuffer(SurfaceStreamType type, SurfaceStream* prevStream); @@ -214,6 +217,18 @@ public: virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer); }; +class SurfaceStream_TripleBuffer_Async + : public SurfaceStream_TripleBuffer +{ +protected: + virtual bool WaitForCompositor() MOZ_OVERRIDE; + +public: + SurfaceStream_TripleBuffer_Async(SurfaceStream* prevStream); + virtual ~SurfaceStream_TripleBuffer_Async(); +}; + + } /* namespace gfx */ } /* namespace mozilla */ diff --git a/gfx/gl/SurfaceTypes.h b/gfx/gl/SurfaceTypes.h index 849bb16ce4a7..639e482fa737 100644 --- a/gfx/gl/SurfaceTypes.h +++ b/gfx/gl/SurfaceTypes.h @@ -87,6 +87,7 @@ MOZ_END_ENUM_CLASS(SharedSurfaceType) MOZ_BEGIN_ENUM_CLASS(SurfaceStreamType, uint8_t) SingleBuffer, TripleBuffer_Copy, + TripleBuffer_Async, TripleBuffer, Max MOZ_END_ENUM_CLASS(SurfaceStreamType)