Bug 1344079 - Convert ColumnRule to WebRenderDisplayItemLayer, r=mattwoodrow

MozReview-Commit-ID: AmAVYi4P7nl

--HG--
extra : rebase_source : a2c7196cca088ed44e3c1dadd7ba599348ffbd29
This commit is contained in:
peter chang 2017-03-24 17:35:35 +08:00
parent 4e82c4bafe
commit 82b62cfc18
4 changed files with 120 additions and 62 deletions

View File

@ -497,6 +497,7 @@ private:
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());

View File

@ -8,11 +8,108 @@
#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:
*
@ -43,17 +140,11 @@ 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)
@ -82,6 +173,7 @@ nsColumnSetFrame::PaintColumnRule(nsRenderingContext* aCtx,
if (!ruleWidth)
return;
aBorderRenderers.Clear();
nscolor ruleColor =
GetVisitedDependentColor(&nsStyleColumn::mColumnRuleColor);
@ -142,13 +234,15 @@ nsColumnSetFrame::PaintColumnRule(nsRenderingContext* aCtx,
// 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();
}
@ -1128,9 +1222,8 @@ nsColumnSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
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.

View File

@ -72,10 +72,6 @@ public:
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
@ -96,6 +92,11 @@ public:
}
#endif
void CreateBorderRenderers(nsTArray<nsCSSBorderRenderer>& aBorderRenderers,
nsRenderingContext* aCtx,
const nsRect& aDirtyRect,
const nsPoint& aPt);
protected:
nscoord mLastBalanceBSize;
nsReflowStatus mLastFrameStatus;

View File

@ -2711,43 +2711,6 @@ protected:
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