зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1083672 - Avoid copying more than needed when drawing a canvas onto itself. r=jrmuizel
This commit is contained in:
Родитель
28bf55dae8
Коммит
1874a2749b
|
@ -3854,6 +3854,32 @@ bool CanvasRenderingContext2D::IsPointInStroke(const CanvasPath& mPath, double x
|
||||||
return tempPath->StrokeContainsPoint(strokeOptions, Point(x, y), mTarget->GetTransform());
|
return tempPath->StrokeContainsPoint(strokeOptions, Point(x, y), mTarget->GetTransform());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a surface that contains only the part needed to draw aSourceRect.
|
||||||
|
// On entry, aSourceRect is relative to aSurface, and on return aSourceRect is
|
||||||
|
// relative to the returned surface.
|
||||||
|
static TemporaryRef<SourceSurface>
|
||||||
|
ExtractSubrect(SourceSurface* aSurface, mgfx::Rect* aSourceRect, DrawTarget* aTargetDT)
|
||||||
|
{
|
||||||
|
mgfx::Rect roundedOutSourceRect = *aSourceRect;
|
||||||
|
roundedOutSourceRect.RoundOut();
|
||||||
|
mgfx::IntRect roundedOutSourceRectInt;
|
||||||
|
if (!roundedOutSourceRect.ToIntRect(&roundedOutSourceRectInt)) {
|
||||||
|
return aSurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<DrawTarget> subrectDT =
|
||||||
|
aTargetDT->CreateSimilarDrawTarget(roundedOutSourceRectInt.Size(), SurfaceFormat::B8G8R8A8);
|
||||||
|
|
||||||
|
if (!subrectDT) {
|
||||||
|
return aSurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aSourceRect -= roundedOutSourceRect.TopLeft();
|
||||||
|
|
||||||
|
subrectDT->CopySurface(aSurface, roundedOutSourceRectInt, IntPoint());
|
||||||
|
return subrectDT->Snapshot();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// image
|
// image
|
||||||
//
|
//
|
||||||
|
@ -3999,10 +4025,19 @@ CanvasRenderingContext2D::DrawImage(const HTMLImageOrCanvasOrVideoElement& image
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcSurf) {
|
if (srcSurf) {
|
||||||
|
mgfx::Rect sourceRect(sx, sy, sw, sh);
|
||||||
|
if (element == mCanvasElement) {
|
||||||
|
// srcSurf is a snapshot of mTarget. If we draw to mTarget now, we'll
|
||||||
|
// trigger a COW copy of the whole canvas into srcSurf. That's a huge
|
||||||
|
// waste if sourceRect doesn't cover the whole canvas.
|
||||||
|
// We avoid copying the whole canvas by manually copying just the part
|
||||||
|
// that we need.
|
||||||
|
srcSurf = ExtractSubrect(srcSurf, &sourceRect, mTarget);
|
||||||
|
}
|
||||||
AdjustedTarget(this, bounds.IsEmpty() ? nullptr : &bounds)->
|
AdjustedTarget(this, bounds.IsEmpty() ? nullptr : &bounds)->
|
||||||
DrawSurface(srcSurf,
|
DrawSurface(srcSurf,
|
||||||
mgfx::Rect(dx, dy, dw, dh),
|
mgfx::Rect(dx, dy, dw, dh),
|
||||||
mgfx::Rect(sx, sy, sw, sh),
|
sourceRect,
|
||||||
DrawSurfaceOptions(filter),
|
DrawSurfaceOptions(filter),
|
||||||
DrawOptions(CurrentState().globalAlpha, UsedOperation()));
|
DrawOptions(CurrentState().globalAlpha, UsedOperation()));
|
||||||
} else {
|
} else {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче