KnowsCompositor.h (8084B)
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/. */ 6 7 #ifndef MOZILLA_LAYERS_KNOWSCOMPOSITOR 8 #define MOZILLA_LAYERS_KNOWSCOMPOSITOR 9 10 #include "mozilla/layers/LayersTypes.h" // for LayersBackend 11 #include "mozilla/layers/CompositorTypes.h" 12 #include "mozilla/DataMutex.h" 13 #include "mozilla/layers/SyncObject.h" 14 15 namespace mozilla::layers { 16 17 class TextureForwarder; 18 class LayersIPCActor; 19 class ImageBridgeChild; 20 21 /** 22 * An abstract interface for classes that are tied to a specific Compositor 23 * across IPDL and uses TextureFactoryIdentifier to describe this Compositor. 24 */ 25 class KnowsCompositor { 26 public: 27 NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING 28 29 KnowsCompositor(); 30 virtual ~KnowsCompositor(); 31 32 void IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier); 33 34 // The sync object for the global content device. 35 RefPtr<SyncObjectClient> GetSyncObject() { 36 auto lock = mData.Lock(); 37 if (lock.ref().mSyncObject) { 38 lock.ref().mSyncObject->EnsureInitialized(); 39 } 40 return lock.ref().mSyncObject; 41 } 42 43 /// And by "thread-safe" here we merely mean "okay to hold strong references 44 /// to from multiple threads". Not all methods actually are thread-safe. 45 virtual bool IsThreadSafe() const { return true; } 46 47 virtual RefPtr<KnowsCompositor> GetForMedia() { 48 return RefPtr<KnowsCompositor>(this); 49 } 50 51 int32_t GetMaxTextureSize() const { 52 auto lock = mData.Lock(); 53 return lock.ref().mTextureFactoryIdentifier.mMaxTextureSize; 54 } 55 56 /** 57 * Returns the type of backend that is used off the main thread. 58 * We only don't allow changing the backend type at runtime so this value can 59 * be queried once and will not change until Gecko is restarted. 60 */ 61 LayersBackend GetCompositorBackendType() const { 62 auto lock = mData.Lock(); 63 return lock.ref().mTextureFactoryIdentifier.mParentBackend; 64 } 65 66 WebRenderCompositor GetWebRenderCompositorType() const { 67 auto lock = mData.Lock(); 68 return lock.ref().mTextureFactoryIdentifier.mWebRenderCompositor; 69 } 70 71 bool SupportsTextureBlitting() const { 72 auto lock = mData.Lock(); 73 return lock.ref().mTextureFactoryIdentifier.mSupportsTextureBlitting; 74 } 75 76 bool SupportsPartialUploads() const { 77 auto lock = mData.Lock(); 78 return lock.ref().mTextureFactoryIdentifier.mSupportsPartialUploads; 79 } 80 81 bool SupportsComponentAlpha() const { 82 auto lock = mData.Lock(); 83 return lock.ref().mTextureFactoryIdentifier.mSupportsComponentAlpha; 84 } 85 86 bool SupportsD3D11NV12() const { 87 auto lock = mData.Lock(); 88 return lock.ref().mTextureFactoryIdentifier.mSupportsD3D11NV12; 89 } 90 91 bool SupportsD3D11() const { 92 auto lock = mData.Lock(); 93 return SupportsD3D11(lock.ref().mTextureFactoryIdentifier); 94 } 95 96 static bool SupportsD3D11( 97 const TextureFactoryIdentifier aTextureFactoryIdentifier) { 98 return aTextureFactoryIdentifier.mParentBackend == 99 layers::LayersBackend::LAYERS_WR && 100 (aTextureFactoryIdentifier.mCompositorUseANGLE || 101 aTextureFactoryIdentifier.mWebRenderCompositor == 102 layers::WebRenderCompositor::D3D11); 103 } 104 105 bool GetCompositorUseANGLE() const { 106 auto lock = mData.Lock(); 107 return lock.ref().mTextureFactoryIdentifier.mCompositorUseANGLE; 108 } 109 110 bool GetCompositorUseDComp() const { 111 auto lock = mData.Lock(); 112 return lock.ref().mTextureFactoryIdentifier.mCompositorUseDComp; 113 } 114 115 bool GetUseLayerCompositor() const { 116 auto lock = mData.Lock(); 117 return lock.ref().mTextureFactoryIdentifier.mUseLayerCompositor; 118 } 119 120 bool GetUseCompositorWnd() const { 121 auto lock = mData.Lock(); 122 return lock.ref().mTextureFactoryIdentifier.mUseCompositorWnd; 123 } 124 125 WebRenderBackend GetWebRenderBackend() const { 126 auto lock = mData.Lock(); 127 MOZ_ASSERT(lock.ref().mTextureFactoryIdentifier.mParentBackend == 128 layers::LayersBackend::LAYERS_WR); 129 return lock.ref().mTextureFactoryIdentifier.mWebRenderBackend; 130 } 131 132 bool UsingHardwareWebRender() const { 133 auto lock = mData.Lock(); 134 return lock.ref().mTextureFactoryIdentifier.mParentBackend == 135 layers::LayersBackend::LAYERS_WR && 136 lock.ref().mTextureFactoryIdentifier.mWebRenderBackend == 137 WebRenderBackend::HARDWARE; 138 } 139 140 bool UsingSoftwareWebRender() const { 141 auto lock = mData.Lock(); 142 return lock.ref().mTextureFactoryIdentifier.mParentBackend == 143 layers::LayersBackend::LAYERS_WR && 144 lock.ref().mTextureFactoryIdentifier.mWebRenderBackend == 145 WebRenderBackend::SOFTWARE; 146 } 147 148 bool UsingSoftwareWebRenderD3D11() const { 149 auto lock = mData.Lock(); 150 return lock.ref().mTextureFactoryIdentifier.mParentBackend == 151 layers::LayersBackend::LAYERS_WR && 152 lock.ref().mTextureFactoryIdentifier.mWebRenderBackend == 153 WebRenderBackend::SOFTWARE && 154 lock.ref().mTextureFactoryIdentifier.mWebRenderCompositor == 155 layers::WebRenderCompositor::D3D11; 156 } 157 158 bool UsingSoftwareWebRenderOpenGL() const { 159 auto lock = mData.Lock(); 160 return lock.ref().mTextureFactoryIdentifier.mParentBackend == 161 layers::LayersBackend::LAYERS_WR && 162 lock.ref().mTextureFactoryIdentifier.mWebRenderBackend == 163 WebRenderBackend::SOFTWARE && 164 lock.ref().mTextureFactoryIdentifier.mWebRenderCompositor == 165 layers::WebRenderCompositor::OPENGL; 166 } 167 168 TextureFactoryIdentifier GetTextureFactoryIdentifier() const { 169 auto lock = mData.Lock(); 170 return lock.ref().mTextureFactoryIdentifier; 171 } 172 173 int32_t GetSerial() const { return mSerial; } 174 175 /** 176 * Sends a synchronous ping to the compsoitor. 177 * 178 * This is bad for performance and should only be called as a last resort if 179 * the compositor may be blocked for a long period of time, to avoid that the 180 * content process accumulates resource allocations that the compositor is not 181 * consuming and releasing. 182 */ 183 virtual void SyncWithCompositor( 184 const Maybe<uint64_t>& aWindowID = Nothing()) { 185 MOZ_ASSERT_UNREACHABLE("Unimplemented"); 186 } 187 188 /** 189 * Helpers for finding other related interface. These are infallible. 190 */ 191 virtual TextureForwarder* GetTextureForwarder() = 0; 192 virtual LayersIPCActor* GetLayersIPCActor() = 0; 193 194 protected: 195 struct SharedData { 196 TextureFactoryIdentifier mTextureFactoryIdentifier; 197 RefPtr<SyncObjectClient> mSyncObject; 198 }; 199 mutable DataMutex<SharedData> mData; 200 201 const int32_t mSerial; 202 static mozilla::Atomic<int32_t> sSerialCounter; 203 }; 204 205 /// Some implementations of KnowsCompositor can be used off their IPDL thread 206 /// like the ImageBridgeChild, and others just can't. Instead of passing them 207 /// we create a proxy KnowsCompositor that has information about compositor 208 /// backend but proxies allocations to the ImageBridge. 209 /// This is kind of specific to the needs of media which wants to allocate 210 /// textures, usually through the Image Bridge accessed by KnowsCompositor but 211 /// also wants access to the compositor backend information that ImageBridge 212 /// doesn't know about. 213 /// 214 /// This is really a band aid to what turned into a class hierarchy horror show. 215 /// Hopefully we can come back and simplify this some way. 216 class KnowsCompositorMediaProxy : public KnowsCompositor { 217 public: 218 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(KnowsCompositorMediaProxy, override); 219 220 explicit KnowsCompositorMediaProxy( 221 const TextureFactoryIdentifier& aIdentifier); 222 223 TextureForwarder* GetTextureForwarder() override; 224 225 LayersIPCActor* GetLayersIPCActor() override; 226 227 void SyncWithCompositor( 228 const Maybe<uint64_t>& aWindowID = Nothing()) override; 229 230 protected: 231 virtual ~KnowsCompositorMediaProxy(); 232 233 RefPtr<ImageBridgeChild> mThreadSafeAllocator; 234 }; 235 236 } // namespace mozilla::layers 237 238 #endif