GPUVideoTextureHost.cpp (8579B)
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 #include "GPUVideoTextureHost.h" 8 9 #include "ImageContainer.h" 10 #include "mozilla/RemoteMediaManagerParent.h" 11 #include "mozilla/layers/ImageBridgeParent.h" 12 #include "mozilla/layers/VideoBridgeParent.h" 13 #include "mozilla/webrender/RenderTextureHostWrapper.h" 14 #include "mozilla/webrender/RenderThread.h" 15 16 namespace mozilla { 17 namespace layers { 18 19 GPUVideoTextureHost::GPUVideoTextureHost( 20 const dom::ContentParentId& aContentId, TextureFlags aFlags, 21 const SurfaceDescriptorGPUVideo& aDescriptor) 22 : TextureHost(TextureHostType::Unknown, aFlags), 23 mContentId(aContentId), 24 mDescriptor(aDescriptor) { 25 MOZ_COUNT_CTOR(GPUVideoTextureHost); 26 } 27 28 GPUVideoTextureHost::~GPUVideoTextureHost() { 29 MOZ_COUNT_DTOR(GPUVideoTextureHost); 30 } 31 32 GPUVideoTextureHost* GPUVideoTextureHost::CreateFromDescriptor( 33 const dom::ContentParentId& aContentId, TextureFlags aFlags, 34 const SurfaceDescriptorGPUVideo& aDescriptor) { 35 return new GPUVideoTextureHost(aContentId, aFlags, aDescriptor); 36 } 37 38 TextureHost* GPUVideoTextureHost::EnsureWrappedTextureHost() { 39 if (mWrappedTextureHost) { 40 return mWrappedTextureHost; 41 } 42 43 const auto& sd = 44 static_cast<const SurfaceDescriptorRemoteDecoder&>(mDescriptor); 45 RefPtr<VideoBridgeParent> parent = 46 VideoBridgeParent::GetSingleton(sd.source()); 47 if (!parent) { 48 // The VideoBridge went away. This can happen if the RDD process 49 // crashes. 50 return nullptr; 51 } 52 53 mWrappedTextureHost = parent->LookupTextureAsync(mContentId, sd.handle()); 54 55 if (!mWrappedTextureHost) { 56 // The TextureHost hasn't been registered yet. This is due to a race 57 // between the ImageBridge (content) and the VideoBridge (RDD) and the 58 // ImageBridge won. See bug 59 // https://bugzilla.mozilla.org/show_bug.cgi?id=1630733#c14 for more 60 // details. 61 return nullptr; 62 } 63 64 if (mExternalImageId.isSome()) { 65 // External image id is allocated by mWrappedTextureHost. 66 mWrappedTextureHost->EnsureRenderTexture(Nothing()); 67 MOZ_ASSERT(mWrappedTextureHost->mExternalImageId.isSome()); 68 auto wrappedId = mWrappedTextureHost->mExternalImageId.ref(); 69 70 RefPtr<wr::RenderTextureHost> texture = 71 new wr::RenderTextureHostWrapper(wrappedId); 72 wr::RenderThread::Get()->RegisterExternalImage(mExternalImageId.ref(), 73 texture.forget()); 74 } 75 76 return mWrappedTextureHost; 77 } 78 79 bool GPUVideoTextureHost::IsValid() { return !!EnsureWrappedTextureHost(); } 80 81 gfx::YUVColorSpace GPUVideoTextureHost::GetYUVColorSpace() const { 82 MOZ_ASSERT(mWrappedTextureHost, "Image isn't valid yet"); 83 if (!mWrappedTextureHost) { 84 return TextureHost::GetYUVColorSpace(); 85 } 86 return mWrappedTextureHost->GetYUVColorSpace(); 87 } 88 89 gfx::ColorDepth GPUVideoTextureHost::GetColorDepth() const { 90 MOZ_ASSERT(mWrappedTextureHost, "Image isn't valid yet"); 91 if (!mWrappedTextureHost) { 92 return TextureHost::GetColorDepth(); 93 } 94 return mWrappedTextureHost->GetColorDepth(); 95 } 96 97 gfx::ColorRange GPUVideoTextureHost::GetColorRange() const { 98 MOZ_ASSERT(mWrappedTextureHost, "Image isn't valid yet"); 99 if (!mWrappedTextureHost) { 100 return TextureHost::GetColorRange(); 101 } 102 return mWrappedTextureHost->GetColorRange(); 103 } 104 105 gfx::IntSize GPUVideoTextureHost::GetSize() const { 106 MOZ_ASSERT(mWrappedTextureHost, "Image isn't valid yet"); 107 if (!mWrappedTextureHost) { 108 return gfx::IntSize(); 109 } 110 return mWrappedTextureHost->GetSize(); 111 } 112 113 gfx::SurfaceFormat GPUVideoTextureHost::GetFormat() const { 114 MOZ_ASSERT(mWrappedTextureHost, "Image isn't valid yet"); 115 if (!mWrappedTextureHost) { 116 return gfx::SurfaceFormat::UNKNOWN; 117 } 118 return mWrappedTextureHost->GetFormat(); 119 } 120 121 void GPUVideoTextureHost::CreateRenderTexture( 122 const wr::ExternalImageId& aExternalImageId) { 123 MOZ_ASSERT(mExternalImageId.isSome()); 124 125 // When mWrappedTextureHost already exist, call CreateRenderTexture() here. 126 // In other cases, EnsureWrappedTextureHost() handles CreateRenderTexture(). 127 128 if (mWrappedTextureHost) { 129 // External image id is allocated by mWrappedTextureHost. 130 mWrappedTextureHost->EnsureRenderTexture(Nothing()); 131 MOZ_ASSERT(mWrappedTextureHost->mExternalImageId.isSome()); 132 auto wrappedId = mWrappedTextureHost->mExternalImageId.ref(); 133 134 RefPtr<wr::RenderTextureHost> texture = 135 new wr::RenderTextureHostWrapper(wrappedId); 136 wr::RenderThread::Get()->RegisterExternalImage(mExternalImageId.ref(), 137 texture.forget()); 138 return; 139 } 140 141 EnsureWrappedTextureHost(); 142 } 143 144 void GPUVideoTextureHost::MaybeDestroyRenderTexture() { 145 if (mExternalImageId.isNothing()) { 146 // RenderTextureHost was not created 147 return; 148 } 149 150 if (mExternalImageId.isSome() && mWrappedTextureHost) { 151 // When GPUVideoTextureHost created RenderTextureHost, delete it here. 152 TextureHost::DestroyRenderTexture(mExternalImageId.ref()); 153 } 154 mExternalImageId = Nothing(); 155 } 156 157 uint32_t GPUVideoTextureHost::NumSubTextures() { 158 if (!EnsureWrappedTextureHost()) { 159 return 0; 160 } 161 return EnsureWrappedTextureHost()->NumSubTextures(); 162 } 163 164 void GPUVideoTextureHost::PushResourceUpdates( 165 wr::TransactionBuilder& aResources, ResourceUpdateOp aOp, 166 const Range<wr::ImageKey>& aImageKeys, const wr::ExternalImageId& aExtID) { 167 MOZ_ASSERT(EnsureWrappedTextureHost(), "Image isn't valid yet"); 168 if (!EnsureWrappedTextureHost()) { 169 return; 170 } 171 EnsureWrappedTextureHost()->PushResourceUpdates(aResources, aOp, aImageKeys, 172 aExtID); 173 } 174 175 void GPUVideoTextureHost::PushDisplayItems( 176 wr::DisplayListBuilder& aBuilder, const wr::LayoutRect& aBounds, 177 const wr::LayoutRect& aClip, wr::ImageRendering aFilter, 178 const Range<wr::ImageKey>& aImageKeys, PushDisplayItemFlagSet aFlags) { 179 MOZ_ASSERT(EnsureWrappedTextureHost(), "Image isn't valid yet"); 180 MOZ_ASSERT(aImageKeys.length() > 0); 181 if (!EnsureWrappedTextureHost()) { 182 return; 183 } 184 185 EnsureWrappedTextureHost()->PushDisplayItems(aBuilder, aBounds, aClip, 186 aFilter, aImageKeys, aFlags); 187 } 188 189 bool GPUVideoTextureHost::SupportsExternalCompositing( 190 WebRenderBackend aBackend) { 191 if (!EnsureWrappedTextureHost()) { 192 return false; 193 } 194 return EnsureWrappedTextureHost()->SupportsExternalCompositing(aBackend); 195 } 196 197 void GPUVideoTextureHost::UnbindTextureSource() { 198 if (EnsureWrappedTextureHost()) { 199 EnsureWrappedTextureHost()->UnbindTextureSource(); 200 } 201 // Handle read unlock 202 TextureHost::UnbindTextureSource(); 203 } 204 205 void GPUVideoTextureHost::NotifyNotUsed() { 206 if (EnsureWrappedTextureHost()) { 207 EnsureWrappedTextureHost()->NotifyNotUsed(); 208 } 209 TextureHost::NotifyNotUsed(); 210 } 211 212 void GPUVideoTextureHost::SetReadFence(Fence* aReadFence) { 213 if (EnsureWrappedTextureHost()) { 214 EnsureWrappedTextureHost()->SetReadFence(aReadFence); 215 } 216 } 217 218 BufferTextureHost* GPUVideoTextureHost::AsBufferTextureHost() { 219 if (EnsureWrappedTextureHost()) { 220 return EnsureWrappedTextureHost()->AsBufferTextureHost(); 221 } 222 return nullptr; 223 } 224 225 DXGITextureHostD3D11* GPUVideoTextureHost::AsDXGITextureHostD3D11() { 226 if (EnsureWrappedTextureHost()) { 227 return EnsureWrappedTextureHost()->AsDXGITextureHostD3D11(); 228 } 229 return nullptr; 230 } 231 232 DXGIYCbCrTextureHostD3D11* GPUVideoTextureHost::AsDXGIYCbCrTextureHostD3D11() { 233 if (EnsureWrappedTextureHost()) { 234 return mWrappedTextureHost->AsDXGIYCbCrTextureHostD3D11(); 235 } 236 return nullptr; 237 } 238 239 bool GPUVideoTextureHost::IsWrappingSurfaceTextureHost() { 240 if (EnsureWrappedTextureHost()) { 241 return EnsureWrappedTextureHost()->IsWrappingSurfaceTextureHost(); 242 } 243 return false; 244 } 245 246 TextureHostType GPUVideoTextureHost::GetTextureHostType() { 247 if (!mWrappedTextureHost) { 248 return TextureHostType::Unknown; 249 } 250 return mWrappedTextureHost->GetTextureHostType(); 251 } 252 253 bool GPUVideoTextureHost::NeedsDeferredDeletion() const { 254 if (!mWrappedTextureHost) { 255 return TextureHost::NeedsDeferredDeletion(); 256 } 257 return mWrappedTextureHost->NeedsDeferredDeletion(); 258 } 259 260 bool GPUVideoTextureHost::NeedsYFlip() const { 261 if (!mWrappedTextureHost) { 262 return TextureHost::NeedsYFlip(); 263 } 264 return mWrappedTextureHost->NeedsYFlip(); 265 } 266 267 } // namespace layers 268 } // namespace mozilla