HANDLE D3D9SurfaceImage::GetShareHandle() { // Ensure the image has completed its synchronization, // and safe to used by the caller on another device. EnsureSynchronized(); return mShareHandle; }
TextureClient* D3D9SurfaceImage::GetTextureClient(CompositableClient* aClient) { MOZ_ASSERT(mTextureClient); MOZ_ASSERT(mTextureClient->GetAllocator() == aClient->GetForwarder()); EnsureSynchronized(); return mTextureClient; }
already_AddRefed<gfxASurface> D3D9SurfaceImage::GetAsSurface() { NS_ENSURE_TRUE(mTexture, nullptr); HRESULT hr; nsRefPtr<gfxImageSurface> surface = new gfxImageSurface(mSize, gfxASurface::ImageFormatRGB24); if (!surface->CairoSurface() || surface->CairoStatus()) { NS_WARNING("Failed to created Cairo image surface for D3D9SurfaceImage."); return nullptr; } // Ensure that the texture is ready to be used. EnsureSynchronized(); // Readback the texture from GPU memory into system memory, so that // we can copy it into the Cairo image. This is expensive. RefPtr<IDirect3DSurface9> textureSurface; hr = mTexture->GetSurfaceLevel(0, byRef(textureSurface)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); RefPtr<IDirect3DDevice9> device; hr = mTexture->GetDevice(byRef(device)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); RefPtr<IDirect3DSurface9> systemMemorySurface; hr = device->CreateOffscreenPlainSurface(mDesc.Width, mDesc.Height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, byRef(systemMemorySurface), 0); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); hr = device->GetRenderTargetData(textureSurface, systemMemorySurface); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); D3DLOCKED_RECT rect; hr = systemMemorySurface->LockRect(&rect, NULL, 0); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); const unsigned char* src = (const unsigned char*)(rect.pBits); const unsigned srcPitch = rect.Pitch; for (int y = 0; y < mSize.height; y++) { memcpy(surface->Data() + surface->Stride() * y, (unsigned char*)(src) + srcPitch * y, mSize.width * 4); } systemMemorySurface->UnlockRect(); return surface.forget(); }
bool D3D9SurfaceImage::IsValid() { EnsureSynchronized(); return mValid; }
already_AddRefed<gfx::SourceSurface> D3D9SurfaceImage::GetAsSourceSurface() { NS_ENSURE_TRUE(mTextureClient, nullptr); HRESULT hr; RefPtr<gfx::DataSourceSurface> surface = gfx::Factory::CreateDataSourceSurface(mSize, gfx::SurfaceFormat::B8G8R8X8); if (NS_WARN_IF(!surface)) { return nullptr; } // Ensure that the texture is ready to be used. EnsureSynchronized(); // Readback the texture from GPU memory into system memory, so that // we can copy it into the Cairo image. This is expensive. RefPtr<IDirect3DSurface9> textureSurface = mTextureClient->GetD3D9Surface(); if (!textureSurface) { return nullptr; } RefPtr<IDirect3DDevice9> device = mTextureClient->GetD3D9Device(); if (!device) { return nullptr; } RefPtr<IDirect3DSurface9> systemMemorySurface; hr = device->CreateOffscreenPlainSurface(mSize.width, mSize.height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, byRef(systemMemorySurface), 0); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); hr = device->GetRenderTargetData(textureSurface, systemMemorySurface); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); D3DLOCKED_RECT rect; hr = systemMemorySurface->LockRect(&rect, nullptr, 0); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); gfx::DataSourceSurface::MappedSurface mappedSurface; if (!surface->Map(gfx::DataSourceSurface::WRITE, &mappedSurface)) { systemMemorySurface->UnlockRect(); return nullptr; } const unsigned char* src = (const unsigned char*)(rect.pBits); const unsigned srcPitch = rect.Pitch; for (int y = 0; y < mSize.height; y++) { memcpy(mappedSurface.mData + mappedSurface.mStride * y, (unsigned char*)(src) + srcPitch * y, mSize.width * 4); } systemMemorySurface->UnlockRect(); surface->Unmap(); return surface.forget(); }