|
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 MOZILLA_GFX_IMAGEBRIDGECHILD_H |
|
7 #define MOZILLA_GFX_IMAGEBRIDGECHILD_H |
|
8 |
|
9 #include <stddef.h> // for size_t |
|
10 #include <stdint.h> // for uint32_t, uint64_t |
|
11 #include "mozilla/Attributes.h" // for MOZ_OVERRIDE |
|
12 #include "mozilla/RefPtr.h" // for TemporaryRef |
|
13 #include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc |
|
14 #include "mozilla/layers/CompositableForwarder.h" |
|
15 #include "mozilla/layers/CompositorTypes.h" // for TextureIdentifier, etc |
|
16 #include "mozilla/layers/LayersSurfaces.h" // for PGrallocBufferChild |
|
17 #include "mozilla/layers/PImageBridgeChild.h" |
|
18 #include "nsDebug.h" // for NS_RUNTIMEABORT |
|
19 #include "nsRegion.h" // for nsIntRegion |
|
20 class MessageLoop; |
|
21 struct nsIntPoint; |
|
22 struct nsIntRect; |
|
23 |
|
24 namespace base { |
|
25 class Thread; |
|
26 } |
|
27 |
|
28 namespace mozilla { |
|
29 namespace ipc { |
|
30 class Shmem; |
|
31 } |
|
32 |
|
33 namespace layers { |
|
34 |
|
35 class ClientTiledLayerBuffer; |
|
36 class ImageClient; |
|
37 class ImageContainer; |
|
38 class ImageBridgeParent; |
|
39 class CompositableClient; |
|
40 class CompositableTransaction; |
|
41 class Image; |
|
42 class TextureClient; |
|
43 |
|
44 /** |
|
45 * Returns true if the current thread is the ImageBrdigeChild's thread. |
|
46 * |
|
47 * Can be called from any thread. |
|
48 */ |
|
49 bool InImageBridgeChildThread(); |
|
50 |
|
51 /** |
|
52 * The ImageBridge protocol is meant to allow ImageContainers to forward images |
|
53 * directly to the compositor thread/process without using the main thread. |
|
54 * |
|
55 * ImageBridgeChild is a CompositableForwarder just like ShadowLayerForwarder. |
|
56 * This means it also does transactions with the compositor thread/process, |
|
57 * except that the transactions are restricted to operations on the Compositables |
|
58 * and cannot contain messages affecting layers directly. |
|
59 * |
|
60 * ImageBridgeChild is also a ISurfaceAllocator. It can be used to allocate or |
|
61 * deallocate data that is shared with the compositor. The main differerence |
|
62 * with other ISurfaceAllocators is that some of its overriden methods can be |
|
63 * invoked from any thread. |
|
64 * |
|
65 * There are three important phases in the ImageBridge protocol. These three steps |
|
66 * can do different things depending if (A) the ImageContainer uses ImageBridge |
|
67 * or (B) it does not use ImageBridge: |
|
68 * |
|
69 * - When an ImageContainer calls its method SetCurrentImage: |
|
70 * - (A) The image is sent directly to the compositor process through the |
|
71 * ImageBridge IPDL protocol. |
|
72 * On the compositor side the image is stored in a global table that associates |
|
73 * the image with an ID corresponding to the ImageContainer, and a composition is |
|
74 * triggered. |
|
75 * - (B) Since it does not have an ImageBridge, the image is not sent yet. |
|
76 * instead the will be sent to the compositor during the next layer transaction |
|
77 * (on the main thread). |
|
78 * |
|
79 * - During a Layer transaction: |
|
80 * - (A) The ImageContainer uses ImageBridge. The image is already available to the |
|
81 * compositor process because it has been sent with SetCurrentImage. Yet, the |
|
82 * CompositableHost on the compositor side will needs the ID referring to the |
|
83 * ImageContainer to access the Image. So during the Swap operation that happens |
|
84 * in the transaction, we swap the container ID rather than the image data. |
|
85 * - (B) Since the ImageContainer does not use ImageBridge, the image data is swaped. |
|
86 * |
|
87 * - During composition: |
|
88 * - (A) The CompositableHost has an AsyncID, it looks up the ID in the |
|
89 * global table to see if there is an image. If there is no image, nothing is rendered. |
|
90 * - (B) The CompositableHost has image data rather than an ID (meaning it is not |
|
91 * using ImageBridge), then it just composites the image data normally. |
|
92 * |
|
93 * This means that there might be a possibility for the ImageBridge to send the first |
|
94 * frame before the first layer transaction that will pass the container ID to the |
|
95 * CompositableHost happens. In this (unlikely) case the layer is not composited |
|
96 * until the layer transaction happens. This means this scenario is not harmful. |
|
97 * |
|
98 * Since sending an image through imageBridge triggers compositing, the main thread is |
|
99 * not used at all (except for the very first transaction that provides the |
|
100 * CompositableHost with an AsyncID). |
|
101 */ |
|
102 class ImageBridgeChild : public PImageBridgeChild |
|
103 , public CompositableForwarder |
|
104 { |
|
105 friend class ImageContainer; |
|
106 public: |
|
107 |
|
108 /** |
|
109 * Creates the image bridge with a dedicated thread for ImageBridgeChild. |
|
110 * |
|
111 * We may want to use a specifi thread in the future. In this case, use |
|
112 * CreateWithThread instead. |
|
113 */ |
|
114 static void StartUp(); |
|
115 |
|
116 static PImageBridgeChild* |
|
117 StartUpInChildProcess(Transport* aTransport, ProcessId aOtherProcess); |
|
118 |
|
119 /** |
|
120 * Destroys the image bridge by calling DestroyBridge, and destroys the |
|
121 * ImageBridge's thread. |
|
122 * |
|
123 * If you don't want to destroy the thread, call DestroyBridge directly |
|
124 * instead. |
|
125 */ |
|
126 static void ShutDown(); |
|
127 |
|
128 /** |
|
129 * Creates the ImageBridgeChild manager protocol. |
|
130 */ |
|
131 static bool StartUpOnThread(base::Thread* aThread); |
|
132 |
|
133 /** |
|
134 * Returns true if the singleton has been created. |
|
135 * |
|
136 * Can be called from any thread. |
|
137 */ |
|
138 static bool IsCreated(); |
|
139 |
|
140 /** |
|
141 * returns the singleton instance. |
|
142 * |
|
143 * can be called from any thread. |
|
144 */ |
|
145 static ImageBridgeChild* GetSingleton(); |
|
146 |
|
147 |
|
148 /** |
|
149 * Dispatches a task to the ImageBridgeChild thread to do the connection |
|
150 */ |
|
151 void ConnectAsync(ImageBridgeParent* aParent); |
|
152 |
|
153 static void IdentifyCompositorTextureHost(const TextureFactoryIdentifier& aIdentifier); |
|
154 |
|
155 void BeginTransaction(); |
|
156 void EndTransaction(); |
|
157 |
|
158 /** |
|
159 * Returns the ImageBridgeChild's thread. |
|
160 * |
|
161 * Can be called from any thread. |
|
162 */ |
|
163 base::Thread * GetThread() const; |
|
164 |
|
165 /** |
|
166 * Returns the ImageBridgeChild's message loop. |
|
167 * |
|
168 * Can be called from any thread. |
|
169 */ |
|
170 MessageLoop * GetMessageLoop() const; |
|
171 |
|
172 PCompositableChild* AllocPCompositableChild(const TextureInfo& aInfo, uint64_t* aID) MOZ_OVERRIDE; |
|
173 bool DeallocPCompositableChild(PCompositableChild* aActor) MOZ_OVERRIDE; |
|
174 |
|
175 /** |
|
176 * This must be called by the static function DeleteImageBridgeSync defined |
|
177 * in ImageBridgeChild.cpp ONLY. |
|
178 */ |
|
179 ~ImageBridgeChild(); |
|
180 |
|
181 virtual PGrallocBufferChild* |
|
182 AllocPGrallocBufferChild(const gfx::IntSize&, const uint32_t&, const uint32_t&, |
|
183 MaybeMagicGrallocBufferHandle*) MOZ_OVERRIDE; |
|
184 |
|
185 virtual bool |
|
186 DeallocPGrallocBufferChild(PGrallocBufferChild* actor) MOZ_OVERRIDE; |
|
187 |
|
188 virtual PTextureChild* |
|
189 AllocPTextureChild(const SurfaceDescriptor& aSharedData, const TextureFlags& aFlags) MOZ_OVERRIDE; |
|
190 |
|
191 virtual bool |
|
192 DeallocPTextureChild(PTextureChild* actor) MOZ_OVERRIDE; |
|
193 |
|
194 TemporaryRef<ImageClient> CreateImageClient(CompositableType aType); |
|
195 TemporaryRef<ImageClient> CreateImageClientNow(CompositableType aType); |
|
196 |
|
197 static void DispatchReleaseImageClient(ImageClient* aClient); |
|
198 static void DispatchReleaseTextureClient(TextureClient* aClient); |
|
199 static void DispatchImageClientUpdate(ImageClient* aClient, ImageContainer* aContainer); |
|
200 |
|
201 /** |
|
202 * Flush all Images sent to CompositableHost. |
|
203 */ |
|
204 static void FlushAllImages(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront); |
|
205 |
|
206 /** |
|
207 * Must be called on the ImageBridgeChild's thread. |
|
208 */ |
|
209 static void FlushAllImagesNow(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront); |
|
210 |
|
211 // CompositableForwarder |
|
212 |
|
213 virtual void Connect(CompositableClient* aCompositable) MOZ_OVERRIDE; |
|
214 |
|
215 /** |
|
216 * See CompositableForwarder::UpdatedTexture |
|
217 */ |
|
218 virtual void UpdatedTexture(CompositableClient* aCompositable, |
|
219 TextureClient* aTexture, |
|
220 nsIntRegion* aRegion) MOZ_OVERRIDE; |
|
221 |
|
222 /** |
|
223 * See CompositableForwarder::UseTexture |
|
224 */ |
|
225 virtual void UseTexture(CompositableClient* aCompositable, |
|
226 TextureClient* aClient) MOZ_OVERRIDE; |
|
227 virtual void UseComponentAlphaTextures(CompositableClient* aCompositable, |
|
228 TextureClient* aClientOnBlack, |
|
229 TextureClient* aClientOnWhite) MOZ_OVERRIDE; |
|
230 |
|
231 virtual void RemoveTextureFromCompositable(CompositableClient* aCompositable, |
|
232 TextureClient* aTexture) MOZ_OVERRIDE; |
|
233 |
|
234 virtual void RemoveTexture(TextureClient* aTexture) MOZ_OVERRIDE; |
|
235 |
|
236 virtual void UseTiledLayerBuffer(CompositableClient* aCompositable, |
|
237 const SurfaceDescriptorTiles& aTileLayerDescriptor) MOZ_OVERRIDE |
|
238 { |
|
239 NS_RUNTIMEABORT("should not be called"); |
|
240 } |
|
241 |
|
242 virtual void UpdateTextureIncremental(CompositableClient* aCompositable, |
|
243 TextureIdentifier aTextureId, |
|
244 SurfaceDescriptor& aDescriptor, |
|
245 const nsIntRegion& aUpdatedRegion, |
|
246 const nsIntRect& aBufferRect, |
|
247 const nsIntPoint& aBufferRotation) MOZ_OVERRIDE |
|
248 { |
|
249 NS_RUNTIMEABORT("should not be called"); |
|
250 } |
|
251 |
|
252 /** |
|
253 * Communicate the picture rect of a YUV image in aLayer to the compositor |
|
254 */ |
|
255 virtual void UpdatePictureRect(CompositableClient* aCompositable, |
|
256 const nsIntRect& aRect) MOZ_OVERRIDE; |
|
257 |
|
258 |
|
259 virtual void CreatedIncrementalBuffer(CompositableClient* aCompositable, |
|
260 const TextureInfo& aTextureInfo, |
|
261 const nsIntRect& aBufferRect) MOZ_OVERRIDE |
|
262 { |
|
263 NS_RUNTIMEABORT("should not be called"); |
|
264 } |
|
265 virtual void UpdateTextureRegion(CompositableClient* aCompositable, |
|
266 const ThebesBufferData& aThebesBufferData, |
|
267 const nsIntRegion& aUpdatedRegion) MOZ_OVERRIDE { |
|
268 NS_RUNTIMEABORT("should not be called"); |
|
269 } |
|
270 |
|
271 // ISurfaceAllocator |
|
272 |
|
273 /** |
|
274 * See ISurfaceAllocator.h |
|
275 * Can be used from any thread. |
|
276 * If used outside the ImageBridgeChild thread, it will proxy a synchronous |
|
277 * call on the ImageBridgeChild thread. |
|
278 */ |
|
279 virtual bool AllocUnsafeShmem(size_t aSize, |
|
280 mozilla::ipc::SharedMemory::SharedMemoryType aType, |
|
281 mozilla::ipc::Shmem* aShmem) MOZ_OVERRIDE; |
|
282 /** |
|
283 * See ISurfaceAllocator.h |
|
284 * Can be used from any thread. |
|
285 * If used outside the ImageBridgeChild thread, it will proxy a synchronous |
|
286 * call on the ImageBridgeChild thread. |
|
287 */ |
|
288 virtual bool AllocShmem(size_t aSize, |
|
289 mozilla::ipc::SharedMemory::SharedMemoryType aType, |
|
290 mozilla::ipc::Shmem* aShmem) MOZ_OVERRIDE; |
|
291 /** |
|
292 * See ISurfaceAllocator.h |
|
293 * Can be used from any thread. |
|
294 * If used outside the ImageBridgeChild thread, it will proxy a synchronous |
|
295 * call on the ImageBridgeChild thread. |
|
296 */ |
|
297 virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem); |
|
298 |
|
299 virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData, |
|
300 TextureFlags aFlags) MOZ_OVERRIDE; |
|
301 |
|
302 virtual bool IsSameProcess() const MOZ_OVERRIDE; |
|
303 |
|
304 void AllocGrallocBufferNow(const gfx::IntSize& aSize, |
|
305 uint32_t aFormat, uint32_t aUsage, |
|
306 MaybeMagicGrallocBufferHandle* aHandle, |
|
307 PGrallocBufferChild** aChild); |
|
308 |
|
309 void MarkShutDown(); |
|
310 protected: |
|
311 ImageBridgeChild(); |
|
312 bool DispatchAllocShmemInternal(size_t aSize, |
|
313 SharedMemory::SharedMemoryType aType, |
|
314 Shmem* aShmem, |
|
315 bool aUnsafe); |
|
316 |
|
317 CompositableTransaction* mTxn; |
|
318 bool mShuttingDown; |
|
319 |
|
320 // ISurfaceAllocator |
|
321 virtual PGrallocBufferChild* AllocGrallocBuffer(const gfx::IntSize& aSize, |
|
322 uint32_t aFormat, uint32_t aUsage, |
|
323 MaybeMagicGrallocBufferHandle* aHandle) MOZ_OVERRIDE; |
|
324 |
|
325 virtual void DeallocGrallocBuffer(PGrallocBufferChild* aChild) MOZ_OVERRIDE; |
|
326 }; |
|
327 |
|
328 } // layers |
|
329 } // mozilla |
|
330 |
|
331 #endif |