|
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_TILEDCONTENTHOST_H |
|
7 #define GFX_TILEDCONTENTHOST_H |
|
8 |
|
9 #include <stdint.h> // for uint16_t |
|
10 #include <stdio.h> // for FILE |
|
11 #include <algorithm> // for swap |
|
12 #include "ContentHost.h" // for ContentHost |
|
13 #include "TiledLayerBuffer.h" // for TiledLayerBuffer, etc |
|
14 #include "CompositableHost.h" |
|
15 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc |
|
16 #include "mozilla/Attributes.h" // for MOZ_OVERRIDE |
|
17 #include "mozilla/RefPtr.h" // for RefPtr |
|
18 #include "mozilla/gfx/Point.h" // for Point |
|
19 #include "mozilla/gfx/Rect.h" // for Rect |
|
20 #include "mozilla/gfx/Types.h" // for Filter |
|
21 #include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc |
|
22 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor |
|
23 #include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc |
|
24 #include "mozilla/layers/TextureHost.h" // for TextureHost |
|
25 #include "mozilla/layers/TiledContentClient.h" |
|
26 #include "mozilla/mozalloc.h" // for operator delete |
|
27 #include "nsRegion.h" // for nsIntRegion |
|
28 #include "nscore.h" // for nsACString |
|
29 |
|
30 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 |
|
31 #include <ui/Fence.h> |
|
32 #endif |
|
33 |
|
34 class gfxReusableSurfaceWrapper; |
|
35 struct nsIntPoint; |
|
36 struct nsIntRect; |
|
37 struct nsIntSize; |
|
38 |
|
39 namespace mozilla { |
|
40 namespace gfx { |
|
41 class Matrix4x4; |
|
42 } |
|
43 |
|
44 namespace layers { |
|
45 |
|
46 class Compositor; |
|
47 class ISurfaceAllocator; |
|
48 class Layer; |
|
49 class ThebesBufferData; |
|
50 struct EffectChain; |
|
51 |
|
52 |
|
53 class TileHost { |
|
54 public: |
|
55 // Constructs a placeholder TileHost. See the comments above |
|
56 // TiledLayerBuffer for more information on what this is used for; |
|
57 // essentially, this is a sentinel used to represent an invalid or blank |
|
58 // tile. |
|
59 TileHost() |
|
60 : mSharedLock(nullptr) |
|
61 , mTextureHost(nullptr) |
|
62 {} |
|
63 |
|
64 // Constructs a TileHost from a gfxSharedReadLock and TextureHost. |
|
65 TileHost(gfxSharedReadLock* aSharedLock, |
|
66 TextureHost* aTextureHost) |
|
67 : mSharedLock(aSharedLock) |
|
68 , mTextureHost(aTextureHost) |
|
69 {} |
|
70 |
|
71 TileHost(const TileHost& o) { |
|
72 mTextureHost = o.mTextureHost; |
|
73 mSharedLock = o.mSharedLock; |
|
74 } |
|
75 TileHost& operator=(const TileHost& o) { |
|
76 if (this == &o) { |
|
77 return *this; |
|
78 } |
|
79 mTextureHost = o.mTextureHost; |
|
80 mSharedLock = o.mSharedLock; |
|
81 return *this; |
|
82 } |
|
83 |
|
84 bool operator== (const TileHost& o) const { |
|
85 return mTextureHost == o.mTextureHost; |
|
86 } |
|
87 bool operator!= (const TileHost& o) const { |
|
88 return mTextureHost != o.mTextureHost; |
|
89 } |
|
90 |
|
91 bool IsPlaceholderTile() const { return mTextureHost == nullptr; } |
|
92 |
|
93 void ReadUnlock() { |
|
94 if (mSharedLock) { |
|
95 mSharedLock->ReadUnlock(); |
|
96 } |
|
97 } |
|
98 |
|
99 RefPtr<gfxSharedReadLock> mSharedLock; |
|
100 RefPtr<TextureHost> mTextureHost; |
|
101 }; |
|
102 |
|
103 class TiledLayerBufferComposite |
|
104 : public TiledLayerBuffer<TiledLayerBufferComposite, TileHost> |
|
105 { |
|
106 friend class TiledLayerBuffer<TiledLayerBufferComposite, TileHost>; |
|
107 |
|
108 public: |
|
109 typedef TiledLayerBuffer<TiledLayerBufferComposite, TileHost>::Iterator Iterator; |
|
110 |
|
111 TiledLayerBufferComposite(); |
|
112 TiledLayerBufferComposite(ISurfaceAllocator* aAllocator, |
|
113 const SurfaceDescriptorTiles& aDescriptor, |
|
114 const nsIntRegion& aOldPaintedRegion); |
|
115 |
|
116 TileHost GetPlaceholderTile() const { return TileHost(); } |
|
117 |
|
118 // Stores the absolute resolution of the containing frame, calculated |
|
119 // by the sum of the resolutions of all parent layers' FrameMetrics. |
|
120 const CSSToParentLayerScale& GetFrameResolution() { return mFrameResolution; } |
|
121 |
|
122 void ReadUnlock(); |
|
123 |
|
124 void ReleaseTextureHosts(); |
|
125 |
|
126 /** |
|
127 * This will synchronously upload any necessary texture contents, making the |
|
128 * sources immediately available for compositing. For texture hosts that |
|
129 * don't have an internal buffer, this is unlikely to actually do anything. |
|
130 */ |
|
131 void Upload(); |
|
132 |
|
133 void SetCompositor(Compositor* aCompositor); |
|
134 |
|
135 bool HasDoubleBufferedTiles() { return mHasDoubleBufferedTiles; } |
|
136 |
|
137 bool IsValid() const { return !mUninitialized; } |
|
138 |
|
139 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 |
|
140 virtual void SetReleaseFence(const android::sp<android::Fence>& aReleaseFence); |
|
141 #endif |
|
142 |
|
143 // Recycle callback for TextureHost. |
|
144 // Used when TiledContentClient is present in client side. |
|
145 static void RecycleCallback(TextureHost* textureHost, void* aClosure); |
|
146 |
|
147 protected: |
|
148 TileHost ValidateTile(TileHost aTile, |
|
149 const nsIntPoint& aTileRect, |
|
150 const nsIntRegion& dirtyRect); |
|
151 |
|
152 // do nothing, the desctructor in the texture host takes care of releasing resources |
|
153 void ReleaseTile(TileHost aTile) {} |
|
154 |
|
155 void SwapTiles(TileHost& aTileA, TileHost& aTileB) { std::swap(aTileA, aTileB); } |
|
156 |
|
157 private: |
|
158 CSSToParentLayerScale mFrameResolution; |
|
159 bool mHasDoubleBufferedTiles; |
|
160 bool mUninitialized; |
|
161 }; |
|
162 |
|
163 /** |
|
164 * ContentHost for tiled Thebes layers. Since tiled layers are special snow |
|
165 * flakes, we have a unique update process. All the textures that back the |
|
166 * tiles are added in the usual way, but Updated is called on the host side |
|
167 * in response to a message that describes the transaction for every tile. |
|
168 * Composition happens in the normal way. |
|
169 * |
|
170 * TiledContentHost has a TiledLayerBufferComposite which keeps hold of the tiles. |
|
171 * Each tile has a reference to a texture host. During the layers transaction, we |
|
172 * receive a list of descriptors for the client-side tile buffer tiles |
|
173 * (UseTiledLayerBuffer). If we receive two transactions before a composition, |
|
174 * we immediately unlock and discard the unused buffer. |
|
175 * |
|
176 * When the content host is composited, we first validate the TiledLayerBuffer |
|
177 * (Upload), which calls Updated on each tile's texture host to make sure the |
|
178 * texture data has been uploaded. For single-buffered tiles, we unlock at this |
|
179 * point, for double-buffered tiles we unlock and discard the last composited |
|
180 * buffer after compositing a new one. Rendering takes us to RenderTile which |
|
181 * is similar to Composite for non-tiled ContentHosts. |
|
182 */ |
|
183 class TiledContentHost : public ContentHost, |
|
184 public TiledLayerComposer |
|
185 { |
|
186 public: |
|
187 TiledContentHost(const TextureInfo& aTextureInfo); |
|
188 |
|
189 ~TiledContentHost(); |
|
190 |
|
191 virtual LayerRenderState GetRenderState() MOZ_OVERRIDE |
|
192 { |
|
193 return LayerRenderState(); |
|
194 } |
|
195 |
|
196 |
|
197 virtual bool UpdateThebes(const ThebesBufferData& aData, |
|
198 const nsIntRegion& aUpdated, |
|
199 const nsIntRegion& aOldValidRegionBack, |
|
200 nsIntRegion* aUpdatedRegionBack) |
|
201 { |
|
202 NS_ERROR("N/A for tiled layers"); |
|
203 return false; |
|
204 } |
|
205 |
|
206 const nsIntRegion& GetValidLowPrecisionRegion() const |
|
207 { |
|
208 return mLowPrecisionTiledBuffer.GetValidRegion(); |
|
209 } |
|
210 |
|
211 void UseTiledLayerBuffer(ISurfaceAllocator* aAllocator, |
|
212 const SurfaceDescriptorTiles& aTiledDescriptor); |
|
213 |
|
214 void Composite(EffectChain& aEffectChain, |
|
215 float aOpacity, |
|
216 const gfx::Matrix4x4& aTransform, |
|
217 const gfx::Filter& aFilter, |
|
218 const gfx::Rect& aClipRect, |
|
219 const nsIntRegion* aVisibleRegion = nullptr, |
|
220 TiledLayerProperties* aLayerProperties = nullptr); |
|
221 |
|
222 virtual CompositableType GetType() { return BUFFER_TILED; } |
|
223 |
|
224 virtual TiledLayerComposer* AsTiledLayerComposer() MOZ_OVERRIDE { return this; } |
|
225 |
|
226 virtual void Attach(Layer* aLayer, |
|
227 Compositor* aCompositor, |
|
228 AttachFlags aFlags = NO_FLAGS) MOZ_OVERRIDE; |
|
229 |
|
230 #ifdef MOZ_DUMP_PAINTING |
|
231 virtual void Dump(FILE* aFile=nullptr, |
|
232 const char* aPrefix="", |
|
233 bool aDumpHtml=false) MOZ_OVERRIDE; |
|
234 #endif |
|
235 |
|
236 virtual void PrintInfo(nsACString& aTo, const char* aPrefix); |
|
237 |
|
238 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 |
|
239 /** |
|
240 * Store a fence that will signal when the current buffer is no longer being read. |
|
241 * Similar to android's GLConsumer::setReleaseFence() |
|
242 */ |
|
243 virtual void SetReleaseFence(const android::sp<android::Fence>& aReleaseFence) |
|
244 { |
|
245 mTiledBuffer.SetReleaseFence(aReleaseFence); |
|
246 mLowPrecisionTiledBuffer.SetReleaseFence(aReleaseFence); |
|
247 } |
|
248 #endif |
|
249 |
|
250 private: |
|
251 |
|
252 void RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer, |
|
253 EffectChain& aEffectChain, |
|
254 float aOpacity, |
|
255 const gfx::Filter& aFilter, |
|
256 const gfx::Rect& aClipRect, |
|
257 nsIntRegion aMaskRegion, |
|
258 gfx::Matrix4x4 aTransform); |
|
259 |
|
260 // Renders a single given tile. |
|
261 void RenderTile(const TileHost& aTile, |
|
262 EffectChain& aEffectChain, |
|
263 float aOpacity, |
|
264 const gfx::Matrix4x4& aTransform, |
|
265 const gfx::Filter& aFilter, |
|
266 const gfx::Rect& aClipRect, |
|
267 const nsIntRegion& aScreenRegion, |
|
268 const nsIntPoint& aTextureOffset, |
|
269 const nsIntSize& aTextureBounds); |
|
270 |
|
271 void EnsureTileStore() {} |
|
272 |
|
273 TiledLayerBufferComposite mTiledBuffer; |
|
274 TiledLayerBufferComposite mLowPrecisionTiledBuffer; |
|
275 TiledLayerBufferComposite mOldTiledBuffer; |
|
276 TiledLayerBufferComposite mOldLowPrecisionTiledBuffer; |
|
277 bool mPendingUpload; |
|
278 bool mPendingLowPrecisionUpload; |
|
279 }; |
|
280 |
|
281 } |
|
282 } |
|
283 |
|
284 #endif |