b=600120; fix canvas composite.uncovered.image tests; r+a=vlad

This commit is contained in:
Masatoshi Kimura 2010-09-29 15:24:40 -07:00
parent b0850c29d5
commit 57f204e676
2 changed files with 52 additions and 13 deletions

View File

@ -549,6 +549,19 @@ protected:
PRUint32 mInvalidateCount;
static const PRUint32 kCanvasMaxInvalidateCount = 100;
/**
* Returns true iff the the given operator should affect areas of the
* destination where the source is transparent. Among other things, this
* implies that a fully transparent source would still affect the canvas.
*/
PRBool OperatorAffectsUncoveredAreas(gfxContext::GraphicsOperator op) const
{
return op == gfxContext::OPERATOR_IN ||
op == gfxContext::OPERATOR_OUT ||
op == gfxContext::OPERATOR_DEST_IN ||
op == gfxContext::OPERATOR_DEST_ATOP;
}
/**
* Returns true iff a shadow should be drawn along with a
* drawing operation.
@ -564,6 +577,22 @@ protected:
(state.shadowOffset != gfxPoint(0, 0) || state.shadowBlur != 0);
}
/**
* Checks the current state to determine if an intermediate surface would
* be necessary to complete a drawing operation. Does not check the
* condition pertaining to global alpha and patterns since that does not
* pertain to all drawing operations.
*/
PRBool NeedToUseIntermediateSurface()
{
// certain operators always need an intermediate surface, except
// with quartz since quartz does compositing differently than cairo
return OperatorAffectsUncoveredAreas(mThebes->CurrentOperator());
// XXX there are other unhandled cases but they should be investigated
// first to ensure we aren't using an intermediate surface unecessarily
}
/**
* If the current operator is "source" then clear the destination before we
* draw into it, to simulate the effect of an unbounded source operator.
@ -1932,7 +1961,8 @@ nsCanvasRenderingContext2D::DrawPath(Style style, gfxRect *dirtyRect)
* - globalAlpha != 1 and gradients/patterns are used (need to paint_with_alpha)
* - certain operators are used
*/
PRBool doUseIntermediateSurface = NeedIntermediateSurfaceToHandleGlobalAlpha(style);
PRBool doUseIntermediateSurface = NeedToUseIntermediateSurface() ||
NeedIntermediateSurfaceToHandleGlobalAlpha(style);
PRBool doDrawShadow = NeedToDrawShadow();
@ -2751,7 +2781,7 @@ nsCanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
// don't need to take care of these with stroke since Stroke() does that
PRBool doDrawShadow = aOp == TEXT_DRAW_OPERATION_FILL && NeedToDrawShadow();
PRBool doUseIntermediateSurface = aOp == TEXT_DRAW_OPERATION_FILL &&
NeedIntermediateSurfaceToHandleGlobalAlpha(STYLE_FILL);
(NeedToUseIntermediateSurface() || NeedIntermediateSurfaceToHandleGlobalAlpha(STYLE_FILL));
// Clear the surface if we need to simulate unbounded SOURCE operator
ClearSurfaceForUnboundedSource();
@ -3559,11 +3589,25 @@ nsCanvasRenderingContext2D::DrawImage(nsIDOMElement *imgElt, float a1,
}
}
PRBool doUseIntermediateSurface = NeedToUseIntermediateSurface();
mThebes->SetPattern(pattern);
DirtyAllStyles();
/* Direct2D isn't very good at clipping so use Fill() when we can */
if (CurrentState().globalAlpha == 1.0f && mThebes->CurrentOperator() == gfxContext::OPERATOR_OVER) {
if (doUseIntermediateSurface) {
// draw onto a pushed group
mThebes->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
mThebes->Clip(clip);
// don't want operators to be applied twice
mThebes->SetOperator(gfxContext::OPERATOR_SOURCE);
mThebes->Paint();
mThebes->PopGroupToSource();
mThebes->Paint(CurrentState().globalAlpha);
} else if (CurrentState().globalAlpha == 1.0f &&
mThebes->CurrentOperator() == gfxContext::OPERATOR_OVER) {
/* Direct2D isn't very good at clipping so use Fill() when we can */
mThebes->NewPath();
mThebes->Rectangle(clip);
mThebes->Fill();

View File

@ -76,6 +76,10 @@ _TEST_FILES_0 = \
test_2d.composite.image.destination-in.html \
test_2d.composite.image.source-in.html \
test_2d.composite.image.source-out.html \
test_2d.composite.uncovered.image.destination-atop.html \
test_2d.composite.uncovered.image.destination-in.html \
test_2d.composite.uncovered.image.source-in.html \
test_2d.composite.uncovered.image.source-out.html \
test_mozGetAsFile.html \
$(NULL)
@ -93,15 +97,6 @@ _TEST_FILES_0 = \
# test_2d.composite.clip.lighter.html \
#
# Temporarily disabled tests; unbounded operators changed behaviour, need to reevaluate tests.
# At one point we were passing these accidentally, because the UpdateSurfaceClip at the end
# of drawImage happened to clear the entire canvas with some operators, which is what these
# tests were checking.
# test_2d.composite.uncovered.image.source-in.html \
# test_2d.composite.uncovered.image.destination-in.html \
# test_2d.composite.uncovered.image.source-out.html \
# test_2d.composite.uncovered.image.destination-atop.html \
# Tests that fail on Mac (possibly because spec is underdefined?). Bug 407105
ifneq ($(MOZ_WIDGET_TOOLKIT),cocoa)
# XXX vlad don't test these anywhere, cairo behaviour changed