diff -r 000000000000 -r 6474c204b198 gfx/gl/SurfaceStream.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/gl/SurfaceStream.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,235 @@ +/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef SURFACESTREAM_H_ +#define SURFACESTREAM_H_ + +#include +#include +#include "mozilla/Monitor.h" +#include "mozilla/Attributes.h" +#include "mozilla/gfx/Point.h" +#include "mozilla/GenericRefCounted.h" +#include "SurfaceTypes.h" + +namespace mozilla { + +namespace gl { +class GLContext; +} + +namespace gfx { +class SharedSurface; +class SurfaceFactory; + +// Owned by: ScreenBuffer +class SurfaceStream : public GenericAtomicRefCounted +{ +public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream) + typedef enum { + MainThread, + OffMainThread + } OMTC; + + static SurfaceStreamType ChooseGLStreamType(OMTC omtc, + bool preserveBuffer); + + static SurfaceStream* CreateForType(SurfaceStreamType type, + mozilla::gl::GLContext* glContext, + SurfaceStream* prevStream = nullptr); + + SurfaceStreamHandle GetShareHandle() { + return reinterpret_cast(this); + } + + static SurfaceStream* FromHandle(SurfaceStreamHandle handle) { + return (SurfaceStream*)handle; + } + + const SurfaceStreamType mType; + + mozilla::gl::GLContext* GLContext() const { return mGLContext; } + + +protected: + // |mProd| is owned by us, but can be ripped away when + // creating a new GLStream from this one. + SharedSurface* mProducer; + std::set mSurfaces; + std::stack mScraps; + mutable Monitor mMonitor; + bool mIsAlive; + + // Do not use this. It exists solely so we can ref it in CanvasClientWebGL::Update() + // before sent up to the compositor. You have been warned (Bug 894405) + mozilla::gl::GLContext* mGLContext; + + // |previous| can be null, indicating this is the first one. + // Otherwise, we pull in |mProd| from |previous| an our initial surface. + SurfaceStream(SurfaceStreamType type, SurfaceStream* prevStream) + : mType(type) + , mProducer(nullptr) + , mMonitor("SurfaceStream monitor") + , mIsAlive(true) + { + MOZ_ASSERT(!prevStream || mType != prevStream->mType, + "We should not need to create a SurfaceStream from another " + "of the same type."); + } + +public: + virtual ~SurfaceStream(); + +protected: + // These functions below are helpers to make trading buffers around easier. + // For instance, using Move(a,b) instead of normal assignment assures that + // we are never leaving anything hanging around, keeping things very safe. + static void Move(SharedSurface*& from, SharedSurface*& to) { + MOZ_ASSERT(!to); + to = from; + from = nullptr; + } + + void New(SurfaceFactory* factory, const gfx::IntSize& size, + SharedSurface*& surf); + void Delete(SharedSurface*& surf); + void Recycle(SurfaceFactory* factory, SharedSurface*& surf); + + // Surrender control of a surface, and return it for use elsewhere. + SharedSurface* Surrender(SharedSurface*& surf); + // Absorb control of a surface from elsewhere, clears its old location. + SharedSurface* Absorb(SharedSurface*& surf); + + // For holding on to surfaces we don't need until we can return them to the + // Producer's factory via SurfaceFactory::Recycle. + // Not thread-safe. + void Scrap(SharedSurface*& scrap); + + // Not thread-safe. + void RecycleScraps(SurfaceFactory* factory); + +public: + /* Note that ownership of the returned surfaces below + * transfers to the caller. + * SwapProd returns null on failure. Returning null doesn't mean nothing + * happened, but rather that a surface allocation failed. After returning + * null, we must be able to call SwapProducer again with better args + * and have everything work again. + * One common failure is asking for a too-large |size|. + */ + virtual SharedSurface* SwapProducer(SurfaceFactory* factory, + const gfx::IntSize& size) = 0; + + virtual SharedSurface* Resize(SurfaceFactory* factory, const gfx::IntSize& size); + + virtual bool CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory) { MOZ_ASSERT(0); return false; } + +protected: + // SwapCons will return the same surface more than once, + // if nothing new has been published. + virtual SharedSurface* SwapConsumer_NoWait() = 0; + +public: + virtual SharedSurface* SwapConsumer(); + + virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer) = 0; +}; + +// Not thread-safe. Don't use cross-threads. +class SurfaceStream_SingleBuffer + : public SurfaceStream +{ +protected: + SharedSurface* mConsumer; // Only present after resize-swap. + +public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_SingleBuffer) + SurfaceStream_SingleBuffer(SurfaceStream* prevStream); + virtual ~SurfaceStream_SingleBuffer(); + + /* Since we're non-OMTC, we know the order of execution here: + * SwapProd gets called in UpdateSurface, followed by + * SwapCons being called in Render. + */ + virtual SharedSurface* SwapProducer(SurfaceFactory* factory, + const gfx::IntSize& size); + + virtual SharedSurface* SwapConsumer_NoWait(); + + virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer); +}; + +// Our hero for preserveDrawingBuffer=true. +class SurfaceStream_TripleBuffer_Copy + : public SurfaceStream +{ +protected: + SharedSurface* mStaging; + SharedSurface* mConsumer; + +public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer_Copy) + SurfaceStream_TripleBuffer_Copy(SurfaceStream* prevStream); + virtual ~SurfaceStream_TripleBuffer_Copy(); + + virtual SharedSurface* SwapProducer(SurfaceFactory* factory, + const gfx::IntSize& size); + + virtual SharedSurface* SwapConsumer_NoWait(); + + virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer); +}; + + +class SurfaceStream_TripleBuffer + : public SurfaceStream +{ +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); + +public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer) + SurfaceStream_TripleBuffer(SurfaceStream* prevStream); + virtual ~SurfaceStream_TripleBuffer(); + virtual bool CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory); + +private: + // Common constructor code. + void Init(SurfaceStream* prevStream); + +public: + // Done writing to prod, swap prod and staging + virtual SharedSurface* SwapProducer(SurfaceFactory* factory, + const gfx::IntSize& size); + + virtual SharedSurface* SwapConsumer_NoWait(); + + 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 */ + +#endif /* SURFACESTREAM_H_ */