|
1 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef SURFACESTREAM_H_ |
|
7 #define SURFACESTREAM_H_ |
|
8 |
|
9 #include <stack> |
|
10 #include <set> |
|
11 #include "mozilla/Monitor.h" |
|
12 #include "mozilla/Attributes.h" |
|
13 #include "mozilla/gfx/Point.h" |
|
14 #include "mozilla/GenericRefCounted.h" |
|
15 #include "SurfaceTypes.h" |
|
16 |
|
17 namespace mozilla { |
|
18 |
|
19 namespace gl { |
|
20 class GLContext; |
|
21 } |
|
22 |
|
23 namespace gfx { |
|
24 class SharedSurface; |
|
25 class SurfaceFactory; |
|
26 |
|
27 // Owned by: ScreenBuffer |
|
28 class SurfaceStream : public GenericAtomicRefCounted |
|
29 { |
|
30 public: |
|
31 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream) |
|
32 typedef enum { |
|
33 MainThread, |
|
34 OffMainThread |
|
35 } OMTC; |
|
36 |
|
37 static SurfaceStreamType ChooseGLStreamType(OMTC omtc, |
|
38 bool preserveBuffer); |
|
39 |
|
40 static SurfaceStream* CreateForType(SurfaceStreamType type, |
|
41 mozilla::gl::GLContext* glContext, |
|
42 SurfaceStream* prevStream = nullptr); |
|
43 |
|
44 SurfaceStreamHandle GetShareHandle() { |
|
45 return reinterpret_cast<SurfaceStreamHandle>(this); |
|
46 } |
|
47 |
|
48 static SurfaceStream* FromHandle(SurfaceStreamHandle handle) { |
|
49 return (SurfaceStream*)handle; |
|
50 } |
|
51 |
|
52 const SurfaceStreamType mType; |
|
53 |
|
54 mozilla::gl::GLContext* GLContext() const { return mGLContext; } |
|
55 |
|
56 |
|
57 protected: |
|
58 // |mProd| is owned by us, but can be ripped away when |
|
59 // creating a new GLStream from this one. |
|
60 SharedSurface* mProducer; |
|
61 std::set<SharedSurface*> mSurfaces; |
|
62 std::stack<SharedSurface*> mScraps; |
|
63 mutable Monitor mMonitor; |
|
64 bool mIsAlive; |
|
65 |
|
66 // Do not use this. It exists solely so we can ref it in CanvasClientWebGL::Update() |
|
67 // before sent up to the compositor. You have been warned (Bug 894405) |
|
68 mozilla::gl::GLContext* mGLContext; |
|
69 |
|
70 // |previous| can be null, indicating this is the first one. |
|
71 // Otherwise, we pull in |mProd| from |previous| an our initial surface. |
|
72 SurfaceStream(SurfaceStreamType type, SurfaceStream* prevStream) |
|
73 : mType(type) |
|
74 , mProducer(nullptr) |
|
75 , mMonitor("SurfaceStream monitor") |
|
76 , mIsAlive(true) |
|
77 { |
|
78 MOZ_ASSERT(!prevStream || mType != prevStream->mType, |
|
79 "We should not need to create a SurfaceStream from another " |
|
80 "of the same type."); |
|
81 } |
|
82 |
|
83 public: |
|
84 virtual ~SurfaceStream(); |
|
85 |
|
86 protected: |
|
87 // These functions below are helpers to make trading buffers around easier. |
|
88 // For instance, using Move(a,b) instead of normal assignment assures that |
|
89 // we are never leaving anything hanging around, keeping things very safe. |
|
90 static void Move(SharedSurface*& from, SharedSurface*& to) { |
|
91 MOZ_ASSERT(!to); |
|
92 to = from; |
|
93 from = nullptr; |
|
94 } |
|
95 |
|
96 void New(SurfaceFactory* factory, const gfx::IntSize& size, |
|
97 SharedSurface*& surf); |
|
98 void Delete(SharedSurface*& surf); |
|
99 void Recycle(SurfaceFactory* factory, SharedSurface*& surf); |
|
100 |
|
101 // Surrender control of a surface, and return it for use elsewhere. |
|
102 SharedSurface* Surrender(SharedSurface*& surf); |
|
103 // Absorb control of a surface from elsewhere, clears its old location. |
|
104 SharedSurface* Absorb(SharedSurface*& surf); |
|
105 |
|
106 // For holding on to surfaces we don't need until we can return them to the |
|
107 // Producer's factory via SurfaceFactory::Recycle. |
|
108 // Not thread-safe. |
|
109 void Scrap(SharedSurface*& scrap); |
|
110 |
|
111 // Not thread-safe. |
|
112 void RecycleScraps(SurfaceFactory* factory); |
|
113 |
|
114 public: |
|
115 /* Note that ownership of the returned surfaces below |
|
116 * transfers to the caller. |
|
117 * SwapProd returns null on failure. Returning null doesn't mean nothing |
|
118 * happened, but rather that a surface allocation failed. After returning |
|
119 * null, we must be able to call SwapProducer again with better args |
|
120 * and have everything work again. |
|
121 * One common failure is asking for a too-large |size|. |
|
122 */ |
|
123 virtual SharedSurface* SwapProducer(SurfaceFactory* factory, |
|
124 const gfx::IntSize& size) = 0; |
|
125 |
|
126 virtual SharedSurface* Resize(SurfaceFactory* factory, const gfx::IntSize& size); |
|
127 |
|
128 virtual bool CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory) { MOZ_ASSERT(0); return false; } |
|
129 |
|
130 protected: |
|
131 // SwapCons will return the same surface more than once, |
|
132 // if nothing new has been published. |
|
133 virtual SharedSurface* SwapConsumer_NoWait() = 0; |
|
134 |
|
135 public: |
|
136 virtual SharedSurface* SwapConsumer(); |
|
137 |
|
138 virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer) = 0; |
|
139 }; |
|
140 |
|
141 // Not thread-safe. Don't use cross-threads. |
|
142 class SurfaceStream_SingleBuffer |
|
143 : public SurfaceStream |
|
144 { |
|
145 protected: |
|
146 SharedSurface* mConsumer; // Only present after resize-swap. |
|
147 |
|
148 public: |
|
149 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_SingleBuffer) |
|
150 SurfaceStream_SingleBuffer(SurfaceStream* prevStream); |
|
151 virtual ~SurfaceStream_SingleBuffer(); |
|
152 |
|
153 /* Since we're non-OMTC, we know the order of execution here: |
|
154 * SwapProd gets called in UpdateSurface, followed by |
|
155 * SwapCons being called in Render. |
|
156 */ |
|
157 virtual SharedSurface* SwapProducer(SurfaceFactory* factory, |
|
158 const gfx::IntSize& size); |
|
159 |
|
160 virtual SharedSurface* SwapConsumer_NoWait(); |
|
161 |
|
162 virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer); |
|
163 }; |
|
164 |
|
165 // Our hero for preserveDrawingBuffer=true. |
|
166 class SurfaceStream_TripleBuffer_Copy |
|
167 : public SurfaceStream |
|
168 { |
|
169 protected: |
|
170 SharedSurface* mStaging; |
|
171 SharedSurface* mConsumer; |
|
172 |
|
173 public: |
|
174 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer_Copy) |
|
175 SurfaceStream_TripleBuffer_Copy(SurfaceStream* prevStream); |
|
176 virtual ~SurfaceStream_TripleBuffer_Copy(); |
|
177 |
|
178 virtual SharedSurface* SwapProducer(SurfaceFactory* factory, |
|
179 const gfx::IntSize& size); |
|
180 |
|
181 virtual SharedSurface* SwapConsumer_NoWait(); |
|
182 |
|
183 virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer); |
|
184 }; |
|
185 |
|
186 |
|
187 class SurfaceStream_TripleBuffer |
|
188 : public SurfaceStream |
|
189 { |
|
190 protected: |
|
191 SharedSurface* mStaging; |
|
192 SharedSurface* mConsumer; |
|
193 |
|
194 // Returns true if we were able to wait, false if not |
|
195 virtual bool WaitForCompositor() { return false; } |
|
196 |
|
197 // To support subclasses initializing the mType. |
|
198 SurfaceStream_TripleBuffer(SurfaceStreamType type, SurfaceStream* prevStream); |
|
199 |
|
200 public: |
|
201 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer) |
|
202 SurfaceStream_TripleBuffer(SurfaceStream* prevStream); |
|
203 virtual ~SurfaceStream_TripleBuffer(); |
|
204 virtual bool CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory); |
|
205 |
|
206 private: |
|
207 // Common constructor code. |
|
208 void Init(SurfaceStream* prevStream); |
|
209 |
|
210 public: |
|
211 // Done writing to prod, swap prod and staging |
|
212 virtual SharedSurface* SwapProducer(SurfaceFactory* factory, |
|
213 const gfx::IntSize& size); |
|
214 |
|
215 virtual SharedSurface* SwapConsumer_NoWait(); |
|
216 |
|
217 virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer); |
|
218 }; |
|
219 |
|
220 class SurfaceStream_TripleBuffer_Async |
|
221 : public SurfaceStream_TripleBuffer |
|
222 { |
|
223 protected: |
|
224 virtual bool WaitForCompositor() MOZ_OVERRIDE; |
|
225 |
|
226 public: |
|
227 SurfaceStream_TripleBuffer_Async(SurfaceStream* prevStream); |
|
228 virtual ~SurfaceStream_TripleBuffer_Async(); |
|
229 }; |
|
230 |
|
231 |
|
232 } /* namespace gfx */ |
|
233 } /* namespace mozilla */ |
|
234 |
|
235 #endif /* SURFACESTREAM_H_ */ |