Bug 1447880. Paint nsDisplayMasks directly instead of using a BasicLayerManager. r=mstange

This allows us to invalidate individual items inside of the mask instead of
treating the mask and it's children as a single item.

Differential Revision: https://phabricator.services.mozilla.com/D6224
This commit is contained in:
Jeff Muizelaar 2018-09-14 10:42:38 -04:00
parent 805679d7c9
commit 90fbfc8d8a
4 changed files with 52 additions and 13 deletions

View File

@ -907,16 +907,14 @@ Grouper::PaintContainerItem(DIGroup* aGroup, nsDisplayItem* aItem, const IntRect
}
case DisplayItemType::TYPE_MASK: {
GP("Paint Mask\n");
// We don't currently support doing invalidation inside nsDisplayMask
// for now just paint it as a single item
BlobItemData* data = GetBlobItemDataForGroup(aItem, aGroup);
if (data->mLayerManager->GetRoot()) {
data->mLayerManager->BeginTransaction();
static_cast<nsDisplayMask*>(aItem)->PaintAsLayer(mDisplayListBuilder,
aContext, data->mLayerManager);
if (data->mLayerManager->InTransaction()) {
data->mLayerManager->AbortTransaction();
}
auto maskItem = static_cast<nsDisplayMask*>(aItem);
if (maskItem->IsValidMask()) {
maskItem->PaintWithContentsPaintCallback(mDisplayListBuilder, aContext, [&] {
GP("beginGroup %s %p-%d\n", aItem->Name(), aItem->Frame(), aItem->GetPerFrameKey());
aContext->GetDrawTarget()->FlushItem(aItemBounds);
aGroup->PaintItemRange(this, aChildren->GetBottom(), nullptr, aContext, aRecorder);
GP("endGroup %s %p-%d\n", aItem->Name(), aItem->Frame(), aItem->GetPerFrameKey());
});
aContext->GetDrawTarget()->FlushItem(aItemBounds);
}
break;
@ -1110,8 +1108,7 @@ Grouper::ConstructItemInsideInactive(WebRenderCommandBuilder* aCommandBuilder,
nsDisplayList* children = aItem->GetChildren();
BlobItemData* data = GetBlobItemDataForGroup(aItem, aGroup);
if (aItem->GetType() == DisplayItemType::TYPE_FILTER ||
aItem->GetType() == DisplayItemType::TYPE_MASK) {
if (aItem->GetType() == DisplayItemType::TYPE_FILTER) {
gfx::Size scale(1, 1);
// If ComputeDifferences finds any change, we invalidate the entire container item.
// This is needed because blob merging requires the entire item to be within the invalid region.

View File

@ -9904,6 +9904,43 @@ nsDisplayMask::PaintAsLayer(nsDisplayListBuilder* aBuilder,
nsDisplayMaskGeometry::UpdateDrawResult(this, imgParams.result);
}
void
nsDisplayMask::PaintWithContentsPaintCallback(nsDisplayListBuilder* aBuilder,
gfxContext* aCtx,
const std::function<void()>& aPaintChildren)
{
// Clip the drawing target by mVisibleRect, which contains the visible
// region of the target frame and its out-of-flow and inflow descendants.
gfxContext* context = aCtx;
Rect bounds =
NSRectToRect(GetPaintRect(), mFrame->PresContext()->AppUnitsPerDevPixel());
bounds.RoundOut();
context->Clip(bounds);
imgDrawingParams imgParams(aBuilder->ShouldSyncDecodeImages()
? imgIContainer::FLAG_SYNC_DECODE
: imgIContainer::FLAG_SYNC_DECODE_IF_FAST);
nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
nsSVGIntegrationUtils::PaintFramesParams params(*aCtx,
mFrame,
GetPaintRect(),
borderArea,
aBuilder,
nullptr,
mHandleOpacity,
imgParams);
ComputeMaskGeometry(params);
nsSVGIntegrationUtils::PaintMaskAndClipPath(params, aPaintChildren);
context->PopClip();
nsDisplayMaskGeometry::UpdateDrawResult(this, imgParams.result);
}
bool
nsDisplayMask::CreateWebRenderCommands(
mozilla::wr::DisplayListBuilder& aBuilder,

View File

@ -6790,6 +6790,11 @@ public:
gfxContext* aCtx,
LayerManager* aManager);
void PaintWithContentsPaintCallback(nsDisplayListBuilder* aBuilder,
gfxContext* aCtx,
const std::function<void()>& aPaintChildren);
/*
* Paint mask onto aMaskContext in mFrame's coordinate space and
* return whether the mask layer was painted successfully.

View File

@ -982,7 +982,7 @@ void PaintMaskAndClipPathInternal(const PaintFramesParams& aParams, const T& aPa
}
if (shouldPushMask) {
if (aParams.layerManager->GetRoot()->GetContentFlags() &
if (aParams.layerManager && aParams.layerManager->GetRoot()->GetContentFlags() &
Layer::CONTENT_COMPONENT_ALPHA) {
context.PushGroupAndCopyBackground(gfxContentType::COLOR_ALPHA,
opacityApplied