1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef MOZILLA_GFX_TEXTUREHOST_H
8 #define MOZILLA_GFX_TEXTUREHOST_H
10 #include <stddef.h> // for size_t
11 #include <stdint.h> // for uint64_t, uint32_t, uint8_t
12 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
13 #include "mozilla/Attributes.h" // for override
14 #include "mozilla/RefPtr.h" // for RefPtr, already_AddRefed, etc
15 #include "mozilla/dom/ipc/IdType.h"
16 #include "mozilla/gfx/Logging.h"
17 #include "mozilla/gfx/Matrix.h"
18 #include "mozilla/gfx/Point.h" // for IntSize, IntPoint
19 #include "mozilla/gfx/Rect.h"
20 #include "mozilla/gfx/Types.h" // for SurfaceFormat, etc
21 #include "mozilla/ipc/FileDescriptor.h"
22 #include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc
23 #include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc
24 #include "mozilla/layers/LayersMessages.h"
25 #include "mozilla/layers/LayersSurfaces.h"
26 #include "mozilla/layers/TextureSourceProvider.h"
27 #include "mozilla/mozalloc.h" // for operator delete
28 #include "mozilla/Range.h"
29 #include "mozilla/UniquePtr.h" // for UniquePtr
30 #include "mozilla/webrender/WebRenderTypes.h"
31 #include "nsCOMPtr.h" // for already_AddRefed
32 #include "nsDebug.h" // for NS_WARNING
33 #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
35 #include "nsRegion.h" // for nsIntRegion
36 #include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
37 #include "nscore.h" // for nsACString
38 #include "mozilla/layers/AtomicRefCountedWithFinalize.h"
43 class DataSourceSurface
;
51 class DisplayListBuilder
;
52 class TransactionBuilder
;
57 class AndroidHardwareBuffer
;
58 class AndroidHardwareBufferTextureHost
;
59 class BufferDescriptor
;
60 class BufferTextureHost
;
62 class CompositableParentManager
;
63 class ReadLockDescriptor
;
64 class CompositorBridgeParent
;
65 class SurfaceDescriptor
;
66 class HostIPCAllocator
;
67 class ISurfaceAllocator
;
68 class MacIOSurfaceTextureHostOGL
;
69 class ShmemTextureHost
;
70 class SurfaceTextureHost
;
72 class TextureReadLock
;
73 class TextureSourceOGL
;
74 class TextureSourceD3D11
;
75 class DataTextureSource
;
77 class RemoteTextureHostWrapper
;
79 class WebRenderTextureHost
;
80 class WrappingTextureSourceYCbCrBasic
;
81 class TextureHostWrapperD3D11
;
84 * A view on a TextureHost where the texture is internally represented as tiles
85 * (contrast with a tiled buffer, where each texture is a tile). For iteration
86 * by the texture's buffer host. This is only useful when the underlying surface
87 * is too big to fit in one device texture, which forces us to split it in
88 * smaller parts. Tiled Compositable is a different thing.
90 class BigImageIterator
{
92 virtual void BeginBigImageIteration() = 0;
93 virtual void EndBigImageIteration(){};
94 virtual gfx::IntRect
GetTileRect() = 0;
95 virtual size_t GetTileCount() = 0;
96 virtual bool NextTile() = 0;
100 * TextureSource is the interface for texture objects that can be composited
101 * by a given compositor backend. Since the drawing APIs are different
102 * between backends, the TextureSource interface is split into different
103 * interfaces (TextureSourceOGL, etc.), and TextureSource mostly provide
104 * access to these interfaces.
106 * This class is used on the compositor side.
108 class TextureSource
: public RefCounted
<TextureSource
> {
110 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(TextureSource
)
114 virtual ~TextureSource();
116 virtual const char* Name() const = 0;
119 * Should be overridden in order to deallocate the data that is associated
120 * with the rendering backend, such as GL textures.
122 virtual void DeallocateDeviceData() {}
125 * Return the size of the texture in texels.
126 * If this is a tile iterator, GetSize must return the size of the current
129 virtual gfx::IntSize
GetSize() const = 0;
132 * Return the pixel format of this texture
134 virtual gfx::SurfaceFormat
GetFormat() const {
135 return gfx::SurfaceFormat::UNKNOWN
;
139 * Cast to a TextureSource for for each backend..
141 virtual TextureSourceOGL
* AsSourceOGL() {
142 gfxCriticalNote
<< "Failed to cast " << Name()
143 << " into a TextureSourceOGL";
146 virtual TextureSourceD3D11
* AsSourceD3D11() { return nullptr; }
148 * Cast to a DataTextureSurce.
150 virtual DataTextureSource
* AsDataTextureSource() { return nullptr; }
153 * Overload this if the TextureSource supports big textures that don't fit in
154 * one device texture and must be tiled internally.
156 virtual BigImageIterator
* AsBigImageIterator() { return nullptr; }
158 virtual void Unbind() {}
160 void SetNextSibling(TextureSource
* aTexture
) { mNextSibling
= aTexture
; }
162 TextureSource
* GetNextSibling() const { return mNextSibling
; }
165 * In some rare cases we currently need to consider a group of textures as one
166 * TextureSource, that can be split in sub-TextureSources.
168 TextureSource
* GetSubSource(int index
) {
173 return GetNextSibling();
175 return GetNextSibling() ? GetNextSibling()->GetNextSibling() : nullptr;
180 void AddCompositableRef() { ++mCompositableCount
; }
182 void ReleaseCompositableRef() {
183 --mCompositableCount
;
184 MOZ_ASSERT(mCompositableCount
>= 0);
187 // When iterating as a BigImage, this creates temporary TextureSources
188 // wrapping individual tiles.
189 virtual RefPtr
<TextureSource
> ExtractCurrentTile() {
190 NS_WARNING("Implementation does not expose tile sources");
194 int NumCompositableRefs() const { return mCompositableCount
; }
196 // The direct-map cpu buffer should be alive when gpu uses it. And it
197 // should not be updated while gpu reads it. This Sync() function
198 // implements this synchronized behavior by allowing us to check if
199 // the GPU is done with the texture, and block on it if aBlocking is
201 virtual bool Sync(bool aBlocking
) { return true; }
204 RefPtr
<TextureSource
> mNextSibling
;
205 int mCompositableCount
;
208 /// Equivalent of a RefPtr<TextureSource>, that calls AddCompositableRef and
209 /// ReleaseCompositableRef in addition to the usual AddRef and Release.
211 /// The semantoics of these CompositableTextureRefs are important because they
212 /// are used both as a synchronization/safety mechanism, and as an optimization
213 /// mechanism. They are also tricky and subtle because we use them in a very
214 /// implicit way (assigning to a CompositableTextureRef is less visible than
215 /// explicitly calling a method or whatnot).
216 /// It is Therefore important to be careful about the way we use this tool.
218 /// CompositableTextureRef is a mechanism that lets us count how many
219 /// compositables are using a given texture (for TextureSource and TextureHost).
220 /// We use it to run specific code when a texture is not used anymore, and also
221 /// we trigger fast paths on some operations when we can see that the texture's
222 /// CompositableTextureRef counter is equal to 1 (the texture is not shared
223 /// between compositables).
224 /// This means that it is important to observe the following rules:
225 /// * CompositableHosts that receive UseTexture and similar messages *must*
226 /// store all of the TextureHosts they receive in CompositableTextureRef slots
227 /// for as long as they may be using them.
228 /// * CompositableHosts must store each texture in a *single*
229 /// CompositableTextureRef slot to ensure that the counter properly reflects how
230 /// many compositables are using the texture. If a compositable needs to hold
231 /// two references to a given texture (for example to have a pointer to the
232 /// current texture in a list of textures that may be used), it can hold its
233 /// extra references with RefPtr or whichever pointer type makes sense.
234 template <typename T
>
235 class CompositableTextureRef
{
237 CompositableTextureRef() = default;
239 explicit CompositableTextureRef(const CompositableTextureRef
& aOther
) {
243 explicit CompositableTextureRef(T
* aOther
) { *this = aOther
; }
245 ~CompositableTextureRef() {
247 mRef
->ReleaseCompositableRef();
251 CompositableTextureRef
& operator=(const CompositableTextureRef
& aOther
) {
253 aOther
->AddCompositableRef();
256 mRef
->ReleaseCompositableRef();
262 CompositableTextureRef
& operator=(T
* aOther
) {
264 aOther
->AddCompositableRef();
267 mRef
->ReleaseCompositableRef();
273 T
* get() const { return mRef
; }
274 operator T
*() const { return mRef
; }
275 T
* operator->() const { return mRef
; }
276 T
& operator*() const { return *mRef
; }
282 typedef CompositableTextureRef
<TextureSource
> CompositableTextureSourceRef
;
283 typedef CompositableTextureRef
<TextureHost
> CompositableTextureHostRef
;
286 * Interface for TextureSources that can be updated from a DataSourceSurface.
288 * All backend should implement at least one DataTextureSource.
290 class DataTextureSource
: public TextureSource
{
292 DataTextureSource() : mOwner(0), mUpdateSerial(0) {}
294 const char* Name() const override
{ return "DataTextureSource"; }
296 DataTextureSource
* AsDataTextureSource() override
{ return this; }
299 * Upload a (portion of) surface to the TextureSource.
301 * The DataTextureSource doesn't own aSurface, although it owns and manage
302 * the device texture it uploads to internally.
304 virtual bool Update(gfx::DataSourceSurface
* aSurface
,
305 nsIntRegion
* aDestRegion
= nullptr,
306 gfx::IntPoint
* aSrcOffset
= nullptr,
307 gfx::IntPoint
* aDstOffset
= nullptr) = 0;
310 * A facility to avoid reuploading when it is not necessary.
311 * The caller of Update can use GetUpdateSerial to see if the number has
312 * changed since last update, and call SetUpdateSerial after each successful
313 * update. The caller is responsible for managing the update serial except
314 * when the texture data is deallocated in which case the TextureSource should
315 * always reset the update serial to zero.
317 uint32_t GetUpdateSerial() const { return mUpdateSerial
; }
318 void SetUpdateSerial(uint32_t aValue
) { mUpdateSerial
= aValue
; }
320 // By default at least set the update serial to zero.
321 // overloaded versions should do that too.
322 void DeallocateDeviceData() override
{ SetUpdateSerial(0); }
326 * Provide read access to the data as a DataSourceSurface.
328 * This is expected to be very slow and should be used for mostly debugging.
329 * XXX - implement everywhere and make it pure virtual.
331 virtual already_AddRefed
<gfx::DataSourceSurface
> ReadBack() {
336 void SetOwner(TextureHost
* aOwner
) {
337 auto newOwner
= (uintptr_t)aOwner
;
338 if (newOwner
!= mOwner
) {
344 bool IsOwnedBy(TextureHost
* aOwner
) const {
345 return mOwner
== (uintptr_t)aOwner
;
348 bool HasOwner() const { return !IsOwnedBy(nullptr); }
351 // We store mOwner as an integer rather than as a pointer to make it clear
352 // it is not intended to be dereferenced.
354 uint32_t mUpdateSerial
;
357 enum class TextureHostType
: int8_t {
365 AndroidSurfaceTexture
,
366 AndroidHardwareBuffer
,
373 * TextureHost is a thin abstraction over texture data that need to be shared
374 * between the content process and the compositor process. It is the
375 * compositor-side half of a TextureClient/TextureHost pair. A corresponding
376 * TextureClient lives on the content-side.
378 * TextureHost only knows how to deserialize or synchronize generic image data
379 * (SurfaceDescriptor) and provide access to one or more TextureSource objects
380 * (these provide the necessary APIs for compositor backends to composite the
383 * A TextureHost implementation corresponds to one SurfaceDescriptor type, as
384 * opposed to TextureSource that corresponds to device textures.
385 * This means that for YCbCr planes, even though they are represented as
386 * 3 textures internally (3 TextureSources), we use 1 TextureHost and not 3,
387 * because the 3 planes are stored in the same buffer of shared memory, before
388 * they are uploaded separately.
390 * There is always one and only one TextureHost per TextureClient, and the
391 * TextureClient/Host pair only owns one buffer of image data through its
392 * lifetime. This means that the lifetime of the underlying shared data
393 * matches the lifetime of the TextureClient/Host pair. It also means
394 * TextureClient/Host do not implement double buffering, which is the
395 * reponsibility of the compositable (which would use two Texture pairs).
397 * The Lock/Unlock mecanism here mirrors Lock/Unlock in TextureClient.
400 class TextureHost
: public AtomicRefCountedWithFinalize
<TextureHost
> {
402 * Called once, just before the destructor.
404 * Here goes the shut-down code that uses virtual methods.
405 * Must only be called by Release().
409 friend class AtomicRefCountedWithFinalize
<TextureHost
>;
412 TextureHost(TextureHostType aType
, TextureFlags aFlags
);
415 virtual ~TextureHost();
421 static already_AddRefed
<TextureHost
> Create(
422 const SurfaceDescriptor
& aDesc
, ReadLockDescriptor
&& aReadLock
,
423 HostIPCAllocator
* aDeallocator
, LayersBackend aBackend
,
424 TextureFlags aFlags
, wr::MaybeExternalImageId
& aExternalImageId
);
427 * Lock the texture host for compositing without using compositor.
429 virtual bool LockWithoutCompositor() { return true; }
431 * Similar to Unlock(), but it should be called with LockWithoutCompositor().
433 virtual void UnlockWithoutCompositor() {}
436 * Note that the texture host format can be different from its corresponding
437 * texture source's. For example a ShmemTextureHost can have the ycbcr
438 * format and produce 3 "alpha" textures sources.
440 virtual gfx::SurfaceFormat
GetFormat() const = 0;
442 * Return the format used for reading the texture.
443 * Apple's YCBCR_422 is R8G8B8X8.
445 virtual gfx::SurfaceFormat
GetReadFormat() const { return GetFormat(); }
447 virtual gfx::YUVColorSpace
GetYUVColorSpace() const {
448 return gfx::YUVColorSpace::Identity
;
452 * Return the color depth of the image. Used with YUV textures.
454 virtual gfx::ColorDepth
GetColorDepth() const {
455 return gfx::ColorDepth::COLOR_8
;
459 * Return true if using full range values (0-255 if 8 bits YUV). Used with YUV
462 virtual gfx::ColorRange
GetColorRange() const {
463 return gfx::ColorRange::LIMITED
;
467 * Called when another TextureHost will take over.
469 virtual void UnbindTextureSource();
471 virtual bool IsValid() { return true; }
474 * Should be overridden in order to deallocate the data that is associated
475 * with the rendering backend, such as GL textures.
477 virtual void DeallocateDeviceData() {}
480 * Should be overridden in order to deallocate the data that is shared with
481 * the content side, such as shared memory.
483 virtual void DeallocateSharedData() {}
486 * Should be overridden in order to force the TextureHost to drop all
487 * references to it's shared data.
489 * This is important to ensure the correctness of the deallocation protocol.
491 virtual void ForgetSharedData() {}
493 virtual gfx::IntSize
GetSize() const = 0;
496 * Should be overridden if TextureHost supports crop rect.
498 virtual void SetCropRect(nsIntRect aCropRect
) {}
502 * XXX - cool kids use Moz2D. See bug 882113.
504 virtual already_AddRefed
<gfx::DataSourceSurface
> GetAsSurface() = 0;
507 * XXX - Flags should only be set at creation time, this will be removed.
509 void SetFlags(TextureFlags aFlags
) { mFlags
= aFlags
; }
512 * XXX - Flags should only be set at creation time, this will be removed.
514 void AddFlag(TextureFlags aFlag
) { mFlags
|= aFlag
; }
516 TextureFlags
GetFlags() { return mFlags
; }
518 wr::MaybeExternalImageId
GetMaybeExternalImageId() const {
519 return mExternalImageId
;
523 * Allocate and deallocate a TextureParent actor.
525 * TextureParent< is an implementation detail of TextureHost that is not
526 * exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor
527 * are for use with the managing IPDL protocols only (so that they can
528 * implement AllocPTextureParent and DeallocPTextureParent).
530 static PTextureParent
* CreateIPDLActor(
531 HostIPCAllocator
* aAllocator
, const SurfaceDescriptor
& aSharedData
,
532 ReadLockDescriptor
&& aDescriptor
, LayersBackend aLayersBackend
,
533 TextureFlags aFlags
, const dom::ContentParentId
& aContentId
,
534 uint64_t aSerial
, const wr::MaybeExternalImageId
& aExternalImageId
);
535 static bool DestroyIPDLActor(PTextureParent
* actor
);
538 * Destroy the TextureChild/Parent pair.
540 static bool SendDeleteIPDLActor(PTextureParent
* actor
);
542 static void ReceivedDestroy(PTextureParent
* actor
);
545 * Get the TextureHost corresponding to the actor passed in parameter.
547 static TextureHost
* AsTextureHost(PTextureParent
* actor
);
549 static uint64_t GetTextureSerial(PTextureParent
* actor
);
551 static dom::ContentParentId
GetTextureContentId(PTextureParent
* actor
);
554 * Return a pointer to the IPDLActor.
556 * This is to be used with IPDL messages only. Do not store the returned
559 PTextureParent
* GetIPDLActor();
561 // If a texture host holds a reference to shmem, it should override this
562 // method to forget about the shmem _without_ releasing it.
563 virtual void OnShutdown() {}
565 // Forget buffer actor. Used only for hacky fix for bug 966446.
566 virtual void ForgetBufferActor() {}
568 virtual const char* Name() { return "TextureHost"; }
571 * Returns true if the TextureHost can be released before the rendering is
572 * completed, otherwise returns false.
574 virtual bool NeedsDeferredDeletion() const { return true; }
576 void AddCompositableRef() {
577 ++mCompositableCount
;
578 if (mCompositableCount
== 1) {
583 void ReleaseCompositableRef() {
584 --mCompositableCount
;
585 MOZ_ASSERT(mCompositableCount
>= 0);
586 if (mCompositableCount
== 0) {
587 UnbindTextureSource();
588 // Send mFwdTransactionId to client side if necessary.
593 int NumCompositableRefs() const { return mCompositableCount
; }
595 void SetLastFwdTransactionId(uint64_t aTransactionId
);
597 void DeserializeReadLock(ReadLockDescriptor
&& aDesc
,
598 ISurfaceAllocator
* aAllocator
);
599 void SetReadLocked();
601 TextureReadLock
* GetReadLock() { return mReadLock
; }
603 virtual BufferTextureHost
* AsBufferTextureHost() { return nullptr; }
604 virtual ShmemTextureHost
* AsShmemTextureHost() { return nullptr; }
605 virtual MacIOSurfaceTextureHostOGL
* AsMacIOSurfaceTextureHost() {
608 virtual WebRenderTextureHost
* AsWebRenderTextureHost() { return nullptr; }
609 virtual SurfaceTextureHost
* AsSurfaceTextureHost() { return nullptr; }
610 virtual AndroidHardwareBufferTextureHost
*
611 AsAndroidHardwareBufferTextureHost() {
614 virtual RemoteTextureHostWrapper
* AsRemoteTextureHostWrapper() {
618 virtual TextureHostWrapperD3D11
* AsTextureHostWrapperD3D11() {
622 virtual bool IsWrappingSurfaceTextureHost() { return false; }
624 // Create the corresponding RenderTextureHost type of this texture, and
625 // register the RenderTextureHost into render thread.
626 virtual void CreateRenderTexture(
627 const wr::ExternalImageId
& aExternalImageId
) {
630 "No CreateRenderTexture() implementation for this TextureHost type.");
633 void EnsureRenderTexture(const wr::MaybeExternalImageId
& aExternalImageId
);
635 // Destroy RenderTextureHost when it was created by the TextureHost.
636 // It is called in TextureHost::Finalize().
637 virtual void MaybeDestroyRenderTexture();
639 static void DestroyRenderTexture(const wr::ExternalImageId
& aExternalImageId
);
641 /// Returns the number of actual textures that will be used to render this.
642 /// For example in a lot of YUV cases it will be 3
643 virtual uint32_t NumSubTextures() { return 1; }
645 enum ResourceUpdateOp
{
650 // Add all necessary TextureHost informations to the resource update queue.
651 virtual void PushResourceUpdates(wr::TransactionBuilder
& aResources
,
652 ResourceUpdateOp aOp
,
653 const Range
<wr::ImageKey
>& aImageKeys
,
654 const wr::ExternalImageId
& aExtID
) {
655 MOZ_ASSERT_UNREACHABLE("Unimplemented");
658 enum class PushDisplayItemFlag
{
659 // Passed if the caller wants these display items to be promoted
660 // to compositor surfaces if possible.
661 PREFER_COMPOSITOR_SURFACE
,
663 // Passed in the RenderCompositor supports BufferTextureHosts
664 // being used directly as external compositor surfaces.
665 SUPPORTS_EXTERNAL_BUFFER_TEXTURES
,
667 using PushDisplayItemFlagSet
= EnumSet
<PushDisplayItemFlag
>;
669 // Put all necessary WR commands into DisplayListBuilder for this textureHost
671 virtual void PushDisplayItems(wr::DisplayListBuilder
& aBuilder
,
672 const wr::LayoutRect
& aBounds
,
673 const wr::LayoutRect
& aClip
,
674 wr::ImageRendering aFilter
,
675 const Range
<wr::ImageKey
>& aKeys
,
676 PushDisplayItemFlagSet aFlags
) {
677 MOZ_ASSERT_UNREACHABLE(
678 "No PushDisplayItems() implementation for this TextureHost type.");
682 * Some API's can use the cross-process IOSurface directly, such as OpenVR
684 virtual MacIOSurface
* GetMacIOSurface() { return nullptr; }
686 virtual bool NeedsYFlip() const;
688 virtual void SetAcquireFence(mozilla::ipc::FileDescriptor
&& aFenceFd
) {}
690 virtual void SetReleaseFence(mozilla::ipc::FileDescriptor
&& aFenceFd
) {}
692 virtual mozilla::ipc::FileDescriptor
GetAndResetReleaseFence() {
693 return mozilla::ipc::FileDescriptor();
696 virtual AndroidHardwareBuffer
* GetAndroidHardwareBuffer() const {
700 virtual bool SupportsExternalCompositing(WebRenderBackend aBackend
) {
704 virtual TextureHostType
GetTextureHostType() { return mTextureHostType
; }
706 // Our WebRender backend may impose restrictions on whether textures are
707 // prepared as native textures or not, or it may have no restriction at
708 // all. This enumerates those possibilities.
709 enum NativeTexturePolicy
{
715 static NativeTexturePolicy
BackendNativeTexturePolicy(
716 layers::WebRenderBackend aBackend
, gfx::IntSize aSize
) {
717 static const int32_t SWGL_DIMENSION_MAX
= 1 << 15;
718 if (aBackend
== WebRenderBackend::SOFTWARE
) {
719 return (aSize
.width
<= SWGL_DIMENSION_MAX
&&
720 aSize
.height
<= SWGL_DIMENSION_MAX
)
727 void SetDestroyedCallback(std::function
<void()>&& aDestroyedCallback
) {
728 MOZ_ASSERT(!mDestroyedCallback
);
729 mDestroyedCallback
= std::move(aDestroyedCallback
);
733 virtual void ReadUnlock();
735 void RecycleTexture(TextureFlags aFlags
);
738 * Called when mCompositableCount becomes from 0 to 1.
740 virtual void PrepareForUse();
743 * Called when mCompositableCount becomes 0.
745 virtual void NotifyNotUsed();
748 void CallNotifyNotUsed();
750 TextureHostType mTextureHostType
;
751 PTextureParent
* mActor
;
752 RefPtr
<TextureReadLock
> mReadLock
;
754 int mCompositableCount
;
755 uint64_t mFwdTransactionId
;
757 wr::MaybeExternalImageId mExternalImageId
;
759 std::function
<void()> mDestroyedCallback
;
761 friend class Compositor
;
762 friend class RemoteTextureHostWrapper
;
763 friend class TextureParent
;
764 friend class TextureSourceProvider
;
765 friend class GPUVideoTextureHost
;
766 friend class WebRenderTextureHost
;
767 friend class TextureHostWrapperD3D11
;
771 * TextureHost that wraps a random access buffer such as a Shmem or some raw
774 * This TextureHost is backend-independent and the backend-specific bits are
775 * in the TextureSource.
776 * This class must be inherited to implement GetBuffer and DeallocSharedData
777 * (see ShmemTextureHost and MemoryTextureHost)
779 * Uploads happen when Lock is called.
781 * BufferTextureHost supports YCbCr and flavours of RGBA images (RGBX, A, etc.).
783 class BufferTextureHost
: public TextureHost
{
785 BufferTextureHost(const BufferDescriptor
& aDescriptor
, TextureFlags aFlags
);
787 virtual ~BufferTextureHost();
789 virtual uint8_t* GetBuffer() = 0;
791 virtual size_t GetBufferSize() = 0;
793 void UnbindTextureSource() override
;
795 void DeallocateDeviceData() override
;
798 * Return the format that is exposed to the compositor when calling
801 * If the shared format is YCbCr and the compositor does not support it,
802 * GetFormat will be RGB32 (even though mFormat is SurfaceFormat::YUV).
804 gfx::SurfaceFormat
GetFormat() const override
;
806 gfx::YUVColorSpace
GetYUVColorSpace() const override
;
808 gfx::ColorDepth
GetColorDepth() const override
;
810 gfx::ColorRange
GetColorRange() const override
;
812 gfx::ChromaSubsampling
GetChromaSubsampling() const;
814 gfx::IntSize
GetSize() const override
{ return mSize
; }
816 already_AddRefed
<gfx::DataSourceSurface
> GetAsSurface() override
;
818 bool NeedsDeferredDeletion() const override
{
819 return TextureHost::NeedsDeferredDeletion() || UseExternalTextures();
822 BufferTextureHost
* AsBufferTextureHost() override
{ return this; }
824 const BufferDescriptor
& GetBufferDescriptor() const { return mDescriptor
; }
826 void CreateRenderTexture(
827 const wr::ExternalImageId
& aExternalImageId
) override
;
829 uint32_t NumSubTextures() override
;
831 void PushResourceUpdates(wr::TransactionBuilder
& aResources
,
832 ResourceUpdateOp aOp
,
833 const Range
<wr::ImageKey
>& aImageKeys
,
834 const wr::ExternalImageId
& aExtID
) override
;
836 void PushDisplayItems(wr::DisplayListBuilder
& aBuilder
,
837 const wr::LayoutRect
& aBounds
,
838 const wr::LayoutRect
& aClip
, wr::ImageRendering aFilter
,
839 const Range
<wr::ImageKey
>& aImageKeys
,
840 PushDisplayItemFlagSet aFlags
) override
;
842 uint8_t* GetYChannel();
843 uint8_t* GetCbChannel();
844 uint8_t* GetCrChannel();
845 int32_t GetYStride() const;
846 int32_t GetCbCrStride() const;
849 bool UseExternalTextures() const { return mUseExternalTextures
; }
851 BufferDescriptor mDescriptor
;
852 RefPtr
<Compositor
> mCompositor
;
854 gfx::SurfaceFormat mFormat
;
856 bool mUseExternalTextures
;
858 class DataTextureSourceYCbCrBasic
;
862 * TextureHost that wraps shared memory.
863 * the corresponding texture on the client side is ShmemTextureClient.
864 * This TextureHost is backend-independent.
866 class ShmemTextureHost
: public BufferTextureHost
{
868 ShmemTextureHost(const mozilla::ipc::Shmem
& aShmem
,
869 const BufferDescriptor
& aDesc
,
870 ISurfaceAllocator
* aDeallocator
, TextureFlags aFlags
);
876 void DeallocateSharedData() override
;
878 void ForgetSharedData() override
;
880 uint8_t* GetBuffer() override
;
882 size_t GetBufferSize() override
;
884 const char* Name() override
{ return "ShmemTextureHost"; }
886 void OnShutdown() override
;
888 ShmemTextureHost
* AsShmemTextureHost() override
{ return this; }
891 UniquePtr
<mozilla::ipc::Shmem
> mShmem
;
892 RefPtr
<ISurfaceAllocator
> mDeallocator
;
896 * TextureHost that wraps raw memory.
897 * The corresponding texture on the client side is MemoryTextureClient.
898 * Can obviously not be used in a cross process setup.
899 * This TextureHost is backend-independent.
901 class MemoryTextureHost
: public BufferTextureHost
{
903 MemoryTextureHost(uint8_t* aBuffer
, const BufferDescriptor
& aDesc
,
904 TextureFlags aFlags
);
907 ~MemoryTextureHost();
910 void DeallocateSharedData() override
;
912 void ForgetSharedData() override
;
914 uint8_t* GetBuffer() override
;
916 size_t GetBufferSize() override
;
918 const char* Name() override
{ return "MemoryTextureHost"; }
924 class MOZ_STACK_CLASS AutoLockTextureHostWithoutCompositor
{
926 explicit AutoLockTextureHostWithoutCompositor(TextureHost
* aTexture
)
927 : mTexture(aTexture
) {
928 mLocked
= mTexture
? mTexture
->LockWithoutCompositor() : false;
931 ~AutoLockTextureHostWithoutCompositor() {
932 if (mTexture
&& mLocked
) {
933 mTexture
->UnlockWithoutCompositor();
937 bool Failed() { return mTexture
&& !mLocked
; }
940 RefPtr
<TextureHost
> mTexture
;
945 * This can be used as an offscreen rendering target by the compositor, and
946 * subsequently can be used as a source by the compositor.
948 class CompositingRenderTarget
: public TextureSource
{
950 explicit CompositingRenderTarget(const gfx::IntPoint
& aOrigin
)
951 : mClearOnBind(false),
955 mHasComplexProjection(false),
956 mEnableDepthBuffer(false) {}
957 virtual ~CompositingRenderTarget() = default;
959 const char* Name() const override
{ return "CompositingRenderTarget"; }
961 #ifdef MOZ_DUMP_PAINTING
962 virtual already_AddRefed
<gfx::DataSourceSurface
> Dump(
963 Compositor
* aCompositor
) {
969 * Perform a clear when recycling a non opaque surface.
970 * The clear is deferred to when the render target is bound.
972 void ClearOnBind() { mClearOnBind
= true; }
974 const gfx::IntPoint
& GetOrigin() const { return mOrigin
; }
975 gfx::IntRect
GetRect() { return gfx::IntRect(GetOrigin(), GetSize()); }
978 * If a Projection matrix is set, then it is used for rendering to
979 * this render target instead of generating one. If no explicit
980 * projection is set, Compositors are expected to generate an
981 * orthogonal maaping that maps 0..1 to the full size of the render
984 bool HasComplexProjection() const { return mHasComplexProjection
; }
985 void ClearProjection() { mHasComplexProjection
= false; }
986 void SetProjection(const gfx::Matrix4x4
& aNewMatrix
, bool aEnableDepthBuffer
,
987 float aZNear
, float aZFar
) {
988 mProjectionMatrix
= aNewMatrix
;
989 mEnableDepthBuffer
= aEnableDepthBuffer
;
992 mHasComplexProjection
= true;
994 void GetProjection(gfx::Matrix4x4
& aMatrix
, bool& aEnableDepth
, float& aZNear
,
996 MOZ_ASSERT(mHasComplexProjection
);
997 aMatrix
= mProjectionMatrix
;
998 aEnableDepth
= mEnableDepthBuffer
;
1007 gfx::IntPoint mOrigin
;
1009 gfx::Matrix4x4 mProjectionMatrix
;
1010 float mZNear
, mZFar
;
1011 bool mHasComplexProjection
;
1012 bool mEnableDepthBuffer
;
1016 * Creates a TextureHost that can be used with any of the existing backends
1017 * Not all SurfaceDescriptor types are supported
1019 already_AddRefed
<TextureHost
> CreateBackendIndependentTextureHost(
1020 const SurfaceDescriptor
& aDesc
, ISurfaceAllocator
* aDeallocator
,
1021 LayersBackend aBackend
, TextureFlags aFlags
);
1023 } // namespace layers
1024 } // namespace mozilla