From 9fa23d568bd00890c4fe914161d7caf9310f3e38 Mon Sep 17 00:00:00 2001 From: Bob Owen Date: Fri, 29 Nov 2019 21:55:04 +0000 Subject: [PATCH] Bug 1572415: Convert clip paths when potentially changing canvas backend in CanvasRenderingContext2D. r=jrmuizel The clip Paths in mStyleStack might not be compatible with the new mTarget, so this converts them to make sure they are. Differential Revision: https://phabricator.services.mozilla.com/D51668 --HG-- extra : moz-landing-system : lando --- dom/canvas/CanvasRenderingContext2D.cpp | 21 ++++++++++++++++----- dom/canvas/CanvasRenderingContext2D.h | 1 + 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 141e5487f791..cac8e1fda3cd 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -1221,15 +1221,25 @@ void CanvasRenderingContext2D::RestoreClipsAndTransformToTarget() { mTarget->PushClipRect(gfx::Rect(0, 0, mWidth, mHeight)); } - for (const auto& style : mStyleStack) { - for (const auto& clipOrTransform : style.clipsAndTransforms) { - if (clipOrTransform.IsClip()) { - mTarget->PushClip(clipOrTransform.clip); + for (auto& style : mStyleStack) { + for (auto clipOrTransform = style.clipsAndTransforms.begin(); + clipOrTransform != style.clipsAndTransforms.end(); clipOrTransform++) { + if (clipOrTransform->IsClip()) { + if (mClipsNeedConverting) { + // We have possibly changed backends, so we need to convert the clips + // in case they are no longer compatible with mTarget. + RefPtr pathBuilder = mTarget->CreatePathBuilder(); + clipOrTransform->clip->StreamToSink(pathBuilder); + clipOrTransform->clip = pathBuilder->Finish(); + } + mTarget->PushClip(clipOrTransform->clip); } else { - mTarget->SetTransform(clipOrTransform.transform); + mTarget->SetTransform(clipOrTransform->transform); } } } + + mClipsNeedConverting = false; } bool CanvasRenderingContext2D::EnsureTarget(const gfx::Rect* aCoveredRect, @@ -1419,6 +1429,7 @@ bool CanvasRenderingContext2D::TrySharedTarget( // we are already using a shared buffer provider, we are allocating a new // one because the current one failed so let's just fall back to the basic // provider. + mClipsNeedConverting = true; return false; } diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h index b7bd2e7e129b..b07430bff1db 100644 --- a/dom/canvas/CanvasRenderingContext2D.h +++ b/dom/canvas/CanvasRenderingContext2D.h @@ -1041,6 +1041,7 @@ class CanvasRenderingContext2D final : public nsICanvasRenderingContextInternal, bool IsWriteOnly() const { return mWriteOnly; } bool mWriteOnly; + bool mClipsNeedConverting = false; }; size_t BindingJSObjectMallocBytes(CanvasRenderingContext2D* aContext);