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