Bug 1294351 - Move restoring the canvas clip stack to its own method and early return form EnsureTarget. r=Bas

This commit is contained in:
Nicolas Silva 2016-08-26 14:31:58 +02:00
Родитель 86043872c7
Коммит b448411938
2 изменённых файлов: 38 добавлений и 24 удалений

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

@ -1505,6 +1505,33 @@ CanvasRenderingContext2D::OnStableState()
mHasPendingStableStateCallback = false;
}
void
CanvasRenderingContext2D::RestoreClipsAndTransformToTarget()
{
// Restore clips and transform.
mTarget->SetTransform(Matrix());
if (mTarget->GetBackendType() == gfx::BackendType::CAIRO) {
// Cairo doesn't play well with huge clips. When given a very big clip it
// will try to allocate big mask surface without taking the target
// size into account which can cause OOM. See bug 1034593.
// This limits the clip extents to the size of the canvas.
// A fix in Cairo would probably be preferable, but requires somewhat
// invasive changes.
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);
} else {
mTarget->SetTransform(clipOrTransform.transform);
}
}
}
}
CanvasRenderingContext2D::RenderingMode
CanvasRenderingContext2D::EnsureTarget(const gfx::Rect* aCoveredRect,
RenderingMode aRenderingMode)
@ -1556,7 +1583,13 @@ CanvasRenderingContext2D::EnsureTarget(const gfx::Rect* aCoveredRect,
: IntRect(0, 0, mWidth, mHeight);
mTarget = mBufferProvider->BorrowDrawTarget(persistedRect);
mode = mRenderingMode;
if (mTarget && !mBufferProvider->PreservesDrawingState()) {
RestoreClipsAndTransformToTarget();
}
if (mTarget) {
return mode;
}
}
mIsSkiaGL = false;
@ -1649,28 +1682,7 @@ CanvasRenderingContext2D::EnsureTarget(const gfx::Rect* aCoveredRect,
if (mBufferProvider != oldBufferProvider || !mBufferProvider ||
!mBufferProvider->PreservesDrawingState()) {
// Restore clips and transform.
mTarget->SetTransform(Matrix());
if (mTarget->GetBackendType() == gfx::BackendType::CAIRO) {
// Cairo doesn't play well with huge clips. When given a very big clip it
// will try to allocate big mask surface without taking the target
// size into account which can cause OOM. See bug 1034593.
// This limits the clip extents to the size of the canvas.
// A fix in Cairo would probably be preferable, but requires somewhat
// invasive changes.
mTarget->PushClipRect(canvasRect);
}
for (const auto& style : mStyleStack) {
for (const auto& clipOrTransform : style.clipsAndTransforms) {
if (clipOrTransform.IsClip()) {
mTarget->PushClip(clipOrTransform.clip);
} else {
mTarget->SetTransform(clipOrTransform.transform);
}
}
}
RestoreClipsAndTransformToTarget();
}
} else {
EnsureErrorTarget();
@ -1792,7 +1804,7 @@ CanvasRenderingContext2D::ReturnTarget(bool aForceReset)
if (mTarget->GetBackendType() == gfx::BackendType::CAIRO) {
// With the cairo backend we pushed an extra clip rect which we have to
// balance out here. See the comment in EnsureDrawTarget.
// balance out here. See the comment in RestoreClipsAndTransformToTarget.
mTarget->PopClip();
}
}

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

@ -643,6 +643,8 @@ protected:
RenderingMode EnsureTarget(const gfx::Rect* aCoveredRect = nullptr,
RenderingMode aRenderMode = RenderingMode::DefaultBackendMode);
void RestoreClipsAndTransformToTarget();
/**
* This method is run at the end of the event-loop spin where
* ScheduleStableStateCallback was called.