зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1678892 - Pass dirty and opaque regions to layers compositor. r=sotaro
The backend CompositorD3D11/CompositorOGL layers compositors can already do partial clear optimizations for us if applicable. The only thing we need to do is pass in the actual dirty/opaque regions so that it can utilize it. Like with RenderCompositorSWGL, we move the actual allocation of the framebuffer into StartCompositing when this information is known, rather than BeginFrame which is too early in the frame to have this information yet. Differential Revision: https://phabricator.services.mozilla.com/D109092
This commit is contained in:
Родитель
0e1c0ff1cf
Коммит
7d630ccb29
|
@ -1044,6 +1044,28 @@ Maybe<IntRect> CompositorOGL::BeginFrame(const nsIntRegion& aInvalidRegion,
|
|||
SetRenderTarget(rt);
|
||||
mWindowRenderTarget = mCurrentRenderTarget;
|
||||
|
||||
for (auto iter = aInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
|
||||
const IntRect& r = iter.Get();
|
||||
mCurrentFrameInvalidRegion.OrWith(
|
||||
IntRect(r.X(), FlipY(r.YMost()), r.Width(), r.Height()));
|
||||
}
|
||||
// Check to see if there is any transparent dirty region that would require
|
||||
// clearing. If not, just invalidate the framebuffer if supported.
|
||||
// TODO: Currently we initialize the clear region to the widget bounds as
|
||||
// SwapBuffers will update the entire framebuffer. On platforms that support
|
||||
// damage regions, we could initialize this to mCurrentFrameInvalidRegion.
|
||||
IntRegion regionToClear(rect);
|
||||
regionToClear.SubOut(aOpaqueRegion);
|
||||
GLbitfield clearBits = LOCAL_GL_DEPTH_BUFFER_BIT;
|
||||
if (regionToClear.IsEmpty() &&
|
||||
mGLContext->IsSupported(GLFeature::invalidate_framebuffer)) {
|
||||
GLenum attachments[] = {LOCAL_GL_COLOR};
|
||||
mGLContext->fInvalidateFramebuffer(
|
||||
LOCAL_GL_FRAMEBUFFER, MOZ_ARRAY_LENGTH(attachments), attachments);
|
||||
} else {
|
||||
clearBits |= LOCAL_GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
if ((mSurfaceOrigin.x > 0) || (mSurfaceOrigin.y > 0)) {
|
||||
mGLContext->fClearColor(
|
||||
|
@ -1059,13 +1081,7 @@ Maybe<IntRect> CompositorOGL::BeginFrame(const nsIntRegion& aInvalidRegion,
|
|||
mGLContext->fClearColor(mClearColor.r, mClearColor.g, mClearColor.b,
|
||||
mClearColor.a);
|
||||
#endif // defined(MOZ_WIDGET_ANDROID)
|
||||
mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
for (auto iter = aInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
|
||||
const IntRect& r = iter.Get();
|
||||
mCurrentFrameInvalidRegion.OrWith(
|
||||
IntRect(r.X(), FlipY(r.YMost()), r.Width(), r.Height()));
|
||||
}
|
||||
mGLContext->fClear(clearBits);
|
||||
|
||||
return Some(rect);
|
||||
}
|
||||
|
|
|
@ -59,33 +59,54 @@ bool RenderCompositorLayersSWGL::MakeCurrent() {
|
|||
bool RenderCompositorLayersSWGL::BeginFrame() {
|
||||
MOZ_ASSERT(!mInFrame);
|
||||
MakeCurrent();
|
||||
gfx::IntRect rect =
|
||||
gfx::IntRect(gfx::IntPoint(0, 0), GetBufferSize().ToUnknownSize());
|
||||
if (!mCompositor->BeginFrameForWindow(nsIntRegion(rect), Nothing(), rect,
|
||||
nsIntRegion())) {
|
||||
return false;
|
||||
}
|
||||
mInFrame = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::CancelFrame() {
|
||||
MOZ_ASSERT(mInFrame);
|
||||
mCompositor->CancelFrame();
|
||||
mInFrame = false;
|
||||
mCompositingStarted = false;
|
||||
if (mCompositingStarted) {
|
||||
mCompositor->CancelFrame();
|
||||
mCompositingStarted = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::StartCompositing(
|
||||
const wr::DeviceIntRect* aDirtyRects, size_t aNumDirtyRects,
|
||||
const wr::DeviceIntRect* aOpaqueRects, size_t aNumOpaqueRects) {
|
||||
mCompositingStarted = mInFrame;
|
||||
if (!mInFrame) {
|
||||
return;
|
||||
}
|
||||
gfx::IntRect bounds(gfx::IntPoint(0, 0), GetBufferSize().ToUnknownSize());
|
||||
nsIntRegion dirty;
|
||||
if (aNumDirtyRects) {
|
||||
for (size_t i = 0; i < aNumDirtyRects; i++) {
|
||||
const auto& rect = aDirtyRects[i];
|
||||
dirty.OrWith(gfx::IntRect(rect.origin.x, rect.origin.y, rect.size.width,
|
||||
rect.size.height));
|
||||
}
|
||||
dirty.AndWith(bounds);
|
||||
} else {
|
||||
dirty = bounds;
|
||||
}
|
||||
nsIntRegion opaque(bounds);
|
||||
opaque.SubOut(mWidget->GetTransparentRegion().ToUnknownRegion());
|
||||
for (size_t i = 0; i < aNumOpaqueRects; i++) {
|
||||
const auto& rect = aOpaqueRects[i];
|
||||
opaque.OrWith(gfx::IntRect(rect.origin.x, rect.origin.y, rect.size.width,
|
||||
rect.size.height));
|
||||
}
|
||||
if (!mCompositor->BeginFrameForWindow(dirty, Nothing(), bounds, opaque)) {
|
||||
return;
|
||||
}
|
||||
mCompositingStarted = true;
|
||||
}
|
||||
|
||||
void RenderCompositorLayersSWGL::CompositorEndFrame() {
|
||||
nsTArray<FrameSurface> frameSurfaces = std::move(mFrameSurfaces);
|
||||
|
||||
if (!mInFrame) {
|
||||
if (!mCompositingStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -133,8 +154,6 @@ RenderedFrameId RenderCompositorLayersSWGL::EndFrame(
|
|||
if (mCompositingStarted) {
|
||||
mCompositor->EndFrame();
|
||||
mCompositingStarted = false;
|
||||
} else {
|
||||
mCompositor->CancelFrame();
|
||||
}
|
||||
return GetNextRenderFrameId();
|
||||
}
|
||||
|
|
|
@ -244,7 +244,7 @@
|
|||
# On Android, we want an opaque background to be visible under the page,
|
||||
# so layout should not force a default background.
|
||||
- name: android.widget_paints_background
|
||||
type: bool
|
||||
type: RelaxedAtomicBool
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
|
|
|
@ -67,7 +67,8 @@ LayoutDeviceIntRegion CompositorWidget::GetTransparentRegion() {
|
|||
// transparent. Widgets wanting more complex transparency region determination
|
||||
// should override this method.
|
||||
auto* widget = RealWidget();
|
||||
if (!widget || widget->GetTransparencyMode() != eTransparencyOpaque) {
|
||||
if (!widget || widget->GetTransparencyMode() != eTransparencyOpaque ||
|
||||
widget->WidgetPaintsBackground()) {
|
||||
return LayoutDeviceIntRect(LayoutDeviceIntPoint(0, 0), GetClientSize());
|
||||
}
|
||||
return LayoutDeviceIntRegion();
|
||||
|
|
Загрузка…
Ссылка в новой задаче