gfx/layers/client/TextureClient.h

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:3ddbb33ab111
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_TEXTURECLIENT_H
7 #define MOZILLA_GFX_TEXTURECLIENT_H
8
9 #include <stddef.h> // for size_t
10 #include <stdint.h> // for uint32_t, uint8_t, uint64_t
11 #include "GLContextTypes.h" // for GLContext (ptr only), etc
12 #include "GLTextureImage.h" // for TextureImage
13 #include "ImageTypes.h" // for StereoMode
14 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
15 #include "mozilla/Attributes.h" // for MOZ_OVERRIDE
16 #include "mozilla/RefPtr.h" // for RefPtr, RefCounted
17 #include "mozilla/gfx/2D.h" // for DrawTarget
18 #include "mozilla/gfx/Point.h" // for IntSize
19 #include "mozilla/gfx/Types.h" // for SurfaceFormat
20 #include "mozilla/layers/FenceUtils.h" // for FenceHandle
21 #include "mozilla/ipc/Shmem.h" // for Shmem
22 #include "mozilla/layers/AtomicRefCountedWithFinalize.h"
23 #include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc
24 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
25 #include "mozilla/layers/PTextureChild.h" // for PTextureChild
26 #include "mozilla/mozalloc.h" // for operator delete
27 #include "nsAutoPtr.h" // for nsRefPtr
28 #include "nsCOMPtr.h" // for already_AddRefed
29 #include "nsISupportsImpl.h" // for TextureImage::AddRef, etc
30
31 class gfxReusableSurfaceWrapper;
32 class gfxImageSurface;
33
34 namespace mozilla {
35 namespace layers {
36
37 class ContentClient;
38 class CompositableForwarder;
39 class ISurfaceAllocator;
40 class CompositableClient;
41 class PlanarYCbCrImage;
42 class PlanarYCbCrData;
43 class Image;
44 class PTextureChild;
45 class TextureChild;
46 class BufferTextureClient;
47 class TextureClient;
48
49 /**
50 * TextureClient is the abstraction that allows us to share data between the
51 * content and the compositor side.
52 */
53
54 enum TextureAllocationFlags {
55 ALLOC_DEFAULT = 0,
56 ALLOC_CLEAR_BUFFER = 1
57 };
58
59 /**
60 * Interface for TextureClients that can be updated using YCbCr data.
61 */
62 class TextureClientYCbCr
63 {
64 public:
65 /**
66 * Copy aData into this texture client.
67 *
68 * This must never be called on a TextureClient that is not sucessfully locked.
69 */
70 virtual bool UpdateYCbCr(const PlanarYCbCrData& aData) = 0;
71
72 /**
73 * Allocates for a given surface size, taking into account the pixel format
74 * which is part of the state of the TextureClient.
75 *
76 * Does not clear the surface, since we consider that the surface
77 * be painted entirely with opaque content.
78 */
79 virtual bool AllocateForYCbCr(gfx::IntSize aYSize,
80 gfx::IntSize aCbCrSize,
81 StereoMode aStereoMode) = 0;
82 };
83
84 /**
85 * Holds the shared data of a TextureClient, to be destroyed later.
86 *
87 * TextureClient's destructor initiates the destruction sequence of the
88 * texture client/host pair. If the shared data is to be deallocated on the
89 * host side, there is nothing to do.
90 * On the other hand, if the client data must be deallocated on the client
91 * side, the CompositableClient will ask the TextureClient to drop its shared
92 * data in the form of a TextureClientData object. This data will be kept alive
93 * until the host side confirms that it is not using the data anymore and that
94 * it is completely safe to deallocate the shared data.
95 *
96 * See:
97 * - The PTexture IPDL protocol
98 * - CompositableChild in TextureClient.cpp
99 */
100 class TextureClientData {
101 public:
102 virtual void DeallocateSharedData(ISurfaceAllocator* allocator) = 0;
103 virtual ~TextureClientData() {}
104 };
105
106 /**
107 * TextureClient is a thin abstraction over texture data that need to be shared
108 * between the content process and the compositor process. It is the
109 * content-side half of a TextureClient/TextureHost pair. A corresponding
110 * TextureHost lives on the compositor-side.
111 *
112 * TextureClient's primary purpose is to present texture data in a way that is
113 * understood by the IPC system. There are two ways to use it:
114 * - Use it to serialize image data that is not IPC-friendly (most likely
115 * involving a copy into shared memory)
116 * - preallocate it and paint directly into it, which avoids copy but requires
117 * the painting code to be aware of TextureClient (or at least the underlying
118 * shared memory).
119 *
120 * There is always one and only one TextureClient per TextureHost, and the
121 * TextureClient/Host pair only owns one buffer of image data through its
122 * lifetime. This means that the lifetime of the underlying shared data
123 * matches the lifetime of the TextureClient/Host pair. It also means
124 * TextureClient/Host do not implement double buffering, which is the
125 * responsibility of the compositable (which would use two Texture pairs).
126 * In order to send several different buffers to the compositor side, use
127 * several TextureClients.
128 */
129 class TextureClient
130 : public AtomicRefCountedWithFinalize<TextureClient>
131 {
132 public:
133 TextureClient(TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT);
134 virtual ~TextureClient();
135
136 static TemporaryRef<BufferTextureClient>
137 CreateBufferTextureClient(ISurfaceAllocator* aAllocator,
138 gfx::SurfaceFormat aFormat,
139 TextureFlags aTextureFlags,
140 gfx::BackendType aMoz2dBackend);
141
142 static TemporaryRef<TextureClient>
143 CreateTextureClientForDrawing(ISurfaceAllocator* aAllocator,
144 gfx::SurfaceFormat aFormat,
145 TextureFlags aTextureFlags,
146 gfx::BackendType aMoz2dBackend,
147 const gfx::IntSize& aSizeHint);
148
149 virtual TextureClientYCbCr* AsTextureClientYCbCr() { return nullptr; }
150
151 /**
152 * Locks the shared data, allowing the caller to get access to it.
153 *
154 * Please always lock/unlock when accessing the shared data.
155 * If Lock() returns false, you should not attempt to access the shared data.
156 */
157 virtual bool Lock(OpenMode aMode) { return IsValid(); }
158
159 virtual void Unlock() {}
160
161 virtual bool IsLocked() const = 0;
162
163 virtual bool CanExposeDrawTarget() const { return false; }
164
165 /**
166 * Returns a DrawTarget to draw into the TextureClient.
167 *
168 * This must never be called on a TextureClient that is not sucessfully locked.
169 * When called several times within one Lock/Unlock pair, this method should
170 * return the same DrawTarget.
171 * The DrawTarget is automatically flushed by the TextureClient when the latter
172 * is unlocked, and the DrawTarget that will be returned within the next
173 * lock/unlock pair may or may not be the same object.
174 * Do not keep references to the DrawTarget outside of the lock/unlock pair.
175 *
176 * This is typically used as follows:
177 *
178 * if (!texture->Lock(OPEN_READ_WRITE)) {
179 * return false;
180 * }
181 * {
182 * // Restrict this code's scope to ensure all references to dt are gone
183 * // when Unlock is called.
184 * RefPtr<DrawTarget> dt = texture->GetAsDrawTarget();
185 * // use the draw target ...
186 * }
187 * texture->Unlock();
188 *
189 */
190 virtual TemporaryRef<gfx::DrawTarget> GetAsDrawTarget() { return nullptr; }
191
192 // TextureClients that can expose a DrawTarget should override this method.
193 virtual gfx::SurfaceFormat GetFormat() const
194 {
195 return gfx::SurfaceFormat::UNKNOWN;
196 }
197
198 /**
199 * Allocates for a given surface size, taking into account the pixel format
200 * which is part of the state of the TextureClient.
201 *
202 * Does not clear the surface by default, clearing the surface can be done
203 * by passing the CLEAR_BUFFER flag.
204 *
205 * TextureClients that can expose a DrawTarget should override this method.
206 */
207 virtual bool AllocateForSurface(gfx::IntSize aSize,
208 TextureAllocationFlags flags = ALLOC_DEFAULT)
209 {
210 return false;
211 }
212
213 /**
214 * Copies a rectangle from this texture client to a position in aTarget.
215 * It is assumed that the necessary locks are in place; so this should at
216 * least have a read lock and aTarget should at least have a write lock.
217 */
218 virtual bool CopyToTextureClient(TextureClient* aTarget,
219 const gfx::IntRect* aRect,
220 const gfx::IntPoint* aPoint);
221
222 /**
223 * Returns true if this texture has a lock/unlock mechanism.
224 * Textures that do not implement locking should be immutable or should
225 * use immediate uploads (see TextureFlags in CompositorTypes.h)
226 */
227 virtual bool ImplementsLocking() const { return false; }
228
229 /**
230 * Indicates whether the TextureClient implementation is backed by an
231 * in-memory buffer. The consequence of this is that locking the
232 * TextureClient does not contend with locking the texture on the host side.
233 */
234 virtual bool HasInternalBuffer() const = 0;
235
236 /**
237 * Allocate and deallocate a TextureChild actor.
238 *
239 * TextureChild is an implementation detail of TextureClient that is not
240 * exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor
241 * are for use with the managing IPDL protocols only (so that they can
242 * implement AllocPextureChild and DeallocPTextureChild).
243 */
244 static PTextureChild* CreateIPDLActor();
245 static bool DestroyIPDLActor(PTextureChild* actor);
246
247 /**
248 * Get the TextureClient corresponding to the actor passed in parameter.
249 */
250 static TextureClient* AsTextureClient(PTextureChild* actor);
251
252 virtual bool IsAllocated() const = 0;
253
254 virtual gfx::IntSize GetSize() const = 0;
255
256 /**
257 * TextureFlags contain important information about various aspects
258 * of the texture, like how its liferime is managed, and how it
259 * should be displayed.
260 * See TextureFlags in CompositorTypes.h.
261 */
262 TextureFlags GetFlags() const { return mFlags; }
263
264 /**
265 * valid only for TEXTURE_RECYCLE TextureClient.
266 * When called this texture client will grab a strong reference and release
267 * it once the compositor notifies that it is done with the texture.
268 * NOTE: In this stage the texture client can no longer be used by the
269 * client in a transaction.
270 */
271 void WaitForCompositorRecycle();
272
273 /**
274 * After being shared with the compositor side, an immutable texture is never
275 * modified, it can only be read. It is safe to not Lock/Unlock immutable
276 * textures.
277 */
278 bool IsImmutable() const { return mFlags & TEXTURE_IMMUTABLE; }
279
280 void MarkImmutable() { AddFlags(TEXTURE_IMMUTABLE); }
281
282 bool IsSharedWithCompositor() const { return mShared; }
283
284 bool ShouldDeallocateInDestructor() const;
285
286 /**
287 * If this method returns false users of TextureClient are not allowed
288 * to access the shared data.
289 */
290 bool IsValid() const { return mValid; }
291
292 /**
293 * Create and init the TextureChild/Parent IPDL actor pair.
294 *
295 * Should be called only once per TextureClient.
296 */
297 bool InitIPDLActor(CompositableForwarder* aForwarder);
298
299 /**
300 * Return a pointer to the IPDLActor.
301 *
302 * This is to be used with IPDL messages only. Do not store the returned
303 * pointer.
304 */
305 PTextureChild* GetIPDLActor();
306
307 /**
308 * Triggers the destruction of the shared data and the corresponding TextureHost.
309 *
310 * If the texture flags contain TEXTURE_DEALLOCATE_CLIENT, the destruction
311 * will be synchronously coordinated with the compositor side, otherwise it
312 * will be done asynchronously.
313 */
314 void ForceRemove();
315
316 virtual void SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle) {}
317
318 const FenceHandle& GetReleaseFenceHandle() const
319 {
320 return mReleaseFenceHandle;
321 }
322
323 /**
324 * Wait until the current buffer is no longer being read.
325 *
326 * Platform support is necessary. gonk JB supports this function.
327 */
328 virtual void WaitReleaseFence() {}
329
330 private:
331 /**
332 * Called once, just before the destructor.
333 *
334 * Here goes the shut-down code that uses virtual methods.
335 * Must only be called by Release().
336 */
337 void Finalize();
338
339 friend class AtomicRefCountedWithFinalize<TextureClient>;
340
341 protected:
342 /**
343 * An invalid TextureClient cannot provide access to its shared data
344 * anymore. This usually means it will soon be destroyed.
345 */
346 void MarkInvalid() { mValid = false; }
347
348 /**
349 * Drop the shared data into a TextureClientData object and mark this
350 * TextureClient as invalid.
351 *
352 * The TextureClient must not hold any reference to the shared data
353 * after this method has been called.
354 * The TextureClientData is owned by the caller.
355 */
356 virtual TextureClientData* DropTextureData() = 0;
357
358 /**
359 * Should only be called *once* per texture, in TextureClient::InitIPDLActor.
360 * Some texture implementations rely on the fact that the descriptor will be
361 * deserialized.
362 * Calling ToSurfaceDescriptor again after it has already returned true,
363 * or never constructing a TextureHost with aDescriptor may result in a memory
364 * leak (see CairoTextureClientD3D9 for example).
365 */
366 virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) = 0;
367
368 void AddFlags(TextureFlags aFlags)
369 {
370 MOZ_ASSERT(!IsSharedWithCompositor());
371 mFlags |= aFlags;
372 }
373
374 RefPtr<TextureChild> mActor;
375 TextureFlags mFlags;
376 bool mShared;
377 bool mValid;
378 FenceHandle mReleaseFenceHandle;
379
380 friend class TextureChild;
381 friend void TestTextureClientSurface(TextureClient*, gfxImageSurface*);
382 friend void TestTextureClientYCbCr(TextureClient*, PlanarYCbCrData&);
383 };
384
385 /**
386 * TextureClient that wraps a random access buffer such as a Shmem or raw memory.
387 * This class must be inherited to implement the memory allocation and access bits.
388 * (see ShmemTextureClient and MemoryTextureClient)
389 */
390 class BufferTextureClient : public TextureClient
391 , public TextureClientYCbCr
392 {
393 public:
394 BufferTextureClient(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
395 gfx::BackendType aBackend, TextureFlags aFlags);
396
397 virtual ~BufferTextureClient();
398
399 virtual bool IsAllocated() const = 0;
400
401 virtual uint8_t* GetBuffer() const = 0;
402
403 virtual gfx::IntSize GetSize() const { return mSize; }
404
405 virtual bool Lock(OpenMode aMode) MOZ_OVERRIDE;
406
407 virtual void Unlock() MOZ_OVERRIDE;
408
409 virtual bool IsLocked() const MOZ_OVERRIDE { return mLocked; }
410
411 virtual bool CanExposeDrawTarget() const MOZ_OVERRIDE { return true; }
412
413 virtual TemporaryRef<gfx::DrawTarget> GetAsDrawTarget() MOZ_OVERRIDE;
414
415 virtual bool AllocateForSurface(gfx::IntSize aSize,
416 TextureAllocationFlags aFlags = ALLOC_DEFAULT) MOZ_OVERRIDE;
417
418 // TextureClientYCbCr
419
420 virtual TextureClientYCbCr* AsTextureClientYCbCr() MOZ_OVERRIDE { return this; }
421
422 virtual bool UpdateYCbCr(const PlanarYCbCrData& aData) MOZ_OVERRIDE;
423
424 virtual bool AllocateForYCbCr(gfx::IntSize aYSize,
425 gfx::IntSize aCbCrSize,
426 StereoMode aStereoMode) MOZ_OVERRIDE;
427
428 virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; }
429
430 // XXX - Bug 908196 - Make Allocate(uint32_t) and GetBufferSize() protected.
431 // these two methods should only be called by methods of BufferTextureClient
432 // that are overridden in GrallocTextureClient (which does not implement the
433 // two methods below)
434 virtual bool Allocate(uint32_t aSize) = 0;
435
436 virtual size_t GetBufferSize() const = 0;
437
438 virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return true; }
439
440 ISurfaceAllocator* GetAllocator() const;
441
442 protected:
443 RefPtr<gfx::DrawTarget> mDrawTarget;
444 RefPtr<ISurfaceAllocator> mAllocator;
445 gfx::SurfaceFormat mFormat;
446 gfx::IntSize mSize;
447 gfx::BackendType mBackend;
448 OpenMode mOpenMode;
449 bool mUsingFallbackDrawTarget;
450 bool mLocked;
451 };
452
453 /**
454 * TextureClient that wraps shared memory.
455 * the corresponding texture on the host side is ShmemTextureHost.
456 */
457 class ShmemTextureClient : public BufferTextureClient
458 {
459 public:
460 ShmemTextureClient(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
461 gfx::BackendType aBackend, TextureFlags aFlags);
462
463 ~ShmemTextureClient();
464
465 virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
466
467 virtual bool Allocate(uint32_t aSize) MOZ_OVERRIDE;
468
469 virtual uint8_t* GetBuffer() const MOZ_OVERRIDE;
470
471 virtual size_t GetBufferSize() const MOZ_OVERRIDE;
472
473 virtual bool IsAllocated() const MOZ_OVERRIDE { return mAllocated; }
474
475 virtual TextureClientData* DropTextureData() MOZ_OVERRIDE;
476
477 virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return true; }
478
479 mozilla::ipc::Shmem& GetShmem() { return mShmem; }
480
481 protected:
482 mozilla::ipc::Shmem mShmem;
483 bool mAllocated;
484 };
485
486 /**
487 * TextureClient that wraps raw memory.
488 * The corresponding texture on the host side is MemoryTextureHost.
489 * Can obviously not be used in a cross process setup.
490 */
491 class MemoryTextureClient : public BufferTextureClient
492 {
493 public:
494 MemoryTextureClient(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
495 gfx::BackendType aBackend, TextureFlags aFlags);
496
497 ~MemoryTextureClient();
498
499 virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE;
500
501 virtual bool Allocate(uint32_t aSize) MOZ_OVERRIDE;
502
503 virtual uint8_t* GetBuffer() const MOZ_OVERRIDE { return mBuffer; }
504
505 virtual size_t GetBufferSize() const MOZ_OVERRIDE { return mBufSize; }
506
507 virtual bool IsAllocated() const MOZ_OVERRIDE { return mBuffer != nullptr; }
508
509 virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return true; }
510
511 virtual TextureClientData* DropTextureData() MOZ_OVERRIDE;
512
513 protected:
514 uint8_t* mBuffer;
515 size_t mBufSize;
516 };
517
518 struct TextureClientAutoUnlock
519 {
520 TextureClient* mTexture;
521
522 TextureClientAutoUnlock(TextureClient* aTexture)
523 : mTexture(aTexture) {}
524
525 ~TextureClientAutoUnlock()
526 {
527 mTexture->Unlock();
528 }
529 };
530
531 }
532 }
533 #endif

mercurial