Bug 1839315: part 4) Link from `SheetLoadData::mWasAlternate` to spec. r=emilio DONTBUILD
[gecko.git] / gfx / layers / IMFYCbCrImage.cpp
blob0534b2126e9080ef4c996ec1bbae96fac7940b27
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/. */
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/TextureClient.h"
16 #include "d3d9.h"
18 namespace mozilla {
19 namespace layers {
21 IMFYCbCrImage::IMFYCbCrImage(IMFMediaBuffer* aBuffer, IMF2DBuffer* a2DBuffer,
22 KnowsCompositor* aKnowsCompositor,
23 ImageContainer* aContainer)
24 : RecyclingPlanarYCbCrImage(nullptr),
25 mBuffer(aBuffer),
26 m2DBuffer(a2DBuffer) {
27 mAllocator = aContainer->GetD3D11YCbCrRecycleAllocator(aKnowsCompositor);
30 IMFYCbCrImage::~IMFYCbCrImage() {
31 if (m2DBuffer) {
32 m2DBuffer->Unlock2D();
33 } else {
34 mBuffer->Unlock();
38 /* static */
39 bool IMFYCbCrImage::CopyDataToTexture(const Data& aData, ID3D11Device* aDevice,
40 DXGIYCbCrTextureData* aTextureData) {
41 MOZ_ASSERT(aTextureData);
43 HRESULT hr;
44 RefPtr<ID3D10Multithread> mt;
46 hr = aDevice->QueryInterface((ID3D10Multithread**)getter_AddRefs(mt));
47 if (FAILED(hr)) {
48 return false;
51 if (!mt->GetMultithreadProtected()) {
52 return false;
55 if (!gfx::DeviceManagerDx::Get()->CanInitializeKeyedMutexTextures()) {
56 return false;
59 ID3D11Texture2D* textureY = aTextureData->GetD3D11Texture(0);
60 ID3D11Texture2D* textureCb = aTextureData->GetD3D11Texture(1);
61 ID3D11Texture2D* textureCr = aTextureData->GetD3D11Texture(2);
63 D3D11MTAutoEnter mtAutoEnter(mt.forget());
65 RefPtr<ID3D11DeviceContext> ctx;
66 aDevice->GetImmediateContext(getter_AddRefs(ctx));
67 if (!ctx) {
68 gfxCriticalError() << "Failed to get immediate context.";
69 return false;
72 // The documentation here seems to suggest using the immediate mode context
73 // on more than one thread is not allowed:
74 // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476891(v=vs.85).aspx
75 // The Debug Layer seems to imply it is though. When the ID3D10Multithread
76 // layer is on. The Enter/Leave of the critical section shouldn't even be
77 // required but were added for extra security.
80 AutoLockD3D11Texture lockY(textureY);
81 AutoLockD3D11Texture lockCr(textureCr);
82 AutoLockD3D11Texture lockCb(textureCb);
83 D3D11MTAutoEnter mtAutoEnter(mt.forget());
85 D3D11_BOX box;
86 box.front = box.top = box.left = 0;
87 box.back = 1;
88 box.right = aData.YDataSize().width;
89 box.bottom = aData.YDataSize().height;
90 ctx->UpdateSubresource(textureY, 0, &box, aData.mYChannel, aData.mYStride,
91 0);
93 box.right = aData.CbCrDataSize().width;
94 box.bottom = aData.CbCrDataSize().height;
95 ctx->UpdateSubresource(textureCb, 0, &box, aData.mCbChannel,
96 aData.mCbCrStride, 0);
97 ctx->UpdateSubresource(textureCr, 0, &box, aData.mCrChannel,
98 aData.mCbCrStride, 0);
101 return true;
104 TextureClient* IMFYCbCrImage::GetD3D11TextureClient(
105 KnowsCompositor* aKnowsCompositor) {
106 if (!mAllocator) {
107 return nullptr;
110 RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetImageDevice();
111 if (!device) {
112 return nullptr;
116 DXGIYCbCrTextureAllocationHelper helper(mData, TextureFlags::DEFAULT,
117 device);
118 mTextureClient = mAllocator->CreateOrRecycle(helper);
121 if (!mTextureClient) {
122 return nullptr;
125 DXGIYCbCrTextureData* data =
126 mTextureClient->GetInternalData()->AsDXGIYCbCrTextureData();
128 if (!CopyDataToTexture(mData, device, data)) {
129 // Failed to copy data
130 mTextureClient = nullptr;
131 return nullptr;
134 return mTextureClient;
137 TextureClient* IMFYCbCrImage::GetTextureClient(
138 KnowsCompositor* aKnowsCompositor) {
139 if (mTextureClient) {
140 return mTextureClient;
143 RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetImageDevice();
144 if (!device || !aKnowsCompositor->SupportsD3D11()) {
145 return nullptr;
147 return GetD3D11TextureClient(aKnowsCompositor);
150 } // namespace layers
151 } // namespace mozilla