Index: src/gpu/batches/GrDrawPathBatch.h |
diff --git a/src/gpu/batches/GrDrawPathBatch.h b/src/gpu/batches/GrDrawPathBatch.h |
index fdd3448a737918086cbe8c6687103832e3dda670..0b24fe0546d3e7f28ba49ba35fccdccb91ade018 100644 |
--- a/src/gpu/batches/GrDrawPathBatch.h |
+++ b/src/gpu/batches/GrDrawPathBatch.h |
@@ -93,84 +93,91 @@ private: |
typedef GrDrawPathBatchBase INHERITED; |
}; |
-/** |
- * This could be nested inside the batch class, but for now it must be declarable in a public |
- * header (GrDrawContext) |
- */ |
-class GrPathRangeDraw : public GrNonAtomicRef { |
-public: |
- typedef GrPathRendering::PathTransformType TransformType; |
- |
- static GrPathRangeDraw* Create(TransformType transformType, int reserveCnt) { |
- return new GrPathRangeDraw(transformType, reserveCnt); |
- } |
- |
- void append(uint16_t index, float transform[]) { |
- fTransforms.push_back_n(GrPathRendering::PathTransformSize(fTransformType), transform); |
- fIndices.push_back(index); |
- } |
- |
- int count() const { return fIndices.count(); } |
- |
- TransformType transformType() const { return fTransformType; } |
- |
- const float* transforms() const { return fTransforms.begin(); } |
- |
- const uint16_t* indices() const { return fIndices.begin(); } |
- |
- static bool CanMerge(const GrPathRangeDraw& a, const GrPathRangeDraw& b) { |
- return a.transformType() == b.transformType(); |
- } |
- |
-private: |
- GrPathRangeDraw(TransformType transformType, int reserveCnt) |
- : fTransformType(transformType) |
- , fIndices(reserveCnt) |
- , fTransforms(reserveCnt * GrPathRendering::PathTransformSize(transformType)) { |
- SkDEBUGCODE(fUsedInBatch = false;) |
- } |
- |
- // Reserve space for 64 paths where indices are 16 bit and transforms are translations. |
- static const int kIndexReserveCnt = 64; |
- static const int kTransformBufferReserveCnt = 2 * 64; |
- |
- GrPathRendering::PathTransformType fTransformType; |
- SkSTArray<kIndexReserveCnt, uint16_t, true> fIndices; |
- SkSTArray<kTransformBufferReserveCnt, float, true> fTransforms; |
- |
- // To ensure we don't reuse these across batches. |
-#ifdef SK_DEBUG |
- bool fUsedInBatch; |
- friend class GrDrawPathRangeBatch; |
-#endif |
- |
- typedef GrNonAtomicRef INHERITED; |
-}; |
- |
// Template this if we decide to support index types other than 16bit |
class GrDrawPathRangeBatch final : public GrDrawPathBatchBase { |
public: |
+ typedef GrPathRendering::PathTransformType TransformType; |
+ |
DEFINE_BATCH_CLASS_ID |
+ struct InstanceData : public SkNoncopyable { |
+ public: |
+ static InstanceData* Alloc(TransformType transformType, int reserveCnt) { |
+ int transformSize = GrPathRendering::PathTransformSize(transformType); |
+ uint8_t* ptr = (uint8_t*)sk_malloc_throw(Align32(sizeof(InstanceData)) + |
+ Align32(reserveCnt * sizeof(uint16_t)) + |
+ reserveCnt * transformSize * sizeof(float)); |
+ InstanceData* instanceData = (InstanceData*)ptr; |
+ instanceData->fIndices = (uint16_t*)&ptr[Align32(sizeof(InstanceData))]; |
+ instanceData->fTransformValues = (float*)&ptr[Align32(sizeof(InstanceData)) + |
+ Align32(reserveCnt * sizeof(uint16_t))]; |
+ instanceData->fTransformType = transformType; |
+ instanceData->fInstanceCount = 0; |
+ instanceData->fRefCnt = 1; |
+ SkDEBUGCODE(instanceData->fReserveCnt = reserveCnt;) |
+ return instanceData; |
+ } |
+ |
+ // Overload this method if we start using other transform types. |
+ void append(uint16_t index, float x, float y) { |
+ SkASSERT(GrPathRendering::kTranslate_PathTransformType == fTransformType); |
+ SkASSERT(fInstanceCount < fReserveCnt); |
+ fIndices[fInstanceCount] = index; |
+ fTransformValues[2 * fInstanceCount] = x; |
+ fTransformValues[2 * fInstanceCount + 1] = y; |
+ ++fInstanceCount; |
+ } |
+ |
+ TransformType transformType() const { return fTransformType; } |
+ int count() const { return fInstanceCount; } |
+ |
+ const uint16_t* indices() const { return fIndices; } |
+ uint16_t* indices() { return fIndices; } |
+ |
+ const float* transformValues() const { return fTransformValues; } |
+ float* transformValues() { return fTransformValues; } |
+ |
+ void ref() const { ++fRefCnt; } |
+ |
+ void unref() const { |
+ if (0 == --fRefCnt) { |
+ sk_free(const_cast<InstanceData*>(this)); |
+ } |
+ } |
+ |
+ private: |
+ static int Align32(int sizeInBytes) { return (sizeInBytes + 3) & ~3; } |
+ |
+ InstanceData() {} |
+ ~InstanceData() {} |
+ |
+ uint16_t* fIndices; |
+ float* fTransformValues; |
+ TransformType fTransformType; |
+ int fInstanceCount; |
+ mutable int fRefCnt; |
+ SkDEBUGCODE(int fReserveCnt;) |
+ }; |
+ |
// This can't return a more abstract type because we install the stencil settings late :( |
- static GrDrawPathBatchBase* Create(const SkMatrix& viewMatrix, const SkMatrix& localMatrix, |
- GrColor color, GrPathRendering::FillType fill, |
- GrPathRange* range, GrPathRangeDraw* draw, |
+ static GrDrawPathBatchBase* Create(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x, |
+ SkScalar y, GrColor color, GrPathRendering::FillType fill, |
+ GrPathRange* range, const InstanceData* instanceData, |
const SkRect& bounds) { |
- return new GrDrawPathRangeBatch(viewMatrix, localMatrix, color, fill, range, draw, |
+ return new GrDrawPathRangeBatch(viewMatrix, scale, x, y, color, fill, range, instanceData, |
bounds); |
} |
- ~GrDrawPathRangeBatch() override; |
- |
const char* name() const override { return "DrawPathRange"; } |
SkString dumpInfo() const override; |
private: |
- GrDrawPathRangeBatch(const SkMatrix& viewMatrix, const SkMatrix& localMatrix, GrColor color, |
- GrPathRendering::FillType fill, GrPathRange* range, |
- GrPathRangeDraw* draw, const SkRect& bounds); |
+ GrDrawPathRangeBatch(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x, SkScalar y, |
+ GrColor color, GrPathRendering::FillType fill, GrPathRange* range, |
+ const InstanceData* instanceData, const SkRect& bounds); |
+ |
+ TransformType transformType() const { return fDraws.head()->fInstanceData->transformType(); } |
bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override; |
@@ -178,12 +185,24 @@ private: |
void onDraw(GrBatchFlushState* state) override; |
+ struct Draw { |
+ void set(const InstanceData* instanceData, SkScalar x, SkScalar y) { |
+ fInstanceData.reset(SkRef(instanceData)); |
+ fX = x; |
+ fY = y; |
+ } |
+ |
+ SkAutoTUnref<const InstanceData> fInstanceData; |
+ SkScalar fX, fY; |
+ }; |
+ |
typedef GrPendingIOResource<const GrPathRange, kRead_GrIOType> PendingPathRange; |
- typedef SkTLList<GrPathRangeDraw*, 4> DrawList; |
+ typedef SkTLList<Draw, 4> DrawList; |
+ |
PendingPathRange fPathRange; |
DrawList fDraws; |
int fTotalPathCount; |
- SkMatrix fLocalMatrix; |
+ SkScalar fScale; |
typedef GrDrawPathBatchBase INHERITED; |
}; |