From e03c8c6a53b51cbebe380083b5b51aeed9a37da2 Mon Sep 17 00:00:00 2001 From: Ethan Lin Date: Fri, 30 Jun 2017 17:23:20 -0700 Subject: [PATCH] Bug 1372118 - Part3. Implement CreateWebRenderCommands for text, transform and background color. r=jrmuizel, r=kats MozReview-Commit-ID: JRoSjygSFHc --- gfx/layers/wr/StackingContextHelper.cpp | 27 ++++++++ gfx/layers/wr/StackingContextHelper.h | 9 +++ layout/generic/nsTextFrame.cpp | 42 +++++++++++++ layout/painting/nsDisplayList.cpp | 82 +++++++++++++++++++++++++ layout/painting/nsDisplayList.h | 11 +++- 5 files changed, 170 insertions(+), 1 deletion(-) diff --git a/gfx/layers/wr/StackingContextHelper.cpp b/gfx/layers/wr/StackingContextHelper.cpp index 8963f25224fe..f4e85e1ff6de 100644 --- a/gfx/layers/wr/StackingContextHelper.cpp +++ b/gfx/layers/wr/StackingContextHelper.cpp @@ -17,6 +17,33 @@ StackingContextHelper::StackingContextHelper() // mOrigin remains at 0,0 } +StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParentSC, + wr::DisplayListBuilder& aBuilder, + LayerRect aBoundForSC, + LayerPoint aOrigin, + uint64_t aAnimationsId, + float* aOpacityPtr, + gfx::Matrix4x4* aTransformPtr, + const nsTArray& aFilters) + : mBuilder(&aBuilder) +{ + WrRect scBounds = aParentSC.ToRelativeWrRect(aBoundForSC); + if (aTransformPtr) { + mTransform = *aTransformPtr; + } + + mBuilder->PushStackingContext(scBounds, + aAnimationsId, + aOpacityPtr, + aTransformPtr, + WrTransformStyle::Flat, + // TODO: set correct blend mode. + wr::ToWrMixBlendMode(gfx::CompositionOp::OP_OVER), + aFilters); + + mOrigin = aOrigin; +} + StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParentSC, wr::DisplayListBuilder& aBuilder, WebRenderLayer* aLayer, diff --git a/gfx/layers/wr/StackingContextHelper.h b/gfx/layers/wr/StackingContextHelper.h index d75d16d73e0c..5b83cf453441 100644 --- a/gfx/layers/wr/StackingContextHelper.h +++ b/gfx/layers/wr/StackingContextHelper.h @@ -42,6 +42,15 @@ public: float* aOpacityPtr, gfx::Matrix4x4* aTransformPtr, const nsTArray& aFilters = nsTArray()); + // The constructor for layers-free mode. + StackingContextHelper(const StackingContextHelper& aParentSC, + wr::DisplayListBuilder& aBuilder, + LayerRect aBoundForSC, + LayerPoint aOrigin, + uint64_t aAnimationsId, + float* aOpacityPtr, + gfx::Matrix4x4* aTransformPtr, + const nsTArray& aFilters = nsTArray()); // This version of the constructor should only be used at the root level // of the tree, so that we have a StackingContextHelper to pass down into // the RenderLayer traversal, but don't actually want it to push a stacking diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 59a9e53867d8..379769718860 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -69,6 +69,10 @@ #include "mozilla/StyleSetHandle.h" #include "mozilla/StyleSetHandleInlines.h" #include "mozilla/layers/LayersMessages.h" +#include "mozilla/layers/WebRenderLayerManager.h" +#include "mozilla/layers/WebRenderBridgeChild.h" +#include "mozilla/webrender/WebRenderAPI.h" +#include "mozilla/layers/StackingContextHelper.h" #include #include @@ -4921,6 +4925,11 @@ public: virtual already_AddRefed BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, const ContainerLayerParameters& aContainerParameters) override; + virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder, + const StackingContextHelper& aSc, + nsTArray& aParentCommands, + WebRenderLayerManager* aManager, + nsDisplayListBuilder* aDisplayListBuilder) override; virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; NS_DISPLAY_DECL_NAME("Text", TYPE_TEXT) @@ -5164,6 +5173,39 @@ nsDisplayText::Paint(nsDisplayListBuilder* aBuilder, RenderToContext(aCtx, aBuilder); } +bool +nsDisplayText::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder, + const StackingContextHelper& aSc, + nsTArray& aParentCommands, + WebRenderLayerManager* aManager, + nsDisplayListBuilder* aDisplayListBuilder) +{ + if (aManager->IsLayersFreeTransaction()) { + ContainerLayerParameters parameter; + if (GetLayerState(aDisplayListBuilder, aManager, parameter) != LAYER_ACTIVE) { + return false; + } + } + + if (mBounds.IsEmpty()) { + return true; + } + + auto appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel(); + LayoutDeviceRect rect = LayoutDeviceRect::FromAppUnits( + mBounds, appUnitsPerDevPixel); + LayoutDeviceRect clipRect = rect; + if (GetClip().HasClip()) { + clipRect = LayoutDeviceRect::FromAppUnits( + GetClip().GetClipRect(), appUnitsPerDevPixel); + } + aManager->WrBridge()->PushGlyphs(aBuilder, mGlyphs, mFont, aSc, + LayerRect::FromUnknownRect(rect.ToUnknownRect()), + LayerRect::FromUnknownRect(clipRect.ToUnknownRect())); + + return true; +} + already_AddRefed nsDisplayText::BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 81628ac63063..8ea713b385c3 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -4148,6 +4148,35 @@ nsDisplayBackgroundColor::BuildLayer(nsDisplayListBuilder* aBuilder, return layer.forget(); } +bool +nsDisplayBackgroundColor::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder, + const StackingContextHelper& aSc, + nsTArray& aParentCommands, + mozilla::layers::WebRenderLayerManager* aManager, + nsDisplayListBuilder* aDisplayListBuilder) +{ + if (aManager->IsLayersFreeTransaction()) { + ContainerLayerParameters parameter; + if (GetLayerState(aDisplayListBuilder, aManager, parameter) != LAYER_ACTIVE) { + return false; + } + } + + if (mColor == Color()) { + return true; + } + + LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits( + mBackgroundRect, mFrame->PresContext()->AppUnitsPerDevPixel()); + WrRect transformedRect = aSc.ToRelativeWrRect(bounds); + + aBuilder.PushRect(transformedRect, + transformedRect, + wr::ToWrColor(ToDeviceColor(mColor))); + + return true; +} + void nsDisplayBackgroundColor::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) @@ -7536,6 +7565,59 @@ nsDisplayTransform::ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuild return MayBeAnimated(aBuilder) || mFrame->Combines3DTransformWithAncestors(); } +bool +nsDisplayTransform::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder, + const StackingContextHelper& aSc, + nsTArray& aParentCommands, + WebRenderLayerManager* aManager, + nsDisplayListBuilder* aDisplayListBuilder) +{ + Matrix4x4 newTransformMatrix = GetTransformForRendering(); + gfx::Matrix4x4* transformForSC = &newTransformMatrix; + if (newTransformMatrix.IsIdentity()) { + // If the transform is an identity transform, strip it out so that WR + // doesn't turn this stacking context into a reference frame, as it + // affects positioning. Bug 1345577 tracks a better fix. + transformForSC = nullptr; + } + + nsRect itemBounds = mStoredList.GetChildren()->GetClippedBoundsWithRespectToASR(aDisplayListBuilder, mActiveScrolledRoot); + nsRect childrenVisible = GetVisibleRectForChildren(); + nsRect visibleRect = itemBounds.Intersect(childrenVisible); + float appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel(); + LayerRect bounds = ViewAs(LayoutDeviceRect::FromAppUnits(visibleRect, appUnitsPerDevPixel), + PixelCastJustification::WebRenderHasUnitResolution); + LayerPoint origin = bounds.TopLeft(); + + gfx::Matrix4x4Typed boundTransform = ViewAs< gfx::Matrix4x4Typed >(newTransformMatrix); + boundTransform._41 = 0.0f; + boundTransform._42 = 0.0f; + boundTransform._43 = 0.0f; + if (!boundTransform.IsIdentity()) { + // WR will only apply the 'translate' of the transform, so we need to do the scale/rotation manually. + bounds.MoveTo(boundTransform.TransformPoint(bounds.TopLeft())); + } + + // TODO: generate animationsId for OMTA. + uint64_t animationsId = 0; + nsTArray filters; + StackingContextHelper sc(aSc, + aBuilder, + bounds, + origin, + animationsId, + nullptr, + transformForSC, + filters); + + aManager->CreateWebRenderCommandsFromDisplayList(mStoredList.GetChildren(), + aDisplayListBuilder, + sc, + aBuilder); + + return true; +} + already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBuilder, LayerManager *aManager, const ContainerLayerParameters& aContainerParameters) diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h index b3fc717ca910..058d95425dce 100644 --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -3354,7 +3354,11 @@ public: virtual already_AddRefed BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, const ContainerLayerParameters& aContainerParameters) override; - + virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder, + const StackingContextHelper& aSc, + nsTArray& aParentCommands, + mozilla::layers::WebRenderLayerManager* aManager, + nsDisplayListBuilder* aDisplayListBuilder) override; virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, bool* aSnap) override; virtual mozilla::Maybe IsUniform(nsDisplayListBuilder* aBuilder) override; @@ -4630,6 +4634,11 @@ public: virtual already_AddRefed BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, const ContainerLayerParameters& aContainerParameters) override; + virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder, + const StackingContextHelper& aSc, + nsTArray& aParentCommands, + mozilla::layers::WebRenderLayerManager* aManager, + nsDisplayListBuilder* aDisplayListBuilder) override; virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) override; virtual bool ComputeVisibility(nsDisplayListBuilder *aBuilder, nsRegion *aVisibleRegion) override;