mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1019856 - avoid double-buffering in BasicCompositor when window allows it. r=mattwoodrow
This commit is contained in:
parent
acacadfda1
commit
ba30bddd22
@ -153,6 +153,32 @@ BasicCompositor::CreateRenderTargetFromSource(const IntRect &aRect,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<CompositingRenderTarget>
|
||||
BasicCompositor::CreateRenderTargetForWindow(const IntRect& aRect, SurfaceInitMode aInit, BufferMode aBufferMode)
|
||||
{
|
||||
if (aBufferMode != BufferMode::BUFFER_NONE) {
|
||||
return CreateRenderTarget(aRect, aInit);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aRect.width != 0 && aRect.height != 0, "Trying to create a render target of invalid size");
|
||||
|
||||
if (aRect.width * aRect.height == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mDrawTarget);
|
||||
|
||||
// Adjust bounds rect to account for new origin at (0, 0).
|
||||
IntRect rect(0, 0, aRect.XMost(), aRect.YMost());
|
||||
RefPtr<BasicCompositingRenderTarget> rt = new BasicCompositingRenderTarget(mDrawTarget, rect);
|
||||
|
||||
if (aInit == INIT_MODE_CLEAR) {
|
||||
mDrawTarget->ClearRect(gfx::Rect(aRect));
|
||||
}
|
||||
|
||||
return rt.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DataTextureSource>
|
||||
BasicCompositor::CreateDataTextureSource(TextureFlags aFlags)
|
||||
{
|
||||
@ -557,13 +583,14 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||
*aRenderBoundsOut = Rect();
|
||||
}
|
||||
|
||||
BufferMode bufferMode = BufferMode::BUFFERED;
|
||||
if (mTarget) {
|
||||
// If we have a copy target, then we don't have a widget-provided mDrawTarget (currently). Use a dummy
|
||||
// placeholder so that CreateRenderTarget() works.
|
||||
mDrawTarget = gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
|
||||
} else {
|
||||
// StartRemoteDrawingInRegion can mutate mInvalidRegion.
|
||||
mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion);
|
||||
mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion, &bufferMode);
|
||||
if (!mDrawTarget) {
|
||||
return;
|
||||
}
|
||||
@ -581,7 +608,7 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||
// 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 =
|
||||
CreateRenderTarget(mInvalidRect.ToUnknownRect(), INIT_MODE_CLEAR);
|
||||
CreateRenderTargetForWindow(mInvalidRect.ToUnknownRect(), INIT_MODE_CLEAR, bufferMode);
|
||||
if (!target) {
|
||||
if (!mTarget) {
|
||||
mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion);
|
||||
@ -592,8 +619,7 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||
|
||||
// We only allocate a surface sized to the invalidated region, so we need to
|
||||
// translate future coordinates.
|
||||
mRenderTarget->mDrawTarget->SetTransform(Matrix::Translation(-mInvalidRect.x,
|
||||
-mInvalidRect.y));
|
||||
mRenderTarget->mDrawTarget->SetTransform(Matrix::Translation(-mRenderTarget->GetOrigin()));
|
||||
|
||||
gfxUtils::ClipToRegion(mRenderTarget->mDrawTarget,
|
||||
mInvalidRegion.ToUnknownRegion());
|
||||
@ -631,22 +657,25 @@ BasicCompositor::EndFrame()
|
||||
// Pop aInvalidregion
|
||||
mRenderTarget->mDrawTarget->PopClip();
|
||||
|
||||
// Note: Most platforms require us to buffer drawing to the widget surface.
|
||||
// That's why we don't draw to mDrawTarget directly.
|
||||
RefPtr<SourceSurface> source = mRenderTarget->mDrawTarget->Snapshot();
|
||||
RefPtr<DrawTarget> dest(mTarget ? mTarget : mDrawTarget);
|
||||
if (mTarget || mRenderTarget->mDrawTarget != mDrawTarget) {
|
||||
// Note: Most platforms require us to buffer drawing to the widget surface.
|
||||
// That's why we don't draw to mDrawTarget directly.
|
||||
RefPtr<SourceSurface> source = mRenderTarget->mDrawTarget->Snapshot();
|
||||
RefPtr<DrawTarget> dest(mTarget ? mTarget : mDrawTarget);
|
||||
|
||||
nsIntPoint offset = mTarget ? mTargetBounds.TopLeft() : nsIntPoint();
|
||||
nsIntPoint offset = mTarget ? mTargetBounds.TopLeft() : nsIntPoint();
|
||||
|
||||
// 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.
|
||||
for (auto iter = mInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
|
||||
const LayoutDeviceIntRect& r = iter.Get();
|
||||
dest->CopySurface(source,
|
||||
IntRect(r.x - mInvalidRect.x, r.y - mInvalidRect.y, r.width, r.height),
|
||||
IntPoint(r.x - offset.x, r.y - offset.y));
|
||||
// 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.
|
||||
for (auto iter = mInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
|
||||
const LayoutDeviceIntRect& r = iter.Get();
|
||||
dest->CopySurface(source,
|
||||
IntRect(r.x, r.y, r.width, r.height) - mRenderTarget->GetOrigin(),
|
||||
IntPoint(r.x, r.y) - offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mTarget) {
|
||||
mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion);
|
||||
}
|
||||
|
@ -62,6 +62,11 @@ public:
|
||||
const CompositingRenderTarget *aSource,
|
||||
const gfx::IntPoint &aSourcePoint) override;
|
||||
|
||||
virtual already_AddRefed<CompositingRenderTarget>
|
||||
CreateRenderTargetForWindow(const gfx::IntRect& aRect,
|
||||
SurfaceInitMode aInit,
|
||||
BufferMode aBufferMode);
|
||||
|
||||
virtual already_AddRefed<DataTextureSource>
|
||||
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) override;
|
||||
|
||||
|
@ -539,7 +539,9 @@ public:
|
||||
return nsCocoaUtils::DevPixelsToCocoaPoints(aRect, BackingScaleFactor());
|
||||
}
|
||||
|
||||
already_AddRefed<mozilla::gfx::DrawTarget> StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) override;
|
||||
already_AddRefed<mozilla::gfx::DrawTarget>
|
||||
StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
|
||||
mozilla::layers::BufferMode* aBufferMode) override;
|
||||
void EndRemoteDrawing() override;
|
||||
void CleanupRemoteDrawing() override;
|
||||
bool InitCompositor(mozilla::layers::Compositor* aCompositor) override;
|
||||
|
@ -2635,7 +2635,8 @@ nsChildView::SwipeFinished()
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DrawTarget>
|
||||
nsChildView::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion)
|
||||
nsChildView::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
|
||||
BufferMode* aBufferMode)
|
||||
{
|
||||
// should have created the GLPresenter in InitCompositor.
|
||||
MOZ_ASSERT(mGLPresenter);
|
||||
|
@ -2225,7 +2225,8 @@ nsWindow::OnExposeEvent(cairo_t *cr)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> dt = GetDrawTarget(region);
|
||||
BufferMode layerBuffering = BufferMode::BUFFERED;
|
||||
RefPtr<DrawTarget> dt = GetDrawTarget(region, &layerBuffering);
|
||||
if (!dt) {
|
||||
return FALSE;
|
||||
}
|
||||
@ -2245,7 +2246,6 @@ nsWindow::OnExposeEvent(cairo_t *cr)
|
||||
gfxUtils::ClipToRegion(dt, region.ToUnknownRegion());
|
||||
}
|
||||
|
||||
BufferMode layerBuffering;
|
||||
if (shaped) {
|
||||
// The double buffering is done here to extract the shape mask.
|
||||
// (The shape mask won't be necessary when a visual with an alpha
|
||||
@ -2254,16 +2254,6 @@ nsWindow::OnExposeEvent(cairo_t *cr)
|
||||
RefPtr<DrawTarget> destDT = dt->CreateSimilarDrawTarget(boundsRect.Size(), SurfaceFormat::B8G8R8A8);
|
||||
ctx = new gfxContext(destDT, boundsRect.TopLeft());
|
||||
} else {
|
||||
#ifdef MOZ_HAVE_SHMIMAGE
|
||||
if (nsShmImage::UseShm()) {
|
||||
// We're using an xshm mapping as a back buffer.
|
||||
layerBuffering = BufferMode::BUFFER_NONE;
|
||||
} else
|
||||
#endif // MOZ_HAVE_SHMIMAGE
|
||||
{
|
||||
// Get the layer manager to do double buffering (if necessary).
|
||||
layerBuffering = BufferMode::BUFFERED;
|
||||
}
|
||||
ctx = new gfxContext(dt);
|
||||
}
|
||||
|
||||
@ -6455,7 +6445,7 @@ nsWindow::GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
|
||||
#endif
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
nsWindow::GetDrawTarget(const LayoutDeviceIntRegion& aRegion)
|
||||
nsWindow::GetDrawTarget(const LayoutDeviceIntRegion& aRegion, BufferMode* aBufferMode)
|
||||
{
|
||||
if (!mGdkWindow) {
|
||||
return nullptr;
|
||||
@ -6474,12 +6464,14 @@ nsWindow::GetDrawTarget(const LayoutDeviceIntRegion& aRegion)
|
||||
if (nsShmImage::UseShm()) {
|
||||
dt = nsShmImage::EnsureShmImage(size,
|
||||
mXDisplay, mXVisual, mXDepth, mShmImage);
|
||||
*aBufferMode = BufferMode::BUFFER_NONE;
|
||||
}
|
||||
# endif // MOZ_HAVE_SHMIMAGE
|
||||
if (!dt) {
|
||||
RefPtr<gfxXlibSurface> surf = new gfxXlibSurface(mXDisplay, mXWindow, mXVisual, size.ToUnknownSize());
|
||||
if (!surf->CairoStatus()) {
|
||||
dt = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surf.get(), surf->GetSize());
|
||||
*aBufferMode = BufferMode::BUFFERED;
|
||||
}
|
||||
}
|
||||
#endif // MOZ_X11
|
||||
@ -6488,9 +6480,9 @@ nsWindow::GetDrawTarget(const LayoutDeviceIntRegion& aRegion)
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
nsWindow::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion)
|
||||
nsWindow::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion, BufferMode* aBufferMode)
|
||||
{
|
||||
return GetDrawTarget(aInvalidRegion);
|
||||
return GetDrawTarget(aInvalidRegion, aBufferMode);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -216,7 +216,8 @@ public:
|
||||
#endif
|
||||
|
||||
virtual already_AddRefed<mozilla::gfx::DrawTarget>
|
||||
StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) override;
|
||||
StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
|
||||
mozilla::layers::BufferMode* aBufferMode) override;
|
||||
virtual void EndRemoteDrawingInRegion(mozilla::gfx::DrawTarget* aDrawTarget,
|
||||
LayoutDeviceIntRegion& aInvalidRegion) override;
|
||||
|
||||
@ -309,7 +310,9 @@ public:
|
||||
virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations) override;
|
||||
nsresult UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect,
|
||||
uint8_t* aAlphas, int32_t aStride);
|
||||
virtual already_AddRefed<mozilla::gfx::DrawTarget> GetDrawTarget(const LayoutDeviceIntRegion& aRegion);
|
||||
|
||||
already_AddRefed<mozilla::gfx::DrawTarget> GetDrawTarget(const LayoutDeviceIntRegion& aRegion,
|
||||
mozilla::layers::BufferMode* aBufferMode);
|
||||
|
||||
#if (MOZ_WIDGET_GTK == 2)
|
||||
static already_AddRefed<gfxASurface> GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
|
||||
|
@ -1287,9 +1287,13 @@ class nsIWidget : public nsISupports {
|
||||
*
|
||||
* Called by BasicCompositor on the compositor thread for OMTC drawing
|
||||
* before each composition.
|
||||
*
|
||||
* The window may specify its buffer mode. If unspecified, it is assumed
|
||||
* to require double-buffering.
|
||||
*/
|
||||
virtual already_AddRefed<mozilla::gfx::DrawTarget> StartRemoteDrawing() = 0;
|
||||
virtual already_AddRefed<mozilla::gfx::DrawTarget> StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) {
|
||||
virtual already_AddRefed<mozilla::gfx::DrawTarget> StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
|
||||
mozilla::layers::BufferMode* aBufferMode) {
|
||||
return StartRemoteDrawing();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user