Bug 1372118 - Part3. Implement CreateWebRenderCommands for text, transform and background color. r=jrmuizel, r=kats
MozReview-Commit-ID: JRoSjygSFHc
--- a/gfx/layers/wr/StackingContextHelper.cpp
+++ b/gfx/layers/wr/StackingContextHelper.cpp
@@ -14,16 +14,43 @@ namespace layers {
StackingContextHelper::StackingContextHelper()
: mBuilder(nullptr)
{
// 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<WrFilterOp>& 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,
const Maybe<gfx::Matrix4x4>& aTransform,
const nsTArray<WrFilterOp>& aFilters)
: mBuilder(&aBuilder)
{
WrRect scBounds = aParentSC.ToRelativeWrRect(aLayer->BoundsForStackingContext());
Layer* layer = aLayer->GetLayer();
mTransform = aTransform.valueOr(layer->GetTransform());
--- a/gfx/layers/wr/StackingContextHelper.h
+++ b/gfx/layers/wr/StackingContextHelper.h
@@ -37,16 +37,25 @@ public:
// for animations.
StackingContextHelper(const StackingContextHelper& aParentSC,
wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
uint64_t aAnimationsId,
float* aOpacityPtr,
gfx::Matrix4x4* aTransformPtr,
const nsTArray<WrFilterOp>& aFilters = nsTArray<WrFilterOp>());
+ // 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<WrFilterOp>& aFilters = nsTArray<WrFilterOp>());
// 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
// context on the display list builder.
StackingContextHelper();
// Pops the stacking context, if one was pushed during the constructor.
~StackingContextHelper();
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -64,16 +64,20 @@
#include "nsContentUtils.h"
#include "nsLineBreaker.h"
#include "nsIWordBreaker.h"
#include "nsGenericDOMDataNode.h"
#include "nsIFrameInlines.h"
#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 <algorithm>
#include <limits>
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
#endif
#include "nsPrintfCString.h"
@@ -4916,16 +4920,21 @@ public:
}
}
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
+ virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsTArray<WebRenderParentCommand>& aParentCommands,
+ WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder) override;
virtual void Paint(nsDisplayListBuilder* aBuilder,
gfxContext* aCtx) override;
NS_DISPLAY_DECL_NAME("Text", TYPE_TEXT)
virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) override
{
if (gfxPlatform::GetPlatform()->RespectsFontStyleSmoothing()) {
// On OS X, web authors can turn off subpixel text rendering using the
@@ -5159,16 +5168,49 @@ nsDisplayText::Paint(nsDisplayListBuilde
MOZ_ASSERT(mMergedFrames.IsEmpty());
DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
mDisableSubpixelAA);
RenderToContext(aCtx, aBuilder);
}
+bool
+nsDisplayText::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsTArray<WebRenderParentCommand>& 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<layers::Layer>
nsDisplayText::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters)
{
// We should have all the glyphs recorded now, build
// the TextLayer.
RefPtr<layers::TextLayer> layer = static_cast<layers::TextLayer*>
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -4143,16 +4143,45 @@ nsDisplayBackgroundColor::BuildLayer(nsD
int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
layer->SetBounds(mBackgroundRect.ToNearestPixels(appUnitsPerDevPixel));
layer->SetBaseTransform(gfx::Matrix4x4::Translation(aContainerParameters.mOffset.x,
aContainerParameters.mOffset.y, 0));
return layer.forget();
}
+bool
+nsDisplayBackgroundColor::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsTArray<WebRenderParentCommand>& 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)
{
if (mColor == Color()) {
return;
}
@@ -7531,16 +7560,69 @@ bool
nsDisplayTransform::ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder)
{
// The visible rect of a Preserves-3D frame is just an intermediate
// result. It should always build a layer to make sure it is
// rendering correctly.
return MayBeAnimated(aBuilder) || mFrame->Combines3DTransformWithAncestors();
}
+bool
+nsDisplayTransform::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsTArray<WebRenderParentCommand>& 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<LayerPixel>(LayoutDeviceRect::FromAppUnits(visibleRect, appUnitsPerDevPixel),
+ PixelCastJustification::WebRenderHasUnitResolution);
+ LayerPoint origin = bounds.TopLeft();
+
+ gfx::Matrix4x4Typed<LayerPixel, LayerPixel> boundTransform = ViewAs< gfx::Matrix4x4Typed<LayerPixel, LayerPixel> >(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<WrFilterOp> filters;
+ StackingContextHelper sc(aSc,
+ aBuilder,
+ bounds,
+ origin,
+ animationsId,
+ nullptr,
+ transformForSC,
+ filters);
+
+ aManager->CreateWebRenderCommandsFromDisplayList(mStoredList.GetChildren(),
+ aDisplayListBuilder,
+ sc,
+ aBuilder);
+
+ return true;
+}
+
already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBuilder,
LayerManager *aManager,
const ContainerLayerParameters& aContainerParameters)
{
/* For frames without transform, it would not be removed for
* backface hidden here. But, it would be removed by the init
* function of nsDisplayTransform.
*/
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -3349,17 +3349,21 @@ public:
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
-
+ virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsTArray<WebRenderParentCommand>& aParentCommands,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder) override;
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) override;
virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override;
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
float aOpacity,
@@ -4625,16 +4629,21 @@ public:
bool* aSnap) override;
virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder *aBuilder) override;
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
+ virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsTArray<WebRenderParentCommand>& aParentCommands,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder) override;
virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) override;
virtual bool ComputeVisibility(nsDisplayListBuilder *aBuilder,
nsRegion *aVisibleRegion) override;
virtual bool TryMerge(nsDisplayItem *aItem) override;
virtual uint32_t GetPerFrameKey() override { return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); }
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,