diff --git a/gfx/layers/PersistentBufferProvider.cpp b/gfx/layers/PersistentBufferProvider.cpp index 8771ffa56c18..1950cf0c89e8 100644 --- a/gfx/layers/PersistentBufferProvider.cpp +++ b/gfx/layers/PersistentBufferProvider.cpp @@ -147,18 +147,22 @@ void PersistentBufferProviderAccelerated::OnMemoryPressure() { static already_AddRefed CreateTexture( KnowsCompositor* aKnowsCompositor, gfx::SurfaceFormat aFormat, - gfx::IntSize aSize) { + gfx::IntSize aSize, bool aWillReadFrequently) { + TextureAllocationFlags flags = ALLOC_DEFAULT; + if (aWillReadFrequently) { + flags = TextureAllocationFlags(flags | ALLOC_DO_NOT_ACCELERATE); + } return TextureClient::CreateForDrawing( aKnowsCompositor, aFormat, aSize, BackendSelector::Canvas, - TextureFlags::DEFAULT | TextureFlags::NON_BLOCKING_READ_LOCK, - TextureAllocationFlags::ALLOC_DEFAULT); + TextureFlags::DEFAULT | TextureFlags::NON_BLOCKING_READ_LOCK, flags); } // static already_AddRefed PersistentBufferProviderShared::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, - KnowsCompositor* aKnowsCompositor) { + KnowsCompositor* aKnowsCompositor, + bool aWillReadFrequently) { if (!aKnowsCompositor || !aKnowsCompositor->GetTextureForwarder() || !aKnowsCompositor->GetTextureForwarder()->IPCOpen()) { return nullptr; @@ -179,25 +183,27 @@ PersistentBufferProviderShared::Create(gfx::IntSize aSize, #endif RefPtr texture = - CreateTexture(aKnowsCompositor, aFormat, aSize); + CreateTexture(aKnowsCompositor, aFormat, aSize, aWillReadFrequently); if (!texture) { return nullptr; } RefPtr provider = new PersistentBufferProviderShared(aSize, aFormat, aKnowsCompositor, - texture); + texture, aWillReadFrequently); return provider.forget(); } PersistentBufferProviderShared::PersistentBufferProviderShared( gfx::IntSize aSize, gfx::SurfaceFormat aFormat, - KnowsCompositor* aKnowsCompositor, RefPtr& aTexture) + KnowsCompositor* aKnowsCompositor, RefPtr& aTexture, + bool aWillReadFrequently) : mSize(aSize), mFormat(aFormat), mKnowsCompositor(aKnowsCompositor), - mFront(Nothing()) { + mFront(Nothing()), + mWillReadFrequently(aWillReadFrequently) { MOZ_ASSERT(aKnowsCompositor); if (mTextures.append(aTexture)) { mBack = Some(0); @@ -253,7 +259,7 @@ bool PersistentBufferProviderShared::SetKnowsCompositor( if (prevTexture) { RefPtr newTexture = - CreateTexture(aKnowsCompositor, mFormat, mSize); + CreateTexture(aKnowsCompositor, mFormat, mSize, mWillReadFrequently); MOZ_ASSERT(newTexture); if (!newTexture) { @@ -383,7 +389,7 @@ PersistentBufferProviderShared::BorrowDrawTarget( } RefPtr newTexture = - CreateTexture(mKnowsCompositor, mFormat, mSize); + CreateTexture(mKnowsCompositor, mFormat, mSize, mWillReadFrequently); MOZ_ASSERT(newTexture); if (newTexture) { @@ -416,7 +422,8 @@ PersistentBufferProviderShared::BorrowDrawTarget( // We are about to read lock a texture that is in use by the compositor // and has synchronization. To prevent possible future contention we // switch to using a permanent back buffer. - mPermanentBackBuffer = CreateTexture(mKnowsCompositor, mFormat, mSize); + mPermanentBackBuffer = CreateTexture(mKnowsCompositor, mFormat, mSize, + mWillReadFrequently); if (!mPermanentBackBuffer) { return nullptr; } @@ -553,7 +560,8 @@ PersistentBufferProviderShared::BorrowSnapshot(gfx::DrawTarget* aTarget) { // We are about to read lock a texture that is in use by the compositor and // has synchronization. To prevent possible future contention we switch to // using a permanent back buffer. - mPermanentBackBuffer = CreateTexture(mKnowsCompositor, mFormat, mSize); + mPermanentBackBuffer = + CreateTexture(mKnowsCompositor, mFormat, mSize, mWillReadFrequently); if (!mPermanentBackBuffer || !mPermanentBackBuffer->Lock(OpenMode::OPEN_READ_WRITE)) { return nullptr; @@ -646,5 +654,19 @@ void PersistentBufferProviderShared::Destroy() { mTextures.clear(); } +bool PersistentBufferProviderShared::IsAccelerated() const { +#ifdef XP_WIN + // Detect if we're using D2D canvas. + if (mWillReadFrequently || mTextures.empty()) { + return false; + } + TextureClient* texture = mTextures.front(); + if (texture->GetInternalData()->AsD3D11TetxureData()) { + return true; + } +#endif + return false; +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/PersistentBufferProvider.h b/gfx/layers/PersistentBufferProvider.h index 46f44db26321..1834b29be7fa 100644 --- a/gfx/layers/PersistentBufferProvider.h +++ b/gfx/layers/PersistentBufferProvider.h @@ -187,7 +187,7 @@ class PersistentBufferProviderShared : public PersistentBufferProvider, static already_AddRefed Create( gfx::IntSize aSize, gfx::SurfaceFormat aFormat, - KnowsCompositor* aKnowsCompositor); + KnowsCompositor* aKnowsCompositor, bool aWillReadFrequently = false); bool IsShared() const override { return true; } @@ -213,10 +213,13 @@ class PersistentBufferProviderShared : public PersistentBufferProvider, bool PreservesDrawingState() const override { return false; } + bool IsAccelerated() const override; + protected: PersistentBufferProviderShared(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, KnowsCompositor* aKnowsCompositor, - RefPtr& aTexture); + RefPtr& aTexture, + bool aWillReadFrequently); ~PersistentBufferProviderShared(); @@ -239,6 +242,8 @@ class PersistentBufferProviderShared : public PersistentBufferProvider, Maybe mBack; // Offset of the texture in mTextures that is presented to the compositor. Maybe mFront; + // Whether to avoid acceleration. + bool mWillReadFrequently = false; RefPtr mDrawTarget; RefPtr mSnapshot; diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index 5ebffe39ca89..6bf6bcd30158 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -267,7 +267,7 @@ static TextureType GetTextureType(gfx::SurfaceFormat aFormat, (moz2DBackend == gfx::BackendType::DIRECT2D || moz2DBackend == gfx::BackendType::DIRECT2D1_1) && aSize.width <= maxTextureSize && aSize.height <= maxTextureSize && - !(aAllocFlags & ALLOC_UPDATE_FROM_SURFACE)) { + !(aAllocFlags & (ALLOC_UPDATE_FROM_SURFACE | ALLOC_DO_NOT_ACCELERATE))) { return TextureType::D3D11; } #endif diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index 510031162052..fa0df57a59a9 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -95,6 +95,9 @@ enum TextureAllocationFlags { // The texture is going to be updated using UpdateFromSurface and needs to // support that call. ALLOC_UPDATE_FROM_SURFACE = 1 << 7, + + // Do not use an accelerated texture type. + ALLOC_DO_NOT_ACCELERATE = 1 << 8, }; enum class BackendSelector { Content, Canvas };