Bug 1344079 - Convert ColumnRule to WebRenderDisplayItemLayer, r?mattwoodrow
MozReview-Commit-ID: AmAVYi4P7nl
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -492,16 +492,17 @@ private:
DECL_OVERRIDE_PREF(Live, "layers.advanced.background-image", LayersAllowBackgroundImage, false);
DECL_OVERRIDE_PREF(Live, "layers.advanced.border-layers", LayersAllowBorderLayers, false);
DECL_OVERRIDE_PREF(Live, "layers.advanced.boxshadow-inset-layers", LayersAllowInsetBoxShadow, gfxPrefs::OverrideBase_WebRender());
DECL_OVERRIDE_PREF(Live, "layers.advanced.boxshadow-outer-layers", LayersAllowOuterBoxShadow, gfxPrefs::OverrideBase_WebRender());
DECL_GFX_PREF(Live, "layers.advanced.bullet-layers", LayersAllowBulletLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.button-foreground-layers", LayersAllowButtonForegroundLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.canvas-background-color", LayersAllowCanvasBackgroundColorLayers, bool, false);
DECL_OVERRIDE_PREF(Live, "layers.advanced.caret-layers", LayersAllowCaretLayers, gfxPrefs::OverrideBase_WebRender());
+ DECL_GFX_PREF(Live, "layers.advanced.columnRule-layers", LayersAllowColumnRuleLayers, bool, false);
DECL_OVERRIDE_PREF(Live, "layers.advanced.displaybuttonborder-layers", LayersAllowDisplayButtonBorder, gfxPrefs::OverrideBase_WebRender());
DECL_GFX_PREF(Live, "layers.advanced.image-layers", LayersAllowImageLayers, bool, false);
DECL_OVERRIDE_PREF(Live, "layers.advanced.outline-layers", LayersAllowOutlineLayers, gfxPrefs::OverrideBase_WebRender());
DECL_GFX_PREF(Live, "layers.advanced.solid-color", LayersAllowSolidColorLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.text-layers", LayersAllowTextLayers, bool, false);
DECL_GFX_PREF(Once, "layers.amd-switchable-gfx.enabled", LayersAMDSwitchableGfxEnabled, bool, false);
DECL_GFX_PREF(Once, "layers.async-pan-zoom.enabled", AsyncPanZoomEnabledDoNotUseDirectly, bool, true);
DECL_GFX_PREF(Once, "layers.async-pan-zoom.separate-event-thread", AsyncPanZoomSeparateEventThread, bool, false);
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -3,21 +3,118 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* rendering object for css3 multi-column layout */
#include "mozilla/Unused.h"
#include "nsColumnSetFrame.h"
#include "nsCSSRendering.h"
-#include "nsDisplayList.h"
using namespace mozilla;
using namespace mozilla::layout;
+
+class nsDisplayColumnRule : public nsDisplayItem {
+public:
+ nsDisplayColumnRule(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
+ : nsDisplayItem(aBuilder, aFrame)
+ {
+ MOZ_COUNT_CTOR(nsDisplayColumnRule);
+ }
+#ifdef NS_BUILD_REFCNT_LOGGING
+ virtual ~nsDisplayColumnRule() {
+ MOZ_COUNT_DTOR(nsDisplayColumnRule);
+ mBorderRenderers.Clear();
+ }
+#endif
+
+ /**
+ * Returns the frame's visual overflow rect instead of the frame's bounds.
+ */
+ virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
+ bool* aSnap) override
+ {
+ *aSnap = false;
+ return Frame()->GetVisualOverflowRect() + ToReferenceFrame();
+ }
+
+ 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 void CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ nsTArray<WebRenderParentCommand>& aParentCommands,
+ mozilla::layers::WebRenderDisplayItemLayer* aLayer) override;
+ virtual void Paint(nsDisplayListBuilder* aBuilder,
+ nsRenderingContext* aCtx) override;
+
+ NS_DISPLAY_DECL_NAME("ColumnRule", nsDisplayItem::TYPE_COLUMN_RULE);
+
+private:
+ nsTArray<nsCSSBorderRenderer> mBorderRenderers;
+};
+
+void
+nsDisplayColumnRule::Paint(nsDisplayListBuilder* aBuilder,
+ nsRenderingContext* aCtx)
+{
+ static_cast<nsColumnSetFrame*>(mFrame)->
+ CreateBorderRenderers(mBorderRenderers, aCtx, mVisibleRect, ToReferenceFrame());
+
+ for (auto iter = mBorderRenderers.begin(); iter != mBorderRenderers.end(); iter++) {
+ iter->DrawBorders();
+ }
+
+
+}
+LayerState
+nsDisplayColumnRule::GetLayerState(nsDisplayListBuilder* aBuilder,
+ LayerManager* aManager,
+ const ContainerLayerParameters& aParameters)
+{
+ if (!gfxPrefs::LayersAllowColumnRuleLayers()) {
+ return LAYER_NONE;
+ }
+
+ RefPtr<gfxContext> screenRefCtx =
+ gfxContext::CreateOrNull(gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget());
+ nsRenderingContext ctx(screenRefCtx);
+
+ static_cast<nsColumnSetFrame*>(mFrame)->
+ CreateBorderRenderers(mBorderRenderers, &ctx, mVisibleRect, ToReferenceFrame());
+
+ if (mBorderRenderers.IsEmpty()) {
+ return LAYER_NONE;
+ }
+
+ return LAYER_ACTIVE;
+}
+
+already_AddRefed<Layer>
+nsDisplayColumnRule::BuildLayer(nsDisplayListBuilder* aBuilder,
+ LayerManager* aManager,
+ const ContainerLayerParameters& aContainerParameters)
+{
+ return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
+}
+
+void
+nsDisplayColumnRule::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
+ nsTArray<WebRenderParentCommand>& aParentCommands,
+ WebRenderDisplayItemLayer* aLayer)
+{
+ MOZ_ASSERT(!mBorderRenderers.IsEmpty());
+ for (auto iter = mBorderRenderers.begin(); iter != mBorderRenderers.end(); iter++) {
+ iter->CreateWebRenderCommands(aBuilder, aLayer);
+ }
+}
+
/**
* Tracking issues:
*
* XXX cursor movement around the top and bottom of colums seems to make the editor
* lose the caret.
*
* XXX should we support CSS columns applied to table elements?
*/
@@ -38,27 +135,21 @@ nsColumnSetFrame::nsColumnSetFrame(nsSty
}
nsIAtom*
nsColumnSetFrame::GetType() const
{
return nsGkAtoms::columnSetFrame;
}
-static void
-PaintColumnRule(nsIFrame* aFrame, nsRenderingContext* aCtx,
- const nsRect& aDirtyRect, nsPoint aPt)
-{
- static_cast<nsColumnSetFrame*>(aFrame)->PaintColumnRule(aCtx, aDirtyRect, aPt);
-}
-
void
-nsColumnSetFrame::PaintColumnRule(nsRenderingContext* aCtx,
- const nsRect& aDirtyRect,
- const nsPoint& aPt)
+nsColumnSetFrame::CreateBorderRenderers(nsTArray<nsCSSBorderRenderer>& aBorderRenderers,
+ nsRenderingContext* aCtx,
+ const nsRect& aDirtyRect,
+ const nsPoint& aPt)
{
nsIFrame* child = mFrames.FirstChild();
if (!child)
return; // no columns
nsIFrame* nextSibling = child->GetNextSibling();
if (!nextSibling)
return; // 1 column only - this means no gap to draw on
@@ -77,16 +168,17 @@ nsColumnSetFrame::PaintColumnRule(nsRend
else
ruleStyle = colStyle->mColumnRuleStyle;
nsPresContext* presContext = PresContext();
nscoord ruleWidth = colStyle->GetComputedColumnRuleWidth();
if (!ruleWidth)
return;
+ aBorderRenderers.Clear();
nscolor ruleColor =
GetVisitedDependentColor(&nsStyleColumn::mColumnRuleColor);
// In order to re-use a large amount of code, we treat the column rule as a border.
// We create a new border style object and fill in all the details of the column rule as
// the left border. PaintBorder() does all the rendering for us, so we not
// only save an enormous amount of code but we'll support all the line styles that
// we support on borders!
@@ -137,23 +229,25 @@ nsColumnSetFrame::PaintColumnRule(nsRend
}
nsRect lineRect(linePt, ruleSize);
// Assert that we're not drawing a border-image here; if we were, we
// couldn't ignore the DrawResult that PaintBorderWithStyleBorder returns.
MOZ_ASSERT(border.mBorderImageSource.GetType() == eStyleImageType_Null);
- Unused <<
- nsCSSRendering::PaintBorderWithStyleBorder(presContext, *aCtx, this,
- aDirtyRect, lineRect, border,
- StyleContext(),
- PaintBorderFlags::SYNC_DECODE_IMAGES,
- skipSides);
-
+ gfx::DrawTarget* dt = aCtx ? aCtx->GetDrawTarget() : nullptr;
+ Maybe<nsCSSBorderRenderer> br =
+ nsCSSRendering::CreateBorderRendererWithStyleBorder(presContext, dt,
+ this, aDirtyRect,
+ lineRect, border,
+ StyleContext(), skipSides);
+ if (br.isSome()) {
+ aBorderRenderers.AppendElement(br.value());
+ }
child = nextSibling;
nextSibling = nextSibling->GetNextSibling();
}
}
static nscoord
GetAvailableContentISize(const ReflowInput& aReflowInput)
{
@@ -1123,19 +1217,18 @@ nsColumnSetFrame::Reflow(nsPresContext*
void
nsColumnSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists)
{
DisplayBorderBackgroundOutline(aBuilder, aLists);
if (IsVisibleForPainting(aBuilder)) {
- aLists.BorderBackground()->AppendNewToTop(new (aBuilder)
- nsDisplayGenericOverflow(aBuilder, this, ::PaintColumnRule, "ColumnRule",
- nsDisplayItem::TYPE_COLUMN_RULE));
+ aLists.BorderBackground()->
+ AppendNewToTop(new (aBuilder)nsDisplayColumnRule(aBuilder, this));
}
// Our children won't have backgrounds so it doesn't matter where we put them.
for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) {
BuildDisplayListForChild(aBuilder, e.get(), aDirtyRect, aLists);
}
}
--- a/layout/generic/nsColumnSetFrame.h
+++ b/layout/generic/nsColumnSetFrame.h
@@ -67,20 +67,16 @@ public:
}
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists) override;
virtual nsIAtom* GetType() const override;
- virtual void PaintColumnRule(nsRenderingContext* aCtx,
- const nsRect& aDirtyRect,
- const nsPoint& aPt);
-
/**
* Similar to nsBlockFrame::DrainOverflowLines. Locate any columns not
* handled by our prev-in-flow, and any columns sitting on our own
* overflow list, and put them in our primary child list for reflowing.
*/
void DrainOverflowColumns();
/**
@@ -91,16 +87,21 @@ public:
nsChangeHint aHintForThisFrame) override;
#ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override {
return MakeFrameName(NS_LITERAL_STRING("ColumnSet"), aResult);
}
#endif
+ void CreateBorderRenderers(nsTArray<nsCSSBorderRenderer>& aBorderRenderers,
+ nsRenderingContext* aCtx,
+ const nsRect& aDirtyRect,
+ const nsPoint& aPt);
+
protected:
nscoord mLastBalanceBSize;
nsReflowStatus mLastFrameStatus;
/**
* These are the parameters that control the layout of columns.
*/
struct ReflowConfig {
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -2706,53 +2706,16 @@ public:
protected:
PaintCallback mPaint;
OldPaintCallback mOldPaint; // XXX: should be removed eventually
const char* mName;
Type mType;
};
-/**
- * Generic display item that can contain overflow. Use this in lieu of
- * nsDisplayGeneric if you have a frame that should use the visual overflow
- * rect of its frame when drawing items, instead of the frame's bounds.
- */
-class nsDisplayGenericOverflow : public nsDisplayGeneric {
- public:
- nsDisplayGenericOverflow(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
- PaintCallback aPaint, const char* aName, Type aType)
- : nsDisplayGeneric(aBuilder, aFrame, aPaint, aName, aType)
- {
- MOZ_COUNT_CTOR(nsDisplayGenericOverflow);
- }
- // XXX: should be removed eventually
- nsDisplayGenericOverflow(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
- OldPaintCallback aOldPaint, const char* aName, Type aType)
- : nsDisplayGeneric(aBuilder, aFrame, aOldPaint, aName, aType)
- {
- MOZ_COUNT_CTOR(nsDisplayGenericOverflow);
- }
- #ifdef NS_BUILD_REFCNT_LOGGING
- virtual ~nsDisplayGenericOverflow() {
- MOZ_COUNT_DTOR(nsDisplayGenericOverflow);
- }
- #endif
-
- /**
- * Returns the frame's visual overflow rect instead of the frame's bounds.
- */
- virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
- bool* aSnap) override
- {
- *aSnap = false;
- return Frame()->GetVisualOverflowRect() + ToReferenceFrame();
- }
-};
-
#if defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF)
/**
* This class implements painting of reflow counts. Ideally, we would simply
* make all the frame names be those returned by nsFrame::GetFrameName
* (except that tosses in the content tag name!) and support only one color
* and eliminate this class altogether in favor of nsDisplayGeneric, but for
* the time being we can't pass args to a PaintCallback, so just have a
* separate class to do the right thing. Sadly, this alsmo means we need to