tor-browser

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

IMFYCbCrImage.cpp (4370B)


      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 "IMFYCbCrImage.h"
      8 #include "mozilla/gfx/DeviceManagerDx.h"
      9 #include "mozilla/gfx/gfxVars.h"
     10 #include "mozilla/gfx/Types.h"
     11 #include "mozilla/layers/TextureD3D11.h"
     12 #include "mozilla/layers/CompositableClient.h"
     13 #include "mozilla/layers/CompositableForwarder.h"
     14 #include "mozilla/layers/D3D11YCbCrImage.h"
     15 #include "mozilla/layers/FenceD3D11.h"
     16 #include "mozilla/layers/CompositeProcessD3D11FencesHolderMap.h"
     17 #include "mozilla/layers/TextureClient.h"
     18 
     19 namespace mozilla {
     20 namespace layers {
     21 
     22 IMFYCbCrImage::IMFYCbCrImage(IMFMediaBuffer* aBuffer, IMF2DBuffer* a2DBuffer,
     23                             KnowsCompositor* aKnowsCompositor,
     24                             ImageContainer* aContainer)
     25    : RecyclingPlanarYCbCrImage(nullptr),
     26      mBuffer(aBuffer),
     27      m2DBuffer(a2DBuffer) {
     28  mAllocator = aContainer->GetD3D11YCbCrRecycleAllocator(aKnowsCompositor);
     29 }
     30 
     31 IMFYCbCrImage::~IMFYCbCrImage() {
     32  if (m2DBuffer) {
     33    m2DBuffer->Unlock2D();
     34  } else {
     35    mBuffer->Unlock();
     36  }
     37 }
     38 
     39 /* static */
     40 bool IMFYCbCrImage::CopyDataToTexture(const Data& aData, ID3D11Device* aDevice,
     41                                      DXGIYCbCrTextureData* aTextureData) {
     42  MOZ_ASSERT(aTextureData);
     43 
     44  if (!gfx::DeviceManagerDx::Get()->CanInitializeKeyedMutexTextures()) {
     45    return false;
     46  }
     47 
     48  ID3D11Texture2D* textureY = aTextureData->GetD3D11Texture(0);
     49  ID3D11Texture2D* textureCb = aTextureData->GetD3D11Texture(1);
     50  ID3D11Texture2D* textureCr = aTextureData->GetD3D11Texture(2);
     51 
     52  RefPtr<ID3D11DeviceContext> ctx;
     53  aDevice->GetImmediateContext(getter_AddRefs(ctx));
     54  if (!ctx) {
     55    gfxCriticalError() << "Failed to get immediate context.";
     56    return false;
     57  }
     58 
     59  D3D11_BOX box;
     60  box.front = box.top = box.left = 0;
     61  box.back = 1;
     62  box.right = aData.YDataSize().width;
     63  box.bottom = aData.YDataSize().height;
     64  ctx->UpdateSubresource(textureY, 0, &box, aData.mYChannel, aData.mYStride, 0);
     65 
     66  box.right = aData.CbCrDataSize().width;
     67  box.bottom = aData.CbCrDataSize().height;
     68  ctx->UpdateSubresource(textureCb, 0, &box, aData.mCbChannel,
     69                         aData.mCbCrStride, 0);
     70  ctx->UpdateSubresource(textureCr, 0, &box, aData.mCrChannel,
     71                         aData.mCbCrStride, 0);
     72 
     73  auto* fenceHolderMap = CompositeProcessD3D11FencesHolderMap::Get();
     74  if (!fenceHolderMap) {
     75    MOZ_ASSERT_UNREACHABLE("unexpected to be called");
     76    return false;
     77  }
     78 
     79  aTextureData->mWriteFence->IncrementAndSignal();
     80  fenceHolderMap->SetWriteFence(aTextureData->mFencesHolderId,
     81                                aTextureData->mWriteFence);
     82 
     83  return true;
     84 }
     85 
     86 TextureClient* IMFYCbCrImage::GetD3D11TextureClient(
     87    KnowsCompositor* aKnowsCompositor) {
     88  if (!mAllocator) {
     89    return nullptr;
     90  }
     91 
     92  auto* fenceHolderMap = CompositeProcessD3D11FencesHolderMap::Get();
     93  if (!fenceHolderMap) {
     94    MOZ_ASSERT_UNREACHABLE("unexpected to be called");
     95    return nullptr;
     96  }
     97 
     98  RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetImageDevice();
     99  if (!device) {
    100    return nullptr;
    101  }
    102 
    103  {
    104    DXGIYCbCrTextureAllocationHelper helper(mData, TextureFlags::DEFAULT,
    105                                            device);
    106    mTextureClient = mAllocator->CreateOrRecycle(helper).unwrapOr(nullptr);
    107  }
    108 
    109  if (!mTextureClient) {
    110    return nullptr;
    111  }
    112 
    113  DXGIYCbCrTextureData* data =
    114      mTextureClient->GetInternalData()->AsDXGIYCbCrTextureData();
    115 
    116  if (!fenceHolderMap->WaitAllFencesAndForget(data->mFencesHolderId, device)) {
    117    return nullptr;
    118  }
    119 
    120  if (!CopyDataToTexture(mData, device, data)) {
    121    // Failed to copy data
    122    mTextureClient = nullptr;
    123    return nullptr;
    124  }
    125 
    126  return mTextureClient;
    127 }
    128 
    129 TextureClient* IMFYCbCrImage::GetTextureClient(
    130    KnowsCompositor* aKnowsCompositor) {
    131  if (mTextureClient) {
    132    return mTextureClient;
    133  }
    134 
    135  RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetImageDevice();
    136  if (!device || !aKnowsCompositor->SupportsD3D11()) {
    137    return nullptr;
    138  }
    139  return GetD3D11TextureClient(aKnowsCompositor);
    140 }
    141 
    142 }  // namespace layers
    143 }  // namespace mozilla