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 36 void preFlush(GrOnFlushResourceProvider* onFlushResourceProvider, const uint32_t*, int, 37 SkTArray<sk_sp<GrRenderTargetContext>>*) override { 38 if (fAtlas) { 39 fAtlas->instantiate(onFlushResourceProvider); 40 } 41 } 42 43 void postFlush(GrDeferredUploadToken startTokenForNextFlush, 44 const uint32_t* opListIDs, int numOpListIDs) override { 45 if (fAtlas) { 46 fAtlas->compact(startTokenForNextFlush); 47 } 48 } 49 50 private: 51 StencilSupport onGetStencilSupport(const GrShape&) const override { 52 return GrPathRenderer::kNoSupport_StencilSupport; 53 } 54 55 CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override; 56 57 bool onDrawPath(const DrawPathArgs&) override; 58 59 struct ShapeData { 60 class Key { 61 public: 62 Key() {} 63 Key(const Key& that) { *this = that; } 64 Key(const GrShape& shape, uint32_t dim) { this->set(shape, dim); } 65 Key(const GrShape& shape, const SkMatrix& ctm) { this->set(shape, ctm); } 66 67 Key& operator=(const Key& that) { 68 fKey.reset(that.fKey.count()); 69 memcpy(fKey.get(), that.fKey.get(), fKey.count() * sizeof(uint32_t)); 70 return *this; 71 } 72 73 // for SDF paths 74 void set(const GrShape& shape, uint32_t dim) { 75 // Shapes' keys are for their pre-style geometry, but by now we shouldn't have any 76 // relevant styling information. 77 SkASSERT(shape.style().isSimpleFill()); 78 SkASSERT(shape.hasUnstyledKey()); 79 int shapeKeySize = shape.unstyledKeySize(); 80 fKey.reset(1 + shapeKeySize); 81 fKey[0] = dim; 82 shape.writeUnstyledKey(&fKey[1]); 83 } 84 85 // for bitmap paths 86 void set(const GrShape& shape, const SkMatrix& ctm) { 87 // Shapes' keys are for their pre-style geometry, but by now we shouldn't have any 88 // relevant styling information. 89 SkASSERT(shape.style().isSimpleFill()); 90 SkASSERT(shape.hasUnstyledKey()); 91 // We require the upper left 2x2 of the matrix to match exactly for a cache hit. 92 SkScalar sx = ctm.get(SkMatrix::kMScaleX); 93 SkScalar sy = ctm.get(SkMatrix::kMScaleY); 94 SkScalar kx = ctm.get(SkMatrix::kMSkewX); 95 SkScalar ky = ctm.get(SkMatrix::kMSkewY); 96 SkScalar tx = ctm.get(SkMatrix::kMTransX); 97 SkScalar ty = ctm.get(SkMatrix::kMTransY); 98 // Allow 8 bits each in x and y of subpixel positioning. 99 SkFixed fracX = SkScalarToFixed(SkScalarFraction(tx)) & 0x0000FF00; 100 SkFixed fracY = SkScalarToFixed(SkScalarFraction(ty)) & 0x0000FF00; 101 int shapeKeySize = shape.unstyledKeySize(); 102 fKey.reset(5 + shapeKeySize); 103 fKey[0] = SkFloat2Bits(sx); 104 fKey[1] = SkFloat2Bits(sy); 105 fKey[2] = SkFloat2Bits(kx); 106 fKey[3] = SkFloat2Bits(ky); 107 fKey[4] = fracX | (fracY >> 8); 108 shape.writeUnstyledKey(&fKey[5]); 109 } 110 111 bool operator==(const Key& that) const { 112 return fKey.count() == that.fKey.count() && 113 0 == memcmp(fKey.get(), that.fKey.get(), sizeof(uint32_t) * fKey.count()); 114 } 115 116 int count32() const { return fKey.count(); } 117 const uint32_t* data() const { return fKey.get(); } 118 119 private: 120 // The key is composed of the GrShape's key, and either the dimensions of the DF 121 // generated for the path (32x32 max, 64x64 max, 128x128 max) if an SDF image or 122 // the matrix for the path with only fractional translation. 123 SkAutoSTArray<24, uint32_t> fKey; 124 }; 125 Key fKey; 126 GrDrawOpAtlas::AtlasID fID; 127 SkRect fBounds; 128 GrIRect16 fTextureCoords; 129 SK_DECLARE_INTERNAL_LLIST_INTERFACE(ShapeData); 130 131 static inline const Key& GetKey(const ShapeData& data) { 132 return data.fKey; 133 } 134 135 static inline uint32_t Hash(Key key) { 136 return SkOpts::hash(key.data(), sizeof(uint32_t) * key.count32()); 137 } 138 }; 139 140 static void HandleEviction(GrDrawOpAtlas::AtlasID, void*); 141 142 typedef SkTDynamicHash<ShapeData, ShapeData::Key> ShapeCache; 143 typedef SkTInternalLList<ShapeData> ShapeDataList; 144 145 std::unique_ptr<GrDrawOpAtlas> fAtlas; 146 ShapeCache fShapeCache; 147 ShapeDataList fShapeList; 148 149 typedef GrPathRenderer INHERITED; 150 }; 151 152 #endif 153