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