Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: src/core/SkPatch.cpp

Issue 405163003: SkPatch abstraction (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« include/core/SkPatch.h ('K') | « include/core/SkPatch.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #include "SkPatch.h"
9 #include "SkGr.h"
10 #include <stdio.h>
11
12 ////////////////////////////////////////////////////////////////////////////////
13
14 CubicEvaluator::CubicEvaluator(SkPoint a, SkPoint b, SkPoint c, SkPoint d){
egdaniel 2014/07/21 21:16:03 There are already some of the eval and coeff calcu
dandov 2014/07/22 13:55:14 I removed the eval function since we already have
15 fPoints[0] = a;
16 fPoints[1] = b;
17 fPoints[2] = c;
18 fPoints[3] = d;
19
20 // save coefficients
21 fCoefs[0].set(-a.x() + 3.0f*b.x() - 3.0f*c.x() + d.x(),
22 -a.y() + 3.0f*b.y() - 3.0f*c.y() + d.y());
23 fCoefs[1].set(3.0f*a.x() - 6.0f*b.x() + 3.0f*c.x(),
24 3.0f*a.y() - 6.0f*b.y() + 3.0f*c.y());
25 fCoefs[2].set(-3.0f*a.x() + 3.0f*b.x(),
26 -3.0f*a.y() + 3.0f*b.y());
27 fCoefs[3].set(a.x(), a.y());
28 }
29
30 SkPoint CubicEvaluator::eval(SkScalar t){
31 return SkPoint::Make(fCoefs[0].x()*t*t*t + fCoefs[1].x()*t*t + fCoefs[2].x() *t +
32 fCoefs[3].x(),
33 fCoefs[0].y()*t*t*t + fCoefs[1].y()*t*t + fCoefs[2].y() *t +
34 fCoefs[3].y());
35 }
36
37 bool CubicEvaluator::hasNext(){
jvanverth1 2014/07/21 22:10:10 This and next() are simple enough, they could be p
dandov 2014/07/22 13:55:14 I substituted this ones with the operator* and ope
38 return fCurrent <= fMax;
39 }
40
41 SkPoint CubicEvaluator::next(){
42 SkPoint point = fFwDiff[0];
43 fFwDiff[0] += fFwDiff[1];
44 fFwDiff[1] += fFwDiff[2];
45 fFwDiff[2] += fFwDiff[3];
46 fCurrent++;
47
48 return point;
49 }
50
51 void CubicEvaluator::reset(int res){
52 fRes = res;
jvanverth1 2014/07/21 22:10:10 Indent
dandov 2014/07/22 13:55:14 Also is ok in my files, I don't know what happened
53 SkScalar h = 1.f/res;
54 fCurrent = 0;
55 fMax = res + 1;
56 fFwDiff[0] = fCoefs[3];
57 SkScalar h2 = h*h;
58 SkScalar h3 = h2*h;
59
60 fFwDiff[3].set(6.f*fCoefs[0].x()*h3, 6.f*fCoefs[0].y()*h3); //6ah^3
61 fFwDiff[2].set(fFwDiff[3].x() + 2.f*fCoefs[1].x()*h2, //6ah^3 + 2bh^2
62 fFwDiff[3].y() + 2.f*fCoefs[1].y()*h2);
63 fFwDiff[1].set(fCoefs[0].x()*h3 + fCoefs[1].x()*h2 + fCoefs[2].x()*h, //ah^3 + bh^2 + ch
64 fCoefs[0].y()*h3 + fCoefs[1].y()*h2 + fCoefs[2].y()*h);
65 }
66
67 const SkPoint* CubicEvaluator::getPoints() {
68 return fPoints;
69 }
70
71 const SkPoint* CubicEvaluator::getCoefs() {
72 return fCoefs;
73 }
74
75 int CubicEvaluator::getResolution() {
76 return fRes;
77 }
78
79 ////////////////////////////////////////////////////////////////////////////////
80
81 SkPatchMesh::SkPatchMesh()
82 : fVertCount(0)
83 , fIndexCount(0)
84 , fData(NULL)
85 , fIndices(NULL)
86 , fUseColors(false)
87 , fUseTexCoords(false)
88 , fIntercalate(false)
89 , fColorFormat(kSkColor_ColorFormat) { }
90
91 void SkPatchMesh::init(int vertCount, int indexCount, SkColorFormat format, bool useTexCoords,
92 bool intercalate) {
93
94 this->reset();
95
96 fUseColors = format != kNoColor_ColorFormat;
97 fUseTexCoords = useTexCoords;
98 fIntercalate = intercalate;
jvanverth1 2014/07/21 22:10:09 I don't know this term. Should this be fInterpolat
dandov 2014/07/22 13:55:14 I couldn't find a nice word to say that the data i
99 fColorFormat = format;
100
101 int colorSize = 0;
102 switch (format) {
103 case SkPatchMesh::kNoColor_ColorFormat:
104 colorSize = 0;
105 break;
106 case SkPatchMesh::kSkColor_ColorFormat:
107 colorSize = sizeof(SkColor);
108 break;
109 //case SkPatchMesh::kSkPMColor_ColorFormat:
110 // colorSize = sizeof(SkPMColor);
111 // break;
112 case SkPatchMesh::kGrColor_ColorFormat:
113 colorSize = sizeof(GrColor);
114 break;
115 }
116
117 fVertCount = vertCount;
118 fIndexCount = indexCount;
119 int totalBytes = fVertCount*sizeof(SkPoint) + (fUseColors ? fVertCount*color Size : 0)
120 + (fUseTexCoords*sizeof(SkPoint) ? fVertCount : 0);
121
122 fData = SkNEW_ARRAY(uint8_t, totalBytes);
123 fIndices = SkNEW_ARRAY(uint16_t, fIndexCount);
124
125 if (fIntercalate) {
126 //here the offset represents the offset inside an intercalated object;
127 // if using colors then the offset is the size of the vertex
128 fColorOffset = fUseColors ? sizeof(SkPoint) : 0;
129 //if using colors then it is the size of the vertex + the size of the co lor
130 //else is the size of the vertex only
131 fTexOffset = fUseColors ? (fUseTexCoords ? sizeof(SkPoint)+colorSize : 0 )
132 : (fUseTexCoords ? sizeof(SkPoint) : 0);
133 fDataSize = sizeof(SkPoint) + (fUseColors ? colorSize : 0) +
134 (fUseTexCoords ? sizeof(SkPoint) : 0);
135 } else {
136 //here the offset is when the array of colors or uv's starts based on fD ata in bytes
137 fColorOffset = fUseColors ? fVertCount*sizeof(SkPoint) : 0;
138 fTexOffset = fUseTexCoords ?
139 (fUseColors ? fVertCount*sizeof(SkPoint) + fVertCount*colorSize :
140 fVertCount*sizeof(SkPoint))
141 : 0;
142 fDataSize = 0;
143 }
144 }
145
146 void SkPatchMesh::reset() {
147 SkDELETE_ARRAY (fData);
148 SkDELETE_ARRAY (fIndices);
149 fVertCount = 0;
150 fIndexCount = 0;
151 fData = NULL;
152 fIndices = NULL;
153 fUseColors = false;
154 fUseTexCoords = false;
155 fIntercalate = false;
156 fColorFormat = kSkColor_ColorFormat;
157 }
158
159 SkPatchMesh::~SkPatchMesh() {
160 this->reset();
161 }
162
163 const SkPoint* SkPatchMesh::getPoints() {
164 if (fIntercalate) {
165 return NULL;
166 } else {
167 return reinterpret_cast<SkPoint*>(fData);
168 }
169 }
170
171 const uint16_t* SkPatchMesh::getIndices() {
172 return fIndices;
173 }
174
175 const SkColor* SkPatchMesh::getColors() {
176 if (fIntercalate || !fUseColors) {
177 return NULL;
178 } else {
179 return reinterpret_cast<SkColor*>(fData + fColorOffset);
180 }
181 }
182
183 const SkPoint* SkPatchMesh::getTexCoords() {
184 if (fIntercalate || !fUseTexCoords) {
185 return NULL;
186 } else {
187 return reinterpret_cast<SkPoint*>(fData + fTexOffset);
188 }
189 }
190
191 const uint8_t* SkPatchMesh::getData() {
192 return reinterpret_cast<uint8_t*>(fData);
193 }
194
195 SkPoint& SkPatchMesh::pointAt(int index) {
196 if (fIntercalate) {
197 index *= fDataSize;
198 }else {
199 index *= sizeof(SkPoint);
200 }
201 return *reinterpret_cast<SkPoint*>(fData + index);
202 }
203
204 uint32_t& SkPatchMesh::colorAt(int index) {
205 SkASSERT(fUseColors);
206
207 if (fIntercalate) {
208 //getting the address of object with fDatasize in position index, move t o color in that obj
209 index = index * fDataSize + fColorOffset;
210 } else {
211 //starting in the colors array, move to the indexth color
212 index = fColorOffset + index * sizeof(SkColor);
213 }
214 return *reinterpret_cast<SkColor*>(fData + index);
215 }
216
217 bool SkPatchMesh::setColorAt(int index, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
218 if (!fUseColors) {
219 return false;
220 }
221 SkColor& colorRef = this->colorAt(index);
222
223 switch (fColorFormat) {
224 case SkPatchMesh::kSkColor_ColorFormat:
225 colorRef = SkColorSetARGB(a,r,g,b);
226 break;
227 //case SkPatchMesh::kSkPMColor_ColorFormat:
228 // colorSize = sizeof(SkPMColor);
229 // break;
230 case SkPatchMesh::kGrColor_ColorFormat:
231 colorRef = SkColor2GrColor(SkPreMultiplyARGB(a,r,g,b));//GrColorPack RGBA(r,g,b,a);
232 break;
233 default:
234 break;
235 }
236 return true;
237 }
238
239 SkPoint& SkPatchMesh::texCoordAt(int index) {
240 SkASSERT(fUseTexCoords);
241
242 if (fIntercalate) {
243 index = index * fDataSize + fTexOffset;
244 } else {
245 index = fTexOffset + index * sizeof(SkPoint);
246 }
247 return *reinterpret_cast<SkPoint*>(fData + index);
248 }
249
250 void SkPatchMesh::setIndices(int index, uint16_t* indices, int size) {
251 for (int i = 0; i < size; ++i) {
252 fIndices[index + i] = indices[i];
253 }
254 }
255
256 int SkPatchMesh::getVertexCount() {
257 return fVertCount;
258 }
259
260 int SkPatchMesh::getIndexCount() {
261 return fIndexCount;
262 }
263
264 bool SkPatchMesh::useColors() {
265 return fUseColors;
266 }
267
268 bool SkPatchMesh::useTexCoords() {
269 return fUseTexCoords;
270 }
271
272 bool SkPatchMesh::isIntercalated() {
273 return fIntercalate;
274 }
275
276 ////////////////////////////////////////////////////////////////////////////////
277
278 SkCoonsPatch::SkCoonsPatch(SkPoint points[12], SkColor (*colors)[4], int res)
279 : fPoints(points)
280 , fBottom(points[0], points[1], points[2], points[3])
281 , fTop(points[4], points[5], points[6], points[7])
282 , fLeft(points[0], points[8], points[9], points[4])
283 , fRight(points[3], points[10], points[11], points[7])
284 , fResX(res)
285 , fResY(res) {
286 fColors[0] = ((*colors)[0]);
287 fColors[1] = ((*colors)[1]);
288 fColors[2] = ((*colors)[2]);
289 fColors[3] = ((*colors)[3]);
290 }
291
292 uint8_t bilinear(SkScalar tx, SkScalar ty, SkScalar c00, SkScalar c10, SkScalar c01, SkScalar c11) {
293 SkScalar a = c00 * (1.f - tx) + c10 * tx;
294 SkScalar b = c01 * (1.f - tx) + c11 * tx;
295 return uint8_t(a * (1.f - ty) + b * ty);
296 }
297
298 // Each patch has the responsability to generate its mesh and the meshpatch hand les the type of data
299 // This method first initializes the mesh by providing the number of vertices, i ndices, the format
300 // of the colors, if it needs texture coordinates and if the data should be inte rcalated.
301 bool SkCoonsPatch::genMesh(SkPatchMesh* mesh, SkPatchMesh::SkColorFormat format, bool useTexCoords,
302 bool intercalate) const {
303
304 //setup how we are going to use the data based on the client preferences and how the patch
305 //behaves, the derived class could just hardcode this parameters or take int o account the
306 //preferences of the caller like we do in this example
307 if (!this->usesColors()) {
308 format = SkPatchMesh::kNoColor_ColorFormat;
309 }
310 mesh->init((fResX + 1) * (fResY + 1), fResX * fResY * 6, format,
311 this->usesTexCoords() && useTexCoords, intercalate);
312
313 fBottom.reset(fResX);
314 fTop.reset(fResX);
315
316 SkScalar u = 0.0f;
317 int stride = fResY+1;
318 for (int x = 0; x <= fResX; x++) {
319 SkPoint bottom = fBottom.next(), top = fTop.next();
320 fLeft.reset(fResY);
321 fRight.reset(fResY);
322 SkScalar v = 0.f;
323 for (int y = 0; y <= fResY; y++) {
324 int dataIndex = x*(fResX + 1) + y;
325
326 SkPoint left = fLeft.next(), right = fRight.next();
327
328 SkPoint s0 = SkPoint::Make((1.0f - v)*bottom.x() + v*top.x(),
329 (1.0f - v)*bottom.y() + v*top.y());
330 SkPoint s1 = SkPoint::Make((1.0f - u)*left.x() + u*right.x(),
331 (1.0f - u)*left.y() + u*right.y());
332 SkPoint s2 = SkPoint::Make(
333 (1.0f - v)*((1.0f - u)*fBottom.getPoints()[0].x()
334 + u*fBottom.getPoints()[3].x())
335 + v*((1.0f - u)*fTop.getPoints()[0].x() + u*fTop.get Points()[3].x()),
336 (1.0f - v)*((1.0f - u)*fBottom.getPoints()[0].y()
337 + u*fBottom.getPoints()[3].y())
338 + v*((1.0f - u)*fTop.getPoints()[0].y() + u*fTop.get Points()[3].y()));
339 //always set the point
340 mesh->pointAt(dataIndex) = s0 + s1 - s2;
341
342 //check if we should set the color
343 if(mesh->useColors()) {
344 //these colors should be premultiplied for the bilerp but curren tly drawVertices
345 //premultiplies them, so here they will be darker
346 uint8_t a = bilinear(u, v, SkScalar(SkColorGetA(fColors[0])),
347 SkScalar(SkColorGetA(fColors[1])), SkScalar(SkColo rGetA(fColors[2])),
348 SkScalar(SkColorGetA(fColors[3])));
349 uint8_t r = bilinear(u, v, SkScalar(SkColorGetR(fColors[0])),
350 SkScalar(SkColorGetR(fColors[1])), SkScalar(SkColo rGetR(fColors[2])),
351 SkScalar(SkColorGetR(fColors[3])));
352 uint8_t g = bilinear(u, v, SkScalar(SkColorGetG(fColors[0])),
353 SkScalar(SkColorGetG(fColors[1])), SkScalar(SkColo rGetG(fColors[2])),
354 SkScalar(SkColorGetG(fColors[3])));
355 uint8_t b = bilinear(u, v, SkScalar(SkColorGetB(fColors[0])),
356 SkScalar(SkColorGetB(fColors[1])), SkScalar(SkColo rGetB(fColors[2])),
357 SkScalar(SkColorGetB(fColors[3])));
358 //mesh->colorAt(dataIndex) = SkColorSetARGB(a, r, g, b);
359 mesh->setColorAt(dataIndex, r,g,b,a);
360 }
361
362 //check if we should set the texture coordinates
363 if (mesh->useTexCoords()) {
364 mesh->texCoordAt(dataIndex) = SkPoint::Make(u, v);
365 }
366
367 //set the indices
368 if(x < fResX && y < fResY) {
369 uint16_t indices[6];
370 int i = 6*(x*fResY + y);
371 indices[0] = x*stride+y;
372 indices[1] = x*stride+1+y;
373 indices[2] = (x+1)*stride+1+y;
374 indices[3] = indices[0];
375 indices[4] = indices[2];
376 indices[5] = (x+1)*stride+y;
377 mesh->setIndices(i, indices, 6);
378 }
379
380 v+=1.f/fResY;
381 }
382 u+=1.f/fResX;
383 }
384 return true;
385 }
OLDNEW
« include/core/SkPatch.h ('K') | « include/core/SkPatch.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698