diff --git a/gfx/layers/client/CompositableClient.cpp b/gfx/layers/client/CompositableClient.cpp index cc4cfc861009..2a4a6ef7dffd 100644 --- a/gfx/layers/client/CompositableClient.cpp +++ b/gfx/layers/client/CompositableClient.cpp @@ -207,8 +207,7 @@ CompositableClient::CreateTextureClientForDrawing(SurfaceFormat aFormat, if (parentBackend == LayersBackend::LAYERS_D3D9 && !GetForwarder()->ForwardsToDifferentProcess() && !(aTextureFlags & TEXTURE_ALLOC_FALLBACK)) { - // non-DIB textures don't work with alpha, see notes in TextureD3D9. - if (ContentForFormat(aFormat) != gfxContentType::COLOR) { + if (!gfxWindowsPlatform::GetPlatform()->GetD3D9Device()) { result = new DIBTextureClientD3D9(aFormat, aTextureFlags); } else { result = new CairoTextureClientD3D9(aFormat, aTextureFlags); diff --git a/gfx/layers/client/ContentClient.cpp b/gfx/layers/client/ContentClient.cpp index 132e0f8bc634..f28ff3b5ade5 100644 --- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -63,7 +63,8 @@ ContentClient::CreateContentClient(CompositableForwarder* aForwarder) } else #endif { - useDoubleBuffering = LayerManagerComposite::SupportsDirectTexturing() || + useDoubleBuffering = (LayerManagerComposite::SupportsDirectTexturing() && + backend != LayersBackend::LAYERS_D3D9) || backend == LayersBackend::LAYERS_BASIC; } diff --git a/gfx/layers/d3d9/TextureD3D9.cpp b/gfx/layers/d3d9/TextureD3D9.cpp index b01cd07c5cb3..18d3f477552a 100644 --- a/gfx/layers/d3d9/TextureD3D9.cpp +++ b/gfx/layers/d3d9/TextureD3D9.cpp @@ -1258,6 +1258,7 @@ CairoTextureClientD3D9::CairoTextureClientD3D9(gfx::SurfaceFormat aFormat, Textu , mFormat(aFormat) , mIsLocked(false) , mNeedsClear(false) + , mLockRect(false) { MOZ_COUNT_CTOR(CairoTextureClientD3D9); } @@ -1291,6 +1292,11 @@ CairoTextureClientD3D9::Unlock() mDrawTarget = nullptr; } + if (mLockRect) { + mD3D9Surface->UnlockRect(); + mLockRect = false; + } + if (mSurface) { mSurface = nullptr; } @@ -1333,11 +1339,19 @@ CairoTextureClientD3D9::GetAsDrawTarget() } } - mSurface = new gfxWindowsSurface(mD3D9Surface); - if (!mSurface || mSurface->CairoStatus()) { - NS_WARNING("Could not create surface for d3d9 surface"); - mSurface = nullptr; - return nullptr; + if (ContentForFormat(mFormat) == gfxContentType::COLOR_ALPHA) { + D3DLOCKED_RECT rect; + mD3D9Surface->LockRect(&rect, nullptr, 0); + mSurface = new gfxImageSurface((uint8_t*)rect.pBits, ThebesIntSize(mSize), + rect.Pitch, gfxImageFormat::ARGB32); + mLockRect = true; + } else { + mSurface = new gfxWindowsSurface(mD3D9Surface); + if (!mSurface || mSurface->CairoStatus()) { + NS_WARNING("Could not create surface for d3d9 surface"); + mSurface = nullptr; + return nullptr; + } } mDrawTarget = diff --git a/gfx/layers/d3d9/TextureD3D9.h b/gfx/layers/d3d9/TextureD3D9.h index e4c9c962f12a..5007176065f1 100644 --- a/gfx/layers/d3d9/TextureD3D9.h +++ b/gfx/layers/d3d9/TextureD3D9.h @@ -181,7 +181,7 @@ protected: }; /** - * Can only be drawn into through Cairo, and only support opaque surfaces. + * Can only be drawn into through Cairo and need a D3D9 context on the client side. * The corresponding TextureHost is TextureHostD3D9. */ class CairoTextureClientD3D9 : public TextureClient @@ -228,11 +228,12 @@ private: gfx::SurfaceFormat mFormat; bool mIsLocked; bool mNeedsClear; + bool mLockRect; }; /** * Can only be drawn into through Cairo. - * Supports opaque surfaces. Prefer CairoTextureClientD3D9 when possible. + * Prefer CairoTextureClientD3D9 when possible. * The coresponding TextureHost is DIBTextureHostD3D9. */ class DIBTextureClientD3D9 : public TextureClient