Make GrStrokeInfo inherit from SkStrokeRec

Make the code more readable by inheriting GrStrokeInfo from SkStrokeRec.
This should avoid the long .getStrokeRec() and .getStrokeRecPtr(). These
were a bit cumbersome especially in cases where an alias variable was
created for these, and then the reader had to keep track to which
StrokeInfo member the StrokeRec alias was pointing.

Removes SkStrokeRec::SkStrokeRec(const SkStrokeRec&). It was memcpying.
Try to play it safe wrt compiler using the possible padding of
superclass for subclass members. Instead, let the compiler generate
the copy constructor. Assignment operator was already
compiler-generated, so at least in that way this is consistent.

Renames GrStrokeInfo::applyDash to applyDashToPath for consistency
with superclass applyToPath.

Review URL: https://codereview.chromium.org/1128113008
This commit is contained in:
kkinnunen 2015-05-18 22:23:54 -07:00 committed by Commit bot
parent 72743b1654
commit d156d36af8
12 changed files with 64 additions and 82 deletions

View File

@ -19,8 +19,6 @@ public:
kFill_InitStyle
};
SkStrokeRec(InitStyle style);
SkStrokeRec(const SkStrokeRec&);
SkStrokeRec(const SkPaint&, SkPaint::Style, SkScalar resScale = 1);
explicit SkStrokeRec(const SkPaint&, SkScalar resScale = 1);

View File

@ -20,10 +20,6 @@ SkStrokeRec::SkStrokeRec(InitStyle s) {
fStrokeAndFill = false;
}
SkStrokeRec::SkStrokeRec(const SkStrokeRec& src) {
memcpy(this, &src, sizeof(src));
}
SkStrokeRec::SkStrokeRec(const SkPaint& paint, SkScalar resScale) {
this->init(paint, paint.getStyle(), resScale);
}

View File

@ -597,7 +597,7 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target,
}
}
AADistanceFieldPathBatch::Geometry geometry(stroke.getStrokeRec());
AADistanceFieldPathBatch::Geometry geometry(stroke);
geometry.fPath = path;
geometry.fAntiAlias = antiAlias;

View File

@ -595,7 +595,7 @@ void GrContext::drawRect(GrRenderTarget* rt,
}
GR_CREATE_TRACE_MARKER("GrContext::drawRect", target);
SkScalar width = NULL == strokeInfo ? -1 : strokeInfo->getStrokeRec().getWidth();
SkScalar width = NULL == strokeInfo ? -1 : strokeInfo->getWidth();
// Check if this is a full RT draw and can be replaced with a clear. We don't bother checking
// cases where the RT is fully inside a stroke.
@ -639,14 +639,13 @@ void GrContext::drawRect(GrRenderTarget* rt,
if (doAA) {
if (width >= 0) {
const SkStrokeRec& strokeRec = strokeInfo->getStrokeRec();
fAARectRenderer->strokeAARect(target,
&pipelineBuilder,
color,
viewMatrix,
rect,
devBoundRect,
strokeRec);
*strokeInfo);
} else {
// filled AA rect
fAARectRenderer->fillAARect(target,
@ -1060,8 +1059,6 @@ void GrContext::drawRRect(GrRenderTarget*rt,
GR_CREATE_TRACE_MARKER("GrContext::drawRRect", target);
const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec();
GrColor color = paint.getColor();
if (!fOvalRenderer->drawRRect(target,
&pipelineBuilder,
@ -1069,7 +1066,7 @@ void GrContext::drawRRect(GrRenderTarget*rt,
viewMatrix,
paint.isAntiAlias(),
rrect,
strokeRec)) {
strokeInfo)) {
SkPath path;
path.addRRect(rrect);
this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(),
@ -1144,8 +1141,6 @@ void GrContext::drawOval(GrRenderTarget* rt,
GR_CREATE_TRACE_MARKER("GrContext::drawOval", target);
const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec();
GrColor color = paint.getColor();
if (!fOvalRenderer->drawOval(target,
&pipelineBuilder,
@ -1153,7 +1148,7 @@ void GrContext::drawOval(GrRenderTarget* rt,
viewMatrix,
paint.isAntiAlias(),
oval,
strokeRec)) {
strokeInfo)) {
SkPath path;
path.addOval(oval);
this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(),
@ -1245,15 +1240,14 @@ void GrContext::drawPath(GrRenderTarget* rt,
GR_CREATE_TRACE_MARKER1("GrContext::drawPath", target, "Is Convex", path.isConvex());
if (!strokeInfo.isDashed()) {
const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec();
bool useCoverageAA = paint.isAntiAlias() &&
!pipelineBuilder.getRenderTarget()->isMultisampled();
if (useCoverageAA && strokeRec.getWidth() < 0 && !path.isConvex()) {
if (useCoverageAA && strokeInfo.getWidth() < 0 && !path.isConvex()) {
// Concave AA paths are expensive - try to avoid them for special cases
SkRect rects[2];
if (is_nested_rects(target, &pipelineBuilder, color, viewMatrix, path, strokeRec,
if (is_nested_rects(target, &pipelineBuilder, color, viewMatrix, path, strokeInfo,
rects)) {
fAARectRenderer->fillAANestedRects(target, &pipelineBuilder, color, viewMatrix,
rects);
@ -1270,7 +1264,7 @@ void GrContext::drawPath(GrRenderTarget* rt,
viewMatrix,
paint.isAntiAlias(),
ovalRect,
strokeRec)) {
strokeInfo)) {
return;
}
}
@ -1315,7 +1309,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target,
GrStrokeInfo dashlessStrokeInfo(strokeInfo, false);
if (NULL == pr && strokeInfo.isDashed()) {
// It didn't work above, so try again with dashed stroke converted to a dashless stroke.
if (!strokeInfo.applyDash(tmpPath.init(), &dashlessStrokeInfo, *pathPtr)) {
if (!strokeInfo.applyDashToPath(tmpPath.init(), &dashlessStrokeInfo, *pathPtr)) {
return;
}
pathPtr = tmpPath.get();
@ -1334,16 +1328,15 @@ void GrContext::internalDrawPath(GrDrawTarget* target,
if (!tmpPath.isValid()) {
tmpPath.init();
}
SkStrokeRec* strokeRec = dashlessStrokeInfo.getStrokeRecPtr();
strokeRec->setResScale(SkScalarAbs(viewMatrix.getMaxScale()));
if (!strokeRec->applyToPath(tmpPath.get(), *pathPtr)) {
dashlessStrokeInfo.setResScale(SkScalarAbs(viewMatrix.getMaxScale()));
if (!dashlessStrokeInfo.applyToPath(tmpPath.get(), *pathPtr)) {
return;
}
pathPtr = tmpPath.get();
if (pathPtr->isEmpty()) {
return;
}
strokeRec->setFillStyle();
dashlessStrokeInfo.setFillStyle();
strokeInfoPtr = &dashlessStrokeInfo;
}

View File

@ -172,7 +172,7 @@ GrDefaultPathRenderer::onGetStencilSupport(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkPath& path,
const GrStrokeInfo& stroke) const {
if (single_pass_path(path, stroke.getStrokeRec())) {
if (single_pass_path(path, stroke)) {
return GrPathRenderer::kNoRestriction_StencilSupport;
} else {
return GrPathRenderer::kStencilOnly_StencilSupport;
@ -547,12 +547,12 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
if (IsStrokeHairlineOrEquivalent(*stroke, viewMatrix, &hairlineCoverage)) {
newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff);
if (!stroke->getStrokeRec().isHairlineStyle()) {
stroke.writable()->getStrokeRecPtr()->setHairlineStyle();
if (!stroke->isHairlineStyle()) {
stroke.writable()->setHairlineStyle();
}
}
const bool isHairline = stroke->getStrokeRec().isHairlineStyle();
const bool isHairline = stroke->isHairlineStyle();
// Save the current xp on the draw state so we can reset it if needed
SkAutoTUnref<const GrXPFactory> backupXPFactory(SkRef(pipelineBuilder->getXPFactory()));
@ -575,7 +575,7 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
lastPassIsBounds = false;
drawFace[0] = GrPipelineBuilder::kBoth_DrawFace;
} else {
if (single_pass_path(path, stroke->getStrokeRec())) {
if (single_pass_path(path, *stroke)) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;

View File

@ -160,14 +160,14 @@ public:
if (stroke.isDashed()) {
return false;
}
if (stroke.getStrokeRec().isHairlineStyle()) {
if (stroke.isHairlineStyle()) {
if (outCoverage) {
*outCoverage = SK_Scalar1;
}
return true;
}
return stroke.getStrokeRec().getStyle() == SkStrokeRec::kStroke_Style &&
SkDrawTreatAAStrokeAsHairline(stroke.getStrokeRec().getWidth(), matrix, outCoverage);
return stroke.getStyle() == SkStrokeRec::kStroke_Style &&
SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, outCoverage);
}
protected:

View File

@ -139,7 +139,7 @@ bool GrSoftwarePathRenderer::onDrawPath(GrDrawTarget* target,
}
SkAutoTUnref<GrTexture> texture(
GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke.getStrokeRec(),
GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke,
devPathBounds,
antiAlias, &viewMatrix));
if (NULL == texture) {

View File

@ -59,7 +59,7 @@ bool GrStencilAndCoverPathRenderer::canDrawPath(const GrDrawTarget* target,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) const {
return !stroke.getStrokeRec().isHairlineStyle() &&
return !stroke.isHairlineStyle() &&
!stroke.isDashed() &&
!antiAlias && // doesn't do per-path AA, relies on the target having MSAA
pipelineBuilder->getStencil().isDisabled();
@ -93,7 +93,7 @@ void GrStencilAndCoverPathRenderer::onStencilPath(GrDrawTarget* target,
const GrStrokeInfo& stroke) {
SkASSERT(!path.isInverseFillType());
SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE, viewMatrix));
SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke.getStrokeRec()));
SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke));
target->stencilPath(pipelineBuilder, pp, p, convert_skpath_filltype(path.getFillType()));
}
@ -105,11 +105,11 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
const GrStrokeInfo& stroke,
bool antiAlias) {
SkASSERT(!antiAlias);
SkASSERT(!stroke.getStrokeRec().isHairlineStyle());
SkASSERT(!stroke.isHairlineStyle());
SkASSERT(!stroke.isDashed());
SkASSERT(pipelineBuilder->getStencil().isDisabled());
SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke.getStrokeRec()));
SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke));
if (path.isInverseFillType()) {
GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass,

View File

@ -9,16 +9,16 @@
#include "SkDashPathPriv.h"
bool GrStrokeInfo::applyDash(SkPath* dst, GrStrokeInfo* dstStrokeInfo, const SkPath& src) const {
bool GrStrokeInfo::applyDashToPath(SkPath* dst, GrStrokeInfo* dstStrokeInfo,
const SkPath& src) const {
if (this->isDashed()) {
SkPathEffect::DashInfo info;
info.fIntervals = fIntervals.get();
info.fCount = fIntervals.count();
info.fPhase = fDashPhase;
SkStrokeRec strokeRec = fStroke;
if (SkDashPath::FilterDashPath(dst, src, &strokeRec, NULL, info)) {
dstStrokeInfo->fStroke = strokeRec;
dstStrokeInfo->removeDash();
GrStrokeInfo filteredStroke(*this, false);
if (SkDashPath::FilterDashPath(dst, src, &filteredStroke, NULL, info)) {
*dstStrokeInfo = filteredStroke;
return true;
}
}

View File

@ -16,12 +16,15 @@
* which holds information on fill style, width, miter, cap, and join. It also holds information
* about the dash like intervals, count, and phase.
*/
class GrStrokeInfo {
public:
GrStrokeInfo(SkStrokeRec::InitStyle style) :
fStroke(style), fDashType(SkPathEffect::kNone_DashType) {}
class GrStrokeInfo : public SkStrokeRec {
public:
GrStrokeInfo(SkStrokeRec::InitStyle style)
: INHERITED(style)
, fDashType(SkPathEffect::kNone_DashType) {
}
GrStrokeInfo(const GrStrokeInfo& src, bool includeDash = true) : fStroke(src.fStroke) {
GrStrokeInfo(const GrStrokeInfo& src, bool includeDash = true)
: INHERITED(src) {
if (includeDash && src.isDashed()) {
fDashType = src.fDashType;
fDashPhase = src.fDashPhase;
@ -32,13 +35,15 @@ public:
}
}
GrStrokeInfo(const SkPaint& paint, SkPaint::Style styleOverride) :
fStroke(paint, styleOverride), fDashType(SkPathEffect::kNone_DashType) {
GrStrokeInfo(const SkPaint& paint, SkPaint::Style styleOverride)
: INHERITED(paint, styleOverride)
, fDashType(SkPathEffect::kNone_DashType) {
this->init(paint);
}
explicit GrStrokeInfo(const SkPaint& paint) :
fStroke(paint), fDashType(SkPathEffect::kNone_DashType) {
explicit GrStrokeInfo(const SkPaint& paint)
: INHERITED(paint)
, fDashType(SkPathEffect::kNone_DashType) {
this->init(paint);
}
@ -51,23 +56,17 @@ public:
} else {
this->removeDash();
}
fStroke = other.fStroke;
this->INHERITED::operator=(other);
return *this;
}
const SkStrokeRec& getStrokeRec() const { return fStroke; }
SkStrokeRec* getStrokeRecPtr() { return &fStroke; }
void setFillStyle() { fStroke.setFillStyle(); }
/*
* This functions takes in a patheffect and updates the dashing information if the path effect
* is a Dash type. Returns true if the path effect is a dashed effect and we are stroking,
* otherwise it returns false.
*/
bool setDashInfo(const SkPathEffect* pe) {
if (pe && !fStroke.isFillStyle()) {
if (pe && !this->isFillStyle()) {
SkPathEffect::DashInfo dashInfo;
fDashType = pe->asADash(&dashInfo);
if (SkPathEffect::kDash_DashType == fDashType) {
@ -85,8 +84,7 @@ public:
* Like the above, but sets with an explicit SkPathEffect::DashInfo
*/
bool setDashInfo(const SkPathEffect::DashInfo& info) {
if (!fStroke.isFillStyle()) {
SkASSERT(!fStroke.isFillStyle());
if (!this->isFillStyle()) {
fDashType = SkPathEffect::kDash_DashType;
fDashPhase = info.fPhase;
fIntervals.reset(info.fCount);
@ -99,11 +97,9 @@ public:
}
bool isDashed() const {
return (!fStroke.isFillStyle() && SkPathEffect::kDash_DashType == fDashType);
return (!this->isFillStyle() && SkPathEffect::kDash_DashType == fDashType);
}
bool isFillStyle() const { return fStroke.isFillStyle(); }
int32_t getDashCount() const {
SkASSERT(this->isDashed());
return fIntervals.count();
@ -129,19 +125,21 @@ public:
* will be unmodified. The stroking in the SkStrokeRec might still
* be applicable.
*/
bool applyDash(SkPath* dst, GrStrokeInfo* dstStrokeInfo, const SkPath& src) const;
bool applyDashToPath(SkPath* dst, GrStrokeInfo* dstStrokeInfo, const SkPath& src) const;
private:
// Prevent accidental usage, not implemented for GrStrokeInfos.
bool hasEqualEffect(const SkStrokeRec& other) const;
void init(const SkPaint& paint) {
const SkPathEffect* pe = paint.getPathEffect();
this->setDashInfo(pe);
}
SkStrokeRec fStroke;
SkPathEffect::DashType fDashType;
SkScalar fDashPhase;
SkAutoSTArray<2, SkScalar> fIntervals;
typedef SkStrokeRec INHERITED;
};
#endif

View File

@ -517,7 +517,7 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect,
&grPaint,
fClip,
*draw.fMatrix,
strokeInfo.getStrokeRec(),
strokeInfo,
devRRect)) {
return;
}
@ -788,8 +788,7 @@ void SkGpuDevice::internalDrawPath(const SkPath& origSrcPath, const SkPaint& pai
// stroking, path effects, and blurs are supposed to be applied *after* the prePathMatrix.
// The pre-path-matrix also should not affect shading.
if (NULL == paint.getMaskFilter() && NULL == pathEffect && NULL == paint.getShader() &&
(strokeInfo.getStrokeRec().isFillStyle() ||
strokeInfo.getStrokeRec().isHairlineStyle())) {
(strokeInfo.isFillStyle() || strokeInfo.isHairlineStyle())) {
viewMatrix.preConcat(*prePathMatrix);
} else {
SkPath* result = pathPtr;
@ -814,25 +813,23 @@ void SkGpuDevice::internalDrawPath(const SkPath& origSrcPath, const SkPaint& pai
}
const SkRect* cullRect = NULL; // TODO: what is our bounds?
SkStrokeRec* strokePtr = strokeInfo.getStrokeRecPtr();
if (!strokeInfo.isDashed() && pathEffect && pathEffect->filterPath(effectPath.init(), *pathPtr,
strokePtr, cullRect)) {
&strokeInfo, cullRect)) {
pathPtr = effectPath.get();
pathIsMutable = true;
}
const SkStrokeRec& stroke = strokeInfo.getStrokeRec();
if (paint.getMaskFilter()) {
if (!stroke.isHairlineStyle()) {
if (!strokeInfo.isHairlineStyle()) {
SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init();
if (strokeInfo.isDashed()) {
if (pathEffect->filterPath(strokedPath, *pathPtr, strokePtr, cullRect)) {
if (pathEffect->filterPath(strokedPath, *pathPtr, &strokeInfo, cullRect)) {
pathPtr = strokedPath;
pathIsMutable = true;
}
strokeInfo.removeDash();
}
if (stroke.applyToPath(strokedPath, *pathPtr)) {
if (strokeInfo.applyToPath(strokedPath, *pathPtr)) {
pathPtr = strokedPath;
pathIsMutable = true;
strokeInfo.setFillStyle();
@ -865,7 +862,7 @@ void SkGpuDevice::internalDrawPath(const SkPath& origSrcPath, const SkPaint& pai
&grPaint,
fClip,
viewMatrix,
stroke,
strokeInfo,
*devPathPtr)) {
// the mask filter was able to draw itself directly, so there's nothing
// left to do.
@ -902,8 +899,8 @@ void SkGpuDevice::internalDrawPath(const SkPath& origSrcPath, const SkPaint& pai
// draw the mask on the CPU - this is a fallthrough path in case the
// GPU path fails
SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style :
SkPaint::kFill_Style;
SkPaint::Style style = strokeInfo.isHairlineStyle() ? SkPaint::kStroke_Style :
SkPaint::kFill_Style;
draw_with_mask_filter(fContext, fRenderTarget, fClip, viewMatrix, *devPathPtr,
paint.getMaskFilter(), clipBounds, &grPaint, style);
return;

View File

@ -51,7 +51,7 @@ bool GrDashingEffect::CanDrawDashLine(const SkPoint pts[2], const GrStrokeInfo&
return false;
}
SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap();
SkPaint::Cap cap = strokeInfo.getCap();
// Current we do don't handle Round or Square cap dashes
if (SkPaint::kRound_Cap == cap && intervals[0] != 0.f) {
return false;
@ -684,10 +684,10 @@ static GrBatch* create_batch(GrColor color, const SkMatrix& viewMatrix, const Sk
const SkScalar* intervals = strokeInfo.getDashIntervals();
SkScalar phase = strokeInfo.getDashPhase();
SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap();
SkPaint::Cap cap = strokeInfo.getCap();
DashBatch::Geometry geometry;
geometry.fSrcStrokeWidth = strokeInfo.getStrokeRec().getWidth();
geometry.fSrcStrokeWidth = strokeInfo.getWidth();
// the phase should be normalized to be [0, sum of all intervals)
SkASSERT(phase >= 0 && phase < intervals[0] + intervals[1]);