Bug 1573343 - Pass a precise clear region to CreateRenderTargetForWindow. r=mattwoodrow

In the past, BeginFrame would clip mDrawTarget to the invalid region and then have
CreateRenderTargetForWindow clear a rectangle. So it was effectively clearing a
region, but only if BeginFrame's region clip happened to be set on the correct
DrawTarget. In the case where a back buffer was used, this was not the case:
The clip would be on mDrawTarget but the clear would happen on the back buffer
draw target. So we were clearing more than necessary.

Now we limit clearing to the invalid region even if a back buffer is used.

Differential Revision: https://phabricator.services.mozilla.com/D41675

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Markus Stange 2019-08-19 22:39:26 +00:00
Родитель a829cf1409
Коммит 8b68a014ae
2 изменённых файлов: 11 добавлений и 17 удалений

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

@ -292,7 +292,7 @@ BasicCompositor::CreateRenderTargetFromSource(
already_AddRefed<CompositingRenderTarget>
BasicCompositor::CreateRenderTargetForWindow(
const LayoutDeviceIntRect& aRect, const LayoutDeviceIntRect& aClearRect,
const LayoutDeviceIntRect& aRect, const LayoutDeviceIntRegion& aClearRegion,
BufferMode aBufferMode) {
MOZ_ASSERT(mDrawTarget);
MOZ_ASSERT(!aRect.IsZeroArea(),
@ -325,9 +325,12 @@ BasicCompositor::CreateRenderTargetForWindow(
rt->mDrawTarget->SetTransform(Matrix::Translation(-rt->GetOrigin()));
if (!aClearRect.IsEmpty() && !isCleared) {
gfx::IntRect clearRect = aClearRect.ToUnknownRect();
if (!aClearRegion.IsEmpty() && !isCleared) {
gfx::IntRegion clearRegion = aClearRegion.ToUnknownRegion();
gfx::IntRect clearRect = clearRegion.GetBounds();
gfxUtils::ClipToRegion(rt->mDrawTarget, clearRegion);
rt->mDrawTarget->ClearRect(gfx::Rect(clearRect));
rt->mDrawTarget->PopClip();
}
return rt.forget();
@ -949,24 +952,15 @@ void BasicCompositor::BeginFrame(
return;
}
LayoutDeviceIntRect clearRect;
LayoutDeviceIntRegion clearRegion = mInvalidRegion;
if (!aOpaqueRegion.IsEmpty()) {
LayoutDeviceIntRegion clearRegion = mInvalidRegion;
clearRegion.SubOut(LayoutDeviceIntRegion::FromUnknownRegion(aOpaqueRegion));
clearRect = clearRegion.GetBounds();
} else {
clearRect = mInvalidRect;
}
// Prevent CreateRenderTargetForWindow from clearing unwanted area.
gfxUtils::ClipToRegion(mDrawTarget, mInvalidRegion.ToUnknownRegion());
// Setup an intermediate render target to buffer all compositing. We will
// copy this into mDrawTarget (the widget), and/or mTarget in EndFrame()
RefPtr<CompositingRenderTarget> target =
CreateRenderTargetForWindow(mInvalidRect, clearRect, bufferMode);
mDrawTarget->PopClip();
CreateRenderTargetForWindow(mInvalidRect, clearRegion, bufferMode);
if (!target) {
if (!mTarget) {
@ -1071,7 +1065,7 @@ void BasicCompositor::TryToEndRemoteDrawing(bool aForceToEnd) {
// The source DrawTarget is clipped to the invalidation region, so we have
// to copy the individual rectangles in the region or else we'll draw
// blank pixels.
// garbage pixels.
// CopySurface ignores both the transform and the clip.
for (auto iter = mInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
const LayoutDeviceIntRect& r = iter.Get();

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

@ -64,8 +64,8 @@ class BasicCompositor : public Compositor {
const gfx::IntPoint& aSourcePoint) override;
virtual already_AddRefed<CompositingRenderTarget> CreateRenderTargetForWindow(
const LayoutDeviceIntRect& aRect, const LayoutDeviceIntRect& aClearRect,
BufferMode aBufferMode);
const LayoutDeviceIntRect& aRect,
const LayoutDeviceIntRegion& aClearRegion, BufferMode aBufferMode);
already_AddRefed<DataTextureSource> CreateDataTextureSource(
TextureFlags aFlags = TextureFlags::NO_FLAGS) override;