Move StrokeRectBatches into .cpp files
BUG=skia: Review URL: https://codereview.chromium.org/1353683003
This commit is contained in:
parent
966e3d30ba
commit
3566d44d85
@ -226,10 +226,10 @@
|
|||||||
'<(skia_src_path)/gpu/batches/GrDrawVerticesBatch.h',
|
'<(skia_src_path)/gpu/batches/GrDrawVerticesBatch.h',
|
||||||
'<(skia_src_path)/gpu/batches/GrNonAAFillRectBatch.h',
|
'<(skia_src_path)/gpu/batches/GrNonAAFillRectBatch.h',
|
||||||
'<(skia_src_path)/gpu/batches/GrNonAAFillRectBatch.cpp',
|
'<(skia_src_path)/gpu/batches/GrNonAAFillRectBatch.cpp',
|
||||||
|
'<(skia_src_path)/gpu/batches/GrNonAAStrokeRectBatch.cpp',
|
||||||
|
'<(skia_src_path)/gpu/batches/GrNonAAStrokeRectBatch.h',
|
||||||
'<(skia_src_path)/gpu/batches/GrRectBatchFactory.h',
|
'<(skia_src_path)/gpu/batches/GrRectBatchFactory.h',
|
||||||
'<(skia_src_path)/gpu/batches/GrRectBatchFactory.cpp',
|
'<(skia_src_path)/gpu/batches/GrRectBatchFactory.cpp',
|
||||||
'<(skia_src_path)/gpu/batches/GrStrokeRectBatch.cpp',
|
|
||||||
'<(skia_src_path)/gpu/batches/GrStrokeRectBatch.h',
|
|
||||||
'<(skia_src_path)/gpu/batches/GrStencilAndCoverPathRenderer.cpp',
|
'<(skia_src_path)/gpu/batches/GrStencilAndCoverPathRenderer.cpp',
|
||||||
'<(skia_src_path)/gpu/batches/GrStencilAndCoverPathRenderer.h',
|
'<(skia_src_path)/gpu/batches/GrStencilAndCoverPathRenderer.h',
|
||||||
'<(skia_src_path)/gpu/batches/GrStencilPathBatch.h',
|
'<(skia_src_path)/gpu/batches/GrStencilPathBatch.h',
|
||||||
|
@ -23,7 +23,7 @@ DRAW_BATCH_TEST_EXTERN(CircleBatch);
|
|||||||
DRAW_BATCH_TEST_EXTERN(DIEllipseBatch);
|
DRAW_BATCH_TEST_EXTERN(DIEllipseBatch);
|
||||||
DRAW_BATCH_TEST_EXTERN(EllipseBatch);
|
DRAW_BATCH_TEST_EXTERN(EllipseBatch);
|
||||||
DRAW_BATCH_TEST_EXTERN(GrDrawAtlasBatch);
|
DRAW_BATCH_TEST_EXTERN(GrDrawAtlasBatch);
|
||||||
DRAW_BATCH_TEST_EXTERN(GrStrokeRectBatch);
|
DRAW_BATCH_TEST_EXTERN(NonAAStrokeRectBatch);
|
||||||
DRAW_BATCH_TEST_EXTERN(RRectBatch);
|
DRAW_BATCH_TEST_EXTERN(RRectBatch);
|
||||||
DRAW_BATCH_TEST_EXTERN(TesselatingPathBatch);
|
DRAW_BATCH_TEST_EXTERN(TesselatingPathBatch);
|
||||||
DRAW_BATCH_TEST_EXTERN(TextBlobBatch);
|
DRAW_BATCH_TEST_EXTERN(TextBlobBatch);
|
||||||
@ -42,7 +42,7 @@ static BatchTestFunc gTestBatches[] = {
|
|||||||
DRAW_BATCH_TEST_ENTRY(DIEllipseBatch),
|
DRAW_BATCH_TEST_ENTRY(DIEllipseBatch),
|
||||||
DRAW_BATCH_TEST_ENTRY(EllipseBatch),
|
DRAW_BATCH_TEST_ENTRY(EllipseBatch),
|
||||||
DRAW_BATCH_TEST_ENTRY(GrDrawAtlasBatch),
|
DRAW_BATCH_TEST_ENTRY(GrDrawAtlasBatch),
|
||||||
DRAW_BATCH_TEST_ENTRY(GrStrokeRectBatch),
|
DRAW_BATCH_TEST_ENTRY(NonAAStrokeRectBatch),
|
||||||
DRAW_BATCH_TEST_ENTRY(RRectBatch),
|
DRAW_BATCH_TEST_ENTRY(RRectBatch),
|
||||||
DRAW_BATCH_TEST_ENTRY(TesselatingPathBatch),
|
DRAW_BATCH_TEST_ENTRY(TesselatingPathBatch),
|
||||||
DRAW_BATCH_TEST_ENTRY(TextBlobBatch),
|
DRAW_BATCH_TEST_ENTRY(TextBlobBatch),
|
||||||
|
@ -43,7 +43,111 @@ static const GrGeometryProcessor* create_stroke_rect_gp(bool tweakAlphaForCovera
|
|||||||
return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix);
|
return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrAAStrokeRectBatch::initBatchTracker(const GrPipelineOptimizations& opt) {
|
class AAStrokeRectBatch : public GrVertexBatch {
|
||||||
|
public:
|
||||||
|
DEFINE_BATCH_CLASS_ID
|
||||||
|
|
||||||
|
// TODO support AA rotated stroke rects by copying around view matrices
|
||||||
|
struct Geometry {
|
||||||
|
SkRect fDevOutside;
|
||||||
|
SkRect fDevOutsideAssist;
|
||||||
|
SkRect fDevInside;
|
||||||
|
GrColor fColor;
|
||||||
|
bool fMiterStroke;
|
||||||
|
};
|
||||||
|
|
||||||
|
static GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& devOutside,
|
||||||
|
const SkRect& devOutsideAssist, const SkRect& devInside,
|
||||||
|
bool miterStroke) {
|
||||||
|
return new AAStrokeRectBatch(color, viewMatrix, devOutside, devOutsideAssist, devInside,
|
||||||
|
miterStroke);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* name() const override { return "AAStrokeRect"; }
|
||||||
|
|
||||||
|
void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
|
||||||
|
// When this is called on a batch, there is only one geometry bundle
|
||||||
|
out->setKnownFourComponents(fGeoData[0].fColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
|
||||||
|
out->setUnknownSingleComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onPrepareDraws(Target*) override;
|
||||||
|
void initBatchTracker(const GrPipelineOptimizations&) override;
|
||||||
|
|
||||||
|
AAStrokeRectBatch(GrColor color, const SkMatrix& viewMatrix, const SkRect& devOutside,
|
||||||
|
const SkRect& devOutsideAssist, const SkRect& devInside, bool miterStroke)
|
||||||
|
: INHERITED(ClassID()) {
|
||||||
|
fBatch.fViewMatrix = viewMatrix;
|
||||||
|
Geometry& geometry = fGeoData.push_back();
|
||||||
|
geometry.fColor = color;
|
||||||
|
geometry.fDevOutside = devOutside;
|
||||||
|
geometry.fDevOutsideAssist = devOutsideAssist;
|
||||||
|
geometry.fDevInside = devInside;
|
||||||
|
geometry.fMiterStroke = miterStroke;
|
||||||
|
|
||||||
|
// If we have miterstroke then we inset devOutside and outset devOutsideAssist, so we need
|
||||||
|
// the join for proper bounds
|
||||||
|
fBounds = geometry.fDevOutside;
|
||||||
|
fBounds.join(geometry.fDevOutsideAssist);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const int kMiterIndexCnt = 3 * 24;
|
||||||
|
static const int kMiterVertexCnt = 16;
|
||||||
|
static const int kNumMiterRectsInIndexBuffer = 256;
|
||||||
|
|
||||||
|
static const int kBevelIndexCnt = 48 + 36 + 24;
|
||||||
|
static const int kBevelVertexCnt = 24;
|
||||||
|
static const int kNumBevelRectsInIndexBuffer = 256;
|
||||||
|
|
||||||
|
static const GrIndexBuffer* GetIndexBuffer(GrResourceProvider* resourceProvider,
|
||||||
|
bool miterStroke);
|
||||||
|
|
||||||
|
GrColor color() const { return fBatch.fColor; }
|
||||||
|
bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
|
||||||
|
bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCoverage; }
|
||||||
|
bool colorIgnored() const { return fBatch.fColorIgnored; }
|
||||||
|
const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; }
|
||||||
|
bool miterStroke() const { return fBatch.fMiterStroke; }
|
||||||
|
bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
|
||||||
|
|
||||||
|
bool onCombineIfPossible(GrBatch* t, const GrCaps&) override;
|
||||||
|
|
||||||
|
void generateAAStrokeRectGeometry(void* vertices,
|
||||||
|
size_t offset,
|
||||||
|
size_t vertexStride,
|
||||||
|
int outerVertexNum,
|
||||||
|
int innerVertexNum,
|
||||||
|
GrColor color,
|
||||||
|
const SkRect& devOutside,
|
||||||
|
const SkRect& devOutsideAssist,
|
||||||
|
const SkRect& devInside,
|
||||||
|
bool miterStroke,
|
||||||
|
bool tweakAlphaForCoverage) const;
|
||||||
|
|
||||||
|
struct BatchTracker {
|
||||||
|
SkMatrix fViewMatrix;
|
||||||
|
GrColor fColor;
|
||||||
|
bool fUsesLocalCoords;
|
||||||
|
bool fColorIgnored;
|
||||||
|
bool fCoverageIgnored;
|
||||||
|
bool fMiterStroke;
|
||||||
|
bool fCanTweakAlphaForCoverage;
|
||||||
|
};
|
||||||
|
|
||||||
|
BatchTracker fBatch;
|
||||||
|
SkSTArray<1, Geometry, true> fGeoData;
|
||||||
|
|
||||||
|
typedef GrVertexBatch INHERITED;
|
||||||
|
};
|
||||||
|
|
||||||
|
void AAStrokeRectBatch::initBatchTracker(const GrPipelineOptimizations& opt) {
|
||||||
// Handle any color overrides
|
// Handle any color overrides
|
||||||
if (!opt.readsColor()) {
|
if (!opt.readsColor()) {
|
||||||
fGeoData[0].fColor = GrColor_ILLEGAL;
|
fGeoData[0].fColor = GrColor_ILLEGAL;
|
||||||
@ -59,7 +163,7 @@ void GrAAStrokeRectBatch::initBatchTracker(const GrPipelineOptimizations& opt) {
|
|||||||
fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage();
|
fBatch.fCanTweakAlphaForCoverage = opt.canTweakAlphaForCoverage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrAAStrokeRectBatch::onPrepareDraws(Target* target) {
|
void AAStrokeRectBatch::onPrepareDraws(Target* target) {
|
||||||
bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage();
|
bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage();
|
||||||
|
|
||||||
SkAutoTUnref<const GrGeometryProcessor> gp(create_stroke_rect_gp(canTweakAlphaForCoverage,
|
SkAutoTUnref<const GrGeometryProcessor> gp(create_stroke_rect_gp(canTweakAlphaForCoverage,
|
||||||
@ -112,8 +216,8 @@ void GrAAStrokeRectBatch::onPrepareDraws(Target* target) {
|
|||||||
helper.recordDraw(target);
|
helper.recordDraw(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrIndexBuffer* GrAAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* resourceProvider,
|
const GrIndexBuffer* AAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* resourceProvider,
|
||||||
bool miterStroke) {
|
bool miterStroke) {
|
||||||
|
|
||||||
if (miterStroke) {
|
if (miterStroke) {
|
||||||
static const uint16_t gMiterIndices[] = {
|
static const uint16_t gMiterIndices[] = {
|
||||||
@ -203,8 +307,8 @@ const GrIndexBuffer* GrAAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* res
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GrAAStrokeRectBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) {
|
bool AAStrokeRectBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) {
|
||||||
GrAAStrokeRectBatch* that = t->cast<GrAAStrokeRectBatch>();
|
AAStrokeRectBatch* that = t->cast<AAStrokeRectBatch>();
|
||||||
|
|
||||||
if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
|
if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
|
||||||
that->bounds(), caps)) {
|
that->bounds(), caps)) {
|
||||||
@ -237,17 +341,17 @@ bool GrAAStrokeRectBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrAAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices,
|
void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices,
|
||||||
size_t offset,
|
size_t offset,
|
||||||
size_t vertexStride,
|
size_t vertexStride,
|
||||||
int outerVertexNum,
|
int outerVertexNum,
|
||||||
int innerVertexNum,
|
int innerVertexNum,
|
||||||
GrColor color,
|
GrColor color,
|
||||||
const SkRect& devOutside,
|
const SkRect& devOutside,
|
||||||
const SkRect& devOutsideAssist,
|
const SkRect& devOutsideAssist,
|
||||||
const SkRect& devInside,
|
const SkRect& devInside,
|
||||||
bool miterStroke,
|
bool miterStroke,
|
||||||
bool tweakAlphaForCoverage) const {
|
bool tweakAlphaForCoverage) const {
|
||||||
intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset;
|
intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset;
|
||||||
|
|
||||||
// We create vertices for four nested rectangles. There are two ramps from 0 to full
|
// We create vertices for four nested rectangles. There are two ramps from 0 to full
|
||||||
@ -350,6 +454,20 @@ void GrAAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace GrAAStrokeRectBatch {
|
||||||
|
|
||||||
|
GrDrawBatch* Create(GrColor color,
|
||||||
|
const SkMatrix& viewMatrix,
|
||||||
|
const SkRect& devOutside,
|
||||||
|
const SkRect& devOutsideAssist,
|
||||||
|
const SkRect& devInside,
|
||||||
|
bool miterStroke) {
|
||||||
|
return AAStrokeRectBatch::Create(color, viewMatrix, devOutside, devOutsideAssist, devInside,
|
||||||
|
miterStroke);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifdef GR_TEST_UTILS
|
#ifdef GR_TEST_UTILS
|
||||||
@ -368,14 +486,10 @@ DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) {
|
|||||||
SkRect inside = outside;
|
SkRect inside = outside;
|
||||||
inside.inset(strokeWidth, strokeWidth);
|
inside.inset(strokeWidth, strokeWidth);
|
||||||
|
|
||||||
GrAAStrokeRectBatch::Geometry geo;
|
GrColor color = GrRandomColor(random);
|
||||||
geo.fColor = GrRandomColor(random);
|
|
||||||
geo.fDevOutside = outside;
|
|
||||||
geo.fDevOutsideAssist = outsideAssist;
|
|
||||||
geo.fDevInside = inside;
|
|
||||||
geo.fMiterStroke = miterStroke;
|
|
||||||
|
|
||||||
return GrAAStrokeRectBatch::Create(geo, GrTest::TestMatrix(random));
|
return GrAAStrokeRectBatch::Create(color, GrTest::TestMatrix(random), outside, outsideAssist,
|
||||||
|
inside, miterStroke);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,107 +9,21 @@
|
|||||||
#define GrAAStrokeRectBatch_DEFINED
|
#define GrAAStrokeRectBatch_DEFINED
|
||||||
|
|
||||||
#include "GrColor.h"
|
#include "GrColor.h"
|
||||||
#include "GrTypes.h"
|
|
||||||
#include "GrVertexBatch.h"
|
|
||||||
#include "SkMatrix.h"
|
|
||||||
#include "SkRect.h"
|
|
||||||
|
|
||||||
|
class GrDrawBatch;
|
||||||
class GrResourceProvider;
|
class GrResourceProvider;
|
||||||
|
class SkMatrix;
|
||||||
|
struct SkRect;
|
||||||
|
|
||||||
class GrAAStrokeRectBatch : public GrVertexBatch {
|
namespace GrAAStrokeRectBatch {
|
||||||
public:
|
|
||||||
DEFINE_BATCH_CLASS_ID
|
|
||||||
|
|
||||||
// TODO support AA rotated stroke rects by copying around view matrices
|
GrDrawBatch* Create(GrColor color,
|
||||||
struct Geometry {
|
const SkMatrix& viewMatrix,
|
||||||
GrColor fColor;
|
const SkRect& devOutside,
|
||||||
SkRect fDevOutside;
|
const SkRect& devOutsideAssist,
|
||||||
SkRect fDevOutsideAssist;
|
const SkRect& devInside,
|
||||||
SkRect fDevInside;
|
bool miterStroke);
|
||||||
bool fMiterStroke;
|
|
||||||
};
|
|
||||||
|
|
||||||
static GrDrawBatch* Create(const Geometry& geometry, const SkMatrix& viewMatrix) {
|
|
||||||
return new GrAAStrokeRectBatch(geometry, viewMatrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* name() const override { return "AAStrokeRect"; }
|
|
||||||
|
|
||||||
void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
|
|
||||||
// When this is called on a batch, there is only one geometry bundle
|
|
||||||
out->setKnownFourComponents(fGeoData[0].fColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
|
|
||||||
out->setUnknownSingleComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
void onPrepareDraws(Target*) override;
|
|
||||||
void initBatchTracker(const GrPipelineOptimizations&) override;
|
|
||||||
|
|
||||||
GrAAStrokeRectBatch(const Geometry& geometry, const SkMatrix& viewMatrix)
|
|
||||||
: INHERITED(ClassID()) {
|
|
||||||
fBatch.fViewMatrix = viewMatrix;
|
|
||||||
fGeoData.push_back(geometry);
|
|
||||||
|
|
||||||
// If we have miterstroke then we inset devOutside and outset devOutsideAssist, so we need
|
|
||||||
// the join for proper bounds
|
|
||||||
fBounds = geometry.fDevOutside;
|
|
||||||
fBounds.join(geometry.fDevOutsideAssist);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static const int kMiterIndexCnt = 3 * 24;
|
|
||||||
static const int kMiterVertexCnt = 16;
|
|
||||||
static const int kNumMiterRectsInIndexBuffer = 256;
|
|
||||||
|
|
||||||
static const int kBevelIndexCnt = 48 + 36 + 24;
|
|
||||||
static const int kBevelVertexCnt = 24;
|
|
||||||
static const int kNumBevelRectsInIndexBuffer = 256;
|
|
||||||
|
|
||||||
static const GrIndexBuffer* GetIndexBuffer(GrResourceProvider* resourceProvider,
|
|
||||||
bool miterStroke);
|
|
||||||
|
|
||||||
GrColor color() const { return fBatch.fColor; }
|
|
||||||
bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
|
|
||||||
bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCoverage; }
|
|
||||||
bool colorIgnored() const { return fBatch.fColorIgnored; }
|
|
||||||
const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; }
|
|
||||||
bool miterStroke() const { return fBatch.fMiterStroke; }
|
|
||||||
bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
|
|
||||||
|
|
||||||
bool onCombineIfPossible(GrBatch* t, const GrCaps&) override;
|
|
||||||
|
|
||||||
void generateAAStrokeRectGeometry(void* vertices,
|
|
||||||
size_t offset,
|
|
||||||
size_t vertexStride,
|
|
||||||
int outerVertexNum,
|
|
||||||
int innerVertexNum,
|
|
||||||
GrColor color,
|
|
||||||
const SkRect& devOutside,
|
|
||||||
const SkRect& devOutsideAssist,
|
|
||||||
const SkRect& devInside,
|
|
||||||
bool miterStroke,
|
|
||||||
bool tweakAlphaForCoverage) const;
|
|
||||||
|
|
||||||
struct BatchTracker {
|
|
||||||
SkMatrix fViewMatrix;
|
|
||||||
GrColor fColor;
|
|
||||||
bool fUsesLocalCoords;
|
|
||||||
bool fColorIgnored;
|
|
||||||
bool fCoverageIgnored;
|
|
||||||
bool fMiterStroke;
|
|
||||||
bool fCanTweakAlphaForCoverage;
|
|
||||||
};
|
|
||||||
|
|
||||||
BatchTracker fBatch;
|
|
||||||
SkSTArray<1, Geometry, true> fGeoData;
|
|
||||||
|
|
||||||
typedef GrVertexBatch INHERITED;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -188,54 +188,59 @@ typedef GrTInstanceBatch<NonAAFillRectBatchImp> NonAAFillRectBatchSimple;
|
|||||||
typedef GrTInstanceBatch<NonAAFillRectBatchPerspectiveImp> NonAAFillRectBatchPerspective;
|
typedef GrTInstanceBatch<NonAAFillRectBatchPerspectiveImp> NonAAFillRectBatchPerspective;
|
||||||
|
|
||||||
namespace GrNonAAFillRectBatch {
|
namespace GrNonAAFillRectBatch {
|
||||||
|
|
||||||
GrDrawBatch* Create(GrColor color,
|
GrDrawBatch* Create(GrColor color,
|
||||||
const SkMatrix& viewMatrix,
|
const SkMatrix& viewMatrix,
|
||||||
const SkRect& rect,
|
const SkRect& rect,
|
||||||
const SkRect* localRect,
|
const SkRect* localRect,
|
||||||
const SkMatrix* localMatrix) {
|
const SkMatrix* localMatrix) {
|
||||||
|
SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective()));
|
||||||
|
NonAAFillRectBatchSimple* batch = NonAAFillRectBatchSimple::Create();
|
||||||
|
NonAAFillRectBatchSimple::Geometry& geo = *batch->geometry();
|
||||||
|
|
||||||
/* Perspective has to be handled in a slow path for now */
|
geo.fColor = color;
|
||||||
if (viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective())) {
|
geo.fViewMatrix = viewMatrix;
|
||||||
NonAAFillRectBatchPerspective* batch = NonAAFillRectBatchPerspective::Create();
|
geo.fRect = rect;
|
||||||
NonAAFillRectBatchPerspective::Geometry& geo = *batch->geometry();
|
|
||||||
|
|
||||||
geo.fColor = color;
|
if (localRect && localMatrix) {
|
||||||
geo.fViewMatrix = viewMatrix;
|
geo.fLocalQuad.setFromMappedRect(*localRect, *localMatrix);
|
||||||
geo.fRect = rect;
|
} else if (localRect) {
|
||||||
geo.fHasLocalRect = SkToBool(localRect);
|
geo.fLocalQuad.set(*localRect);
|
||||||
geo.fHasLocalMatrix = SkToBool(localMatrix);
|
} else if (localMatrix) {
|
||||||
if (localMatrix) {
|
geo.fLocalQuad.setFromMappedRect(rect, *localMatrix);
|
||||||
geo.fLocalMatrix = *localMatrix;
|
|
||||||
}
|
|
||||||
if (localRect) {
|
|
||||||
geo.fLocalRect = *localRect;
|
|
||||||
}
|
|
||||||
|
|
||||||
batch->init();
|
|
||||||
return batch;
|
|
||||||
} else {
|
} else {
|
||||||
// TODO bubble these up as separate calls
|
geo.fLocalQuad.set(rect);
|
||||||
NonAAFillRectBatchSimple* batch = NonAAFillRectBatchSimple::Create();
|
|
||||||
NonAAFillRectBatchSimple::Geometry& geo = *batch->geometry();
|
|
||||||
|
|
||||||
geo.fColor = color;
|
|
||||||
geo.fViewMatrix = viewMatrix;
|
|
||||||
geo.fRect = rect;
|
|
||||||
|
|
||||||
if (localRect && localMatrix) {
|
|
||||||
geo.fLocalQuad.setFromMappedRect(*localRect, *localMatrix);
|
|
||||||
} else if (localRect) {
|
|
||||||
geo.fLocalQuad.set(*localRect);
|
|
||||||
} else if (localMatrix) {
|
|
||||||
geo.fLocalQuad.setFromMappedRect(rect, *localMatrix);
|
|
||||||
} else {
|
|
||||||
geo.fLocalQuad.set(rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
batch->init();
|
|
||||||
return batch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
batch->init();
|
||||||
|
return batch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GrDrawBatch* CreateWithPerspective(GrColor color,
|
||||||
|
const SkMatrix& viewMatrix,
|
||||||
|
const SkRect& rect,
|
||||||
|
const SkRect* localRect,
|
||||||
|
const SkMatrix* localMatrix) {
|
||||||
|
SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective()));
|
||||||
|
NonAAFillRectBatchPerspective* batch = NonAAFillRectBatchPerspective::Create();
|
||||||
|
NonAAFillRectBatchPerspective::Geometry& geo = *batch->geometry();
|
||||||
|
|
||||||
|
geo.fColor = color;
|
||||||
|
geo.fViewMatrix = viewMatrix;
|
||||||
|
geo.fRect = rect;
|
||||||
|
geo.fHasLocalRect = SkToBool(localRect);
|
||||||
|
geo.fHasLocalMatrix = SkToBool(localMatrix);
|
||||||
|
if (localMatrix) {
|
||||||
|
geo.fLocalMatrix = *localMatrix;
|
||||||
|
}
|
||||||
|
if (localRect) {
|
||||||
|
geo.fLocalRect = *localRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
batch->init();
|
||||||
|
return batch;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -15,11 +15,19 @@ class SkMatrix;
|
|||||||
struct SkRect;
|
struct SkRect;
|
||||||
|
|
||||||
namespace GrNonAAFillRectBatch {
|
namespace GrNonAAFillRectBatch {
|
||||||
|
|
||||||
GrDrawBatch* Create(GrColor color,
|
GrDrawBatch* Create(GrColor color,
|
||||||
const SkMatrix& viewMatrix,
|
const SkMatrix& viewMatrix,
|
||||||
const SkRect& rect,
|
const SkRect& rect,
|
||||||
const SkRect* localRect,
|
const SkRect* localRect,
|
||||||
const SkMatrix* localMatrix);
|
const SkMatrix* localMatrix);
|
||||||
|
|
||||||
|
GrDrawBatch* CreateWithPerspective(GrColor color,
|
||||||
|
const SkMatrix& viewMatrix,
|
||||||
|
const SkRect& rect,
|
||||||
|
const SkRect* localRect,
|
||||||
|
const SkMatrix* localMatrix);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
226
src/gpu/batches/GrNonAAStrokeRectBatch.cpp
Normal file
226
src/gpu/batches/GrNonAAStrokeRectBatch.cpp
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "GrNonAAStrokeRectBatch.h"
|
||||||
|
|
||||||
|
#include "GrBatchTest.h"
|
||||||
|
#include "GrBatchFlushState.h"
|
||||||
|
#include "GrColor.h"
|
||||||
|
#include "GrDefaultGeoProcFactory.h"
|
||||||
|
#include "GrVertexBatch.h"
|
||||||
|
#include "SkRandom.h"
|
||||||
|
|
||||||
|
/* create a triangle strip that strokes the specified rect. There are 8
|
||||||
|
unique vertices, but we repeat the last 2 to close up. Alternatively we
|
||||||
|
could use an indices array, and then only send 8 verts, but not sure that
|
||||||
|
would be faster.
|
||||||
|
*/
|
||||||
|
static void init_stroke_rect_strip(SkPoint verts[10], const SkRect& rect, SkScalar width) {
|
||||||
|
const SkScalar rad = SkScalarHalf(width);
|
||||||
|
// TODO we should be able to enable this assert, but we'd have to filter these draws
|
||||||
|
// this is a bug
|
||||||
|
//SkASSERT(rad < rect.width() / 2 && rad < rect.height() / 2);
|
||||||
|
|
||||||
|
verts[0].set(rect.fLeft + rad, rect.fTop + rad);
|
||||||
|
verts[1].set(rect.fLeft - rad, rect.fTop - rad);
|
||||||
|
verts[2].set(rect.fRight - rad, rect.fTop + rad);
|
||||||
|
verts[3].set(rect.fRight + rad, rect.fTop - rad);
|
||||||
|
verts[4].set(rect.fRight - rad, rect.fBottom - rad);
|
||||||
|
verts[5].set(rect.fRight + rad, rect.fBottom + rad);
|
||||||
|
verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
|
||||||
|
verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
|
||||||
|
verts[8] = verts[0];
|
||||||
|
verts[9] = verts[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
class NonAAStrokeRectBatch : public GrVertexBatch {
|
||||||
|
public:
|
||||||
|
DEFINE_BATCH_CLASS_ID
|
||||||
|
|
||||||
|
struct Geometry {
|
||||||
|
SkMatrix fViewMatrix;
|
||||||
|
SkRect fRect;
|
||||||
|
SkScalar fStrokeWidth;
|
||||||
|
GrColor fColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
static GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect,
|
||||||
|
SkScalar strokeWidth, bool snapToPixelCenters) {
|
||||||
|
return new NonAAStrokeRectBatch(color, viewMatrix, rect, strokeWidth, snapToPixelCenters);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* name() const override { return "GrStrokeRectBatch"; }
|
||||||
|
|
||||||
|
void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
|
||||||
|
// When this is called on a batch, there is only one geometry bundle
|
||||||
|
out->setKnownFourComponents(fGeoData[0].fColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
|
||||||
|
out->setKnownSingleComponent(0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onPrepareDraws(Target* target) override {
|
||||||
|
SkAutoTUnref<const GrGeometryProcessor> gp;
|
||||||
|
{
|
||||||
|
using namespace GrDefaultGeoProcFactory;
|
||||||
|
Color color(this->color());
|
||||||
|
Coverage coverage(this->coverageIgnored() ? Coverage::kSolid_Type :
|
||||||
|
Coverage::kNone_Type);
|
||||||
|
LocalCoords localCoords(this->usesLocalCoords() ? LocalCoords::kUsePosition_Type :
|
||||||
|
LocalCoords::kUnused_Type);
|
||||||
|
gp.reset(GrDefaultGeoProcFactory::Create(color, coverage, localCoords,
|
||||||
|
this->viewMatrix()));
|
||||||
|
}
|
||||||
|
|
||||||
|
target->initDraw(gp, this->pipeline());
|
||||||
|
|
||||||
|
size_t vertexStride = gp->getVertexStride();
|
||||||
|
|
||||||
|
SkASSERT(vertexStride == sizeof(GrDefaultGeoProcFactory::PositionAttr));
|
||||||
|
|
||||||
|
Geometry& args = fGeoData[0];
|
||||||
|
|
||||||
|
int vertexCount = kVertsPerHairlineRect;
|
||||||
|
if (args.fStrokeWidth > 0) {
|
||||||
|
vertexCount = kVertsPerStrokeRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GrVertexBuffer* vertexBuffer;
|
||||||
|
int firstVertex;
|
||||||
|
|
||||||
|
void* verts = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer,
|
||||||
|
&firstVertex);
|
||||||
|
|
||||||
|
if (!verts) {
|
||||||
|
SkDebugf("Could not allocate vertices\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkPoint* vertex = reinterpret_cast<SkPoint*>(verts);
|
||||||
|
|
||||||
|
GrPrimitiveType primType;
|
||||||
|
|
||||||
|
if (args.fStrokeWidth > 0) {;
|
||||||
|
primType = kTriangleStrip_GrPrimitiveType;
|
||||||
|
args.fRect.sort();
|
||||||
|
init_stroke_rect_strip(vertex, args.fRect, args.fStrokeWidth);
|
||||||
|
} else {
|
||||||
|
// hairline
|
||||||
|
primType = kLineStrip_GrPrimitiveType;
|
||||||
|
vertex[0].set(args.fRect.fLeft, args.fRect.fTop);
|
||||||
|
vertex[1].set(args.fRect.fRight, args.fRect.fTop);
|
||||||
|
vertex[2].set(args.fRect.fRight, args.fRect.fBottom);
|
||||||
|
vertex[3].set(args.fRect.fLeft, args.fRect.fBottom);
|
||||||
|
vertex[4].set(args.fRect.fLeft, args.fRect.fTop);
|
||||||
|
}
|
||||||
|
|
||||||
|
GrVertices vertices;
|
||||||
|
vertices.init(primType, vertexBuffer, firstVertex, vertexCount);
|
||||||
|
target->draw(vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initBatchTracker(const GrPipelineOptimizations& opt) override {
|
||||||
|
// Handle any color overrides
|
||||||
|
if (!opt.readsColor()) {
|
||||||
|
fGeoData[0].fColor = GrColor_ILLEGAL;
|
||||||
|
}
|
||||||
|
opt.getOverrideColorIfSet(&fGeoData[0].fColor);
|
||||||
|
|
||||||
|
// setup batch properties
|
||||||
|
fBatch.fColorIgnored = !opt.readsColor();
|
||||||
|
fBatch.fColor = fGeoData[0].fColor;
|
||||||
|
fBatch.fUsesLocalCoords = opt.readsLocalCoords();
|
||||||
|
fBatch.fCoverageIgnored = !opt.readsCoverage();
|
||||||
|
}
|
||||||
|
|
||||||
|
NonAAStrokeRectBatch(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect,
|
||||||
|
SkScalar strokeWidth, bool snapToPixelCenters)
|
||||||
|
: INHERITED(ClassID()) {
|
||||||
|
Geometry& geometry = fGeoData.push_back();
|
||||||
|
geometry.fViewMatrix = viewMatrix;
|
||||||
|
geometry.fRect = rect;
|
||||||
|
geometry.fStrokeWidth = strokeWidth;
|
||||||
|
geometry.fColor = color;
|
||||||
|
|
||||||
|
fBatch.fHairline = geometry.fStrokeWidth == 0;
|
||||||
|
|
||||||
|
fGeoData.push_back(geometry);
|
||||||
|
|
||||||
|
// setup bounds
|
||||||
|
fBounds = geometry.fRect;
|
||||||
|
SkScalar rad = SkScalarHalf(geometry.fStrokeWidth);
|
||||||
|
fBounds.outset(rad, rad);
|
||||||
|
geometry.fViewMatrix.mapRect(&fBounds);
|
||||||
|
|
||||||
|
// If our caller snaps to pixel centers then we have to round out the bounds
|
||||||
|
if (snapToPixelCenters) {
|
||||||
|
fBounds.roundOut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GrColor color() const { return fBatch.fColor; }
|
||||||
|
bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
|
||||||
|
bool colorIgnored() const { return fBatch.fColorIgnored; }
|
||||||
|
const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
|
||||||
|
bool hairline() const { return fBatch.fHairline; }
|
||||||
|
bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
|
||||||
|
|
||||||
|
bool onCombineIfPossible(GrBatch* t, const GrCaps&) override {
|
||||||
|
// if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *t->pipeline(),
|
||||||
|
// t->bounds(), caps)) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// GrStrokeRectBatch* that = t->cast<StrokeRectBatch>();
|
||||||
|
|
||||||
|
// NonAA stroke rects cannot batch right now
|
||||||
|
// TODO make these batchable
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BatchTracker {
|
||||||
|
GrColor fColor;
|
||||||
|
bool fUsesLocalCoords;
|
||||||
|
bool fColorIgnored;
|
||||||
|
bool fCoverageIgnored;
|
||||||
|
bool fHairline;
|
||||||
|
};
|
||||||
|
|
||||||
|
const static int kVertsPerHairlineRect = 5;
|
||||||
|
const static int kVertsPerStrokeRect = 10;
|
||||||
|
|
||||||
|
BatchTracker fBatch;
|
||||||
|
SkSTArray<1, Geometry, true> fGeoData;
|
||||||
|
|
||||||
|
typedef GrVertexBatch INHERITED;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace GrNonAAStrokeRectBatch {
|
||||||
|
|
||||||
|
GrDrawBatch* Create(GrColor color,
|
||||||
|
const SkMatrix& viewMatrix,
|
||||||
|
const SkRect& rect,
|
||||||
|
SkScalar strokeWidth,
|
||||||
|
bool snapToPixelCenters) {
|
||||||
|
return NonAAStrokeRectBatch::Create(color, viewMatrix, rect, strokeWidth, snapToPixelCenters);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef GR_TEST_UTILS
|
||||||
|
|
||||||
|
DRAW_BATCH_TEST_DEFINE(NonAAStrokeRectBatch) {
|
||||||
|
SkMatrix viewMatrix = GrTest::TestMatrix(random);
|
||||||
|
GrColor color = GrRandomColor(random);
|
||||||
|
SkRect rect = GrTest::TestRect(random);
|
||||||
|
SkScalar strokeWidth = random->nextBool() ? 0.0f : 1.0f;
|
||||||
|
|
||||||
|
return NonAAStrokeRectBatch::Create(color, viewMatrix, rect, strokeWidth, random->nextBool());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
29
src/gpu/batches/GrNonAAStrokeRectBatch.h
Normal file
29
src/gpu/batches/GrNonAAStrokeRectBatch.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GrNonAAStrokeRectBatch_DEFINED
|
||||||
|
#define GrNonAAStrokeRectBatch_DEFINED
|
||||||
|
|
||||||
|
#include "GrColor.h"
|
||||||
|
|
||||||
|
#include "SkTypes.h"
|
||||||
|
|
||||||
|
class GrDrawBatch;
|
||||||
|
struct SkRect;
|
||||||
|
class SkMatrix;
|
||||||
|
|
||||||
|
namespace GrNonAAStrokeRectBatch {
|
||||||
|
|
||||||
|
GrDrawBatch* Create(GrColor color,
|
||||||
|
const SkMatrix& viewMatrix,
|
||||||
|
const SkRect& rect,
|
||||||
|
SkScalar strokeWidth,
|
||||||
|
bool snapToPixelCenters);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -8,41 +8,11 @@
|
|||||||
#include "GrRectBatchFactory.h"
|
#include "GrRectBatchFactory.h"
|
||||||
|
|
||||||
#include "GrAAStrokeRectBatch.h"
|
#include "GrAAStrokeRectBatch.h"
|
||||||
#include "GrStrokeRectBatch.h"
|
|
||||||
|
|
||||||
#include "SkStrokeRec.h"
|
#include "SkStrokeRec.h"
|
||||||
|
|
||||||
static GrDrawBatch* create_stroke_aa_batch(GrColor color,
|
|
||||||
const SkMatrix& viewMatrix,
|
|
||||||
const SkRect& devOutside,
|
|
||||||
const SkRect& devOutsideAssist,
|
|
||||||
const SkRect& devInside,
|
|
||||||
bool miterStroke) {
|
|
||||||
GrAAStrokeRectBatch::Geometry geometry;
|
|
||||||
geometry.fColor = color;
|
|
||||||
geometry.fDevOutside = devOutside;
|
|
||||||
geometry.fDevOutsideAssist = devOutsideAssist;
|
|
||||||
geometry.fDevInside = devInside;
|
|
||||||
geometry.fMiterStroke = miterStroke;
|
|
||||||
|
|
||||||
return GrAAStrokeRectBatch::Create(geometry, viewMatrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace GrRectBatchFactory {
|
namespace GrRectBatchFactory {
|
||||||
|
|
||||||
GrDrawBatch* CreateNonAAStroke(GrColor color,
|
|
||||||
const SkMatrix& viewMatrix,
|
|
||||||
const SkRect& rect,
|
|
||||||
SkScalar strokeWidth,
|
|
||||||
bool snapToPixelCenters) {
|
|
||||||
GrStrokeRectBatch::Geometry geometry;
|
|
||||||
geometry.fColor = color;
|
|
||||||
geometry.fViewMatrix = viewMatrix;
|
|
||||||
geometry.fRect = rect;
|
|
||||||
geometry.fStrokeWidth = strokeWidth;
|
|
||||||
return GrStrokeRectBatch::Create(geometry, snapToPixelCenters);
|
|
||||||
}
|
|
||||||
|
|
||||||
GrDrawBatch* CreateAAStroke(GrColor color,
|
GrDrawBatch* CreateAAStroke(GrColor color,
|
||||||
const SkMatrix& viewMatrix,
|
const SkMatrix& viewMatrix,
|
||||||
const SkRect& rect,
|
const SkRect& rect,
|
||||||
@ -98,8 +68,8 @@ GrDrawBatch* CreateAAStroke(GrColor color,
|
|||||||
devOutsideAssist.outset(0, ry);
|
devOutsideAssist.outset(0, ry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return create_stroke_aa_batch(color, viewMatrix, devOutside, devOutsideAssist, devInside,
|
return GrAAStrokeRectBatch::Create(color, viewMatrix, devOutside, devOutsideAssist, devInside,
|
||||||
miterStroke);
|
miterStroke);
|
||||||
}
|
}
|
||||||
|
|
||||||
GrDrawBatch* CreateAAFillNestedRects(GrColor color,
|
GrDrawBatch* CreateAAFillNestedRects(GrColor color,
|
||||||
@ -116,7 +86,7 @@ GrDrawBatch* CreateAAFillNestedRects(GrColor color,
|
|||||||
return CreateAAFill(color, viewMatrix, devOutside, devOutside);
|
return CreateAAFill(color, viewMatrix, devOutside, devOutside);
|
||||||
}
|
}
|
||||||
|
|
||||||
return create_stroke_aa_batch(color, viewMatrix, devOutside, devOutside, devInside, true);
|
return GrAAStrokeRectBatch::Create(color, viewMatrix, devOutside, devOutside, devInside, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -11,9 +11,10 @@
|
|||||||
#include "GrAAFillRectBatch.h"
|
#include "GrAAFillRectBatch.h"
|
||||||
#include "GrColor.h"
|
#include "GrColor.h"
|
||||||
#include "GrNonAAFillRectBatch.h"
|
#include "GrNonAAFillRectBatch.h"
|
||||||
|
#include "GrNonAAStrokeRectBatch.h"
|
||||||
|
#include "SkMatrix.h"
|
||||||
|
|
||||||
class GrBatch;
|
class GrBatch;
|
||||||
class SkMatrix;
|
|
||||||
struct SkRect;
|
struct SkRect;
|
||||||
class SkStrokeRec;
|
class SkStrokeRec;
|
||||||
|
|
||||||
@ -27,7 +28,12 @@ inline GrDrawBatch* CreateNonAAFill(GrColor color,
|
|||||||
const SkRect& rect,
|
const SkRect& rect,
|
||||||
const SkRect* localRect,
|
const SkRect* localRect,
|
||||||
const SkMatrix* localMatrix) {
|
const SkMatrix* localMatrix) {
|
||||||
return GrNonAAFillRectBatch::Create(color, viewMatrix, rect, localRect, localMatrix);
|
if (viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective())) {
|
||||||
|
return GrNonAAFillRectBatch::CreateWithPerspective(color, viewMatrix, rect, localRect,
|
||||||
|
localMatrix);
|
||||||
|
} else {
|
||||||
|
return GrNonAAFillRectBatch::Create(color, viewMatrix, rect, localRect, localMatrix);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline GrDrawBatch* CreateAAFill(GrColor color,
|
inline GrDrawBatch* CreateAAFill(GrColor color,
|
||||||
@ -45,11 +51,13 @@ inline GrDrawBatch* CreateAAFill(GrColor color,
|
|||||||
return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRect);
|
return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
GrDrawBatch* CreateNonAAStroke(GrColor color,
|
inline GrDrawBatch* CreateNonAAStroke(GrColor color,
|
||||||
const SkMatrix& viewMatrix,
|
const SkMatrix& viewMatrix,
|
||||||
const SkRect& rect,
|
const SkRect& rect,
|
||||||
SkScalar strokeWidth,
|
SkScalar strokeWidth,
|
||||||
bool snapToPixelCenters);
|
bool snapToPixelCenters) {
|
||||||
|
return GrNonAAStrokeRectBatch::Create(color, viewMatrix, rect, strokeWidth, snapToPixelCenters);
|
||||||
|
}
|
||||||
|
|
||||||
GrDrawBatch* CreateAAStroke(GrColor,
|
GrDrawBatch* CreateAAStroke(GrColor,
|
||||||
const SkMatrix& viewMatrix,
|
const SkMatrix& viewMatrix,
|
||||||
|
@ -1,139 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2015 Google Inc.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license that can be
|
|
||||||
* found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "GrStrokeRectBatch.h"
|
|
||||||
#include "GrBatchTest.h"
|
|
||||||
#include "GrBatchFlushState.h"
|
|
||||||
#include "SkRandom.h"
|
|
||||||
|
|
||||||
GrStrokeRectBatch::GrStrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters)
|
|
||||||
: INHERITED(ClassID()) {
|
|
||||||
fBatch.fHairline = geometry.fStrokeWidth == 0;
|
|
||||||
|
|
||||||
fGeoData.push_back(geometry);
|
|
||||||
|
|
||||||
// setup bounds
|
|
||||||
fBounds = geometry.fRect;
|
|
||||||
SkScalar rad = SkScalarHalf(geometry.fStrokeWidth);
|
|
||||||
fBounds.outset(rad, rad);
|
|
||||||
geometry.fViewMatrix.mapRect(&fBounds);
|
|
||||||
|
|
||||||
// If our caller snaps to pixel centers then we have to round out the bounds
|
|
||||||
if (snapToPixelCenters) {
|
|
||||||
fBounds.roundOut();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrStrokeRectBatch::initBatchTracker(const GrPipelineOptimizations& opt) {
|
|
||||||
// Handle any color overrides
|
|
||||||
if (!opt.readsColor()) {
|
|
||||||
fGeoData[0].fColor = GrColor_ILLEGAL;
|
|
||||||
}
|
|
||||||
opt.getOverrideColorIfSet(&fGeoData[0].fColor);
|
|
||||||
|
|
||||||
// setup batch properties
|
|
||||||
fBatch.fColorIgnored = !opt.readsColor();
|
|
||||||
fBatch.fColor = fGeoData[0].fColor;
|
|
||||||
fBatch.fUsesLocalCoords = opt.readsLocalCoords();
|
|
||||||
fBatch.fCoverageIgnored = !opt.readsCoverage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create a triangle strip that strokes the specified rect. There are 8
|
|
||||||
unique vertices, but we repeat the last 2 to close up. Alternatively we
|
|
||||||
could use an indices array, and then only send 8 verts, but not sure that
|
|
||||||
would be faster.
|
|
||||||
*/
|
|
||||||
static void init_stroke_rect_strip(SkPoint verts[10], const SkRect& rect, SkScalar width) {
|
|
||||||
const SkScalar rad = SkScalarHalf(width);
|
|
||||||
// TODO we should be able to enable this assert, but we'd have to filter these draws
|
|
||||||
// this is a bug
|
|
||||||
//SkASSERT(rad < rect.width() / 2 && rad < rect.height() / 2);
|
|
||||||
|
|
||||||
verts[0].set(rect.fLeft + rad, rect.fTop + rad);
|
|
||||||
verts[1].set(rect.fLeft - rad, rect.fTop - rad);
|
|
||||||
verts[2].set(rect.fRight - rad, rect.fTop + rad);
|
|
||||||
verts[3].set(rect.fRight + rad, rect.fTop - rad);
|
|
||||||
verts[4].set(rect.fRight - rad, rect.fBottom - rad);
|
|
||||||
verts[5].set(rect.fRight + rad, rect.fBottom + rad);
|
|
||||||
verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
|
|
||||||
verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
|
|
||||||
verts[8] = verts[0];
|
|
||||||
verts[9] = verts[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrStrokeRectBatch::onPrepareDraws(Target* target) {
|
|
||||||
SkAutoTUnref<const GrGeometryProcessor> gp;
|
|
||||||
{
|
|
||||||
using namespace GrDefaultGeoProcFactory;
|
|
||||||
Color color(this->color());
|
|
||||||
Coverage coverage(this->coverageIgnored() ? Coverage::kSolid_Type :
|
|
||||||
Coverage::kNone_Type);
|
|
||||||
LocalCoords localCoords(this->usesLocalCoords() ? LocalCoords::kUsePosition_Type :
|
|
||||||
LocalCoords::kUnused_Type);
|
|
||||||
gp.reset(GrDefaultGeoProcFactory::Create(color, coverage, localCoords,
|
|
||||||
this->viewMatrix()));
|
|
||||||
}
|
|
||||||
|
|
||||||
target->initDraw(gp, this->pipeline());
|
|
||||||
|
|
||||||
size_t vertexStride = gp->getVertexStride();
|
|
||||||
|
|
||||||
SkASSERT(vertexStride == sizeof(GrDefaultGeoProcFactory::PositionAttr));
|
|
||||||
|
|
||||||
Geometry& args = fGeoData[0];
|
|
||||||
|
|
||||||
int vertexCount = kVertsPerHairlineRect;
|
|
||||||
if (args.fStrokeWidth > 0) {
|
|
||||||
vertexCount = kVertsPerStrokeRect;
|
|
||||||
}
|
|
||||||
|
|
||||||
const GrVertexBuffer* vertexBuffer;
|
|
||||||
int firstVertex;
|
|
||||||
|
|
||||||
void* verts = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex);
|
|
||||||
|
|
||||||
if (!verts) {
|
|
||||||
SkDebugf("Could not allocate vertices\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SkPoint* vertex = reinterpret_cast<SkPoint*>(verts);
|
|
||||||
|
|
||||||
GrPrimitiveType primType;
|
|
||||||
|
|
||||||
if (args.fStrokeWidth > 0) {;
|
|
||||||
primType = kTriangleStrip_GrPrimitiveType;
|
|
||||||
args.fRect.sort();
|
|
||||||
init_stroke_rect_strip(vertex, args.fRect, args.fStrokeWidth);
|
|
||||||
} else {
|
|
||||||
// hairline
|
|
||||||
primType = kLineStrip_GrPrimitiveType;
|
|
||||||
vertex[0].set(args.fRect.fLeft, args.fRect.fTop);
|
|
||||||
vertex[1].set(args.fRect.fRight, args.fRect.fTop);
|
|
||||||
vertex[2].set(args.fRect.fRight, args.fRect.fBottom);
|
|
||||||
vertex[3].set(args.fRect.fLeft, args.fRect.fBottom);
|
|
||||||
vertex[4].set(args.fRect.fLeft, args.fRect.fTop);
|
|
||||||
}
|
|
||||||
|
|
||||||
GrVertices vertices;
|
|
||||||
vertices.init(primType, vertexBuffer, firstVertex, vertexCount);
|
|
||||||
target->draw(vertices);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef GR_TEST_UTILS
|
|
||||||
|
|
||||||
DRAW_BATCH_TEST_DEFINE(GrStrokeRectBatch) {
|
|
||||||
GrStrokeRectBatch::Geometry geometry;
|
|
||||||
geometry.fViewMatrix = GrTest::TestMatrix(random);
|
|
||||||
geometry.fColor = GrRandomColor(random);
|
|
||||||
geometry.fRect = GrTest::TestRect(random);
|
|
||||||
geometry.fStrokeWidth = random->nextBool() ? 0.0f : 1.0f;
|
|
||||||
|
|
||||||
return GrStrokeRectBatch::Create(geometry, random->nextBool());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2015 Google Inc.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license that can be
|
|
||||||
* found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GrStrokeRectBatch_DEFINED
|
|
||||||
#define GrStrokeRectBatch_DEFINED
|
|
||||||
|
|
||||||
#include "GrColor.h"
|
|
||||||
#include "GrDefaultGeoProcFactory.h"
|
|
||||||
#include "GrVertexBatch.h"
|
|
||||||
|
|
||||||
class GrStrokeRectBatch : public GrVertexBatch {
|
|
||||||
public:
|
|
||||||
DEFINE_BATCH_CLASS_ID
|
|
||||||
|
|
||||||
struct Geometry {
|
|
||||||
GrColor fColor;
|
|
||||||
SkMatrix fViewMatrix;
|
|
||||||
SkRect fRect;
|
|
||||||
SkScalar fStrokeWidth;
|
|
||||||
};
|
|
||||||
|
|
||||||
static GrDrawBatch* Create(const Geometry& geometry, bool snapToPixelCenters) {
|
|
||||||
return new GrStrokeRectBatch(geometry, snapToPixelCenters);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* name() const override { return "GrStrokeRectBatch"; }
|
|
||||||
|
|
||||||
void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
|
|
||||||
// When this is called on a batch, there is only one geometry bundle
|
|
||||||
out->setKnownFourComponents(fGeoData[0].fColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
|
|
||||||
out->setKnownSingleComponent(0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void onPrepareDraws(Target*) override;
|
|
||||||
void initBatchTracker(const GrPipelineOptimizations&) override;
|
|
||||||
|
|
||||||
GrStrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters);
|
|
||||||
|
|
||||||
GrColor color() const { return fBatch.fColor; }
|
|
||||||
bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
|
|
||||||
bool colorIgnored() const { return fBatch.fColorIgnored; }
|
|
||||||
const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
|
|
||||||
bool hairline() const { return fBatch.fHairline; }
|
|
||||||
bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
|
|
||||||
|
|
||||||
bool onCombineIfPossible(GrBatch* t, const GrCaps&) override {
|
|
||||||
// if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *t->pipeline(),
|
|
||||||
// t->bounds(), caps)) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// GrStrokeRectBatch* that = t->cast<StrokeRectBatch>();
|
|
||||||
|
|
||||||
// NonAA stroke rects cannot batch right now
|
|
||||||
// TODO make these batchable
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct BatchTracker {
|
|
||||||
GrColor fColor;
|
|
||||||
bool fUsesLocalCoords;
|
|
||||||
bool fColorIgnored;
|
|
||||||
bool fCoverageIgnored;
|
|
||||||
bool fHairline;
|
|
||||||
};
|
|
||||||
|
|
||||||
const static int kVertsPerHairlineRect = 5;
|
|
||||||
const static int kVertsPerStrokeRect = 10;
|
|
||||||
|
|
||||||
BatchTracker fBatch;
|
|
||||||
SkSTArray<1, Geometry, true> fGeoData;
|
|
||||||
|
|
||||||
typedef GrVertexBatch INHERITED;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue
Block a user