Bug 1959409 - Ensure canvas clips always get converted to the correct type. r=aosmond
When falling back from DrawTargetRecording to DrawTargetSkia, clips may be left that were created as PathRecordings, which DrawTargetSkia will ignore. This changes the code to unconditionally convert clips to the desired type for a given DrawTarget (which may differ from its actual backend type) when restoring clips, so that we avoid any such future scenarios. Differential Revision: https://phabricator.services.mozilla.com/D245038
This commit is contained in:
@@ -66,7 +66,7 @@ class CanvasPath final : public nsWrapperCache {
|
||||
gfx::BackendType aBackendType) const;
|
||||
already_AddRefed<gfx::Path> GetPath(const CanvasWindingRule& aWinding,
|
||||
const gfx::DrawTarget* aTarget) const {
|
||||
return GetPath(aWinding, aTarget->GetBackendType());
|
||||
return GetPath(aWinding, aTarget->GetPathType());
|
||||
}
|
||||
|
||||
explicit CanvasPath(nsISupports* aParent);
|
||||
|
||||
@@ -1475,7 +1475,7 @@ void CanvasRenderingContext2D::RestoreClipsAndTransformToTarget() {
|
||||
for (auto& style : mStyleStack) {
|
||||
for (auto& clipOrTransform : style.clipsAndTransforms) {
|
||||
if (clipOrTransform.IsClip()) {
|
||||
if (mClipsNeedConverting) {
|
||||
if (clipOrTransform.clip->GetBackendType() != mPathType) {
|
||||
// We have possibly changed backends, so we need to convert the clips
|
||||
// in case they are no longer compatible with mTarget.
|
||||
RefPtr<PathBuilder> pathBuilder = mTarget->CreatePathBuilder();
|
||||
@@ -1488,8 +1488,6 @@ void CanvasRenderingContext2D::RestoreClipsAndTransformToTarget() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mClipsNeedConverting = false;
|
||||
}
|
||||
|
||||
bool CanvasRenderingContext2D::BorrowTarget(const IntRect& aPersistedRect,
|
||||
@@ -1684,7 +1682,7 @@ bool CanvasRenderingContext2D::EnsureTarget(ErrorResult& aError,
|
||||
|
||||
// Ensure any Path state is compatible with the type of DrawTarget used. This
|
||||
// may require making a copy with the correct type if they (rarely) mismatch.
|
||||
mPathType = newTarget->GetBackendType();
|
||||
mPathType = newTarget->GetPathType();
|
||||
MOZ_ASSERT(mPathType != BackendType::NONE);
|
||||
if (mPathBuilder && mPathBuilder->GetBackendType() != mPathType) {
|
||||
RefPtr<Path> path = mPathBuilder->Finish();
|
||||
@@ -1732,7 +1730,7 @@ void CanvasRenderingContext2D::SetInitialState() {
|
||||
mPathTransformDirty = false;
|
||||
mPathType =
|
||||
(mTarget ? mTarget : gfxPlatform::ThreadLocalScreenReferenceDrawTarget())
|
||||
->GetBackendType();
|
||||
->GetPathType();
|
||||
MOZ_ASSERT(mPathType != BackendType::NONE);
|
||||
|
||||
mStyleStack.Clear();
|
||||
@@ -1846,7 +1844,6 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1225,7 +1225,6 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal,
|
||||
bool IsWriteOnly() const { return mWriteOnly; }
|
||||
|
||||
bool mWriteOnly;
|
||||
bool mClipsNeedConverting = false;
|
||||
|
||||
uint8_t mFillTextCalls = 0;
|
||||
// Flags used by the fingerprinting detection heuristic
|
||||
|
||||
@@ -473,6 +473,7 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
|
||||
return DrawTargetType::HARDWARE_RASTER;
|
||||
}
|
||||
BackendType GetBackendType() const override { return BackendType::WEBGL; }
|
||||
BackendType GetPathType() const override { return BackendType::SKIA; }
|
||||
IntSize GetSize() const override { return mSize; }
|
||||
const RefPtr<SharedContextWebgl>& GetSharedContext() const {
|
||||
return mSharedContext;
|
||||
|
||||
@@ -1957,6 +1957,14 @@ class DrawTarget : public external::AtomicRefCounted<DrawTarget> {
|
||||
return CreateSimilarDrawTarget(aSize, aFormat);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the BackendType of Paths/PathBuilders created from this DrawTarget.
|
||||
* This will usually just be the same as the DrawTarget's BackendType.
|
||||
* However, some DrawTargets may create PathBuilders with differing type.
|
||||
*/
|
||||
virtual BackendType GetPathType() const { return GetBackendType(); }
|
||||
|
||||
/**
|
||||
* Create a path builder with the specified fillmode.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user