Line data Source code
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_TEXTUREHOST_H
7 : #define MOZILLA_GFX_TEXTUREHOST_H
8 :
9 : #include <functional>
10 : #include <stddef.h> // for size_t
11 : #include <stdint.h> // for uint64_t, uint32_t, uint8_t
12 : #include "gfxTypes.h"
13 : #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
14 : #include "mozilla/Attributes.h" // for override
15 : #include "mozilla/RefPtr.h" // for RefPtr, already_AddRefed, etc
16 : #include "mozilla/gfx/2D.h" // for DataSourceSurface
17 : #include "mozilla/gfx/Point.h" // for IntSize, IntPoint
18 : #include "mozilla/gfx/Types.h" // for SurfaceFormat, etc
19 : #include "mozilla/layers/Compositor.h" // for Compositor
20 : #include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc
21 : #include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc
22 : #include "mozilla/layers/LayersSurfaces.h"
23 : #include "mozilla/mozalloc.h" // for operator delete
24 : #include "mozilla/Range.h"
25 : #include "mozilla/UniquePtr.h" // for UniquePtr
26 : #include "mozilla/webrender/WebRenderTypes.h"
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 "nsRegion.h" // for nsIntRegion
31 : #include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
32 : #include "nscore.h" // for nsACString
33 : #include "mozilla/layers/AtomicRefCountedWithFinalize.h"
34 : #include "mozilla/gfx/Rect.h"
35 :
36 : namespace mozilla {
37 : namespace ipc {
38 : class Shmem;
39 : } // namespace ipc
40 :
41 : namespace wr {
42 : class DisplayListBuilder;
43 : class WebRenderAPI;
44 : }
45 :
46 : namespace layers {
47 :
48 : class BufferDescriptor;
49 : class BufferTextureHost;
50 : class Compositor;
51 : class CompositableParentManager;
52 : class ReadLockDescriptor;
53 : class CompositorBridgeParent;
54 : class SurfaceDescriptor;
55 : class HostIPCAllocator;
56 : class ISurfaceAllocator;
57 : class MacIOSurfaceTextureHostOGL;
58 : class TextureHostOGL;
59 : class TextureReadLock;
60 : class TextureSourceOGL;
61 : class TextureSourceD3D11;
62 : class TextureSourceBasic;
63 : class DataTextureSource;
64 : class PTextureParent;
65 : class TextureParent;
66 : class WebRenderTextureHost;
67 : class WrappingTextureSourceYCbCrBasic;
68 :
69 : /**
70 : * A view on a TextureHost where the texture is internally represented as tiles
71 : * (contrast with a tiled buffer, where each texture is a tile). For iteration by
72 : * the texture's buffer host.
73 : * This is only useful when the underlying surface is too big to fit in one
74 : * device texture, which forces us to split it in smaller parts.
75 : * Tiled Compositable is a different thing.
76 : */
77 0 : class BigImageIterator
78 : {
79 : public:
80 : virtual void BeginBigImageIteration() = 0;
81 0 : virtual void EndBigImageIteration() {};
82 : virtual gfx::IntRect GetTileRect() = 0;
83 : virtual size_t GetTileCount() = 0;
84 : virtual bool NextTile() = 0;
85 : };
86 :
87 : /**
88 : * TextureSource is the interface for texture objects that can be composited
89 : * by a given compositor backend. Since the drawing APIs are different
90 : * between backends, the TextureSource interface is split into different
91 : * interfaces (TextureSourceOGL, etc.), and TextureSource mostly provide
92 : * access to these interfaces.
93 : *
94 : * This class is used on the compositor side.
95 : */
96 : class TextureSource: public RefCounted<TextureSource>
97 : {
98 : public:
99 469 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(TextureSource)
100 :
101 : TextureSource();
102 :
103 : virtual ~TextureSource();
104 :
105 : virtual const char* Name() const = 0;
106 :
107 : /**
108 : * Should be overridden in order to deallocate the data that is associated
109 : * with the rendering backend, such as GL textures.
110 : */
111 0 : virtual void DeallocateDeviceData() {}
112 :
113 :
114 : /**
115 : * Return the size of the texture in texels.
116 : * If this is a tile iterator, GetSize must return the size of the current tile.
117 : */
118 : virtual gfx::IntSize GetSize() const = 0;
119 :
120 : /**
121 : * Return the pixel format of this texture
122 : */
123 0 : virtual gfx::SurfaceFormat GetFormat() const { return gfx::SurfaceFormat::UNKNOWN; }
124 :
125 : /**
126 : * Cast to a TextureSource for for each backend..
127 : */
128 0 : virtual TextureSourceOGL* AsSourceOGL() {
129 0 : gfxCriticalNote << "Failed to cast " << Name() << " into a TextureSourceOGL";
130 0 : return nullptr;
131 : }
132 0 : virtual TextureSourceD3D11* AsSourceD3D11() { return nullptr; }
133 0 : virtual TextureSourceBasic* AsSourceBasic() { return nullptr; }
134 : /**
135 : * Cast to a DataTextureSurce.
136 : */
137 0 : virtual DataTextureSource* AsDataTextureSource() { return nullptr; }
138 0 : virtual WrappingTextureSourceYCbCrBasic* AsWrappingTextureSourceYCbCrBasic() { return nullptr; }
139 :
140 : /**
141 : * Overload this if the TextureSource supports big textures that don't fit in
142 : * one device texture and must be tiled internally.
143 : */
144 56 : virtual BigImageIterator* AsBigImageIterator() { return nullptr; }
145 :
146 0 : virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) {}
147 :
148 31 : virtual void Unbind() {}
149 :
150 0 : void SetNextSibling(TextureSource* aTexture) { mNextSibling = aTexture; }
151 :
152 6 : TextureSource* GetNextSibling() const { return mNextSibling; }
153 :
154 : /**
155 : * In some rare cases we currently need to consider a group of textures as one
156 : * TextureSource, that can be split in sub-TextureSources.
157 : */
158 0 : TextureSource* GetSubSource(int index)
159 : {
160 0 : switch (index) {
161 0 : case 0: return this;
162 0 : case 1: return GetNextSibling();
163 0 : case 2: return GetNextSibling() ? GetNextSibling()->GetNextSibling() : nullptr;
164 : }
165 0 : return nullptr;
166 : }
167 :
168 89 : void AddCompositableRef() { ++mCompositableCount; }
169 :
170 87 : void ReleaseCompositableRef() {
171 87 : --mCompositableCount;
172 87 : MOZ_ASSERT(mCompositableCount >= 0);
173 87 : }
174 :
175 : // When iterating as a BigImage, this creates temporary TextureSources wrapping
176 : // individual tiles.
177 0 : virtual RefPtr<TextureSource> ExtractCurrentTile() {
178 0 : NS_WARNING("Implementation does not expose tile sources");
179 0 : return nullptr;
180 : }
181 :
182 12 : int NumCompositableRefs() const { return mCompositableCount; }
183 :
184 : protected:
185 :
186 : RefPtr<TextureSource> mNextSibling;
187 : int mCompositableCount;
188 : };
189 :
190 : /// Equivalent of a RefPtr<TextureSource>, that calls AddCompositableRef and
191 : /// ReleaseCompositableRef in addition to the usual AddRef and Release.
192 : ///
193 : /// The semantoics of these CompositableTextureRefs are important because they
194 : /// are used both as a synchronization/safety mechanism, and as an optimization
195 : /// mechanism. They are also tricky and subtle because we use them in a very
196 : /// implicit way (assigning to a CompositableTextureRef is less visible than
197 : /// explicitly calling a method or whatnot).
198 : /// It is Therefore important to be careful about the way we use this tool.
199 : ///
200 : /// CompositableTextureRef is a mechanism that lets us count how many compositables
201 : /// are using a given texture (for TextureSource and TextureHost).
202 : /// We use it to run specific code when a texture is not used anymore, and also
203 : /// we trigger fast paths on some operations when we can see that the texture's
204 : /// CompositableTextureRef counter is equal to 1 (the texture is not shared
205 : /// between compositables).
206 : /// This means that it is important to observe the following rules:
207 : /// * CompositableHosts that receive UseTexture and similar messages *must* store
208 : /// all of the TextureHosts they receive in CompositableTextureRef slots for as
209 : /// long as they may be using them.
210 : /// * CompositableHosts must store each texture in a *single* CompositableTextureRef
211 : /// slot to ensure that the counter properly reflects how many compositables are
212 : /// using the texture.
213 : /// If a compositable needs to hold two references to a given texture (for example
214 : /// to have a pointer to the current texture in a list of textures that may be
215 : /// used), it can hold its extra references with RefPtr or whichever pointer type
216 : /// makes sense.
217 : template<typename T>
218 : class CompositableTextureRef {
219 : public:
220 121 : CompositableTextureRef() {}
221 :
222 0 : explicit CompositableTextureRef(const CompositableTextureRef& aOther)
223 0 : {
224 0 : *this = aOther;
225 0 : }
226 :
227 0 : explicit CompositableTextureRef(T* aOther)
228 0 : {
229 0 : *this = aOther;
230 0 : }
231 :
232 109 : ~CompositableTextureRef()
233 : {
234 109 : if (mRef) {
235 37 : mRef->ReleaseCompositableRef();
236 : }
237 109 : }
238 :
239 33 : CompositableTextureRef& operator=(const CompositableTextureRef& aOther)
240 : {
241 33 : if (aOther.get()) {
242 33 : aOther->AddCompositableRef();
243 : }
244 33 : if (mRef) {
245 29 : mRef->ReleaseCompositableRef();
246 : }
247 33 : mRef = aOther.get();
248 33 : return *this;
249 : }
250 :
251 244 : CompositableTextureRef& operator=(T* aOther)
252 : {
253 244 : if (aOther) {
254 122 : aOther->AddCompositableRef();
255 : }
256 244 : if (mRef) {
257 85 : mRef->ReleaseCompositableRef();
258 : }
259 244 : mRef = aOther;
260 244 : return *this;
261 : }
262 :
263 234 : T* get() const { return mRef; }
264 634 : operator T*() const { return mRef; }
265 478 : T* operator->() const { return mRef; }
266 : T& operator*() const { return *mRef; }
267 :
268 : private:
269 : RefPtr<T> mRef;
270 : };
271 :
272 : typedef CompositableTextureRef<TextureSource> CompositableTextureSourceRef;
273 : typedef CompositableTextureRef<TextureHost> CompositableTextureHostRef;
274 :
275 : /**
276 : * Interface for TextureSources that can be updated from a DataSourceSurface.
277 : *
278 : * All backend should implement at least one DataTextureSource.
279 : */
280 6 : class DataTextureSource : public TextureSource
281 : {
282 : public:
283 9 : DataTextureSource()
284 9 : : mOwner(0)
285 9 : , mUpdateSerial(0)
286 9 : {}
287 :
288 0 : virtual const char* Name() const override { return "DataTextureSource"; }
289 :
290 0 : virtual DataTextureSource* AsDataTextureSource() override { return this; }
291 :
292 : /**
293 : * Upload a (portion of) surface to the TextureSource.
294 : *
295 : * The DataTextureSource doesn't own aSurface, although it owns and manage
296 : * the device texture it uploads to internally.
297 : */
298 : virtual bool Update(gfx::DataSourceSurface* aSurface,
299 : nsIntRegion* aDestRegion = nullptr,
300 : gfx::IntPoint* aSrcOffset = nullptr) = 0;
301 :
302 : /**
303 : * A facility to avoid reuploading when it is not necessary.
304 : * The caller of Update can use GetUpdateSerial to see if the number has changed
305 : * since last update, and call SetUpdateSerial after each successful update.
306 : * The caller is responsible for managing the update serial except when the
307 : * texture data is deallocated in which case the TextureSource should always
308 : * reset the update serial to zero.
309 : */
310 89 : uint32_t GetUpdateSerial() const { return mUpdateSerial; }
311 63 : void SetUpdateSerial(uint32_t aValue) { mUpdateSerial = aValue; }
312 :
313 : // By default at least set the update serial to zero.
314 : // overloaded versions should do that too.
315 0 : virtual void DeallocateDeviceData() override
316 : {
317 0 : SetUpdateSerial(0);
318 0 : }
319 :
320 : #ifdef DEBUG
321 : /**
322 : * Provide read access to the data as a DataSourceSurface.
323 : *
324 : * This is expected to be very slow and should be used for mostly debugging.
325 : * XXX - implement everywhere and make it pure virtual.
326 : */
327 0 : virtual already_AddRefed<gfx::DataSourceSurface> ReadBack() { return nullptr; };
328 : #endif
329 :
330 15 : void SetOwner(TextureHost* aOwner)
331 : {
332 15 : auto newOwner = (uintptr_t)aOwner;
333 15 : if (newOwner != mOwner) {
334 15 : mOwner = newOwner;
335 15 : SetUpdateSerial(0);
336 : }
337 15 : }
338 :
339 133 : bool IsOwnedBy(TextureHost* aOwner) const { return mOwner == (uintptr_t)aOwner; }
340 :
341 0 : bool HasOwner() const { return !IsOwnedBy(nullptr); }
342 :
343 : private:
344 : // We store mOwner as an integer rather than as a pointer to make it clear
345 : // it is not intended to be dereferenced.
346 : uintptr_t mOwner;
347 : uint32_t mUpdateSerial;
348 : };
349 :
350 : /**
351 : * TextureHost is a thin abstraction over texture data that need to be shared
352 : * between the content process and the compositor process. It is the
353 : * compositor-side half of a TextureClient/TextureHost pair. A corresponding
354 : * TextureClient lives on the content-side.
355 : *
356 : * TextureHost only knows how to deserialize or synchronize generic image data
357 : * (SurfaceDescriptor) and provide access to one or more TextureSource objects
358 : * (these provide the necessary APIs for compositor backends to composite the
359 : * image).
360 : *
361 : * A TextureHost implementation corresponds to one SurfaceDescriptor type, as
362 : * opposed to TextureSource that corresponds to device textures.
363 : * This means that for YCbCr planes, even though they are represented as
364 : * 3 textures internally (3 TextureSources), we use 1 TextureHost and not 3,
365 : * because the 3 planes are stored in the same buffer of shared memory, before
366 : * they are uploaded separately.
367 : *
368 : * There is always one and only one TextureHost per TextureClient, and the
369 : * TextureClient/Host pair only owns one buffer of image data through its
370 : * lifetime. This means that the lifetime of the underlying shared data
371 : * matches the lifetime of the TextureClient/Host pair. It also means
372 : * TextureClient/Host do not implement double buffering, which is the
373 : * reponsibility of the compositable (which would use two Texture pairs).
374 : *
375 : * The Lock/Unlock mecanism here mirrors Lock/Unlock in TextureClient.
376 : *
377 : */
378 : class TextureHost
379 : : public AtomicRefCountedWithFinalize<TextureHost>
380 : {
381 : /**
382 : * Called once, just before the destructor.
383 : *
384 : * Here goes the shut-down code that uses virtual methods.
385 : * Must only be called by Release().
386 : */
387 : void Finalize();
388 :
389 : friend class AtomicRefCountedWithFinalize<TextureHost>;
390 : public:
391 : explicit TextureHost(TextureFlags aFlags);
392 :
393 : protected:
394 : virtual ~TextureHost();
395 :
396 : public:
397 : /**
398 : * Factory method.
399 : */
400 : static already_AddRefed<TextureHost> Create(
401 : const SurfaceDescriptor& aDesc,
402 : ISurfaceAllocator* aDeallocator,
403 : LayersBackend aBackend,
404 : TextureFlags aFlags,
405 : wr::MaybeExternalImageId& aExternalImageId);
406 :
407 : /**
408 : * Lock the texture host for compositing.
409 : */
410 0 : virtual bool Lock() { return true; }
411 : /**
412 : * Unlock the texture host after compositing. Lock() and Unlock() should be
413 : * called in pair.
414 : */
415 0 : virtual void Unlock() {}
416 :
417 : /**
418 : * Lock the texture host for compositing without using compositor.
419 : */
420 0 : virtual bool LockWithoutCompositor() { return true; }
421 : /**
422 : * Similar to Unlock(), but it should be called with LockWithoutCompositor().
423 : */
424 0 : virtual void UnlockWithoutCompositor() {}
425 :
426 : /**
427 : * Note that the texture host format can be different from its corresponding
428 : * texture source's. For example a ShmemTextureHost can have the ycbcr
429 : * format and produce 3 "alpha" textures sources.
430 : */
431 : virtual gfx::SurfaceFormat GetFormat() const = 0;
432 : /**
433 : * Return the format used for reading the texture.
434 : * Apple's YCBCR_422 is R8G8B8X8.
435 : */
436 0 : virtual gfx::SurfaceFormat GetReadFormat() const { return GetFormat(); }
437 :
438 0 : virtual YUVColorSpace GetYUVColorSpace() const { return YUVColorSpace::UNKNOWN; }
439 :
440 : /**
441 : * Called during the transaction. The TextureSource may or may not be composited.
442 : *
443 : * Note that this is called outside of lock/unlock.
444 : */
445 0 : virtual void PrepareTextureSource(CompositableTextureSourceRef& aTexture) {}
446 :
447 : /**
448 : * Called at composition time, just before compositing the TextureSource composited.
449 : *
450 : * Note that this is called only withing lock/unlock.
451 : */
452 : virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) = 0;
453 :
454 : /**
455 : * Called when preparing the rendering pipeline for advanced-layers. This is
456 : * a lockless version of BindTextureSource.
457 : */
458 0 : virtual bool AcquireTextureSource(CompositableTextureSourceRef& aTexture) {
459 0 : return false;
460 : }
461 :
462 : /**
463 : * Called when another TextureHost will take over.
464 : */
465 : virtual void UnbindTextureSource();
466 :
467 : /**
468 : * Is called before compositing if the shared data has changed since last
469 : * composition.
470 : * This method should be overload in cases like when we need to do a texture
471 : * upload for example.
472 : *
473 : * @param aRegion The region that has been changed, if nil, it means that the
474 : * entire surface should be updated.
475 : */
476 : void Updated(const nsIntRegion* aRegion = nullptr);
477 :
478 : /**
479 : * Sets this TextureHost's compositor. A TextureHost can change compositor
480 : * on certain occasions, in particular if it belongs to an async Compositable.
481 : * aCompositor can be null, in which case the TextureHost must cleanup all
482 : * of its device textures.
483 : *
484 : * Setting mProvider from this callback implicitly causes the texture to
485 : * be locked for an extra frame after being detached from a compositable.
486 : */
487 0 : virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) {}
488 :
489 : /**
490 : * Should be overridden in order to deallocate the data that is associated
491 : * with the rendering backend, such as GL textures.
492 : */
493 0 : virtual void DeallocateDeviceData() {}
494 :
495 : /**
496 : * Should be overridden in order to deallocate the data that is shared with
497 : * the content side, such as shared memory.
498 : */
499 0 : virtual void DeallocateSharedData() {}
500 :
501 : /**
502 : * Should be overridden in order to force the TextureHost to drop all references
503 : * to it's shared data.
504 : *
505 : * This is important to ensure the correctness of the deallocation protocol.
506 : */
507 0 : virtual void ForgetSharedData() {}
508 :
509 : virtual gfx::IntSize GetSize() const = 0;
510 :
511 : /**
512 : * Should be overridden if TextureHost supports crop rect.
513 : */
514 0 : virtual void SetCropRect(nsIntRect aCropRect) {}
515 :
516 : /**
517 : * Debug facility.
518 : * XXX - cool kids use Moz2D. See bug 882113.
519 : */
520 : virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() = 0;
521 :
522 : /**
523 : * XXX - Flags should only be set at creation time, this will be removed.
524 : */
525 : void SetFlags(TextureFlags aFlags) { mFlags = aFlags; }
526 :
527 : /**
528 : * XXX - Flags should only be set at creation time, this will be removed.
529 : */
530 : void AddFlag(TextureFlags aFlag) { mFlags |= aFlag; }
531 :
532 74 : TextureFlags GetFlags() { return mFlags; }
533 :
534 : /**
535 : * Allocate and deallocate a TextureParent actor.
536 : *
537 : * TextureParent< is an implementation detail of TextureHost that is not
538 : * exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor
539 : * are for use with the managing IPDL protocols only (so that they can
540 : * implement AllocPTextureParent and DeallocPTextureParent).
541 : */
542 : static PTextureParent* CreateIPDLActor(HostIPCAllocator* aAllocator,
543 : const SurfaceDescriptor& aSharedData,
544 : LayersBackend aLayersBackend,
545 : TextureFlags aFlags,
546 : uint64_t aSerial,
547 : const wr::MaybeExternalImageId& aExternalImageId);
548 : static bool DestroyIPDLActor(PTextureParent* actor);
549 :
550 : /**
551 : * Destroy the TextureChild/Parent pair.
552 : */
553 : static bool SendDeleteIPDLActor(PTextureParent* actor);
554 :
555 : static void ReceivedDestroy(PTextureParent* actor);
556 :
557 : /**
558 : * Get the TextureHost corresponding to the actor passed in parameter.
559 : */
560 : static TextureHost* AsTextureHost(PTextureParent* actor);
561 :
562 : static uint64_t GetTextureSerial(PTextureParent* actor);
563 :
564 : /**
565 : * Return a pointer to the IPDLActor.
566 : *
567 : * This is to be used with IPDL messages only. Do not store the returned
568 : * pointer.
569 : */
570 : PTextureParent* GetIPDLActor();
571 :
572 : // If a texture host holds a reference to shmem, it should override this method
573 : // to forget about the shmem _without_ releasing it.
574 0 : virtual void OnShutdown() {}
575 :
576 : // Forget buffer actor. Used only for hacky fix for bug 966446.
577 0 : virtual void ForgetBufferActor() {}
578 :
579 0 : virtual const char *Name() { return "TextureHost"; }
580 : virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
581 :
582 : /**
583 : * Indicates whether the TextureHost implementation is backed by an
584 : * in-memory buffer. The consequence of this is that locking the
585 : * TextureHost does not contend with locking the texture on the client side.
586 : */
587 0 : virtual bool HasIntermediateBuffer() const { return false; }
588 :
589 66 : void AddCompositableRef() { ++mCompositableCount; }
590 :
591 64 : void ReleaseCompositableRef()
592 : {
593 64 : --mCompositableCount;
594 64 : MOZ_ASSERT(mCompositableCount >= 0);
595 64 : if (mCompositableCount == 0) {
596 31 : UnbindTextureSource();
597 : // Send mFwdTransactionId to client side if necessary.
598 31 : NotifyNotUsed();
599 : }
600 64 : }
601 :
602 33 : int NumCompositableRefs() const { return mCompositableCount; }
603 :
604 : void SetLastFwdTransactionId(uint64_t aTransactionId);
605 :
606 : void DeserializeReadLock(const ReadLockDescriptor& aDesc,
607 : ISurfaceAllocator* aAllocator);
608 : void SetReadLock(TextureReadLock* aReadLock);
609 :
610 : TextureReadLock* GetReadLock() { return mReadLock; }
611 :
612 0 : virtual BufferTextureHost* AsBufferTextureHost() { return nullptr; }
613 0 : virtual MacIOSurfaceTextureHostOGL* AsMacIOSurfaceTextureHost() { return nullptr; }
614 0 : virtual WebRenderTextureHost* AsWebRenderTextureHost() { return nullptr; }
615 :
616 : // Create the corresponding RenderTextureHost type of this texture, and
617 : // register the RenderTextureHost into render thread.
618 0 : virtual void CreateRenderTexture(const wr::ExternalImageId& aExternalImageId)
619 : {
620 0 : MOZ_RELEASE_ASSERT(false, "No CreateRenderTexture() implementation for this TextureHost type.");
621 : }
622 :
623 : // Create all necessary image keys for this textureHost rendering.
624 : // @param aImageKeys - [out] The set of ImageKeys used for this textureHost
625 : // composing.
626 : // @param aImageKeyAllocator - [in] The function which is used for creating
627 : // the new ImageKey.
628 0 : virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
629 : const std::function<wr::ImageKey()>& aImageKeyAllocator)
630 : {
631 0 : MOZ_ASSERT(aImageKeys.IsEmpty());
632 0 : MOZ_ASSERT_UNREACHABLE("No GetWRImageKeys() implementation for this TextureHost type.");
633 : }
634 :
635 : // Add all necessary textureHost informations to WebrenderAPI. Then, WR could
636 : // use these informations to compose this textureHost.
637 0 : virtual void AddWRImage(wr::WebRenderAPI* aAPI,
638 : Range<const wr::ImageKey>& aImageKeys,
639 : const wr::ExternalImageId& aExtID)
640 : {
641 0 : MOZ_ASSERT_UNREACHABLE("No AddWRImage() implementation for this TextureHost type.");
642 : }
643 :
644 : // Put all necessary WR commands into DisplayListBuilder for this textureHost rendering.
645 0 : virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
646 : const WrRect& aBounds,
647 : const WrRect& aClip,
648 : wr::ImageRendering aFilter,
649 : Range<const wr::ImageKey>& aKeys)
650 : {
651 0 : MOZ_ASSERT_UNREACHABLE("No PushExternalImage() implementation for this TextureHost type.");
652 : }
653 :
654 : protected:
655 : void ReadUnlock();
656 :
657 : void RecycleTexture(TextureFlags aFlags);
658 :
659 0 : virtual void UpdatedInternal(const nsIntRegion *Region) {}
660 :
661 : /**
662 : * Called when mCompositableCount becomes 0.
663 : */
664 : virtual void NotifyNotUsed();
665 :
666 : // for Compositor.
667 : void CallNotifyNotUsed();
668 :
669 : PTextureParent* mActor;
670 : RefPtr<TextureSourceProvider> mProvider;
671 : RefPtr<TextureReadLock> mReadLock;
672 : TextureFlags mFlags;
673 : int mCompositableCount;
674 : uint64_t mFwdTransactionId;
675 :
676 : friend class Compositor;
677 : friend class TextureParent;
678 : friend class TiledLayerBufferComposite;
679 : friend class TextureSourceProvider;
680 : };
681 :
682 : /**
683 : * TextureHost that wraps a random access buffer such as a Shmem or some raw
684 : * memory.
685 : *
686 : * This TextureHost is backend-independent and the backend-specific bits are
687 : * in the TextureSource.
688 : * This class must be inherited to implement GetBuffer and DeallocSharedData
689 : * (see ShmemTextureHost and MemoryTextureHost)
690 : *
691 : * Uploads happen when Lock is called.
692 : *
693 : * BufferTextureHost supports YCbCr and flavours of RGBA images (RGBX, A, etc.).
694 : */
695 : class BufferTextureHost : public TextureHost
696 : {
697 : public:
698 : BufferTextureHost(const BufferDescriptor& aDescriptor, TextureFlags aFlags);
699 :
700 : ~BufferTextureHost();
701 :
702 : virtual uint8_t* GetBuffer() = 0;
703 :
704 : virtual size_t GetBufferSize() = 0;
705 :
706 : virtual bool Lock() override;
707 :
708 : virtual void Unlock() override;
709 :
710 : virtual void PrepareTextureSource(CompositableTextureSourceRef& aTexture) override;
711 :
712 : virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override;
713 : virtual bool AcquireTextureSource(CompositableTextureSourceRef& aTexture) override;
714 :
715 : virtual void UnbindTextureSource() override;
716 :
717 : virtual void DeallocateDeviceData() override;
718 :
719 : virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
720 :
721 : /**
722 : * Return the format that is exposed to the compositor when calling
723 : * BindTextureSource.
724 : *
725 : * If the shared format is YCbCr and the compositor does not support it,
726 : * GetFormat will be RGB32 (even though mFormat is SurfaceFormat::YUV).
727 : */
728 : virtual gfx::SurfaceFormat GetFormat() const override;
729 :
730 : virtual YUVColorSpace GetYUVColorSpace() const override;
731 :
732 33 : virtual gfx::IntSize GetSize() const override { return mSize; }
733 :
734 : virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
735 :
736 0 : virtual bool HasIntermediateBuffer() const override { return mHasIntermediateBuffer; }
737 :
738 0 : virtual BufferTextureHost* AsBufferTextureHost() override { return this; }
739 :
740 0 : const BufferDescriptor& GetBufferDescriptor() const { return mDescriptor; }
741 :
742 : virtual void CreateRenderTexture(const wr::ExternalImageId& aExternalImageId) override;
743 :
744 : virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
745 : const std::function<wr::ImageKey()>& aImageKeyAllocator) override;
746 :
747 : virtual void AddWRImage(wr::WebRenderAPI* aAPI,
748 : Range<const wr::ImageKey>& aImageKeys,
749 : const wr::ExternalImageId& aExtID) override;
750 :
751 : virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
752 : const WrRect& aBounds,
753 : const WrRect& aClip,
754 : wr::ImageRendering aFilter,
755 : Range<const wr::ImageKey>& aImageKeys) override;
756 :
757 : protected:
758 : bool Upload(nsIntRegion *aRegion = nullptr);
759 : bool UploadIfNeeded();
760 : bool MaybeUpload(nsIntRegion *aRegion);
761 : bool EnsureWrappingTextureSource();
762 :
763 : virtual void UpdatedInternal(const nsIntRegion* aRegion = nullptr) override;
764 :
765 : BufferDescriptor mDescriptor;
766 : RefPtr<Compositor> mCompositor;
767 : RefPtr<DataTextureSource> mFirstSource;
768 : nsIntRegion mMaybeUpdatedRegion;
769 : gfx::IntSize mSize;
770 : gfx::SurfaceFormat mFormat;
771 : uint32_t mUpdateSerial;
772 : bool mLocked;
773 : bool mNeedsFullUpdate;
774 : bool mHasIntermediateBuffer;
775 :
776 : class DataTextureSourceYCbCrBasic;
777 : };
778 :
779 : /**
780 : * TextureHost that wraps shared memory.
781 : * the corresponding texture on the client side is ShmemTextureClient.
782 : * This TextureHost is backend-independent.
783 : */
784 : class ShmemTextureHost : public BufferTextureHost
785 : {
786 : public:
787 : ShmemTextureHost(const mozilla::ipc::Shmem& aShmem,
788 : const BufferDescriptor& aDesc,
789 : ISurfaceAllocator* aDeallocator,
790 : TextureFlags aFlags);
791 :
792 : protected:
793 : ~ShmemTextureHost();
794 :
795 : public:
796 : virtual void DeallocateSharedData() override;
797 :
798 : virtual void ForgetSharedData() override;
799 :
800 : virtual uint8_t* GetBuffer() override;
801 :
802 : virtual size_t GetBufferSize() override;
803 :
804 0 : virtual const char *Name() override { return "ShmemTextureHost"; }
805 :
806 : virtual void OnShutdown() override;
807 :
808 : protected:
809 : UniquePtr<mozilla::ipc::Shmem> mShmem;
810 : RefPtr<ISurfaceAllocator> mDeallocator;
811 : };
812 :
813 : /**
814 : * TextureHost that wraps raw memory.
815 : * The corresponding texture on the client side is MemoryTextureClient.
816 : * Can obviously not be used in a cross process setup.
817 : * This TextureHost is backend-independent.
818 : */
819 : class MemoryTextureHost : public BufferTextureHost
820 : {
821 : public:
822 : MemoryTextureHost(uint8_t* aBuffer,
823 : const BufferDescriptor& aDesc,
824 : TextureFlags aFlags);
825 :
826 : protected:
827 : ~MemoryTextureHost();
828 :
829 : public:
830 : virtual void DeallocateSharedData() override;
831 :
832 : virtual void ForgetSharedData() override;
833 :
834 : virtual uint8_t* GetBuffer() override;
835 :
836 : virtual size_t GetBufferSize() override;
837 :
838 0 : virtual const char *Name() override { return "MemoryTextureHost"; }
839 :
840 : protected:
841 : uint8_t* mBuffer;
842 : };
843 :
844 : class MOZ_STACK_CLASS AutoLockTextureHost
845 : {
846 : public:
847 0 : explicit AutoLockTextureHost(TextureHost* aTexture)
848 0 : : mTexture(aTexture)
849 : {
850 0 : mLocked = mTexture ? mTexture->Lock() : false;
851 0 : }
852 :
853 0 : ~AutoLockTextureHost()
854 0 : {
855 0 : if (mTexture && mLocked) {
856 0 : mTexture->Unlock();
857 : }
858 0 : }
859 :
860 0 : bool Failed() { return mTexture && !mLocked; }
861 :
862 : private:
863 : RefPtr<TextureHost> mTexture;
864 : bool mLocked;
865 : };
866 :
867 : class MOZ_STACK_CLASS AutoLockTextureHostWithoutCompositor
868 : {
869 : public:
870 : explicit AutoLockTextureHostWithoutCompositor(TextureHost* aTexture)
871 : : mTexture(aTexture)
872 : {
873 : mLocked = mTexture ? mTexture->LockWithoutCompositor() : false;
874 : }
875 :
876 : ~AutoLockTextureHostWithoutCompositor()
877 : {
878 : if (mTexture && mLocked) {
879 : mTexture->UnlockWithoutCompositor();
880 : }
881 : }
882 :
883 : bool Failed() { return mTexture && !mLocked; }
884 :
885 : private:
886 : RefPtr<TextureHost> mTexture;
887 : bool mLocked;
888 : };
889 :
890 : /**
891 : * This can be used as an offscreen rendering target by the compositor, and
892 : * subsequently can be used as a source by the compositor.
893 : */
894 : class CompositingRenderTarget: public TextureSource
895 : {
896 : public:
897 :
898 27 : explicit CompositingRenderTarget(const gfx::IntPoint& aOrigin)
899 27 : : mClearOnBind(false)
900 : , mOrigin(aOrigin)
901 27 : , mHasComplexProjection(false)
902 27 : {}
903 27 : virtual ~CompositingRenderTarget() {}
904 :
905 0 : virtual const char* Name() const override { return "CompositingRenderTarget"; }
906 :
907 : #ifdef MOZ_DUMP_PAINTING
908 0 : virtual already_AddRefed<gfx::DataSourceSurface> Dump(Compositor* aCompositor) { return nullptr; }
909 : #endif
910 :
911 : /**
912 : * Perform a clear when recycling a non opaque surface.
913 : * The clear is deferred to when the render target is bound.
914 : */
915 0 : void ClearOnBind() {
916 0 : mClearOnBind = true;
917 0 : }
918 :
919 89 : const gfx::IntPoint& GetOrigin() const { return mOrigin; }
920 0 : gfx::IntRect GetRect() { return gfx::IntRect(GetOrigin(), GetSize()); }
921 :
922 : /**
923 : * If a Projection matrix is set, then it is used for rendering to
924 : * this render target instead of generating one. If no explicit
925 : * projection is set, Compositors are expected to generate an
926 : * orthogonal maaping that maps 0..1 to the full size of the render
927 : * target.
928 : */
929 0 : bool HasComplexProjection() const { return mHasComplexProjection; }
930 : void ClearProjection() { mHasComplexProjection = false; }
931 : void SetProjection(const gfx::Matrix4x4& aNewMatrix, bool aEnableDepthBuffer,
932 : float aZNear, float aZFar)
933 : {
934 : mProjectionMatrix = aNewMatrix;
935 : mEnableDepthBuffer = aEnableDepthBuffer;
936 : mZNear = aZNear;
937 : mZFar = aZFar;
938 : mHasComplexProjection = true;
939 : }
940 0 : void GetProjection(gfx::Matrix4x4& aMatrix, bool& aEnableDepth, float& aZNear, float& aZFar)
941 : {
942 0 : MOZ_ASSERT(mHasComplexProjection);
943 0 : aMatrix = mProjectionMatrix;
944 0 : aEnableDepth = mEnableDepthBuffer;
945 0 : aZNear = mZNear;
946 0 : aZFar = mZFar;
947 0 : }
948 : protected:
949 : bool mClearOnBind;
950 :
951 : private:
952 : gfx::IntPoint mOrigin;
953 :
954 : gfx::Matrix4x4 mProjectionMatrix;
955 : float mZNear, mZFar;
956 : bool mHasComplexProjection;
957 : bool mEnableDepthBuffer;
958 : };
959 :
960 : /**
961 : * Creates a TextureHost that can be used with any of the existing backends
962 : * Not all SurfaceDescriptor types are supported
963 : */
964 : already_AddRefed<TextureHost>
965 : CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
966 : ISurfaceAllocator* aDeallocator,
967 : LayersBackend aBackend,
968 : TextureFlags aFlags);
969 :
970 : } // namespace layers
971 : } // namespace mozilla
972 :
973 : #endif
|