void CompositorD3D11::PaintToTarget() { nsRefPtr<ID3D11Texture2D> backBuf; HRESULT hr; hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)backBuf.StartAssignment()); if (Failed(hr)) { return; } D3D11_TEXTURE2D_DESC bbDesc; backBuf->GetDesc(&bbDesc); CD3D11_TEXTURE2D_DESC softDesc(bbDesc.Format, bbDesc.Width, bbDesc.Height); softDesc.MipLevels = 1; softDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; softDesc.Usage = D3D11_USAGE_STAGING; softDesc.BindFlags = 0; nsRefPtr<ID3D11Texture2D> readTexture; hr = mDevice->CreateTexture2D(&softDesc, nullptr, getter_AddRefs(readTexture)); if (Failed(hr)) { return; } mContext->CopyResource(readTexture, backBuf); D3D11_MAPPED_SUBRESOURCE map; hr = mContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &map); if (Failed(hr)) { return; } RefPtr<DataSourceSurface> sourceSurface = Factory::CreateWrappingDataSourceSurface((uint8_t*)map.pData, map.RowPitch, IntSize(bbDesc.Width, bbDesc.Height), SurfaceFormat::B8G8R8A8); mTarget->CopySurface(sourceSurface, IntRect(0, 0, bbDesc.Width, bbDesc.Height), IntPoint(-mTargetBounds.x, -mTargetBounds.y)); mTarget->Flush(); mContext->Unmap(readTexture, 0); }
void LayerManagerD3D10::PaintToTarget() { nsRefPtr<ID3D10Texture2D> backBuf; mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)backBuf.StartAssignment()); D3D10_TEXTURE2D_DESC bbDesc; backBuf->GetDesc(&bbDesc); CD3D10_TEXTURE2D_DESC softDesc(bbDesc.Format, bbDesc.Width, bbDesc.Height); softDesc.MipLevels = 1; softDesc.CPUAccessFlags = D3D10_CPU_ACCESS_READ; softDesc.Usage = D3D10_USAGE_STAGING; softDesc.BindFlags = 0; nsRefPtr<ID3D10Texture2D> readTexture; device()->CreateTexture2D(&softDesc, NULL, getter_AddRefs(readTexture)); device()->CopyResource(readTexture, backBuf); D3D10_MAPPED_TEXTURE2D map; readTexture->Map(0, D3D10_MAP_READ, 0, &map); nsRefPtr<gfxImageSurface> tmpSurface = new gfxImageSurface((unsigned char*)map.pData, gfxIntSize(bbDesc.Width, bbDesc.Height), map.RowPitch, gfxASurface::ImageFormatARGB32); mTarget->SetSource(tmpSurface); mTarget->SetOperator(gfxContext::OPERATOR_OVER); mTarget->Paint(); readTexture->Unmap(0); }
already_AddRefed<gfx::SourceSurface> D3D11ShareHandleImage::GetAsSourceSurface() { RefPtr<ID3D11Texture2D> texture = GetTexture(); if (!texture) { NS_WARNING("Cannot readback from shared texture because no texture is available."); return nullptr; } RefPtr<ID3D11Device> device; texture->GetDevice(byRef(device)); RefPtr<IDXGIKeyedMutex> keyedMutex; if (FAILED(texture->QueryInterface(static_cast<IDXGIKeyedMutex**>(byRef(keyedMutex))))) { NS_WARNING("Failed to QueryInterface for IDXGIKeyedMutex, strange."); return nullptr; } if (FAILED(keyedMutex->AcquireSync(0, 0))) { NS_WARNING("Failed to acquire sync for keyedMutex, plugin failed to release?"); return nullptr; } D3D11_TEXTURE2D_DESC desc; texture->GetDesc(&desc); CD3D11_TEXTURE2D_DESC softDesc(desc.Format, desc.Width, desc.Height); softDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; softDesc.BindFlags = 0; softDesc.MiscFlags = 0; softDesc.MipLevels = 1; softDesc.Usage = D3D11_USAGE_STAGING; RefPtr<ID3D11Texture2D> softTexture; HRESULT hr = device->CreateTexture2D(&softDesc, NULL, static_cast<ID3D11Texture2D**>(byRef(softTexture))); if (FAILED(hr)) { NS_WARNING("Failed to create 2D staging texture."); keyedMutex->ReleaseSync(0); return nullptr; } RefPtr<ID3D11DeviceContext> context; device->GetImmediateContext(byRef(context)); if (!context) { keyedMutex->ReleaseSync(0); return nullptr; } context->CopyResource(softTexture, texture); keyedMutex->ReleaseSync(0); RefPtr<gfx::DataSourceSurface> surface = gfx::Factory::CreateDataSourceSurface(mSize, gfx::SurfaceFormat::B8G8R8X8); if (NS_WARN_IF(!surface)) { return nullptr; } gfx::DataSourceSurface::MappedSurface mappedSurface; if (!surface->Map(gfx::DataSourceSurface::WRITE, &mappedSurface)) { return nullptr; } D3D11_MAPPED_SUBRESOURCE map; hr = context->Map(softTexture, 0, D3D11_MAP_READ, 0, &map); if (!SUCCEEDED(hr)) { surface->Unmap(); return nullptr; } for (int y = 0; y < mSize.height; y++) { memcpy(mappedSurface.mData + mappedSurface.mStride * y, (unsigned char*)(map.pData) + map.RowPitch * y, mSize.width * 4); } context->Unmap(softTexture, 0); surface->Unmap(); return surface.forget(); }