Line data Source code
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:
27 0 : StencilSupport onGetStencilSupport(const GrShape&) const override {
28 0 : return GrPathRenderer::kNoSupport_StencilSupport;
29 : }
30 :
31 : bool onCanDrawPath(const CanDrawPathArgs&) const override;
32 :
33 : bool onDrawPath(const DrawPathArgs&) override;
34 :
35 0 : struct ShapeData {
36 0 : class Key {
37 : public:
38 0 : Key() {}
39 0 : Key(const Key& that) { *this = that; }
40 0 : Key(const GrShape& shape, uint32_t dim) { this->set(shape, dim); }
41 0 : Key(const GrShape& shape, const SkMatrix& ctm) { this->set(shape, ctm); }
42 :
43 0 : Key& operator=(const Key& that) {
44 0 : fKey.reset(that.fKey.count());
45 0 : memcpy(fKey.get(), that.fKey.get(), fKey.count() * sizeof(uint32_t));
46 0 : return *this;
47 : }
48 :
49 0 : 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 0 : SkASSERT(shape.style().isSimpleFill());
53 0 : SkASSERT(shape.hasUnstyledKey());
54 0 : int shapeKeySize = shape.unstyledKeySize();
55 0 : fKey.reset(1 + shapeKeySize);
56 0 : fKey[0] = dim;
57 0 : shape.writeUnstyledKey(&fKey[1]);
58 0 : }
59 :
60 0 : void set(const GrShape& shape, const SkMatrix& ctm) {
61 0 : 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 0 : SkASSERT(shape.style().isSimpleFill());
70 0 : SkASSERT(shape.hasUnstyledKey());
71 : // We require the upper left 2x2 of the matrix to match exactly for a cache hit.
72 0 : SkScalar sx = ctm.get(SkMatrix::kMScaleX);
73 0 : SkScalar sy = ctm.get(SkMatrix::kMScaleY);
74 0 : SkScalar kx = ctm.get(SkMatrix::kMSkewX);
75 0 : SkScalar ky = ctm.get(SkMatrix::kMSkewY);
76 0 : SkScalar tx = ctm.get(SkMatrix::kMTransX);
77 0 : SkScalar ty = ctm.get(SkMatrix::kMTransY);
78 : // Allow 8 bits each in x and y of subpixel positioning.
79 0 : SkFixed fracX = SkScalarToFixed(SkScalarFraction(tx)) & 0x0000FF00;
80 0 : SkFixed fracY = SkScalarToFixed(SkScalarFraction(ty)) & 0x0000FF00;
81 0 : int shapeKeySize = shape.unstyledKeySize();
82 0 : fKey.reset(5 + shapeKeySize);
83 0 : fKey[0] = SkFloat2Bits(sx);
84 0 : fKey[1] = SkFloat2Bits(sy);
85 0 : fKey[2] = SkFloat2Bits(kx);
86 0 : fKey[3] = SkFloat2Bits(ky);
87 0 : fKey[4] = fracX | (fracY >> 8);
88 0 : shape.writeUnstyledKey(&fKey[5]);
89 0 : }
90 :
91 0 : bool operator==(const Key& that) const {
92 0 : return fKey.count() == that.fKey.count() &&
93 0 : 0 == memcmp(fKey.get(), that.fKey.get(), sizeof(uint32_t) * fKey.count());
94 : }
95 :
96 0 : int count32() const { return fKey.count(); }
97 0 : 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 :
112 0 : static inline const Key& GetKey(const ShapeData& data) {
113 0 : return data.fKey;
114 : }
115 :
116 0 : static inline uint32_t Hash(Key key) {
117 0 : 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
|