• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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