bool TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags) { mSize = aSize; ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device(); CD3D10_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1, D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE); newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX; HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture)); if (FAILED(hr)) { LOGD3D11("Error creating texture for client!"); return false; } // Defer clearing to the next time we lock to avoid an extra (expensive) lock. mNeedsClear = aFlags & ALLOC_CLEAR_BUFFER; mNeedsClearWhite = aFlags & ALLOC_CLEAR_BUFFER_WHITE; return true; }
bool DeprecatedTextureClientD3D11::EnsureAllocated(gfx::IntSize aSize, gfxContentType aType) { D3D10_TEXTURE2D_DESC desc; if (mTexture) { mTexture->GetDesc(&desc); if (desc.Width == aSize.width && desc.Height == aSize.height) { return true; } mTexture = nullptr; mSurface = nullptr; ClearDT(); } mSize = aSize; ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device(); CD3D10_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1, D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE); newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX; HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture)); if (FAILED(hr)) { LOGD3D11("Error creating texture for client!"); return false; } RefPtr<IDXGIResource> resource; mTexture->QueryInterface((IDXGIResource**)byRef(resource)); HANDLE sharedHandle; hr = resource->GetSharedHandle(&sharedHandle); if (FAILED(hr)) { LOGD3D11("Error getting shared handle for texture."); return false; } mDescriptor = SurfaceDescriptorD3D10((WindowsHandle)sharedHandle, aType == GFX_CONTENT_COLOR_ALPHA); mContentType = aType; return true; }
already_AddRefed<TextureClient> D3D11YCbCrRecycleAllocator::Allocate(SurfaceFormat aFormat, IntSize aSize, BackendSelector aSelector, TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags) { MOZ_ASSERT(aFormat == SurfaceFormat::A8); gfx::IntSize YSize = mYSize.refOr(aSize); gfx::IntSize CbCrSize = mCbCrSize.refOr(gfx::IntSize(YSize.width, YSize.height)); CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_R8_UNORM, YSize.width, YSize.height, 1, 1); newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; RefPtr<ID3D11Texture2D> textureY; HRESULT hr = mDevice->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureY)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); newDesc.Width = CbCrSize.width; newDesc.Height = CbCrSize.height; RefPtr<ID3D11Texture2D> textureCb; hr = mDevice->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCb)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); RefPtr<ID3D11Texture2D> textureCr; hr = mDevice->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCr)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); return TextureClient::CreateWithData( DXGIYCbCrTextureData::Create( textureY, textureCb, textureCr, aSize, YSize, CbCrSize), TextureFlags::DEFAULT, mSurfaceAllocator->GetTextureForwarder()); }
RecordingRenderResource(const physx::apex::NxUserRenderResourceDesc& desc, physx::apex::NxUserRenderResourceManager* childRrm, RecordingRenderResourceManager::RecorderInterface* recorder) : mChild(NULL), mDescriptor(desc), mRecorder(recorder) { assert(desc.numVertexBuffers > 0); mResourceId = resourceIds++; vertexBufferOriginal.resize(desc.numVertexBuffers); vertexBufferChild.resize(desc.numVertexBuffers); for (size_t i = 0; i < vertexBufferOriginal.size(); i++) { vertexBufferOriginal[i] = desc.vertexBuffers[i]; vertexBufferChild[i] = reinterpret_cast<RecordingVertexBuffer*>(desc.vertexBuffers[i])->getChild(); } mDescriptor.vertexBuffers = &vertexBufferOriginal[0]; physx::apex::NxUserRenderResourceDesc newDesc(desc); newDesc.vertexBuffers = &vertexBufferChild[0]; if (desc.indexBuffer != NULL) { newDesc.indexBuffer = reinterpret_cast<RecordingIndexBuffer*>(desc.indexBuffer)->getChild(); } if (desc.boneBuffer != NULL) { newDesc.boneBuffer = reinterpret_cast<RecordingBoneBuffer*>(desc.boneBuffer)->getChild(); } if (childRrm != NULL) { mChild = childRrm->createResource(newDesc); } if (mRecorder != NULL) { mRecorder->createResource(mResourceId, desc); } }
TextureClient* IMFYCbCrImage::GetTextureClient(CompositableClient* aClient) { ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ImageBridgeDevice(); if (!device || aClient->GetForwarder()->GetCompositorBackendType() != LayersBackend::LAYERS_D3D11) { IDirect3DDevice9* d3d9device = gfxWindowsPlatform::GetPlatform()->GetD3D9Device(); if (d3d9device && aClient->GetForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_D3D9) { return GetD3D9TextureClient(aClient); } return nullptr; } if (mTextureClient) { return mTextureClient; } RefPtr<ID3D11DeviceContext> ctx; device->GetImmediateContext(byRef(ctx)); CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_A8_UNORM, mData.mYSize.width, mData.mYSize.height, 1, 1); newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; RefPtr<ID3D11Texture2D> textureY; HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureY)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); newDesc.Width = mData.mCbCrSize.width; newDesc.Height = mData.mCbCrSize.height; RefPtr<ID3D11Texture2D> textureCb; hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureCb)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); RefPtr<ID3D11Texture2D> textureCr; hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureCr)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); { AutoLockTexture lockY(textureY); AutoLockTexture lockCb(textureCb); AutoLockTexture lockCr(textureCr); ctx->UpdateSubresource(textureY, 0, nullptr, mData.mYChannel, mData.mYStride, mData.mYStride * mData.mYSize.height); ctx->UpdateSubresource(textureCb, 0, nullptr, mData.mCbChannel, mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height); ctx->UpdateSubresource(textureCr, 0, nullptr, mData.mCrChannel, mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height); } RefPtr<IDXGIResource> resource; HANDLE shareHandleY; textureY->QueryInterface((IDXGIResource**)byRef(resource)); hr = resource->GetSharedHandle(&shareHandleY); HANDLE shareHandleCb; textureCb->QueryInterface((IDXGIResource**)byRef(resource)); hr = resource->GetSharedHandle(&shareHandleCb); HANDLE shareHandleCr; textureCr->QueryInterface((IDXGIResource**)byRef(resource)); hr = resource->GetSharedHandle(&shareHandleCr); mTextureClient = DXGIYCbCrTextureClient::Create(aClient->GetForwarder(), TextureFlags::DEFAULT, textureY, textureCb, textureCr, shareHandleY, shareHandleCb, shareHandleCr, GetSize(), mData.mYSize, mData.mCbCrSize); return mTextureClient; }
TextureClient* IMFYCbCrImage::GetTextureClient(CompositableClient* aClient) { if (mTextureClient) { return mTextureClient; } RefPtr<ID3D11Device> device; gfxWindowsPlatform::GetPlatform()->GetD3D11ImageBridgeDevice(&device); LayersBackend backend = aClient->GetForwarder()->GetCompositorBackendType(); if (!device || backend != LayersBackend::LAYERS_D3D11) { if (backend == LayersBackend::LAYERS_D3D9 || backend == LayersBackend::LAYERS_D3D11) { return GetD3D9TextureClient(aClient); } return nullptr; } RefPtr<ID3D11DeviceContext> ctx; device->GetImmediateContext(getter_AddRefs(ctx)); CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_R8_UNORM, mData.mYSize.width, mData.mYSize.height, 1, 1); newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; RefPtr<ID3D11Texture2D> textureY; HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureY)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); newDesc.Width = mData.mCbCrSize.width; newDesc.Height = mData.mCbCrSize.height; RefPtr<ID3D11Texture2D> textureCb; hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCb)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); RefPtr<ID3D11Texture2D> textureCr; hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCr)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); { AutoLockTexture lockY(textureY); AutoLockTexture lockCb(textureCb); AutoLockTexture lockCr(textureCr); ctx->UpdateSubresource(textureY, 0, nullptr, mData.mYChannel, mData.mYStride, mData.mYStride * mData.mYSize.height); ctx->UpdateSubresource(textureCb, 0, nullptr, mData.mCbChannel, mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height); ctx->UpdateSubresource(textureCr, 0, nullptr, mData.mCrChannel, mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height); } mTextureClient = TextureClient::CreateWithData( DXGIYCbCrTextureData::Create(aClient->GetForwarder(), TextureFlags::DEFAULT, textureY, textureCb, textureCr, GetSize(), mData.mYSize, mData.mCbCrSize), TextureFlags::DEFAULT, aClient->GetForwarder() ); return mTextureClient; }
void Atlas::AddImageDescriptor(Real left, Real top, Real right, Real bottom) { ImageDescriptor newDesc(left, top, right, bottom); imageDescriptors.push_back(newDesc); imageCount++; }
TextureClient* IMFYCbCrImage::GetTextureClient(KnowsCompositor* aForwarder) { if (mTextureClient) { return mTextureClient; } RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetContentDevice(); if (!device) { device = gfx::DeviceManagerDx::Get()->GetCompositorDevice(); } LayersBackend backend = aForwarder->GetCompositorBackendType(); if (!device || backend != LayersBackend::LAYERS_D3D11) { if (backend == LayersBackend::LAYERS_D3D9 || backend == LayersBackend::LAYERS_D3D11) { return GetD3D9TextureClient(aForwarder); } return nullptr; } if (!gfx::DeviceManagerDx::Get()->CanInitializeKeyedMutexTextures()) { return nullptr; } if (mData.mYStride < 0 || mData.mCbCrStride < 0) { // D3D11 only supports unsigned stride values. return nullptr; } CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_R8_UNORM, mData.mYSize.width, mData.mYSize.height, 1, 1); if (device == gfx::DeviceManagerDx::Get()->GetCompositorDevice()) { newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; } else { newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; } RefPtr<ID3D11Texture2D> textureY; D3D11_SUBRESOURCE_DATA yData = { mData.mYChannel, (UINT)mData.mYStride, 0 }; HRESULT hr = device->CreateTexture2D(&newDesc, &yData, getter_AddRefs(textureY)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); newDesc.Width = mData.mCbCrSize.width; newDesc.Height = mData.mCbCrSize.height; RefPtr<ID3D11Texture2D> textureCb; D3D11_SUBRESOURCE_DATA cbData = { mData.mCbChannel, (UINT)mData.mCbCrStride, 0 }; hr = device->CreateTexture2D(&newDesc, &cbData, getter_AddRefs(textureCb)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); RefPtr<ID3D11Texture2D> textureCr; D3D11_SUBRESOURCE_DATA crData = { mData.mCrChannel, (UINT)mData.mCbCrStride, 0 }; hr = device->CreateTexture2D(&newDesc, &crData, getter_AddRefs(textureCr)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); // Even though the textures we created are meant to be protected by a keyed mutex, // it appears that D3D doesn't include the initial memory upload within this // synchronization. Add an empty lock/unlock pair since that appears to // be sufficient to make sure we synchronize. { AutoLockTexture lockCr(textureCr); } mTextureClient = TextureClient::CreateWithData( DXGIYCbCrTextureData::Create(TextureFlags::DEFAULT, textureY, textureCb, textureCr, GetSize(), mData.mYSize, mData.mCbCrSize), TextureFlags::DEFAULT, aForwarder->GetTextureForwarder() ); return mTextureClient; }
DXGIYCbCrTextureData* IMFYCbCrImage::GetD3D11TextureData(Data aData, gfx::IntSize aSize) { HRESULT hr; RefPtr<ID3D10Multithread> mt; RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetContentDevice(); if (!device) { device = gfx::DeviceManagerDx::Get()->GetCompositorDevice(); } hr = device->QueryInterface((ID3D10Multithread**)getter_AddRefs(mt)); if (FAILED(hr)) { return nullptr; } if (!mt->GetMultithreadProtected()) { return nullptr; } if (!gfx::DeviceManagerDx::Get()->CanInitializeKeyedMutexTextures()) { return nullptr; } if (aData.mYStride < 0 || aData.mCbCrStride < 0) { // D3D11 only supports unsigned stride values. return nullptr; } CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_R8_UNORM, aData.mYSize.width, aData.mYSize.height, 1, 1); if (device == gfx::DeviceManagerDx::Get()->GetCompositorDevice()) { newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; } else { newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; } RefPtr<ID3D11Texture2D> textureY; hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureY)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); newDesc.Width = aData.mCbCrSize.width; newDesc.Height = aData.mCbCrSize.height; RefPtr<ID3D11Texture2D> textureCb; hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCb)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); RefPtr<ID3D11Texture2D> textureCr; hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCr)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); // The documentation here seems to suggest using the immediate mode context // on more than one thread is not allowed: // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476891(v=vs.85).aspx // The Debug Layer seems to imply it is though. When the ID3D10Multithread // layer is on. The Enter/Leave of the critical section shouldn't even be // required but were added for extra security. { AutoLockTexture lockY(textureY); AutoLockTexture lockCr(textureCr); AutoLockTexture lockCb(textureCb); mt->Enter(); RefPtr<ID3D11DeviceContext> ctx; device->GetImmediateContext((ID3D11DeviceContext**)getter_AddRefs(ctx)); D3D11_BOX box; box.front = box.top = box.left = 0; box.back = 1; box.right = aData.mYSize.width; box.bottom = aData.mYSize.height; ctx->UpdateSubresource(textureY, 0, &box, aData.mYChannel, aData.mYStride, 0); box.right = aData.mCbCrSize.width; box.bottom = aData.mCbCrSize.height; ctx->UpdateSubresource(textureCb, 0, &box, aData.mCbChannel, aData.mCbCrStride, 0); ctx->UpdateSubresource(textureCr, 0, &box, aData.mCrChannel, aData.mCbCrStride, 0); mt->Leave(); } return DXGIYCbCrTextureData::Create(TextureFlags::DEFAULT, textureY, textureCb, textureCr, aSize, aData.mYSize, aData.mCbCrSize); }