OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrShape.h" | 8 #include "GrShape.h" |
9 | 9 |
10 GrShape& GrShape::operator=(const GrShape& that) { | 10 GrShape& GrShape::operator=(const GrShape& that) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 | 65 |
66 SkRect GrShape::styledBounds() const { | 66 SkRect GrShape::styledBounds() const { |
67 if (Type::kEmpty == fType && !fStyle.hasNonDashPathEffect()) { | 67 if (Type::kEmpty == fType && !fStyle.hasNonDashPathEffect()) { |
68 return SkRect::MakeEmpty(); | 68 return SkRect::MakeEmpty(); |
69 } | 69 } |
70 SkRect bounds; | 70 SkRect bounds; |
71 fStyle.adjustBounds(&bounds, this->bounds()); | 71 fStyle.adjustBounds(&bounds, this->bounds()); |
72 return bounds; | 72 return bounds; |
73 } | 73 } |
74 | 74 |
| 75 // If the path is small enough to be keyed from its data this returns key length
, otherwise -1. |
| 76 static int path_key_from_data_size(const SkPath& path) { |
| 77 const int verbCnt = path.countVerbs(); |
| 78 if (verbCnt > GrShape::kMaxKeyFromDataVerbCnt) { |
| 79 return -1; |
| 80 } |
| 81 const int pointCnt = path.countPoints(); |
| 82 const int conicWeightCnt = SkPathPriv::ConicWeightCnt(path); |
| 83 |
| 84 GR_STATIC_ASSERT(sizeof(SkPoint) == 2 * sizeof(uint32_t)); |
| 85 GR_STATIC_ASSERT(sizeof(SkScalar) == sizeof(uint32_t)); |
| 86 // 2 is for the verb cnt and a fill type. Each verb is a byte but we'll pad
the verb data out to |
| 87 // a uint32_t length. |
| 88 return 2 + (SkAlign4(verbCnt) >> 2) + 2 * pointCnt + conicWeightCnt; |
| 89 } |
| 90 |
| 91 // Writes the path data key into the passed pointer. |
| 92 static void write_path_key_from(const SkPath& path, uint32_t* origKey) { |
| 93 uint32_t* key = origKey; |
| 94 // The check below should take care of negative values casted positive. |
| 95 const int verbCnt = path.countVerbs(); |
| 96 const int pointCnt = path.countPoints(); |
| 97 const int conicWeightCnt = SkPathPriv::ConicWeightCnt(path); |
| 98 SkASSERT(verbCnt <= GrShape::kMaxKeyFromDataVerbCnt); |
| 99 SkASSERT(pointCnt && verbCnt); |
| 100 *key++ = path.getFillType(); |
| 101 *key++ = verbCnt; |
| 102 memcpy(key, SkPathPriv::VerbData(path), verbCnt * sizeof(uint8_t)); |
| 103 int verbKeySize = SkAlign4(verbCnt); |
| 104 // pad out to uint32_t alignment using value that will stand out when debugg
ing. |
| 105 uint8_t* pad = reinterpret_cast<uint8_t*>(key)+ verbCnt; |
| 106 memset(pad, 0xDE, verbKeySize - verbCnt); |
| 107 key += verbKeySize >> 2; |
| 108 |
| 109 memcpy(key, SkPathPriv::PointData(path), sizeof(SkPoint) * pointCnt); |
| 110 GR_STATIC_ASSERT(sizeof(SkPoint) == 2 * sizeof(uint32_t)); |
| 111 key += 2 * pointCnt; |
| 112 memcpy(key, SkPathPriv::ConicWeightData(path), sizeof(SkScalar) * conicWeigh
tCnt); |
| 113 GR_STATIC_ASSERT(sizeof(SkScalar) == sizeof(uint32_t)); |
| 114 SkDEBUGCODE(key += conicWeightCnt); |
| 115 SkASSERT(key - origKey == path_key_from_data_size(path)); |
| 116 } |
| 117 |
75 int GrShape::unstyledKeySize() const { | 118 int GrShape::unstyledKeySize() const { |
76 if (fInheritedKey.count()) { | 119 if (fInheritedKey.count()) { |
77 return fInheritedKey.count(); | 120 return fInheritedKey.count(); |
78 } | 121 } |
79 switch (fType) { | 122 switch (fType) { |
80 case Type::kEmpty: | 123 case Type::kEmpty: |
81 return 1; | 124 return 1; |
82 case Type::kRRect: | 125 case Type::kRRect: |
83 SkASSERT(!fInheritedKey.count()); | 126 SkASSERT(!fInheritedKey.count()); |
84 SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t)); | 127 SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t)); |
85 // + 1 for the direction, start index, and inverseness. | 128 // + 1 for the direction, start index, and inverseness. |
86 return SkRRect::kSizeInMemory / sizeof(uint32_t) + 1; | 129 return SkRRect::kSizeInMemory / sizeof(uint32_t) + 1; |
87 case Type::kLine: | 130 case Type::kLine: |
88 GR_STATIC_ASSERT(2 * sizeof(uint32_t) == sizeof(SkPoint)); | 131 GR_STATIC_ASSERT(2 * sizeof(uint32_t) == sizeof(SkPoint)); |
89 // 4 for the end points and 1 for the inverseness | 132 // 4 for the end points and 1 for the inverseness |
90 return 5; | 133 return 5; |
91 case Type::kPath: | 134 case Type::kPath: { |
| 135 int dataKeySize = path_key_from_data_size(fPathData.fPath); |
| 136 if (dataKeySize >= 0) { |
| 137 return dataKeySize; |
| 138 } |
92 if (0 == fPathData.fGenID) { | 139 if (0 == fPathData.fGenID) { |
93 return -1; | 140 return -1; |
94 } else { | |
95 // The key is the path ID and fill type. | |
96 return 2; | |
97 } | 141 } |
| 142 // The key is the path ID and fill type. |
| 143 return 2; |
| 144 } |
98 } | 145 } |
99 SkFAIL("Should never get here."); | 146 SkFAIL("Should never get here."); |
100 return 0; | 147 return 0; |
101 } | 148 } |
102 | 149 |
103 void GrShape::writeUnstyledKey(uint32_t* key) const { | 150 void GrShape::writeUnstyledKey(uint32_t* key) const { |
104 SkASSERT(this->unstyledKeySize()); | 151 SkASSERT(this->unstyledKeySize()); |
105 SkDEBUGCODE(uint32_t* origKey = key;) | 152 SkDEBUGCODE(uint32_t* origKey = key;) |
106 if (fInheritedKey.count()) { | 153 if (fInheritedKey.count()) { |
107 memcpy(key, fInheritedKey.get(), sizeof(uint32_t) * fInheritedKey.count(
)); | 154 memcpy(key, fInheritedKey.get(), sizeof(uint32_t) * fInheritedKey.count(
)); |
108 SkDEBUGCODE(key += fInheritedKey.count();) | 155 SkDEBUGCODE(key += fInheritedKey.count();) |
109 } else { | 156 } else { |
110 switch (fType) { | 157 switch (fType) { |
111 case Type::kEmpty: | 158 case Type::kEmpty: |
112 *key++ = 1; | 159 *key++ = 1; |
113 break; | 160 break; |
114 case Type::kRRect: | 161 case Type::kRRect: |
115 fRRectData.fRRect.writeToMemory(key); | 162 fRRectData.fRRect.writeToMemory(key); |
116 key += SkRRect::kSizeInMemory / sizeof(uint32_t); | 163 key += SkRRect::kSizeInMemory / sizeof(uint32_t); |
117 *key = (fRRectData.fDir == SkPath::kCCW_Direction) ? (1 << 31) :
0; | 164 *key = (fRRectData.fDir == SkPath::kCCW_Direction) ? (1 << 31) :
0; |
118 *key |= fRRectData.fInverted ? (1 << 30) : 0; | 165 *key |= fRRectData.fInverted ? (1 << 30) : 0; |
119 *key++ |= fRRectData.fStart; | 166 *key++ |= fRRectData.fStart; |
120 SkASSERT(fRRectData.fStart < 8); | 167 SkASSERT(fRRectData.fStart < 8); |
121 break; | 168 break; |
122 case Type::kLine: | 169 case Type::kLine: |
123 memcpy(key, fLineData.fPts, 2 * sizeof(SkPoint)); | 170 memcpy(key, fLineData.fPts, 2 * sizeof(SkPoint)); |
124 key += 4; | 171 key += 4; |
125 *key++ = fLineData.fInverted ? 1 : 0; | 172 *key++ = fLineData.fInverted ? 1 : 0; |
126 break; | 173 break; |
127 case Type::kPath: | 174 case Type::kPath: { |
| 175 int dataKeySize = path_key_from_data_size(fPathData.fPath); |
| 176 if (dataKeySize >= 0) { |
| 177 write_path_key_from(fPathData.fPath, key); |
| 178 return; |
| 179 } |
128 SkASSERT(fPathData.fGenID); | 180 SkASSERT(fPathData.fGenID); |
129 *key++ = fPathData.fGenID; | 181 *key++ = fPathData.fGenID; |
130 // We could canonicalize the fill rule for paths that don't diff
erentiate between | 182 // We could canonicalize the fill rule for paths that don't diff
erentiate between |
131 // even/odd or winding fill (e.g. convex). | 183 // even/odd or winding fill (e.g. convex). |
132 *key++ = this->path().getFillType(); | 184 *key++ = this->path().getFillType(); |
133 break; | 185 break; |
| 186 } |
134 } | 187 } |
135 } | 188 } |
136 SkASSERT(key - origKey == this->unstyledKeySize()); | 189 SkASSERT(key - origKey == this->unstyledKeySize()); |
137 } | 190 } |
138 | 191 |
139 void GrShape::setInheritedKey(const GrShape &parent, GrStyle::Apply apply, SkSca
lar scale) { | 192 void GrShape::setInheritedKey(const GrShape &parent, GrStyle::Apply apply, SkSca
lar scale) { |
140 SkASSERT(!fInheritedKey.count()); | 193 SkASSERT(!fInheritedKey.count()); |
141 // If the output shape turns out to be simple, then we will just use its geo
metric key | 194 // If the output shape turns out to be simple, then we will just use its geo
metric key |
142 if (Type::kPath == fType) { | 195 if (Type::kPath == fType) { |
143 // We want ApplyFullStyle(ApplyPathEffect(shape)) to have the same key a
s | 196 // We want ApplyFullStyle(ApplyPathEffect(shape)) to have the same key a
s |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 fStyle = GrStyle::SimpleFill(); | 531 fStyle = GrStyle::SimpleFill(); |
479 return; | 532 return; |
480 } | 533 } |
481 } | 534 } |
482 // Only path effects could care about the order of the points. Otherwise can
onicalize | 535 // Only path effects could care about the order of the points. Otherwise can
onicalize |
483 // the point order. | 536 // the point order. |
484 if (pts[1].fY < pts[0].fY || (pts[1].fY == pts[0].fY && pts[1].fX < pts[0].f
X)) { | 537 if (pts[1].fY < pts[0].fY || (pts[1].fY == pts[0].fY && pts[1].fX < pts[0].f
X)) { |
485 SkTSwap(pts[0], pts[1]); | 538 SkTSwap(pts[0], pts[1]); |
486 } | 539 } |
487 } | 540 } |
OLD | NEW |