Bug 1258168: Push ClearType compatible clipping layers when the last pushed layer was marked as opaque. r=jrmuizel

MozReview-Commit-ID: IM1srXx7CfB
This commit is contained in:
Bas Schouten 2016-03-20 19:51:46 +01:00
parent ce36c0e082
commit 9c327300bf
2 changed files with 35 additions and 16 deletions

View File

@ -1171,12 +1171,24 @@ DrawTargetD2D1::MarkChanged()
}
}
bool
DrawTargetD2D1::ShouldClipTemporarySurfaceDrawing(CompositionOp aOp,
const Pattern& aPattern,
bool aClipIsComplex)
{
bool patternSupported = IsPatternSupportedByD2D(aPattern);
return patternSupported && !CurrentLayer().mIsOpaque && D2DSupportsCompositeMode(aOp) &&
IsOperatorBoundByMask(aOp) && aClipIsComplex;
}
void
DrawTargetD2D1::PrepareForDrawing(CompositionOp aOp, const Pattern &aPattern)
{
MarkChanged();
if (D2DSupportsPrimitiveBlendMode(aOp) && IsPatternSupportedByD2D(aPattern)) {
bool patternSupported = IsPatternSupportedByD2D(aPattern);
if (D2DSupportsPrimitiveBlendMode(aOp) && patternSupported) {
// It's important to do this before FlushTransformToDC! As this will cause
// the transform to become dirty.
PushAllClips();
@ -1189,13 +1201,18 @@ DrawTargetD2D1::PrepareForDrawing(CompositionOp aOp, const Pattern &aPattern)
return;
}
PopAllClips();
mDC->CreateCommandList(getter_AddRefs(mCommandList));
mDC->SetTarget(mCommandList);
mUsedCommandListsSincePurge++;
PushAllClips();
D2D1_RECT_F rect;
bool isAligned;
bool clipIsComplex = CurrentLayer().mPushedClips.size() && !GetDeviceSpaceClipRect(rect, isAligned);
if (ShouldClipTemporarySurfaceDrawing(aOp, aPattern, clipIsComplex)) {
PushClipsToDC(mDC);
}
FlushTransformToDC();
}
@ -1210,7 +1227,13 @@ DrawTargetD2D1::FinalizeDrawing(CompositionOp aOp, const Pattern &aPattern)
return;
}
PopAllClips();
D2D1_RECT_F rect;
bool isAligned;
bool clipIsComplex = CurrentLayer().mPushedClips.size() && !GetDeviceSpaceClipRect(rect, isAligned);
if (ShouldClipTemporarySurfaceDrawing(aOp, aPattern, clipIsComplex)) {
PopClipsFromDC(mDC);
}
mDC->SetTarget(CurrentTarget());
mCommandList->Close();
@ -1223,17 +1246,12 @@ DrawTargetD2D1::FinalizeDrawing(CompositionOp aOp, const Pattern &aPattern)
if (patternSupported) {
if (D2DSupportsCompositeMode(aOp)) {
D2D1_RECT_F rect;
bool isAligned;
RefPtr<ID2D1Image> tmpImage;
bool clipIsComplex = CurrentLayer().mPushedClips.size() && !GetDeviceSpaceClipRect(rect, isAligned);
if (clipIsComplex) {
PopAllClips();
if (!IsOperatorBoundByMask(aOp)) {
tmpImage = GetImageForLayerContent();
}
} else {
PushAllClips();
}
mDC->DrawImage(source, D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR, D2DCompositionMode(aOp));
@ -1264,8 +1282,6 @@ DrawTargetD2D1::FinalizeDrawing(CompositionOp aOp, const Pattern &aPattern)
blendEffect->SetInput(1, source);
blendEffect->SetValue(D2D1_BLEND_PROP_MODE, D2DBlendMode(aOp));
PushAllClips();
mDC->DrawImage(blendEffect, D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR, D2D1_COMPOSITE_MODE_BOUNDED_SOURCE_COPY);
return;
}
@ -1276,8 +1292,6 @@ DrawTargetD2D1::FinalizeDrawing(CompositionOp aOp, const Pattern &aPattern)
return;
}
PushAllClips();
RefPtr<ID2D1Effect> radialGradientEffect;
HRESULT hr = mDC->CreateEffect(CLSID_RadialGradientEffect, getter_AddRefs(radialGradientEffect));
@ -1360,6 +1374,8 @@ DrawTargetD2D1::GetImageForLayerContent()
tmpBitmap->CopyFromBitmap(nullptr, mBitmap, nullptr);
return tmpBitmap.forget();
} else {
PopAllClips();
RefPtr<ID2D1CommandList> list = CurrentLayer().mCurrentList;
mDC->CreateCommandList(getter_AddRefs(CurrentLayer().mCurrentList));
mDC->SetTarget(CurrentTarget());
@ -1368,6 +1384,8 @@ DrawTargetD2D1::GetImageForLayerContent()
DCCommandSink sink(mDC);
list->Stream(&sink);
PushAllClips();
return list.forget();
}
}
@ -1786,7 +1804,7 @@ DrawTargetD2D1::PushD2DLayer(ID2D1DeviceContext *aDC, ID2D1Geometry *aGeometry,
{
D2D1_LAYER_OPTIONS1 options = D2D1_LAYER_OPTIONS1_NONE;
if (aDC->GetPixelFormat().alphaMode == D2D1_ALPHA_MODE_IGNORE || aForceIgnoreAlpha) {
if (CurrentLayer().mIsOpaque || aForceIgnoreAlpha) {
options = D2D1_LAYER_OPTIONS1_IGNORE_ALPHA | D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND;
}

View File

@ -164,6 +164,7 @@ private:
// This function will mark the surface as changing, and make sure any
// copy-on-write snapshots are notified.
void MarkChanged();
bool ShouldClipTemporarySurfaceDrawing(CompositionOp aOp, const Pattern& aPattern, bool aClipIsComplex);
void PrepareForDrawing(CompositionOp aOp, const Pattern &aPattern);
void FinalizeDrawing(CompositionOp aOp, const Pattern &aPattern);
void FlushTransformToDC() {