• 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 "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