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