Bug 1574745 - Maintain a full window render target when rendering to native layers with CompositorOGL. r=mattwoodrow

This makes profiler screenshots and frame recording work again, when native
layers are used. The copying is a bit unfortunate. Maybe we can combine this
copy with the first downscaling step in the future. Or for frame recording,
which doesn't use downscaling, we could readback the layers individually and
reassemble them in CPU memory. But both of those solutions are more complex
than this.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Markus Stange 2019-08-30 19:52:40 +00:00
Родитель b2ce563f4b
Коммит 2fccca3dcc
2 изменённых файлов: 87 добавлений и 2 удалений

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

@ -305,6 +305,7 @@ void CompositorOGL::CleanupResources() {
mGLContext = nullptr;
mPrograms.clear();
mNativeLayersReferenceRT = nullptr;
mFullWindowRenderTarget = nullptr;
return;
}
@ -315,6 +316,7 @@ void CompositorOGL::CleanupResources() {
}
mPrograms.clear();
mNativeLayersReferenceRT = nullptr;
mFullWindowRenderTarget = nullptr;
#ifdef MOZ_WIDGET_GTK
// TextureSources might hold RefPtr<gl::GLContext>.
@ -906,6 +908,7 @@ void CompositorOGL::BeginFrameForNativeLayers() {
mGLContext->fEnable(LOCAL_GL_BLEND);
mFrameInProgress = true;
mShouldInvalidateWindow = NeedToRecreateFullWindowRenderTarget();
// Make a 1x1 dummy render target so that GetCurrentRenderTarget() returns
// something non-null even outside of calls to
@ -915,6 +918,7 @@ void CompositorOGL::BeginFrameForNativeLayers() {
CreateRenderTarget(IntRect(0, 0, 1, 1), INIT_MODE_CLEAR);
}
SetRenderTarget(mNativeLayersReferenceRT);
mWindowRenderTarget = mFullWindowRenderTarget;
}
Maybe<gfx::IntRect> CompositorOGL::BeginRenderingToNativeLayer(
@ -928,7 +932,11 @@ Maybe<gfx::IntRect> CompositorOGL::BeginRenderingToNativeLayer(
IntRect rect = aNativeLayer->GetRect();
IntRegion layerInvalid;
layerInvalid.And(aInvalidRegion, rect);
if (mShouldInvalidateWindow) {
layerInvalid = rect;
} else {
layerInvalid.And(aInvalidRegion, rect);
}
RefPtr<CompositingRenderTarget> rt =
RenderTargetForNativeLayer(aNativeLayer, layerInvalid);
@ -965,6 +973,55 @@ Maybe<gfx::IntRect> CompositorOGL::BeginRenderingToNativeLayer(
return Some(rect);
}
void CompositorOGL::NormalDrawingDone() {
// Now is a good time to update mFullWindowRenderTarget.
if (!mCurrentNativeLayer) {
return;
}
if (!mGLContext->IsSupported(GLFeature::framebuffer_blit)) {
return;
}
if (!ShouldRecordFrames()) {
// If we are no longer recording a profile, we can drop the render target if
// it exists.
mWindowRenderTarget = nullptr;
mFullWindowRenderTarget = nullptr;
return;
}
if (NeedToRecreateFullWindowRenderTarget()) {
// We have either (1) just started recording and not yet allocated a
// buffer or (2) are already recording and have resized the window. In
// either case, we need a new render target.
IntRect windowRect(IntPoint(0, 0),
mWidget->GetClientSize().ToUnknownSize());
RefPtr<CompositingRenderTarget> rt =
CreateRenderTarget(windowRect, INIT_MODE_NONE);
mFullWindowRenderTarget =
static_cast<CompositingRenderTargetOGL*>(rt.get());
mWindowRenderTarget = mFullWindowRenderTarget;
// Initialize the render target by binding it.
RefPtr<CompositingRenderTarget> previousTarget = mCurrentRenderTarget;
SetRenderTarget(mFullWindowRenderTarget);
SetRenderTarget(previousTarget);
}
// Copy the appropriate rectangle from the layer to mFullWindowRenderTarget.
RefPtr<CompositingRenderTargetOGL> layerRT = mCurrentRenderTarget;
IntRect copyRect = layerRT->GetClipRect().valueOr(layerRT->GetRect());
IntRect sourceRect = copyRect - layerRT->GetOrigin();
sourceRect.y = layerRT->GetSize().height - sourceRect.YMost();
IntRect destRect = copyRect;
destRect.y = mFullWindowRenderTarget->GetSize().height - destRect.YMost();
GLuint sourceFBO = layerRT->GetFBO();
GLuint destFBO = mFullWindowRenderTarget->GetFBO();
mGLContext->BlitHelper()->BlitFramebufferToFramebuffer(
sourceFBO, destFBO, sourceRect, destRect, LOCAL_GL_NEAREST);
}
void CompositorOGL::EndRenderingToNativeLayer() {
MOZ_RELEASE_ASSERT(mCurrentNativeLayer,
"EndRenderingToNativeLayer not paired with a call to "
@ -1981,6 +2038,7 @@ void CompositorOGL::EndFrame() {
#endif
mFrameInProgress = false;
mShouldInvalidateWindow = false;
if (mTarget) {
CopyToTarget(mTarget, mTargetBounds.TopLeft(), Matrix());
@ -2042,6 +2100,17 @@ void CompositorOGL::WaitForGPU() {
mThisFrameDoneSync = nullptr;
}
bool CompositorOGL::NeedToRecreateFullWindowRenderTarget() const {
if (!ShouldRecordFrames()) {
return false;
}
if (!mFullWindowRenderTarget) {
return true;
}
IntSize windowSize = mWidget->GetClientSize().ToUnknownSize();
return mFullWindowRenderTarget->GetSize() != windowSize;
}
void CompositorOGL::SetDestinationSurfaceSize(const IntSize& aSize) {
mSurfaceSize.width = aSize.width;
mSurfaceSize.height = aSize.height;

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

@ -195,6 +195,8 @@ class CompositorOGL final : public Compositor {
bool SupportsLayerGeometry() const override;
void NormalDrawingDone() override;
void EndFrame() override;
void WaitForGPU() override;
@ -301,6 +303,8 @@ class CompositorOGL final : public Compositor {
void InsertFrameDoneSync();
bool NeedToRecreateFullWindowRenderTarget() const;
/** Widget associated with this compositor */
LayoutDeviceIntSize mWidgetSize;
RefPtr<GLContext> mGLContext;
@ -333,7 +337,15 @@ class CompositorOGL final : public Compositor {
// Begin/EndRenderingToNativeLayer. Created on demand.
RefPtr<CompositingRenderTarget> mNativeLayersReferenceRT;
CompositingRenderTargetOGL* mWindowRenderTarget;
// The render target that profiler screenshots / frame recording read from.
// This will be the actual window framebuffer when rendering to a window, and
// it will be mFullWindowRenderTarget when rendering to native layers.
RefPtr<CompositingRenderTargetOGL> mWindowRenderTarget;
// Non-null when using native layers and frame recording is requested.
// EndNormalDrawing() maintains a copy of the entire window contents in this
// render target, by copying from the native layer render targets.
RefPtr<CompositingRenderTargetOGL> mFullWindowRenderTarget;
/**
* VBO that has some basics in it for a textured quad, including vertex
@ -364,6 +376,10 @@ class CompositorOGL final : public Compositor {
*/
bool mFrameInProgress;
// Only true between BeginFromeForNativeLayers and EndFrame, and only if the
// full window render target needed to be recreated in the current frame.
bool mShouldInvalidateWindow = false;
/*
* Clear aRect on current render target.
*/