tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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