1 /* 2 * Copyright 2014 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrSmallPathRenderer_DEFINED 9 #define GrSmallPathRenderer_DEFINED 10 11 #include "GrDrawOpAtlas.h" 12 #include "GrOnFlushResourceProvider.h" 13 #include "GrPathRenderer.h" 14 #include "GrRect.h" 15 #include "GrShape.h" 16 17 #include "SkOpts.h" 18 #include "SkTDynamicHash.h" 19 20 class GrContext; 21 22 class GrSmallPathRenderer : public GrPathRenderer, public GrOnFlushCallbackObject { 23 public: 24 GrSmallPathRenderer(); 25 ~GrSmallPathRenderer() override; 26 27 class SmallPathOp; 28 struct PathTestStruct; 29 30 // GrOnFlushCallbackObject overrides 31 // 32 // Note: because this class is associated with a path renderer we want it to be removed from 33 // the list of active OnFlushBackkbackObjects in an freeGpuResources call (i.e., we accept the 34 // default retainOnFreeGpuResources implementation). 35 preFlush(GrOnFlushResourceProvider *,const uint32_t *,int,SkTArray<sk_sp<GrRenderTargetContext>> *)36 void preFlush(GrOnFlushResourceProvider*, const uint32_t*, int, 37 SkTArray<sk_sp<GrRenderTargetContext>>*) override {} 38 postFlush(GrDeferredUploadToken startTokenForNextFlush,const uint32_t * opListIDs,int numOpListIDs)39 void postFlush(GrDeferredUploadToken startTokenForNextFlush, 40 const uint32_t* opListIDs, int numOpListIDs) override { 41 if (fAtlas) { 42 fAtlas->compact(startTokenForNextFlush); 43 } 44 } 45 46 private: onGetStencilSupport(const GrShape &)47 StencilSupport onGetStencilSupport(const GrShape&) const override { 48 return GrPathRenderer::kNoSupport_StencilSupport; 49 } 50 51 CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override; 52 53 bool onDrawPath(const DrawPathArgs&) override; 54 55 struct ShapeData { 56 class Key { 57 public: KeyShapeData58 Key() {} KeyShapeData59 Key(const Key& that) { *this = that; } KeyShapeData60 Key(const GrShape& shape, uint32_t dim) { this->set(shape, dim); } KeyShapeData61 Key(const GrShape& shape, const SkMatrix& ctm) { this->set(shape, ctm); } 62 63 Key& operator=(const Key& that) { 64 fKey.reset(that.fKey.count()); 65 memcpy(fKey.get(), that.fKey.get(), fKey.count() * sizeof(uint32_t)); 66 return *this; 67 } 68 69 // for SDF paths setShapeData70 void set(const GrShape& shape, uint32_t dim) { 71 // Shapes' keys are for their pre-style geometry, but by now we shouldn't have any 72 // relevant styling information. 73 SkASSERT(shape.style().isSimpleFill()); 74 SkASSERT(shape.hasUnstyledKey()); 75 int shapeKeySize = shape.unstyledKeySize(); 76 fKey.reset(1 + shapeKeySize); 77 fKey[0] = dim; 78 shape.writeUnstyledKey(&fKey[1]); 79 } 80 81 // for bitmap paths setShapeData82 void set(const GrShape& shape, const SkMatrix& ctm) { 83 // Shapes' keys are for their pre-style geometry, but by now we shouldn't have any 84 // relevant styling information. 85 SkASSERT(shape.style().isSimpleFill()); 86 SkASSERT(shape.hasUnstyledKey()); 87 // We require the upper left 2x2 of the matrix to match exactly for a cache hit. 88 SkScalar sx = ctm.get(SkMatrix::kMScaleX); 89 SkScalar sy = ctm.get(SkMatrix::kMScaleY); 90 SkScalar kx = ctm.get(SkMatrix::kMSkewX); 91 SkScalar ky = ctm.get(SkMatrix::kMSkewY); 92 SkScalar tx = ctm.get(SkMatrix::kMTransX); 93 SkScalar ty = ctm.get(SkMatrix::kMTransY); 94 // Allow 8 bits each in x and y of subpixel positioning. 95 SkFixed fracX = SkScalarToFixed(SkScalarFraction(tx)) & 0x0000FF00; 96 SkFixed fracY = SkScalarToFixed(SkScalarFraction(ty)) & 0x0000FF00; 97 int shapeKeySize = shape.unstyledKeySize(); 98 fKey.reset(5 + shapeKeySize); 99 fKey[0] = SkFloat2Bits(sx); 100 fKey[1] = SkFloat2Bits(sy); 101 fKey[2] = SkFloat2Bits(kx); 102 fKey[3] = SkFloat2Bits(ky); 103 fKey[4] = fracX | (fracY >> 8); 104 shape.writeUnstyledKey(&fKey[5]); 105 } 106 107 bool operator==(const Key& that) const { 108 return fKey.count() == that.fKey.count() && 109 0 == memcmp(fKey.get(), that.fKey.get(), sizeof(uint32_t) * fKey.count()); 110 } 111 count32ShapeData112 int count32() const { return fKey.count(); } dataShapeData113 const uint32_t* data() const { return fKey.get(); } 114 115 private: 116 // The key is composed of the GrShape's key, and either the dimensions of the DF 117 // generated for the path (32x32 max, 64x64 max, 128x128 max) if an SDF image or 118 // the matrix for the path with only fractional translation. 119 SkAutoSTArray<24, uint32_t> fKey; 120 }; 121 Key fKey; 122 GrDrawOpAtlas::AtlasID fID; 123 SkRect fBounds; 124 GrIRect16 fTextureCoords; 125 SK_DECLARE_INTERNAL_LLIST_INTERFACE(ShapeData); 126 GetKeyShapeData127 static inline const Key& GetKey(const ShapeData& data) { 128 return data.fKey; 129 } 130 HashShapeData131 static inline uint32_t Hash(Key key) { 132 return SkOpts::hash(key.data(), sizeof(uint32_t) * key.count32()); 133 } 134 }; 135 136 static void HandleEviction(GrDrawOpAtlas::AtlasID, void*); 137 138 typedef SkTDynamicHash<ShapeData, ShapeData::Key> ShapeCache; 139 typedef SkTInternalLList<ShapeData> ShapeDataList; 140 141 std::unique_ptr<GrDrawOpAtlas> fAtlas; 142 ShapeCache fShapeCache; 143 ShapeDataList fShapeList; 144 145 typedef GrPathRenderer INHERITED; 146 }; 147 148 #endif 149