Bug 1344082 - Create webrender commands for nsDisplayTableBorderCollapse. r=mstange

Gecko only draw one line for each collapsed border. In order to draw
only one line border in webrender, I create normal border webrender
command but only show top side of border for inline direction and left
side for block direction.

MozReview-Commit-ID: 7QChXuzVbg7
This commit is contained in:
Morris Tseng 2017-05-12 09:39:01 +08:00
Родитель 5068b9bf11
Коммит cef7414265
4 изменённых файлов: 379 добавлений и 72 удалений

Просмотреть файл

@ -505,6 +505,7 @@ private:
DECL_GFX_PREF(Live, "layers.advanced.image-layers", LayersAllowImageLayers, bool, false);
DECL_OVERRIDE_PREF(Live, "layers.advanced.outline-layers", LayersAllowOutlineLayers, gfxPrefs::OverrideBase_WebRender());
DECL_OVERRIDE_PREF(Live, "layers.advanced.solid-color", LayersAllowSolidColorLayers, gfxPrefs::OverrideBase_WebRender());
DECL_GFX_PREF(Live, "layers.advanced.table", LayersAllowTable, 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);

Просмотреть файл

@ -27,6 +27,8 @@ UNIFIED_SOURCES += [
'SpanningCellSorter.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [

Просмотреть файл

@ -49,6 +49,10 @@
#include "nsStyleChangeList.h"
#include <algorithm>
#include "gfxPrefs.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/WebRenderDisplayItemLayer.h"
using namespace mozilla;
using namespace mozilla::image;
using namespace mozilla::layout;
@ -1270,6 +1274,16 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) override;
virtual already_AddRefed<layers::Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
virtual void CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aSc,
nsTArray<WebRenderParentCommand>& aParentCommands,
WebRenderDisplayItemLayer* aLayer) override;
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
NS_DISPLAY_DECL_NAME("TableBorderCollapse", TYPE_TABLE_BORDER_COLLAPSE)
};
@ -1292,6 +1306,39 @@ nsDisplayTableBorderCollapse::Paint(nsDisplayListBuilder* aBuilder,
static_cast<nsTableFrame*>(mFrame)->PaintBCBorders(*drawTarget, mVisibleRect - pt);
}
already_AddRefed<layers::Layer>
nsDisplayTableBorderCollapse::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters)
{
return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
}
void
nsDisplayTableBorderCollapse::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aSc,
nsTArray<WebRenderParentCommand>& aParentCommands,
WebRenderDisplayItemLayer* aLayer)
{
static_cast<nsTableFrame*>(mFrame)->CreateWebRenderCommandsForBCBorders(aBuilder,
aSc,
aParentCommands,
aLayer,
ToReferenceFrame());
}
LayerState
nsDisplayTableBorderCollapse::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters)
{
if (gfxPrefs::LayersAllowTable()) {
return LAYER_ACTIVE;
}
return LAYER_NONE;
}
/* static */ void
nsTableFrame::GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame,
const nsRect& aDirtyRect, const nsDisplayListSet& aLists)
@ -6315,6 +6362,19 @@ nsTableFrame::CalcBCBorders()
class BCPaintBorderIterator;
struct BCBorderParameters
{
uint8_t mBorderStyle;
nscolor mBorderColor;
nscolor mBGColor;
nsRect mBorderRect;
int32_t mAppUnitsPerDevPixel;
uint8_t mStartBevelSide;
nscoord mStartBevelOffset;
uint8_t mEndBevelSide;
nscoord mEndBevelOffset;
};
struct BCBlockDirSeg
{
BCBlockDirSeg();
@ -6328,10 +6388,18 @@ struct BCBlockDirSeg
void GetBEndCorner(BCPaintBorderIterator& aIter,
BCPixelSize aInlineSegBSize);
Maybe<BCBorderParameters> BuildBorderParameters(BCPaintBorderIterator& aIter,
BCPixelSize aInlineSegBSize);
void Paint(BCPaintBorderIterator& aIter,
DrawTarget& aDrawTarget,
BCPixelSize aInlineSegBSize);
void CreateWebRenderCommands(BCPaintBorderIterator& aIter,
BCPixelSize aInlineSegBSize,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
layers::WebRenderDisplayItemLayer* aLayer,
const nsPoint& aPt);
void AdvanceOffsetB();
void IncludeCurrentBorder(BCPaintBorderIterator& aIter);
@ -6380,7 +6448,14 @@ struct BCInlineDirSeg
BCPixelSize aIStartSegISize);
void AdvanceOffsetI();
void IncludeCurrentBorder(BCPaintBorderIterator& aIter);
Maybe<BCBorderParameters> BuildBorderParameters(BCPaintBorderIterator& aIter);
void Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget);
void CreateWebRenderCommands(BCPaintBorderIterator& aIter,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
layers::WebRenderDisplayItemLayer* aLayer,
const nsPoint& aPt);
nscoord mOffsetI; // i-offset with respect to the table edge
nscoord mOffsetB; // b-offset with respect to the table edge
@ -6403,6 +6478,70 @@ struct BCInlineDirSeg
// the owner of a segment
};
struct BCPaintData
{
explicit BCPaintData(DrawTarget& aDrawTarget)
: mDrawTarget(aDrawTarget)
{
}
DrawTarget& mDrawTarget;
};
struct BCCreateWebRenderCommandsData
{
BCCreateWebRenderCommandsData(wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
layers::WebRenderDisplayItemLayer* aLayer,
const nsPoint& aOffsetToReferenceFrame)
: mBuilder(aBuilder)
, mSc(aSc)
, mParentCommands(aParentCommands)
, mLayer(aLayer)
, mOffsetToReferenceFrame(aOffsetToReferenceFrame)
{
}
wr::DisplayListBuilder& mBuilder;
const layers::StackingContextHelper& mSc;
nsTArray<layers::WebRenderParentCommand>& mParentCommands;
layers::WebRenderDisplayItemLayer* mLayer;
const nsPoint& mOffsetToReferenceFrame;
};
struct BCPaintBorderAction
{
explicit BCPaintBorderAction(DrawTarget& aDrawTarget)
: mMode(Mode::PAINT)
, mPaintData(aDrawTarget)
{
}
BCPaintBorderAction(wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
layers::WebRenderDisplayItemLayer* aLayer,
const nsPoint& aOffsetToReferenceFrame)
: mMode(Mode::CREATE_WEBRENDER_COMMANDS)
, mCreateWebRenderCommandsData(aBuilder, aSc, aParentCommands, aLayer, aOffsetToReferenceFrame)
{
mMode = Mode::CREATE_WEBRENDER_COMMANDS;
}
enum class Mode {
PAINT,
CREATE_WEBRENDER_COMMANDS,
};
Mode mMode;
union {
BCPaintData mPaintData;
BCCreateWebRenderCommandsData mCreateWebRenderCommandsData;
};
};
// Iterates over borders (iStart border, corner, bStart border) in the cell map within a damage area
// from iStart to iEnd, bStart to bEnd. All members are in terms of the 1st in flow frames, except
// where suffixed by InFlow.
@ -6424,8 +6563,8 @@ public:
bool SetDamageArea(const nsRect& aDamageRect);
void First();
void Next();
void AccumulateOrPaintInlineDirSegment(DrawTarget& aDrawTarget);
void AccumulateOrPaintBlockDirSegment(DrawTarget& aDrawTarget);
void AccumulateOrDoActionInlineDirSegment(BCPaintBorderAction& aAction);
void AccumulateOrDoActionBlockDirSegment(BCPaintBorderAction& aAction);
void ResetVerInfo();
void StoreColumnWidth(int32_t aIndex);
bool BlockDirSegmentOwnsCorner();
@ -7048,31 +7187,26 @@ BCBlockDirSeg::GetBEndCorner(BCPaintBorderIterator& aIter,
mLength += mBEndOffset;
}
/**
* Paint the block-dir segment
* @param aIter - iterator containing the structural information
* @param aDrawTarget - the draw target
* @param aInlineSegBSize - the width of the inline-dir segment joining the
* corner at the start
*/
void
BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter,
DrawTarget& aDrawTarget,
Maybe<BCBorderParameters>
BCBlockDirSeg::BuildBorderParameters(BCPaintBorderIterator& aIter,
BCPixelSize aInlineSegBSize)
{
BCBorderParameters result;
// get the border style, color and paint the segment
LogicalSide side =
aIter.IsDamageAreaIEndMost() ? eLogicalSideIEnd : eLogicalSideIStart;
int32_t relColIndex = aIter.GetRelativeColIndex();
nsTableColFrame* col = mCol; if (!col) ABORT0();
nsTableColFrame* col = mCol; if (!col) ABORT1(Nothing());
nsTableCellFrame* cell = mFirstCell; // ???
nsIFrame* owner = nullptr;
uint8_t style = NS_STYLE_BORDER_STYLE_SOLID;
nscolor color = 0xFFFFFFFF;
result.mBorderStyle = NS_STYLE_BORDER_STYLE_SOLID;
result.mBorderColor = 0xFFFFFFFF;
result.mBGColor = aIter.mTableBgColor;
// All the tables frames have the same presContext, so we just use any one
// that exists here:
int32_t appUnitsPerDevPixel = col->PresContext()->AppUnitsPerDevPixel();
result.mAppUnitsPerDevPixel = col->PresContext()->AppUnitsPerDevPixel();
switch (mOwner) {
case eTableOwner:
@ -7123,7 +7257,7 @@ BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter,
break;
}
if (owner) {
::GetPaintStyleInfo(owner, aIter.mTableWM, side, &style, &color);
::GetPaintStyleInfo(owner, aIter.mTableWM, side, &result.mBorderStyle, &result.mBorderColor);
}
BCPixelSize smallHalf, largeHalf;
DivideBCBorderSize(mWidth, smallHalf, largeHalf);
@ -7138,17 +7272,16 @@ BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter,
// Convert logical to physical sides/coordinates for DrawTableBorderSegment.
nsRect physicalRect = segRect.GetPhysicalRect(aIter.mTableWM,
aIter.mTable->GetSize());
result.mBorderRect = segRect.GetPhysicalRect(aIter.mTableWM, aIter.mTable->GetSize());
// XXX For reversed vertical writing-modes (with direction:rtl), we need to
// invert physicalRect's y-position here, with respect to the table.
// However, it's not worth fixing the border positions here until the
// ordering of the table columns themselves is also fixed (bug 1180528).
uint8_t startBevelSide = aIter.mTableWM.PhysicalSide(mBStartBevelSide);
uint8_t endBevelSide = aIter.mTableWM.PhysicalSide(bEndBevelSide);
nscoord startBevelOffset = mBStartBevelOffset;
nscoord endBevelOffset = bEndBevelOffset;
result.mStartBevelSide = aIter.mTableWM.PhysicalSide(mBStartBevelSide);
result.mEndBevelSide = aIter.mTableWM.PhysicalSide(bEndBevelSide);
result.mStartBevelOffset = mBStartBevelOffset;
result.mEndBevelOffset = bEndBevelOffset;
// In vertical-rl mode, the 'start' and 'end' of the block-dir (horizontal)
// border segment need to be swapped because DrawTableBorderSegment will
// apply the 'start' bevel at the left edge, and 'end' at the right.
@ -7160,15 +7293,78 @@ BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter,
// end of the border-segment. We've got them reversed, since our block dir
// is RTL, so we have to swap them here.)
if (aIter.mTableWM.IsVerticalRL()) {
Swap(startBevelSide, endBevelSide);
Swap(startBevelOffset, endBevelOffset);
Swap(result.mStartBevelSide, result.mEndBevelSide);
Swap(result.mStartBevelOffset, result.mEndBevelOffset);
}
nsCSSRendering::DrawTableBorderSegment(aDrawTarget, style, color,
aIter.mTableBgColor, physicalRect,
appUnitsPerDevPixel,
return Some(result);
}
/**
* Paint the block-dir segment
* @param aIter - iterator containing the structural information
* @param aDrawTarget - the draw target
* @param aInlineSegBSize - the width of the inline-dir segment joining the
* corner at the start
*/
void
BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter,
DrawTarget& aDrawTarget,
BCPixelSize aInlineSegBSize)
{
Maybe<BCBorderParameters> param = BuildBorderParameters(aIter, aInlineSegBSize);
if (param.isNothing()) {
return;
}
nsCSSRendering::DrawTableBorderSegment(aDrawTarget, param->mBorderStyle, param->mBorderColor,
param->mBGColor, param->mBorderRect,
param->mAppUnitsPerDevPixel,
nsPresContext::AppUnitsPerCSSPixel(),
startBevelSide, startBevelOffset,
endBevelSide, endBevelOffset);
param->mStartBevelSide, param->mStartBevelOffset,
param->mEndBevelSide, param->mEndBevelOffset);
}
void
BCBlockDirSeg::CreateWebRenderCommands(BCPaintBorderIterator& aIter,
BCPixelSize aInlineSegBSize,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
layers::WebRenderDisplayItemLayer* aLayer,
const nsPoint& aOffset)
{
Maybe<BCBorderParameters> param = BuildBorderParameters(aIter, aInlineSegBSize);
if (param.isNothing()) {
return;
}
//TODO: Currently, we don't support border with m{Start,End}Bevel{Side,Offset} attributes.
LayoutDeviceRect borderRect = LayoutDeviceRect::FromUnknownRect(NSRectToRect(param->mBorderRect + aOffset,
param->mAppUnitsPerDevPixel));
WrRect transformedRect = aSc.ToRelativeWrRect(borderRect);
WrBorderSide wrSide[4];
NS_FOR_CSS_SIDES(i) {
wrSide[i] = wr::ToWrBorderSide(ToDeviceColor(param->mBorderColor), NS_STYLE_BORDER_STYLE_NONE);
}
wrSide[eSideLeft] = wr::ToWrBorderSide(ToDeviceColor(param->mBorderColor), param->mBorderStyle);
WrBorderRadius borderRadii = wr::ToWrBorderRadius( {0, 0}, {0, 0}, {0, 0}, {0, 0} );
// All border style is set to none except left side. So setting the widths of
// each side to width of rect is fine.
WrBorderWidths borderWidths = wr::ToWrBorderWidths(transformedRect.width,
transformedRect.width,
transformedRect.width,
transformedRect.width);
WrClipRegionToken clipRegion = aBuilder.PushClipRegion(transformedRect);
transformedRect.width *= 2.0f;
aBuilder.PushBorder(transformedRect,
clipRegion,
borderWidths,
wrSide[0], wrSide[1], wrSide[2], wrSide[3],
borderRadii);
}
/**
@ -7263,29 +7459,27 @@ BCInlineDirSeg::GetIEndCorner(BCPaintBorderIterator& aIter,
mIEndBevelSide = (aIStartSegISize > 0) ? eLogicalSideBEnd : eLogicalSideBStart;
}
/**
* Paint the inline-dir segment
* @param aIter - iterator containing the structural information
* @param aDrawTarget - the draw target
*/
void
BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget)
Maybe<BCBorderParameters>
BCInlineDirSeg::BuildBorderParameters(BCPaintBorderIterator& aIter)
{
BCBorderParameters result;
// get the border style, color and paint the segment
LogicalSide side =
aIter.IsDamageAreaBEndMost() ? eLogicalSideBEnd : eLogicalSideBStart;
nsIFrame* rg = aIter.mRg; if (!rg) ABORT0();
nsIFrame* row = aIter.mRow; if (!row) ABORT0();
nsIFrame* rg = aIter.mRg; if (!rg) ABORT1(Nothing());
nsIFrame* row = aIter.mRow; if (!row) ABORT1(Nothing());
nsIFrame* cell = mFirstCell;
nsIFrame* col;
nsIFrame* owner = nullptr;
// All the tables frames have the same presContext, so we just use any one
// that exists here:
int32_t appUnitsPerDevPixel = row->PresContext()->AppUnitsPerDevPixel();
result.mAppUnitsPerDevPixel = row->PresContext()->AppUnitsPerDevPixel();
uint8_t style = NS_STYLE_BORDER_STYLE_SOLID;
nscolor color = 0xFFFFFFFF;
result.mBorderStyle = NS_STYLE_BORDER_STYLE_SOLID;
result.mBorderColor = 0xFFFFFFFF;
result.mBGColor = aIter.mTableBgColor;
switch (mOwner) {
case eTableOwner:
@ -7298,7 +7492,7 @@ BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget)
NS_ASSERTION(aIter.IsTableBStartMost() || aIter.IsTableBEndMost(),
"col group can own border only at the table edge");
col = aIter.mTableFirstInFlow->GetColFrame(aIter.mColIndex - 1);
if (!col) ABORT0();
if (!col) ABORT1(Nothing());
owner = col->GetParent();
break;
case eAjaColOwner:
@ -7334,7 +7528,7 @@ BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget)
break;
}
if (owner) {
::GetPaintStyleInfo(owner, aIter.mTableWM, side, &style, &color);
::GetPaintStyleInfo(owner, aIter.mTableWM, side, &result.mBorderStyle, &result.mBorderColor);
}
BCPixelSize smallHalf, largeHalf;
DivideBCBorderSize(mWidth, smallHalf, largeHalf);
@ -7344,13 +7538,12 @@ BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget)
nsPresContext::CSSPixelsToAppUnits(mWidth));
// Convert logical to physical sides/coordinates for DrawTableBorderSegment.
nsRect physicalRect = segRect.GetPhysicalRect(aIter.mTableWM,
aIter.mTable->GetSize());
uint8_t startBevelSide = aIter.mTableWM.PhysicalSide(mIStartBevelSide);
uint8_t endBevelSide = aIter.mTableWM.PhysicalSide(mIEndBevelSide);
nscoord startBevelOffset =
result.mBorderRect = segRect.GetPhysicalRect(aIter.mTableWM, aIter.mTable->GetSize());
result.mStartBevelSide = aIter.mTableWM.PhysicalSide(mIStartBevelSide);
result.mEndBevelSide = aIter.mTableWM.PhysicalSide(mIEndBevelSide);
result.mStartBevelOffset =
nsPresContext::CSSPixelsToAppUnits(mIStartBevelOffset);
nscoord endBevelOffset = mIEndBevelOffset;
result.mEndBevelOffset = mIEndBevelOffset;
// With inline-RTL directionality, the 'start' and 'end' of the inline-dir
// border segment need to be swapped because DrawTableBorderSegment will
// apply the 'start' bevel physically at the left or top edge, and 'end' at
@ -7364,15 +7557,73 @@ BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget)
// "end" will be reversed from this physical-coord view, so we have to swap
// them here.
if (!aIter.mTableWM.IsBidiLTR()) {
Swap(startBevelSide, endBevelSide);
Swap(startBevelOffset, endBevelOffset);
Swap(result.mStartBevelSide, result.mEndBevelSide);
Swap(result.mStartBevelOffset, result.mEndBevelOffset);
}
nsCSSRendering::DrawTableBorderSegment(aDrawTarget, style, color,
aIter.mTableBgColor, physicalRect,
appUnitsPerDevPixel,
return Some(result);
}
/**
* Paint the inline-dir segment
* @param aIter - iterator containing the structural information
* @param aDrawTarget - the draw target
*/
void
BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget)
{
Maybe<BCBorderParameters> param = BuildBorderParameters(aIter);
if (param.isNothing()) {
return;
}
nsCSSRendering::DrawTableBorderSegment(aDrawTarget, param->mBorderStyle, param->mBorderColor,
param->mBGColor, param->mBorderRect,
param->mAppUnitsPerDevPixel,
nsPresContext::AppUnitsPerCSSPixel(),
startBevelSide, startBevelOffset,
endBevelSide, endBevelOffset);
param->mStartBevelSide, param->mStartBevelOffset,
param->mEndBevelSide, param->mEndBevelOffset);
}
void
BCInlineDirSeg::CreateWebRenderCommands(BCPaintBorderIterator& aIter,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
layers::WebRenderDisplayItemLayer* aLayer,
const nsPoint& aPt)
{
Maybe<BCBorderParameters> param = BuildBorderParameters(aIter);
if (param.isNothing()) {
return;
}
//TODO: Currently, we don't support border with m{Start,End}Bevel{Side,Offset} attributes.
LayoutDeviceRect borderRect = LayoutDeviceRect::FromUnknownRect(NSRectToRect(param->mBorderRect + aPt,
param->mAppUnitsPerDevPixel));
WrRect transformedRect = aSc.ToRelativeWrRect(borderRect);
WrBorderSide wrSide[4];
NS_FOR_CSS_SIDES(i) {
wrSide[i] = wr::ToWrBorderSide(ToDeviceColor(param->mBorderColor), NS_STYLE_BORDER_STYLE_NONE);
}
wrSide[eSideTop] = wr::ToWrBorderSide(ToDeviceColor(param->mBorderColor), param->mBorderStyle);
WrBorderRadius borderRadii = wr::ToWrBorderRadius( {0, 0}, {0, 0}, {0, 0}, {0, 0} );
// All border style is set to none except top side. So setting the widths of
// each side to height of rect is fine.
WrBorderWidths borderWidths = wr::ToWrBorderWidths(transformedRect.height,
transformedRect.height,
transformedRect.height,
transformedRect.height);
WrClipRegionToken clipRegion = aBuilder.PushClipRegion(transformedRect);
transformedRect.height *= 2.0f;
aBuilder.PushBorder(transformedRect,
clipRegion,
borderWidths,
wrSide[0], wrSide[1], wrSide[2], wrSide[3],
borderRadii);
}
/**
@ -7429,7 +7680,7 @@ BCPaintBorderIterator::BlockDirSegmentOwnsCorner()
* @param aDrawTarget - the draw target
*/
void
BCPaintBorderIterator::AccumulateOrPaintInlineDirSegment(DrawTarget& aDrawTarget)
BCPaintBorderIterator::AccumulateOrDoActionInlineDirSegment(BCPaintBorderAction& aAction)
{
int32_t relColIndex = GetRelativeColIndex();
@ -7462,7 +7713,17 @@ BCPaintBorderIterator::AccumulateOrPaintInlineDirSegment(DrawTarget& aDrawTarget
if (mInlineSeg.mLength > 0) {
mInlineSeg.GetIEndCorner(*this, iStartSegISize);
if (mInlineSeg.mWidth > 0) {
mInlineSeg.Paint(*this, aDrawTarget);
if (aAction.mMode == BCPaintBorderAction::Mode::PAINT) {
mInlineSeg.Paint(*this, aAction.mPaintData.mDrawTarget);
} else {
MOZ_ASSERT(aAction.mMode == BCPaintBorderAction::Mode::CREATE_WEBRENDER_COMMANDS);
mInlineSeg.CreateWebRenderCommands(*this,
aAction.mCreateWebRenderCommandsData.mBuilder,
aAction.mCreateWebRenderCommandsData.mSc,
aAction.mCreateWebRenderCommandsData.mParentCommands,
aAction.mCreateWebRenderCommandsData.mLayer,
aAction.mCreateWebRenderCommandsData.mOffsetToReferenceFrame);
}
}
mInlineSeg.AdvanceOffsetI();
}
@ -7472,12 +7733,13 @@ BCPaintBorderIterator::AccumulateOrPaintInlineDirSegment(DrawTarget& aDrawTarget
mBlockDirInfo[relColIndex].mWidth = iStartSegISize;
mBlockDirInfo[relColIndex].mLastCell = mCell;
}
/**
* Paint if necessary a block-dir segment, otherwise accumulate it
* @param aDrawTarget - the draw target
*/
void
BCPaintBorderIterator::AccumulateOrPaintBlockDirSegment(DrawTarget& aDrawTarget)
BCPaintBorderIterator::AccumulateOrDoActionBlockDirSegment(BCPaintBorderAction& aAction)
{
BCBorderOwner borderOwner = eCellOwner;
BCBorderOwner ignoreBorderOwner;
@ -7504,7 +7766,18 @@ BCPaintBorderIterator::AccumulateOrPaintBlockDirSegment(DrawTarget& aDrawTarget)
if (blockDirSeg.mLength > 0) {
blockDirSeg.GetBEndCorner(*this, inlineSegBSize);
if (blockDirSeg.mWidth > 0) {
blockDirSeg.Paint(*this, aDrawTarget, inlineSegBSize);
if (aAction.mMode == BCPaintBorderAction::Mode::PAINT) {
blockDirSeg.Paint(*this, aAction.mPaintData.mDrawTarget, inlineSegBSize);
} else {
MOZ_ASSERT(aAction.mMode == BCPaintBorderAction::Mode::CREATE_WEBRENDER_COMMANDS);
blockDirSeg.CreateWebRenderCommands(*this,
inlineSegBSize,
aAction.mCreateWebRenderCommandsData.mBuilder,
aAction.mCreateWebRenderCommandsData.mSc,
aAction.mCreateWebRenderCommandsData.mParentCommands,
aAction.mCreateWebRenderCommandsData.mLayer,
aAction.mCreateWebRenderCommandsData.mOffsetToReferenceFrame);
}
}
blockDirSeg.AdvanceOffsetB();
}
@ -7529,14 +7802,8 @@ BCPaintBorderIterator::ResetVerInfo()
}
}
/**
* Method to paint BCBorders, this does not use currently display lists although
* it will do this in future
* @param aDrawTarget - the rendering context
* @param aDirtyRect - inside this rectangle the BC Borders will redrawn
*/
void
nsTableFrame::PaintBCBorders(DrawTarget& aDrawTarget, const nsRect& aDirtyRect)
nsTableFrame::IterateBCBorders(BCPaintBorderAction& aAction, const nsRect& aDirtyRect)
{
// We first transfer the aDirtyRect into cellmap coordinates to compute which
// cell borders need to be painted
@ -7555,7 +7822,7 @@ nsTableFrame::PaintBCBorders(DrawTarget& aDrawTarget, const nsRect& aDirtyRect)
// this we the now active segment with the current border. These
// segments are stored in mBlockDirInfo to be used on the next row
for (iter.First(); !iter.mAtEnd; iter.Next()) {
iter.AccumulateOrPaintBlockDirSegment(aDrawTarget);
iter.AccumulateOrDoActionBlockDirSegment(aAction);
}
// Next, paint all of the inline-dir border segments from bStart to bEnd reuse
@ -7563,10 +7830,36 @@ nsTableFrame::PaintBCBorders(DrawTarget& aDrawTarget, const nsRect& aDirtyRect)
// corner calculations
iter.Reset();
for (iter.First(); !iter.mAtEnd; iter.Next()) {
iter.AccumulateOrPaintInlineDirSegment(aDrawTarget);
iter.AccumulateOrDoActionInlineDirSegment(aAction);
}
}
/**
* Method to paint BCBorders, this does not use currently display lists although
* it will do this in future
* @param aDrawTarget - the rendering context
* @param aDirtyRect - inside this rectangle the BC Borders will redrawn
*/
void
nsTableFrame::PaintBCBorders(DrawTarget& aDrawTarget, const nsRect& aDirtyRect)
{
BCPaintBorderAction action(aDrawTarget);
IterateBCBorders(action, aDirtyRect);
}
void
nsTableFrame::CreateWebRenderCommandsForBCBorders(wr::DisplayListBuilder& aBuilder,
const mozilla::layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
layers::WebRenderDisplayItemLayer* aLayer,
const nsPoint& aOffsetToReferenceFrame)
{
BCPaintBorderAction action(aBuilder, aSc, aParentCommands, aLayer, aOffsetToReferenceFrame);
// We always draw whole table border for webrender. Passing the table rect as
// dirty rect.
IterateBCBorders(action, GetRect());
}
bool
nsTableFrame::RowHasSpanningCells(int32_t aRowIndex, int32_t aNumEffCols)
{

Просмотреть файл

@ -17,6 +17,7 @@
#include "nsDisplayList.h"
#include "TableArea.h"
struct BCPaintBorderAction;
class nsTableCellFrame;
class nsTableCellMap;
class nsTableColFrame;
@ -29,6 +30,9 @@ namespace mozilla {
class WritingMode;
class LogicalMargin;
struct TableReflowInput;
namespace layers {
class StackingContextHelper;
}
} // namespace mozilla
struct BCPropertyData;
@ -302,6 +306,11 @@ public:
bool BCRecalcNeeded(nsStyleContext* aOldStyleContext,
nsStyleContext* aNewStyleContext);
void PaintBCBorders(DrawTarget& aDrawTarget, const nsRect& aDirtyRect);
void CreateWebRenderCommandsForBCBorders(mozilla::wr::DisplayListBuilder& aBuilder,
const mozilla::layers::StackingContextHelper& aSc,
nsTArray<mozilla::layers::WebRenderParentCommand>& aParentCommands,
mozilla::layers::WebRenderDisplayItemLayer* aLayer,
const nsPoint& aPt);
virtual void MarkIntrinsicISizesDirty() override;
// For border-collapse tables, the caller must not add padding and
@ -604,6 +613,8 @@ protected:
virtual LogicalSides GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override;
void IterateBCBorders(BCPaintBorderAction& aAction, const nsRect& aDirtyRect);
public:
bool IsRowInserted() const;
void SetRowInserted(bool aValue);