Bug 600909: Optimize DrawPath for working with D2D surfaces. r=vlad a=blocking-betaN

This commit is contained in:
Bas Schouten 2010-10-08 18:02:56 +02:00
Родитель 727b51cc4d
Коммит 109d792791
1 изменённых файлов: 41 добавлений и 12 удалений

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

@ -1960,13 +1960,25 @@ nsCanvasRenderingContext2D::ShadowFinalize(gfxAlphaBoxBlur& blur)
nsresult
nsCanvasRenderingContext2D::DrawPath(Style style, gfxRect *dirtyRect)
{
/*
* Need an intermediate surface when:
* - globalAlpha != 1 and gradients/patterns are used (need to paint_with_alpha)
* - certain operators are used
*/
PRBool doUseIntermediateSurface = NeedToUseIntermediateSurface() ||
NeedIntermediateSurfaceToHandleGlobalAlpha(style);
PRBool doUseIntermediateSurface = PR_FALSE;
if (mSurface->GetType() == gfxASurface::SurfaceTypeD2D) {
if (style == STYLE_FILL) {
// D2D does all operators correctly even if transparent areas of SOURCE
// affect dest. We need to use an intermediate surface for STROKE because
// we can't clip to the actual stroke shape easily, but prefer a geometric
// clip over an intermediate surface for a FILL.
doUseIntermediateSurface = NeedIntermediateSurfaceToHandleGlobalAlpha(style);
}
} else {
/*
* Need an intermediate surface when:
* - globalAlpha != 1 and gradients/patterns are used (need to paint_with_alpha)
* - certain operators are used
*/
doUseIntermediateSurface = NeedToUseIntermediateSurface() ||
NeedIntermediateSurfaceToHandleGlobalAlpha(style);
}
PRBool doDrawShadow = NeedToDrawShadow();
@ -2018,14 +2030,31 @@ nsCanvasRenderingContext2D::DrawPath(Style style, gfxRect *dirtyRect)
mThebes->NewPath();
mThebes->AppendPath(path);
// don't want operators to be applied twice
mThebes->SetOperator(gfxContext::OPERATOR_SOURCE);
// don't want operators to be applied twice,
if (mSurface->GetType() != gfxASurface::SurfaceTypeD2D) {
mThebes->SetOperator(gfxContext::OPERATOR_SOURCE);
} else {
// In the case of D2D OPERATOR_OVER is much faster. So we can just
// use that since it's the same as SOURCE for a transparent
// destinations. It would be nice if cairo backends could make this
// optimization internally but I see no very good way of doing this.
mThebes->SetOperator(gfxContext::OPERATOR_OVER);
}
}
ApplyStyle(style);
if (style == STYLE_FILL)
mThebes->Fill();
else
if (style == STYLE_FILL) {
if (!doUseIntermediateSurface &&
CurrentState().globalAlpha != 1.0 &&
!CurrentState().StyleIsColor(style))
{
mThebes->Clip();
mThebes->Paint(CurrentState().globalAlpha);
} else {
mThebes->Fill();
}
} else
mThebes->Stroke();
// XXX do some more work to calculate the extents of shadows