Bug 1961115 - Skip compositor-related work when rendering without presenting. r=gfx-reviewers,gw
Differential Revision: https://phabricator.services.mozilla.com/D245565
This commit is contained in:
@@ -169,31 +169,49 @@ RenderedFrameId RendererOGL::UpdateAndRender(
|
|||||||
widgetContext.mGL = mCompositor->gl();
|
widgetContext.mGL = mCompositor->gl();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!mCompositor->GetWidget()->PreRender(&widgetContext)) {
|
// If present is false, WebRender needs to render some offscreen content
|
||||||
// XXX This could cause oom in webrender since pending_texture_updates is
|
// but we don't want to touch the window, so we avoid most interactions
|
||||||
// not handled. It needs to be addressed.
|
// with mCompositor.
|
||||||
return RenderedFrameId();
|
bool present = aFrameParams.present;
|
||||||
}
|
|
||||||
// XXX set clear color if MOZ_WIDGET_ANDROID is defined.
|
|
||||||
|
|
||||||
if (mThread->IsHandlingDeviceReset() || !mCompositor->BeginFrame()) {
|
LayoutDeviceIntSize size(0, 0);
|
||||||
|
auto bufferAge = 0;
|
||||||
|
bool fullRender = false;
|
||||||
|
|
||||||
|
bool beginFrame = !mThread->IsHandlingDeviceReset();
|
||||||
|
|
||||||
|
if (beginFrame && present) {
|
||||||
|
if (!mCompositor->GetWidget()->PreRender(&widgetContext)) {
|
||||||
|
// XXX This could cause oom in webrender since pending_texture_updates is
|
||||||
|
// not handled. It needs to be addressed.
|
||||||
|
return RenderedFrameId();
|
||||||
|
}
|
||||||
|
// XXX set clear color if MOZ_WIDGET_ANDROID is defined.
|
||||||
|
|
||||||
|
if (!mCompositor->BeginFrame()) {
|
||||||
|
beginFrame = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = mCompositor->GetBufferSize();
|
||||||
|
bufferAge = mCompositor->GetBufferAge();
|
||||||
|
|
||||||
|
fullRender = mCompositor->RequestFullRender();
|
||||||
|
// When we're rendering to an external target, we want to render everything.
|
||||||
|
if (mCompositor->UsePartialPresent() &&
|
||||||
|
(aReadbackBuffer.isSome() ||
|
||||||
|
layers::ProfilerScreenshots::IsEnabled())) {
|
||||||
|
fullRender = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!beginFrame) {
|
||||||
CheckGraphicsResetStatus(gfx::DeviceResetDetectPlace::WR_BEGIN_FRAME,
|
CheckGraphicsResetStatus(gfx::DeviceResetDetectPlace::WR_BEGIN_FRAME,
|
||||||
/* aForce */ true);
|
/* aForce */ true);
|
||||||
mCompositor->GetWidget()->PostRender(&widgetContext);
|
|
||||||
return RenderedFrameId();
|
return RenderedFrameId();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto size = mCompositor->GetBufferSize();
|
|
||||||
auto bufferAge = mCompositor->GetBufferAge();
|
|
||||||
|
|
||||||
wr_renderer_update(mRenderer);
|
wr_renderer_update(mRenderer);
|
||||||
|
|
||||||
bool fullRender = mCompositor->RequestFullRender();
|
|
||||||
// When we're rendering to an external target, we want to render everything.
|
|
||||||
if (mCompositor->UsePartialPresent() &&
|
|
||||||
(aReadbackBuffer.isSome() || layers::ProfilerScreenshots::IsEnabled())) {
|
|
||||||
fullRender = true;
|
|
||||||
}
|
|
||||||
if (fullRender) {
|
if (fullRender) {
|
||||||
wr_renderer_force_redraw(mRenderer);
|
wr_renderer_force_redraw(mRenderer);
|
||||||
}
|
}
|
||||||
@@ -203,42 +221,47 @@ RenderedFrameId RendererOGL::UpdateAndRender(
|
|||||||
bufferAge, aOutStats, &dirtyRects);
|
bufferAge, aOutStats, &dirtyRects);
|
||||||
FlushPipelineInfo();
|
FlushPipelineInfo();
|
||||||
if (!rendered) {
|
if (!rendered) {
|
||||||
mCompositor->CancelFrame();
|
if (present) {
|
||||||
|
mCompositor->CancelFrame();
|
||||||
|
mCompositor->GetWidget()->PostRender(&widgetContext);
|
||||||
|
}
|
||||||
RenderThread::Get()->HandleWebRenderError(WebRenderError::RENDER);
|
RenderThread::Get()->HandleWebRenderError(WebRenderError::RENDER);
|
||||||
mCompositor->GetWidget()->PostRender(&widgetContext);
|
|
||||||
return RenderedFrameId();
|
return RenderedFrameId();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aReadbackBuffer.isSome()) {
|
RenderedFrameId frameId;
|
||||||
MOZ_ASSERT(aReadbackSize.isSome());
|
|
||||||
MOZ_ASSERT(aReadbackFormat.isSome());
|
if (present) {
|
||||||
if (!mCompositor->MaybeReadback(aReadbackSize.ref(), aReadbackFormat.ref(),
|
if (aReadbackBuffer.isSome()) {
|
||||||
aReadbackBuffer.ref(), aNeedsYFlip)) {
|
MOZ_ASSERT(aReadbackSize.isSome());
|
||||||
wr_renderer_readback(mRenderer, aReadbackSize.ref().width,
|
MOZ_ASSERT(aReadbackFormat.isSome());
|
||||||
aReadbackSize.ref().height, aReadbackFormat.ref(),
|
if (!mCompositor->MaybeReadback(aReadbackSize.ref(),
|
||||||
&aReadbackBuffer.ref()[0],
|
aReadbackFormat.ref(),
|
||||||
aReadbackBuffer.ref().length());
|
aReadbackBuffer.ref(), aNeedsYFlip)) {
|
||||||
if (aNeedsYFlip) {
|
wr_renderer_readback(mRenderer, aReadbackSize.ref().width,
|
||||||
*aNeedsYFlip = !mCompositor->SurfaceOriginIsTopLeft();
|
aReadbackSize.ref().height, aReadbackFormat.ref(),
|
||||||
|
&aReadbackBuffer.ref()[0],
|
||||||
|
aReadbackBuffer.ref().length());
|
||||||
|
if (aNeedsYFlip != nullptr) {
|
||||||
|
*aNeedsYFlip = !mCompositor->SurfaceOriginIsTopLeft();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (size.Width() != 0 && size.Height() != 0) {
|
if (size.Width() != 0 && size.Height() != 0) {
|
||||||
if (!mCompositor->MaybeGrabScreenshot(size.ToUnknownSize())) {
|
if (!mCompositor->MaybeGrabScreenshot(size.ToUnknownSize())) {
|
||||||
mScreenshotGrabber.MaybeGrabScreenshot(this, size.ToUnknownSize());
|
mScreenshotGrabber.MaybeGrabScreenshot(this, size.ToUnknownSize());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Frame recording must happen before EndFrame, as we must ensure we read
|
||||||
|
// the contents of the back buffer before any calls to SwapBuffers which
|
||||||
|
// might invalidate it.
|
||||||
|
MaybeRecordFrame(mLastPipelineInfo);
|
||||||
|
frameId = mCompositor->EndFrame(dirtyRects);
|
||||||
|
mCompositor->GetWidget()->PostRender(&widgetContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Frame recording must happen before EndFrame, as we must ensure we read the
|
|
||||||
// contents of the back buffer before any calls to SwapBuffers which might
|
|
||||||
// invalidate it.
|
|
||||||
MaybeRecordFrame(mLastPipelineInfo);
|
|
||||||
|
|
||||||
RenderedFrameId frameId = mCompositor->EndFrame(dirtyRects);
|
|
||||||
|
|
||||||
mCompositor->GetWidget()->PostRender(&widgetContext);
|
|
||||||
|
|
||||||
#if defined(ENABLE_FRAME_LATENCY_LOG)
|
#if defined(ENABLE_FRAME_LATENCY_LOG)
|
||||||
if (mFrameStartTime) {
|
if (mFrameStartTime) {
|
||||||
uint32_t latencyMs =
|
uint32_t latencyMs =
|
||||||
@@ -249,8 +272,10 @@ RenderedFrameId RendererOGL::UpdateAndRender(
|
|||||||
mFrameStartTime = TimeStamp();
|
mFrameStartTime = TimeStamp();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!mCompositor->MaybeProcessScreenshotQueue()) {
|
if (present) {
|
||||||
mScreenshotGrabber.MaybeProcessQueue(this);
|
if (!mCompositor->MaybeProcessScreenshotQueue()) {
|
||||||
|
mScreenshotGrabber.MaybeProcessQueue(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Flush pending actions such as texture deletions/unlocks and
|
// TODO: Flush pending actions such as texture deletions/unlocks and
|
||||||
|
|||||||
@@ -1274,10 +1274,16 @@ impl Renderer {
|
|||||||
.remove(&doc_id)
|
.remove(&doc_id)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let size = if !device_size.is_empty() {
|
||||||
|
Some(device_size)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let result = self.render_impl(
|
let result = self.render_impl(
|
||||||
doc_id,
|
doc_id,
|
||||||
&mut doc,
|
&mut doc,
|
||||||
Some(device_size),
|
size,
|
||||||
buffer_age,
|
buffer_age,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -3127,7 +3133,7 @@ impl Renderer {
|
|||||||
&mut self.renderer_errors,
|
&mut self.renderer_errors,
|
||||||
&mut self.profile,
|
&mut self.profile,
|
||||||
);
|
);
|
||||||
|
|
||||||
( textures, instance )
|
( textures, instance )
|
||||||
},
|
},
|
||||||
ResolvedExternalSurfaceColorData::Rgb{ ref plane, .. } => {
|
ResolvedExternalSurfaceColorData::Rgb{ ref plane, .. } => {
|
||||||
|
|||||||
Reference in New Issue
Block a user