1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/gl/SurfaceStream.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,235 @@ 1.4 +/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef SURFACESTREAM_H_ 1.10 +#define SURFACESTREAM_H_ 1.11 + 1.12 +#include <stack> 1.13 +#include <set> 1.14 +#include "mozilla/Monitor.h" 1.15 +#include "mozilla/Attributes.h" 1.16 +#include "mozilla/gfx/Point.h" 1.17 +#include "mozilla/GenericRefCounted.h" 1.18 +#include "SurfaceTypes.h" 1.19 + 1.20 +namespace mozilla { 1.21 + 1.22 +namespace gl { 1.23 +class GLContext; 1.24 +} 1.25 + 1.26 +namespace gfx { 1.27 +class SharedSurface; 1.28 +class SurfaceFactory; 1.29 + 1.30 +// Owned by: ScreenBuffer 1.31 +class SurfaceStream : public GenericAtomicRefCounted 1.32 +{ 1.33 +public: 1.34 + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream) 1.35 + typedef enum { 1.36 + MainThread, 1.37 + OffMainThread 1.38 + } OMTC; 1.39 + 1.40 + static SurfaceStreamType ChooseGLStreamType(OMTC omtc, 1.41 + bool preserveBuffer); 1.42 + 1.43 + static SurfaceStream* CreateForType(SurfaceStreamType type, 1.44 + mozilla::gl::GLContext* glContext, 1.45 + SurfaceStream* prevStream = nullptr); 1.46 + 1.47 + SurfaceStreamHandle GetShareHandle() { 1.48 + return reinterpret_cast<SurfaceStreamHandle>(this); 1.49 + } 1.50 + 1.51 + static SurfaceStream* FromHandle(SurfaceStreamHandle handle) { 1.52 + return (SurfaceStream*)handle; 1.53 + } 1.54 + 1.55 + const SurfaceStreamType mType; 1.56 + 1.57 + mozilla::gl::GLContext* GLContext() const { return mGLContext; } 1.58 + 1.59 + 1.60 +protected: 1.61 + // |mProd| is owned by us, but can be ripped away when 1.62 + // creating a new GLStream from this one. 1.63 + SharedSurface* mProducer; 1.64 + std::set<SharedSurface*> mSurfaces; 1.65 + std::stack<SharedSurface*> mScraps; 1.66 + mutable Monitor mMonitor; 1.67 + bool mIsAlive; 1.68 + 1.69 + // Do not use this. It exists solely so we can ref it in CanvasClientWebGL::Update() 1.70 + // before sent up to the compositor. You have been warned (Bug 894405) 1.71 + mozilla::gl::GLContext* mGLContext; 1.72 + 1.73 + // |previous| can be null, indicating this is the first one. 1.74 + // Otherwise, we pull in |mProd| from |previous| an our initial surface. 1.75 + SurfaceStream(SurfaceStreamType type, SurfaceStream* prevStream) 1.76 + : mType(type) 1.77 + , mProducer(nullptr) 1.78 + , mMonitor("SurfaceStream monitor") 1.79 + , mIsAlive(true) 1.80 + { 1.81 + MOZ_ASSERT(!prevStream || mType != prevStream->mType, 1.82 + "We should not need to create a SurfaceStream from another " 1.83 + "of the same type."); 1.84 + } 1.85 + 1.86 +public: 1.87 + virtual ~SurfaceStream(); 1.88 + 1.89 +protected: 1.90 + // These functions below are helpers to make trading buffers around easier. 1.91 + // For instance, using Move(a,b) instead of normal assignment assures that 1.92 + // we are never leaving anything hanging around, keeping things very safe. 1.93 + static void Move(SharedSurface*& from, SharedSurface*& to) { 1.94 + MOZ_ASSERT(!to); 1.95 + to = from; 1.96 + from = nullptr; 1.97 + } 1.98 + 1.99 + void New(SurfaceFactory* factory, const gfx::IntSize& size, 1.100 + SharedSurface*& surf); 1.101 + void Delete(SharedSurface*& surf); 1.102 + void Recycle(SurfaceFactory* factory, SharedSurface*& surf); 1.103 + 1.104 + // Surrender control of a surface, and return it for use elsewhere. 1.105 + SharedSurface* Surrender(SharedSurface*& surf); 1.106 + // Absorb control of a surface from elsewhere, clears its old location. 1.107 + SharedSurface* Absorb(SharedSurface*& surf); 1.108 + 1.109 + // For holding on to surfaces we don't need until we can return them to the 1.110 + // Producer's factory via SurfaceFactory::Recycle. 1.111 + // Not thread-safe. 1.112 + void Scrap(SharedSurface*& scrap); 1.113 + 1.114 + // Not thread-safe. 1.115 + void RecycleScraps(SurfaceFactory* factory); 1.116 + 1.117 +public: 1.118 + /* Note that ownership of the returned surfaces below 1.119 + * transfers to the caller. 1.120 + * SwapProd returns null on failure. Returning null doesn't mean nothing 1.121 + * happened, but rather that a surface allocation failed. After returning 1.122 + * null, we must be able to call SwapProducer again with better args 1.123 + * and have everything work again. 1.124 + * One common failure is asking for a too-large |size|. 1.125 + */ 1.126 + virtual SharedSurface* SwapProducer(SurfaceFactory* factory, 1.127 + const gfx::IntSize& size) = 0; 1.128 + 1.129 + virtual SharedSurface* Resize(SurfaceFactory* factory, const gfx::IntSize& size); 1.130 + 1.131 + virtual bool CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory) { MOZ_ASSERT(0); return false; } 1.132 + 1.133 +protected: 1.134 + // SwapCons will return the same surface more than once, 1.135 + // if nothing new has been published. 1.136 + virtual SharedSurface* SwapConsumer_NoWait() = 0; 1.137 + 1.138 +public: 1.139 + virtual SharedSurface* SwapConsumer(); 1.140 + 1.141 + virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer) = 0; 1.142 +}; 1.143 + 1.144 +// Not thread-safe. Don't use cross-threads. 1.145 +class SurfaceStream_SingleBuffer 1.146 + : public SurfaceStream 1.147 +{ 1.148 +protected: 1.149 + SharedSurface* mConsumer; // Only present after resize-swap. 1.150 + 1.151 +public: 1.152 + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_SingleBuffer) 1.153 + SurfaceStream_SingleBuffer(SurfaceStream* prevStream); 1.154 + virtual ~SurfaceStream_SingleBuffer(); 1.155 + 1.156 + /* Since we're non-OMTC, we know the order of execution here: 1.157 + * SwapProd gets called in UpdateSurface, followed by 1.158 + * SwapCons being called in Render. 1.159 + */ 1.160 + virtual SharedSurface* SwapProducer(SurfaceFactory* factory, 1.161 + const gfx::IntSize& size); 1.162 + 1.163 + virtual SharedSurface* SwapConsumer_NoWait(); 1.164 + 1.165 + virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer); 1.166 +}; 1.167 + 1.168 +// Our hero for preserveDrawingBuffer=true. 1.169 +class SurfaceStream_TripleBuffer_Copy 1.170 + : public SurfaceStream 1.171 +{ 1.172 +protected: 1.173 + SharedSurface* mStaging; 1.174 + SharedSurface* mConsumer; 1.175 + 1.176 +public: 1.177 + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer_Copy) 1.178 + SurfaceStream_TripleBuffer_Copy(SurfaceStream* prevStream); 1.179 + virtual ~SurfaceStream_TripleBuffer_Copy(); 1.180 + 1.181 + virtual SharedSurface* SwapProducer(SurfaceFactory* factory, 1.182 + const gfx::IntSize& size); 1.183 + 1.184 + virtual SharedSurface* SwapConsumer_NoWait(); 1.185 + 1.186 + virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer); 1.187 +}; 1.188 + 1.189 + 1.190 +class SurfaceStream_TripleBuffer 1.191 + : public SurfaceStream 1.192 +{ 1.193 +protected: 1.194 + SharedSurface* mStaging; 1.195 + SharedSurface* mConsumer; 1.196 + 1.197 + // Returns true if we were able to wait, false if not 1.198 + virtual bool WaitForCompositor() { return false; } 1.199 + 1.200 + // To support subclasses initializing the mType. 1.201 + SurfaceStream_TripleBuffer(SurfaceStreamType type, SurfaceStream* prevStream); 1.202 + 1.203 +public: 1.204 + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer) 1.205 + SurfaceStream_TripleBuffer(SurfaceStream* prevStream); 1.206 + virtual ~SurfaceStream_TripleBuffer(); 1.207 + virtual bool CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory); 1.208 + 1.209 +private: 1.210 + // Common constructor code. 1.211 + void Init(SurfaceStream* prevStream); 1.212 + 1.213 +public: 1.214 + // Done writing to prod, swap prod and staging 1.215 + virtual SharedSurface* SwapProducer(SurfaceFactory* factory, 1.216 + const gfx::IntSize& size); 1.217 + 1.218 + virtual SharedSurface* SwapConsumer_NoWait(); 1.219 + 1.220 + virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer); 1.221 +}; 1.222 + 1.223 +class SurfaceStream_TripleBuffer_Async 1.224 + : public SurfaceStream_TripleBuffer 1.225 +{ 1.226 +protected: 1.227 + virtual bool WaitForCompositor() MOZ_OVERRIDE; 1.228 + 1.229 +public: 1.230 + SurfaceStream_TripleBuffer_Async(SurfaceStream* prevStream); 1.231 + virtual ~SurfaceStream_TripleBuffer_Async(); 1.232 +}; 1.233 + 1.234 + 1.235 +} /* namespace gfx */ 1.236 +} /* namespace mozilla */ 1.237 + 1.238 +#endif /* SURFACESTREAM_H_ */