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 "GrPathRenderer.h" 13 #include "GrRect.h" 14 #include "GrShape.h" 15 16 #include "SkOpts.h" 17 #include "SkTDynamicHash.h" 18 19 class GrContext; 20 21 class GrSmallPathRenderer : public GrPathRenderer { 22 public: 23 GrSmallPathRenderer(); 24 ~GrSmallPathRenderer() override; 25 26 class SmallPathOp; 27 struct PathTestStruct; 28 29 private: onGetStencilSupport(const GrShape &)30 StencilSupport onGetStencilSupport(const GrShape&) const override { 31 return GrPathRenderer::kNoSupport_StencilSupport; 32 } 33 34 bool onCanDrawPath(const CanDrawPathArgs&) const override; 35 36 bool onDrawPath(const DrawPathArgs&) override; 37 38 struct ShapeData { 39 class Key { 40 public: KeyShapeData41 Key() {} KeyShapeData42 Key(const Key& that) { *this = that; } KeyShapeData43 Key(const GrShape& shape, uint32_t dim) { this->set(shape, dim); } KeyShapeData44 Key(const GrShape& shape, const SkMatrix& ctm) { this->set(shape, ctm); } 45 46 Key& operator=(const Key& that) { 47 fKey.reset(that.fKey.count()); 48 memcpy(fKey.get(), that.fKey.get(), fKey.count() * sizeof(uint32_t)); 49 return *this; 50 } 51 setShapeData52 void set(const GrShape& shape, uint32_t dim) { 53 // Shapes' keys are for their pre-style geometry, but by now we shouldn't have any 54 // relevant styling information. 55 SkASSERT(shape.style().isSimpleFill()); 56 SkASSERT(shape.hasUnstyledKey()); 57 int shapeKeySize = shape.unstyledKeySize(); 58 fKey.reset(1 + shapeKeySize); 59 fKey[0] = dim; 60 shape.writeUnstyledKey(&fKey[1]); 61 } 62 setShapeData63 void set(const GrShape& shape, const SkMatrix& ctm) { 64 GrUniqueKey maskKey; 65 struct KeyData { 66 SkScalar fFractionalTranslateX; 67 SkScalar fFractionalTranslateY; 68 }; 69 70 // Shapes' keys are for their pre-style geometry, but by now we shouldn't have any 71 // relevant styling information. 72 SkASSERT(shape.style().isSimpleFill()); 73 SkASSERT(shape.hasUnstyledKey()); 74 // We require the upper left 2x2 of the matrix to match exactly for a cache hit. 75 SkScalar sx = ctm.get(SkMatrix::kMScaleX); 76 SkScalar sy = ctm.get(SkMatrix::kMScaleY); 77 SkScalar kx = ctm.get(SkMatrix::kMSkewX); 78 SkScalar ky = ctm.get(SkMatrix::kMSkewY); 79 SkScalar tx = ctm.get(SkMatrix::kMTransX); 80 SkScalar ty = ctm.get(SkMatrix::kMTransY); 81 // Allow 8 bits each in x and y of subpixel positioning. 82 SkFixed fracX = SkScalarToFixed(SkScalarFraction(tx)) & 0x0000FF00; 83 SkFixed fracY = SkScalarToFixed(SkScalarFraction(ty)) & 0x0000FF00; 84 int shapeKeySize = shape.unstyledKeySize(); 85 fKey.reset(5 + shapeKeySize); 86 fKey[0] = SkFloat2Bits(sx); 87 fKey[1] = SkFloat2Bits(sy); 88 fKey[2] = SkFloat2Bits(kx); 89 fKey[3] = SkFloat2Bits(ky); 90 fKey[4] = fracX | (fracY >> 8); 91 shape.writeUnstyledKey(&fKey[5]); 92 } 93 94 bool operator==(const Key& that) const { 95 return fKey.count() == that.fKey.count() && 96 0 == memcmp(fKey.get(), that.fKey.get(), sizeof(uint32_t) * fKey.count()); 97 } 98 count32ShapeData99 int count32() const { return fKey.count(); } dataShapeData100 const uint32_t* data() const { return fKey.get(); } 101 102 private: 103 // The key is composed of the GrShape's key, and either the dimensions of the DF 104 // generated for the path (32x32 max, 64x64 max, 128x128 max) if an SDF image or 105 // the matrix for the path with only fractional translation. 106 SkAutoSTArray<24, uint32_t> fKey; 107 }; 108 Key fKey; 109 GrDrawOpAtlas::AtlasID fID; 110 SkRect fBounds; 111 SkScalar fScale; 112 SkVector fTranslate; 113 SK_DECLARE_INTERNAL_LLIST_INTERFACE(ShapeData); 114 GetKeyShapeData115 static inline const Key& GetKey(const ShapeData& data) { 116 return data.fKey; 117 } 118 HashShapeData119 static inline uint32_t Hash(Key key) { 120 return SkOpts::hash(key.data(), sizeof(uint32_t) * key.count32()); 121 } 122 }; 123 124 static void HandleEviction(GrDrawOpAtlas::AtlasID, void*); 125 126 typedef SkTDynamicHash<ShapeData, ShapeData::Key> ShapeCache; 127 typedef SkTInternalLList<ShapeData> ShapeDataList; 128 129 std::unique_ptr<GrDrawOpAtlas> fAtlas; 130 ShapeCache fShapeCache; 131 ShapeDataList fShapeList; 132 133 typedef GrPathRenderer INHERITED; 134 }; 135 136 #endif 137