Bug 1795768 - Do not use Direct2D canvas if willReadFrequently is set. r=jrmuizel

Differential Revision: https://phabricator.services.mozilla.com/D164364
This commit is contained in:
Lee Salzman 2022-12-09 17:03:03 +00:00
Родитель cc4a5841c2
Коммит edd1ee2ec0
4 изменённых файлов: 45 добавлений и 15 удалений

Просмотреть файл

@ -147,18 +147,22 @@ void PersistentBufferProviderAccelerated::OnMemoryPressure() {
static already_AddRefed<TextureClient> 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>
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<TextureClient> texture =
CreateTexture(aKnowsCompositor, aFormat, aSize);
CreateTexture(aKnowsCompositor, aFormat, aSize, aWillReadFrequently);
if (!texture) {
return nullptr;
}
RefPtr<PersistentBufferProviderShared> provider =
new PersistentBufferProviderShared(aSize, aFormat, aKnowsCompositor,
texture);
texture, aWillReadFrequently);
return provider.forget();
}
PersistentBufferProviderShared::PersistentBufferProviderShared(
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
KnowsCompositor* aKnowsCompositor, RefPtr<TextureClient>& aTexture)
KnowsCompositor* aKnowsCompositor, RefPtr<TextureClient>& aTexture,
bool aWillReadFrequently)
: mSize(aSize),
mFormat(aFormat),
mKnowsCompositor(aKnowsCompositor),
mFront(Nothing()) {
mFront(Nothing()),
mWillReadFrequently(aWillReadFrequently) {
MOZ_ASSERT(aKnowsCompositor);
if (mTextures.append(aTexture)) {
mBack = Some<uint32_t>(0);
@ -253,7 +259,7 @@ bool PersistentBufferProviderShared::SetKnowsCompositor(
if (prevTexture) {
RefPtr<TextureClient> newTexture =
CreateTexture(aKnowsCompositor, mFormat, mSize);
CreateTexture(aKnowsCompositor, mFormat, mSize, mWillReadFrequently);
MOZ_ASSERT(newTexture);
if (!newTexture) {
@ -383,7 +389,7 @@ PersistentBufferProviderShared::BorrowDrawTarget(
}
RefPtr<TextureClient> 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

Просмотреть файл

@ -187,7 +187,7 @@ class PersistentBufferProviderShared : public PersistentBufferProvider,
static already_AddRefed<PersistentBufferProviderShared> 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<TextureClient>& aTexture);
RefPtr<TextureClient>& aTexture,
bool aWillReadFrequently);
~PersistentBufferProviderShared();
@ -239,6 +242,8 @@ class PersistentBufferProviderShared : public PersistentBufferProvider,
Maybe<uint32_t> mBack;
// Offset of the texture in mTextures that is presented to the compositor.
Maybe<uint32_t> mFront;
// Whether to avoid acceleration.
bool mWillReadFrequently = false;
RefPtr<gfx::DrawTarget> mDrawTarget;
RefPtr<gfx::SourceSurface> mSnapshot;

Просмотреть файл

@ -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

Просмотреть файл

@ -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 };