tor-browser

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

D3D11ZeroCopyTextureImage.cpp (6167B)


      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 <d3d11.h>
      8 #include <mfobjects.h>
      9 
     10 #include "D3D11ZeroCopyTextureImage.h"
     11 #include "D3D11TextureWrapper.h"
     12 #include "WMF.h"
     13 #include "mozilla/gfx/SourceSurfaceRawData.h"
     14 #include "mozilla/layers/FenceD3D11.h"
     15 #include "mozilla/layers/KnowsCompositor.h"
     16 #include "mozilla/layers/TextureForwarder.h"
     17 
     18 namespace mozilla {
     19 namespace layers {
     20 
     21 using namespace gfx;
     22 
     23 /* static */
     24 RefPtr<IMFSampleWrapper> IMFSampleWrapper::Create(IMFSample* aVideoSample) {
     25  RefPtr<IMFSampleWrapper> wrapper = new IMFSampleWrapper(aVideoSample);
     26  return wrapper;
     27 }
     28 
     29 IMFSampleWrapper::IMFSampleWrapper(IMFSample* aVideoSample)
     30    : mVideoSample(aVideoSample) {}
     31 
     32 IMFSampleWrapper::~IMFSampleWrapper() {}
     33 
     34 void IMFSampleWrapper::ClearVideoSample() { mVideoSample = nullptr; }
     35 
     36 D3D11ZeroCopyTextureImage::D3D11ZeroCopyTextureImage(
     37    ID3D11Texture2D* aTexture, const uint32_t aArrayIndex,
     38    const gfx::IntSize& aSize, const gfx::IntRect& aRect,
     39    const gfx::SurfaceFormat aFormat, const gfx::ColorSpace2 aColorSpace,
     40    const gfx::ColorRange aColorRange, const gfx::ColorDepth aColorDepth)
     41    : Image(nullptr, ImageFormat::D3D11_TEXTURE_ZERO_COPY),
     42      mTexture(aTexture),
     43      mArrayIndex(aArrayIndex),
     44      mSize(aSize),
     45      mPictureRect(aRect),
     46      mFormat(aFormat),
     47      mColorSpace(aColorSpace),
     48      mColorRange(aColorRange),
     49      mColorDepth(aColorDepth) {
     50  MOZ_ASSERT(XRE_IsGPUProcess());
     51  MOZ_ASSERT(mFormat == gfx::SurfaceFormat::NV12 ||
     52             mFormat == gfx::SurfaceFormat::P010 ||
     53             mFormat == gfx::SurfaceFormat::P016);
     54 }
     55 
     56 D3D11ZeroCopyTextureImage::~D3D11ZeroCopyTextureImage() {
     57  // XXX add shutdown check for fence?
     58 }
     59 
     60 void D3D11ZeroCopyTextureImage::AllocateTextureClient(
     61    KnowsCompositor* aKnowsCompositor, RefPtr<ZeroCopyUsageInfo> aUsageInfo,
     62    const RefPtr<FenceD3D11> aWriteFence) {
     63  if (aWriteFence) {
     64    aWriteFence->IncrementAndSignal();
     65  }
     66  mTextureClient = D3D11TextureData::CreateTextureClient(
     67      mTexture, mArrayIndex, mSize, mFormat, mColorSpace, mColorRange,
     68      aKnowsCompositor, aUsageInfo, aWriteFence);
     69  MOZ_ASSERT(mTextureClient);
     70 }
     71 
     72 gfx::IntSize D3D11ZeroCopyTextureImage::GetSize() const { return mSize; }
     73 
     74 TextureClient* D3D11ZeroCopyTextureImage::GetTextureClient(
     75    KnowsCompositor* aKnowsCompositor) {
     76  return mTextureClient;
     77 }
     78 
     79 already_AddRefed<gfx::SourceSurface>
     80 D3D11ZeroCopyTextureImage::GetAsSourceSurface() {
     81  RefPtr<ID3D11Texture2D> src = GetTexture();
     82  if (!src) {
     83    gfxWarning() << "Cannot readback from shared texture because no texture is "
     84                    "available.";
     85    return nullptr;
     86  }
     87 
     88  RefPtr<gfx::SourceSurface> sourceSurface =
     89      gfx::Factory::CreateBGRA8DataSourceSurfaceForD3D11Texture(
     90          src, mArrayIndex, mColorSpace, mColorRange);
     91 
     92  // There is a case that mSize and size of mTexture are different. In this
     93  // case, size of sourceSurface is different from mSize.
     94  if (sourceSurface && sourceSurface->GetSize() != mSize) {
     95    MOZ_RELEASE_ASSERT(sourceSurface->GetType() == SurfaceType::DATA_ALIGNED);
     96    RefPtr<gfx::SourceSurfaceAlignedRawData> rawData =
     97        static_cast<gfx::SourceSurfaceAlignedRawData*>(sourceSurface.get());
     98    auto data = rawData->GetData();
     99    auto stride = rawData->Stride();
    100    auto size = rawData->GetSize();
    101    auto format = rawData->GetFormat();
    102    sourceSurface = gfx::Factory::CreateWrappingDataSourceSurface(
    103        data, stride, Min(size, mSize), format,
    104        [](void* aClosure) {
    105          RefPtr<SourceSurfaceAlignedRawData> surface =
    106              dont_AddRef(static_cast<SourceSurfaceAlignedRawData*>(aClosure));
    107        },
    108        rawData.forget().take());
    109  }
    110  return sourceSurface.forget();
    111 }
    112 
    113 nsresult D3D11ZeroCopyTextureImage::BuildSurfaceDescriptorBuffer(
    114    SurfaceDescriptorBuffer& aSdBuffer, BuildSdbFlags aFlags,
    115    const std::function<MemoryOrShmem(uint32_t)>& aAllocate) {
    116  RefPtr<ID3D11Texture2D> src = GetTexture();
    117  if (!src) {
    118    gfxWarning() << "Cannot readback from shared texture because no texture is "
    119                    "available.";
    120    return NS_ERROR_FAILURE;
    121  }
    122 
    123  nsresult rv =
    124      gfx::Factory::CreateSdbForD3D11Texture(src, mSize, aSdBuffer, aAllocate);
    125  if (rv != NS_ERROR_NOT_IMPLEMENTED) {
    126    // TODO(aosmond): We only support BGRA on this path, but depending on
    127    // aFlags, we may be able to return a YCbCr format without conversion.
    128    return rv;
    129  }
    130 
    131  return Image::BuildSurfaceDescriptorBuffer(aSdBuffer, aFlags, aAllocate);
    132 }
    133 
    134 ID3D11Texture2D* D3D11ZeroCopyTextureImage::GetTexture() const {
    135  return mTexture;
    136 }
    137 
    138 D3D11TextureIMFSampleImage::D3D11TextureIMFSampleImage(
    139    IMFSample* aVideoSample, ID3D11Texture2D* aTexture,
    140    const uint32_t aArrayIndex, const gfx::IntSize& aSize,
    141    const gfx::IntRect& aRect, const gfx::SurfaceFormat aFormat,
    142    const gfx::ColorSpace2 aColorSpace, const gfx::ColorRange aColorRange,
    143    const gfx::ColorDepth aColorDepth)
    144    : D3D11ZeroCopyTextureImage(aTexture, aArrayIndex, aSize, aRect, aFormat,
    145                                aColorSpace, aColorRange, aColorDepth),
    146      mVideoSample(IMFSampleWrapper::Create(aVideoSample)) {
    147  MOZ_ASSERT(XRE_IsGPUProcess());
    148 }
    149 
    150 RefPtr<IMFSampleWrapper> D3D11TextureIMFSampleImage::GetIMFSampleWrapper() {
    151  return mVideoSample;
    152 }
    153 
    154 D3D11TextureAVFrameImage::D3D11TextureAVFrameImage(
    155    D3D11TextureWrapper* aWrapper, const gfx::IntSize& aSize,
    156    const gfx::IntRect& aRect, const gfx::ColorSpace2 aColorSpace,
    157    const gfx::ColorRange aColorRange, const gfx::ColorDepth aColorDepth)
    158    : D3D11ZeroCopyTextureImage(aWrapper->GetTexture(), aWrapper->mArrayIdx,
    159                                aSize, aRect, aWrapper->mFormat, aColorSpace,
    160                                aColorRange, aColorDepth),
    161      mWrapper(aWrapper) {
    162  MOZ_ASSERT(XRE_IsGPUProcess());
    163 }
    164 
    165 }  // namespace layers
    166 }  // namespace mozilla