| |
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
| |
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 GFX_CONTENTHOST_H |
| |
7 #define GFX_CONTENTHOST_H |
| |
8 |
| |
9 #include <stdint.h> // for uint32_t |
| |
10 #include <stdio.h> // for FILE |
| |
11 #include "mozilla-config.h" // for MOZ_DUMP_PAINTING |
| |
12 #include "CompositableHost.h" // for CompositableHost, etc |
| |
13 #include "RotatedBuffer.h" // for RotatedContentBuffer, etc |
| |
14 #include "mozilla/Attributes.h" // for MOZ_OVERRIDE |
| |
15 #include "mozilla/RefPtr.h" // for RefPtr |
| |
16 #include "mozilla/gfx/BasePoint.h" // for BasePoint |
| |
17 #include "mozilla/gfx/Point.h" // for Point |
| |
18 #include "mozilla/gfx/Rect.h" // for Rect |
| |
19 #include "mozilla/gfx/Types.h" // for Filter |
| |
20 #include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc |
| |
21 #include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator |
| |
22 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor |
| |
23 #include "mozilla/layers/LayersTypes.h" // for etc |
| |
24 #include "mozilla/layers/TextureHost.h" // for TextureHost |
| |
25 #include "mozilla/mozalloc.h" // for operator delete |
| |
26 #include "nsAutoPtr.h" // for nsAutoPtr |
| |
27 #include "nsCOMPtr.h" // for already_AddRefed |
| |
28 #include "nsDebug.h" // for NS_RUNTIMEABORT |
| |
29 #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc |
| |
30 #include "nsPoint.h" // for nsIntPoint |
| |
31 #include "nsRect.h" // for nsIntRect |
| |
32 #include "nsRegion.h" // for nsIntRegion |
| |
33 #include "nsTArray.h" // for nsTArray |
| |
34 #include "nscore.h" // for nsACString |
| |
35 |
| |
36 namespace mozilla { |
| |
37 namespace gfx { |
| |
38 class Matrix4x4; |
| |
39 } |
| |
40 namespace layers { |
| |
41 class Compositor; |
| |
42 class ThebesBufferData; |
| |
43 class TiledLayerComposer; |
| |
44 struct EffectChain; |
| |
45 class TextureImageTextureSourceOGL; |
| |
46 |
| |
47 struct TexturedEffect; |
| |
48 |
| |
49 /** |
| |
50 * ContentHosts are used for compositing Thebes layers, always matched by a |
| |
51 * ContentClient of the same type. |
| |
52 * |
| |
53 * ContentHosts support only UpdateThebes(), not Update(). |
| |
54 */ |
| |
55 class ContentHost : public CompositableHost |
| |
56 { |
| |
57 public: |
| |
58 // Subclasses should implement this method if they support being used as a |
| |
59 // tiling. |
| |
60 virtual TiledLayerComposer* AsTiledLayerComposer() { return nullptr; } |
| |
61 |
| |
62 virtual bool UpdateThebes(const ThebesBufferData& aData, |
| |
63 const nsIntRegion& aUpdated, |
| |
64 const nsIntRegion& aOldValidRegionBack, |
| |
65 nsIntRegion* aUpdatedRegionBack) = 0; |
| |
66 |
| |
67 virtual void SetPaintWillResample(bool aResample) { } |
| |
68 |
| |
69 protected: |
| |
70 ContentHost(const TextureInfo& aTextureInfo) |
| |
71 : CompositableHost(aTextureInfo) |
| |
72 {} |
| |
73 }; |
| |
74 |
| |
75 /** |
| |
76 * Base class for non-tiled ContentHosts. |
| |
77 * |
| |
78 * Ownership of the SurfaceDescriptor and the resources it represents is passed |
| |
79 * from the ContentClient to the ContentHost when the TextureClient/Hosts are |
| |
80 * created, that is recevied here by SetTextureHosts which assigns one or two |
| |
81 * texture hosts (for single and double buffering) to the ContentHost. |
| |
82 * |
| |
83 * It is the responsibility of the ContentHost to destroy its resources when |
| |
84 * they are recreated or the ContentHost dies. |
| |
85 */ |
| |
86 class ContentHostBase : public ContentHost |
| |
87 { |
| |
88 public: |
| |
89 typedef RotatedContentBuffer::ContentType ContentType; |
| |
90 typedef RotatedContentBuffer::PaintState PaintState; |
| |
91 |
| |
92 ContentHostBase(const TextureInfo& aTextureInfo); |
| |
93 virtual ~ContentHostBase(); |
| |
94 |
| |
95 virtual void Composite(EffectChain& aEffectChain, |
| |
96 float aOpacity, |
| |
97 const gfx::Matrix4x4& aTransform, |
| |
98 const gfx::Filter& aFilter, |
| |
99 const gfx::Rect& aClipRect, |
| |
100 const nsIntRegion* aVisibleRegion = nullptr, |
| |
101 TiledLayerProperties* aLayerProperties = nullptr); |
| |
102 |
| |
103 virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; } |
| |
104 |
| |
105 virtual bool Lock() = 0; |
| |
106 virtual void Unlock() = 0; |
| |
107 |
| |
108 virtual NewTextureSource* GetTextureSource() = 0; |
| |
109 virtual NewTextureSource* GetTextureSourceOnWhite() = 0; |
| |
110 |
| |
111 protected: |
| |
112 virtual nsIntPoint GetOriginOffset() |
| |
113 { |
| |
114 return mBufferRect.TopLeft() - mBufferRotation; |
| |
115 } |
| |
116 |
| |
117 bool PaintWillResample() { return mPaintWillResample; } |
| |
118 |
| |
119 nsIntRect mBufferRect; |
| |
120 nsIntPoint mBufferRotation; |
| |
121 bool mPaintWillResample; |
| |
122 bool mInitialised; |
| |
123 }; |
| |
124 |
| |
125 /** |
| |
126 * Shared ContentHostBase implementation for content hosts that |
| |
127 * use up to two TextureHosts. |
| |
128 */ |
| |
129 class ContentHostTexture : public ContentHostBase |
| |
130 { |
| |
131 public: |
| |
132 ContentHostTexture(const TextureInfo& aTextureInfo) |
| |
133 : ContentHostBase(aTextureInfo) |
| |
134 , mLocked(false) |
| |
135 { } |
| |
136 |
| |
137 virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE; |
| |
138 |
| |
139 #ifdef MOZ_DUMP_PAINTING |
| |
140 virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE; |
| |
141 |
| |
142 virtual void Dump(FILE* aFile=nullptr, |
| |
143 const char* aPrefix="", |
| |
144 bool aDumpHtml=false) MOZ_OVERRIDE; |
| |
145 #endif |
| |
146 |
| |
147 virtual void PrintInfo(nsACString& aTo, const char* aPrefix) MOZ_OVERRIDE; |
| |
148 |
| |
149 virtual void UseTextureHost(TextureHost* aTexture) MOZ_OVERRIDE; |
| |
150 virtual void UseComponentAlphaTextures(TextureHost* aTextureOnBlack, |
| |
151 TextureHost* aTextureOnWhite) MOZ_OVERRIDE; |
| |
152 |
| |
153 virtual bool Lock() { |
| |
154 MOZ_ASSERT(!mLocked); |
| |
155 if (!mTextureHost) { |
| |
156 return false; |
| |
157 } |
| |
158 if (!mTextureHost->Lock()) { |
| |
159 return false; |
| |
160 } |
| |
161 |
| |
162 if (mTextureHostOnWhite && !mTextureHostOnWhite->Lock()) { |
| |
163 return false; |
| |
164 } |
| |
165 |
| |
166 mLocked = true; |
| |
167 return true; |
| |
168 } |
| |
169 virtual void Unlock() { |
| |
170 MOZ_ASSERT(mLocked); |
| |
171 mTextureHost->Unlock(); |
| |
172 if (mTextureHostOnWhite) { |
| |
173 mTextureHostOnWhite->Unlock(); |
| |
174 } |
| |
175 mLocked = false; |
| |
176 } |
| |
177 |
| |
178 virtual NewTextureSource* GetTextureSource() { |
| |
179 MOZ_ASSERT(mLocked); |
| |
180 return mTextureHost->GetTextureSources(); |
| |
181 } |
| |
182 virtual NewTextureSource* GetTextureSourceOnWhite() { |
| |
183 MOZ_ASSERT(mLocked); |
| |
184 if (mTextureHostOnWhite) { |
| |
185 return mTextureHostOnWhite->GetTextureSources(); |
| |
186 } |
| |
187 return nullptr; |
| |
188 } |
| |
189 |
| |
190 LayerRenderState GetRenderState(); |
| |
191 |
| |
192 protected: |
| |
193 RefPtr<TextureHost> mTextureHost; |
| |
194 RefPtr<TextureHost> mTextureHostOnWhite; |
| |
195 bool mLocked; |
| |
196 }; |
| |
197 |
| |
198 /** |
| |
199 * Double buffering is implemented by swapping the front and back TextureHosts. |
| |
200 * We assume that whenever we use double buffering, then we have |
| |
201 * render-to-texture and thus no texture upload to do. |
| |
202 */ |
| |
203 class ContentHostDoubleBuffered : public ContentHostTexture |
| |
204 { |
| |
205 public: |
| |
206 ContentHostDoubleBuffered(const TextureInfo& aTextureInfo) |
| |
207 : ContentHostTexture(aTextureInfo) |
| |
208 {} |
| |
209 |
| |
210 virtual ~ContentHostDoubleBuffered() {} |
| |
211 |
| |
212 virtual CompositableType GetType() { return COMPOSITABLE_CONTENT_DOUBLE; } |
| |
213 |
| |
214 virtual bool UpdateThebes(const ThebesBufferData& aData, |
| |
215 const nsIntRegion& aUpdated, |
| |
216 const nsIntRegion& aOldValidRegionBack, |
| |
217 nsIntRegion* aUpdatedRegionBack); |
| |
218 |
| |
219 protected: |
| |
220 nsIntRegion mValidRegionForNextBackBuffer; |
| |
221 }; |
| |
222 |
| |
223 /** |
| |
224 * Single buffered, therefore we must synchronously upload the image from the |
| |
225 * TextureHost in the layers transaction (i.e., in UpdateThebes). |
| |
226 */ |
| |
227 class ContentHostSingleBuffered : public ContentHostTexture |
| |
228 { |
| |
229 public: |
| |
230 ContentHostSingleBuffered(const TextureInfo& aTextureInfo) |
| |
231 : ContentHostTexture(aTextureInfo) |
| |
232 {} |
| |
233 virtual ~ContentHostSingleBuffered() {} |
| |
234 |
| |
235 virtual CompositableType GetType() { return COMPOSITABLE_CONTENT_SINGLE; } |
| |
236 |
| |
237 virtual bool UpdateThebes(const ThebesBufferData& aData, |
| |
238 const nsIntRegion& aUpdated, |
| |
239 const nsIntRegion& aOldValidRegionBack, |
| |
240 nsIntRegion* aUpdatedRegionBack); |
| |
241 }; |
| |
242 |
| |
243 /** |
| |
244 * Maintains a host-side only texture, and gets provided with |
| |
245 * surfaces that only cover the changed pixels during an update. |
| |
246 * |
| |
247 * Takes ownership of the passed in update surfaces, and must |
| |
248 * free them once texture upload is complete. |
| |
249 * |
| |
250 * Delays texture uploads until the next composite to |
| |
251 * avoid blocking the main thread. |
| |
252 */ |
| |
253 class ContentHostIncremental : public ContentHostBase |
| |
254 { |
| |
255 public: |
| |
256 ContentHostIncremental(const TextureInfo& aTextureInfo); |
| |
257 ~ContentHostIncremental(); |
| |
258 |
| |
259 virtual CompositableType GetType() { return BUFFER_CONTENT_INC; } |
| |
260 |
| |
261 virtual LayerRenderState GetRenderState() MOZ_OVERRIDE { return LayerRenderState(); } |
| |
262 |
| |
263 virtual bool CreatedIncrementalTexture(ISurfaceAllocator* aAllocator, |
| |
264 const TextureInfo& aTextureInfo, |
| |
265 const nsIntRect& aBufferRect) MOZ_OVERRIDE; |
| |
266 |
| |
267 virtual void UpdateIncremental(TextureIdentifier aTextureId, |
| |
268 SurfaceDescriptor& aSurface, |
| |
269 const nsIntRegion& aUpdated, |
| |
270 const nsIntRect& aBufferRect, |
| |
271 const nsIntPoint& aBufferRotation) MOZ_OVERRIDE; |
| |
272 |
| |
273 virtual bool UpdateThebes(const ThebesBufferData& aData, |
| |
274 const nsIntRegion& aUpdated, |
| |
275 const nsIntRegion& aOldValidRegionBack, |
| |
276 nsIntRegion* aUpdatedRegionBack) |
| |
277 { |
| |
278 NS_ERROR("Shouldn't call this"); |
| |
279 return false; |
| |
280 } |
| |
281 |
| |
282 virtual bool Lock() { |
| |
283 MOZ_ASSERT(!mLocked); |
| |
284 ProcessTextureUpdates(); |
| |
285 mLocked = true; |
| |
286 return true; |
| |
287 } |
| |
288 |
| |
289 virtual void Unlock() { |
| |
290 MOZ_ASSERT(mLocked); |
| |
291 mLocked = false; |
| |
292 } |
| |
293 |
| |
294 virtual NewTextureSource* GetTextureSource(); |
| |
295 virtual NewTextureSource* GetTextureSourceOnWhite(); |
| |
296 |
| |
297 private: |
| |
298 |
| |
299 void FlushUpdateQueue(); |
| |
300 void ProcessTextureUpdates(); |
| |
301 |
| |
302 class Request |
| |
303 { |
| |
304 public: |
| |
305 Request() |
| |
306 { |
| |
307 MOZ_COUNT_CTOR(ContentHostIncremental::Request); |
| |
308 } |
| |
309 |
| |
310 virtual ~Request() |
| |
311 { |
| |
312 MOZ_COUNT_DTOR(ContentHostIncremental::Request); |
| |
313 } |
| |
314 |
| |
315 virtual void Execute(ContentHostIncremental *aHost) = 0; |
| |
316 }; |
| |
317 |
| |
318 class TextureCreationRequest : public Request |
| |
319 { |
| |
320 public: |
| |
321 TextureCreationRequest(const TextureInfo& aTextureInfo, |
| |
322 const nsIntRect& aBufferRect) |
| |
323 : mTextureInfo(aTextureInfo) |
| |
324 , mBufferRect(aBufferRect) |
| |
325 {} |
| |
326 |
| |
327 virtual void Execute(ContentHostIncremental *aHost); |
| |
328 |
| |
329 private: |
| |
330 TextureInfo mTextureInfo; |
| |
331 nsIntRect mBufferRect; |
| |
332 }; |
| |
333 |
| |
334 class TextureUpdateRequest : public Request |
| |
335 { |
| |
336 public: |
| |
337 TextureUpdateRequest(ISurfaceAllocator* aDeAllocator, |
| |
338 TextureIdentifier aTextureId, |
| |
339 SurfaceDescriptor& aDescriptor, |
| |
340 const nsIntRegion& aUpdated, |
| |
341 const nsIntRect& aBufferRect, |
| |
342 const nsIntPoint& aBufferRotation) |
| |
343 : mDeAllocator(aDeAllocator) |
| |
344 , mTextureId(aTextureId) |
| |
345 , mDescriptor(aDescriptor) |
| |
346 , mUpdated(aUpdated) |
| |
347 , mBufferRect(aBufferRect) |
| |
348 , mBufferRotation(aBufferRotation) |
| |
349 {} |
| |
350 |
| |
351 ~TextureUpdateRequest() |
| |
352 { |
| |
353 //TODO: Recycle these? |
| |
354 mDeAllocator->DestroySharedSurface(&mDescriptor); |
| |
355 } |
| |
356 |
| |
357 virtual void Execute(ContentHostIncremental *aHost); |
| |
358 |
| |
359 private: |
| |
360 enum XSide { |
| |
361 LEFT, RIGHT |
| |
362 }; |
| |
363 enum YSide { |
| |
364 TOP, BOTTOM |
| |
365 }; |
| |
366 |
| |
367 nsIntRect GetQuadrantRectangle(XSide aXSide, YSide aYSide) const; |
| |
368 |
| |
369 RefPtr<ISurfaceAllocator> mDeAllocator; |
| |
370 TextureIdentifier mTextureId; |
| |
371 SurfaceDescriptor mDescriptor; |
| |
372 nsIntRegion mUpdated; |
| |
373 nsIntRect mBufferRect; |
| |
374 nsIntPoint mBufferRotation; |
| |
375 }; |
| |
376 |
| |
377 nsTArray<nsAutoPtr<Request> > mUpdateList; |
| |
378 |
| |
379 // Specific to OGL to avoid exposing methods on TextureSource that only |
| |
380 // have one implementation. |
| |
381 RefPtr<TextureImageTextureSourceOGL> mSource; |
| |
382 RefPtr<TextureImageTextureSourceOGL> mSourceOnWhite; |
| |
383 |
| |
384 RefPtr<ISurfaceAllocator> mDeAllocator; |
| |
385 bool mLocked; |
| |
386 }; |
| |
387 |
| |
388 } |
| |
389 } |
| |
390 |
| |
391 #endif |