OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "GrAARectRenderer.h" | 8 #include "GrAARectRenderer.h" |
9 #include "GrDefaultGeoProcFactory.h" | 9 #include "GrDefaultGeoProcFactory.h" |
10 #include "GrGeometryProcessor.h" | 10 #include "GrGeometryProcessor.h" |
11 #include "GrGpu.h" | 11 #include "GrGpu.h" |
12 #include "GrInvariantOutput.h" | 12 #include "GrInvariantOutput.h" |
13 #include "SkColorPriv.h" | 13 #include "SkColorPriv.h" |
14 #include "gl/GrGLProcessor.h" | 14 #include "gl/GrGLProcessor.h" |
15 #include "gl/GrGLGeometryProcessor.h" | 15 #include "gl/GrGLGeometryProcessor.h" |
16 #include "gl/builders/GrGLProgramBuilder.h" | 16 #include "gl/builders/GrGLProgramBuilder.h" |
17 | 17 |
18 /////////////////////////////////////////////////////////////////////////////// | 18 /////////////////////////////////////////////////////////////////////////////// |
19 | 19 |
20 namespace { | 20 namespace { |
21 // Should the coverage be multiplied into the color attrib or use a separate att
rib. | 21 // Should the coverage be multiplied into the color attrib or use a separate att
rib. |
22 enum CoverageAttribType { | 22 enum CoverageAttribType { |
23 kUseColor_CoverageAttribType, | 23 kUseColor_CoverageAttribType, |
24 kUseCoverage_CoverageAttribType, | 24 kUseCoverage_CoverageAttribType, |
25 }; | 25 }; |
26 } | 26 } |
27 | 27 |
28 static const GrGeometryProcessor* create_rect_gp(const GrDrawState& drawState, G
rColor color, | 28 static const GrGeometryProcessor* create_rect_gp(const GrDrawState& drawState, |
| 29 GrColor color, |
29 CoverageAttribType* type, | 30 CoverageAttribType* type, |
30 const SkMatrix& localMatrix) { | 31 const SkMatrix& localMatrix) { |
31 uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; | 32 uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; |
32 const GrGeometryProcessor* gp; | 33 const GrGeometryProcessor* gp; |
33 if (drawState.canTweakAlphaForCoverage()) { | 34 if (drawState.canTweakAlphaForCoverage()) { |
34 gp = GrDefaultGeoProcFactory::Create(color, flags, localMatrix); | 35 gp = GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), localM
atrix); |
35 SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::Positi
onColorAttr)); | 36 SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::Positi
onColorAttr)); |
36 *type = kUseColor_CoverageAttribType; | 37 *type = kUseColor_CoverageAttribType; |
37 } else { | 38 } else { |
38 flags |= GrDefaultGeoProcFactory::kCoverage_GPType; | 39 flags |= GrDefaultGeoProcFactory::kCoverage_GPType; |
39 gp = GrDefaultGeoProcFactory::Create(color, flags, GrColorIsOpaque(color
), 0xff, | 40 gp = GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), localM
atrix, |
40 localMatrix); | 41 GrColorIsOpaque(color)); |
41 SkASSERT(gp->getVertexStride()==sizeof(GrDefaultGeoProcFactory::Position
ColorCoverageAttr)); | 42 SkASSERT(gp->getVertexStride()==sizeof(GrDefaultGeoProcFactory::Position
ColorCoverageAttr)); |
42 *type = kUseCoverage_CoverageAttribType; | 43 *type = kUseCoverage_CoverageAttribType; |
43 } | 44 } |
44 return gp; | 45 return gp; |
45 } | 46 } |
46 | 47 |
47 static void set_inset_fan(SkPoint* pts, size_t stride, | 48 static void set_inset_fan(SkPoint* pts, size_t stride, |
48 const SkRect& r, SkScalar dx, SkScalar dy) { | 49 const SkRect& r, SkScalar dx, SkScalar dy) { |
49 pts->setRectFan(r.fLeft + dx, r.fTop + dy, | 50 pts->setRectFan(r.fLeft + dx, r.fTop + dy, |
50 r.fRight - dx, r.fBottom - dy, stride); | 51 r.fRight - dx, r.fBottom - dy, stride); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 kNumBevelStrokeRectsInIndex
Buffer, | 174 kNumBevelStrokeRectsInIndex
Buffer, |
174 kVertsPerBevelStrokeRect); | 175 kVertsPerBevelStrokeRect); |
175 } | 176 } |
176 return fAABevelStrokeRectIndexBuffer; | 177 return fAABevelStrokeRectIndexBuffer; |
177 } | 178 } |
178 } | 179 } |
179 | 180 |
180 void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target, | 181 void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target, |
181 GrDrawState* drawState, | 182 GrDrawState* drawState, |
182 GrColor color, | 183 GrColor color, |
183 const SkMatrix& localMatrix, | 184 const SkMatrix& viewMatrix, |
184 const SkRect& rect, | 185 const SkRect& rect, |
185 const SkMatrix& combinedMatrix, | |
186 const SkRect& devRect) { | 186 const SkRect& devRect) { |
187 GrDrawState::AutoRestoreEffects are(drawState); | 187 GrDrawState::AutoRestoreEffects are(drawState); |
188 | 188 |
| 189 SkMatrix localMatrix; |
| 190 if (!viewMatrix.invert(&localMatrix)) { |
| 191 SkDebugf("Cannot invert\n"); |
| 192 return; |
| 193 } |
| 194 |
189 CoverageAttribType type; | 195 CoverageAttribType type; |
190 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color,
&type, | 196 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color,
&type, |
191 localMatrix)); | 197 localMatrix)); |
192 | 198 |
193 size_t vertexStride = gp->getVertexStride(); | 199 size_t vertexStride = gp->getVertexStride(); |
194 GrDrawTarget::AutoReleaseGeometry geo(target, 8, vertexStride, 0); | 200 GrDrawTarget::AutoReleaseGeometry geo(target, 8, vertexStride, 0); |
195 if (!geo.succeeded()) { | 201 if (!geo.succeeded()) { |
196 SkDebugf("Failed to get space for vertices!\n"); | 202 SkDebugf("Failed to get space for vertices!\n"); |
197 return; | 203 return; |
198 } | 204 } |
(...skipping 11 matching lines...) Expand all Loading... |
210 } | 216 } |
211 | 217 |
212 intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); | 218 intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); |
213 | 219 |
214 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); | 220 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); |
215 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); | 221 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); |
216 | 222 |
217 SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1); | 223 SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1); |
218 inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height()); | 224 inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height()); |
219 | 225 |
220 if (combinedMatrix.rectStaysRect()) { | 226 if (viewMatrix.rectStaysRect()) { |
221 // Temporarily #if'ed out. We don't want to pass in the devRect but | 227 // Temporarily #if'ed out. We don't want to pass in the devRect but |
222 // right now it is computed in GrContext::apply_aa_to_rect and we don't | 228 // right now it is computed in GrContext::apply_aa_to_rect and we don't |
223 // want to throw away the work | 229 // want to throw away the work |
224 #if 0 | 230 #if 0 |
225 SkRect devRect; | 231 SkRect devRect; |
226 combinedMatrix.mapRect(&devRect, rect); | 232 combinedMatrix.mapRect(&devRect, rect); |
227 #endif | 233 #endif |
228 | 234 |
229 set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_Scalar
Half); | 235 set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_Scalar
Half); |
230 set_inset_fan(fan1Pos, vertexStride, devRect, inset, inset); | 236 set_inset_fan(fan1Pos, vertexStride, devRect, inset, inset); |
231 } else { | 237 } else { |
232 // compute transformed (1, 0) and (0, 1) vectors | 238 // compute transformed (1, 0) and (0, 1) vectors |
233 SkVector vec[2] = { | 239 SkVector vec[2] = { |
234 { combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY
] }, | 240 { viewMatrix[SkMatrix::kMScaleX], viewMatrix[SkMatrix::kMSkewY] }, |
235 { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix::kMScale
Y] } | 241 { viewMatrix[SkMatrix::kMSkewX], viewMatrix[SkMatrix::kMScaleY] } |
236 }; | 242 }; |
237 | 243 |
238 vec[0].normalize(); | 244 vec[0].normalize(); |
239 vec[0].scale(SK_ScalarHalf); | 245 vec[0].scale(SK_ScalarHalf); |
240 vec[1].normalize(); | 246 vec[1].normalize(); |
241 vec[1].scale(SK_ScalarHalf); | 247 vec[1].scale(SK_ScalarHalf); |
242 | 248 |
243 // create the rotated rect | 249 // create the rotated rect |
244 fan0Pos->setRectFan(rect.fLeft, rect.fTop, | 250 fan0Pos->setRectFan(rect.fLeft, rect.fTop, |
245 rect.fRight, rect.fBottom, vertexStride); | 251 rect.fRight, rect.fBottom, vertexStride); |
246 combinedMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4); | 252 viewMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4); |
247 | 253 |
248 // Now create the inset points and then outset the original | 254 // Now create the inset points and then outset the original |
249 // rotated points | 255 // rotated points |
250 | 256 |
251 // TL | 257 // TL |
252 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) = | 258 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) = |
253 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + vec[1
]; | 259 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + vec[1
]; |
254 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[1]; | 260 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[1]; |
255 // BL | 261 // BL |
256 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) = | 262 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) = |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 kTriangles_GrPrimitiveType, | 311 kTriangles_GrPrimitiveType, |
306 1, | 312 1, |
307 kVertsPerAAFillRect, | 313 kVertsPerAAFillRect, |
308 kIndicesPerAAFillRect); | 314 kIndicesPerAAFillRect); |
309 target->resetIndexSource(); | 315 target->resetIndexSource(); |
310 } | 316 } |
311 | 317 |
312 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, | 318 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, |
313 GrDrawState* drawState, | 319 GrDrawState* drawState, |
314 GrColor color, | 320 GrColor color, |
315 const SkMatrix& localMatrix, | 321 const SkMatrix& viewMatrix, |
316 const SkRect& rect, | 322 const SkRect& rect, |
317 const SkMatrix& combinedMatrix, | |
318 const SkRect& devRect, | 323 const SkRect& devRect, |
319 const SkStrokeRec& stroke) { | 324 const SkStrokeRec& stroke) { |
320 SkVector devStrokeSize; | 325 SkVector devStrokeSize; |
321 SkScalar width = stroke.getWidth(); | 326 SkScalar width = stroke.getWidth(); |
322 if (width > 0) { | 327 if (width > 0) { |
323 devStrokeSize.set(width, width); | 328 devStrokeSize.set(width, width); |
324 combinedMatrix.mapVectors(&devStrokeSize, 1); | 329 viewMatrix.mapVectors(&devStrokeSize, 1); |
325 devStrokeSize.setAbs(devStrokeSize); | 330 devStrokeSize.setAbs(devStrokeSize); |
326 } else { | 331 } else { |
327 devStrokeSize.set(SK_Scalar1, SK_Scalar1); | 332 devStrokeSize.set(SK_Scalar1, SK_Scalar1); |
328 } | 333 } |
329 | 334 |
330 const SkScalar dx = devStrokeSize.fX; | 335 const SkScalar dx = devStrokeSize.fX; |
331 const SkScalar dy = devStrokeSize.fY; | 336 const SkScalar dy = devStrokeSize.fY; |
332 const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); | 337 const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); |
333 const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf); | 338 const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf); |
334 | 339 |
(...skipping 17 matching lines...) Expand all Loading... |
352 | 357 |
353 bool miterStroke = true; | 358 bool miterStroke = true; |
354 // For hairlines, make bevel and round joins appear the same as mitered ones
. | 359 // For hairlines, make bevel and round joins appear the same as mitered ones
. |
355 // small miter limit means right angles show bevel... | 360 // small miter limit means right angles show bevel... |
356 if ((width > 0) && (stroke.getJoin() != SkPaint::kMiter_Join || | 361 if ((width > 0) && (stroke.getJoin() != SkPaint::kMiter_Join || |
357 stroke.getMiter() < SK_ScalarSqrt2)) { | 362 stroke.getMiter() < SK_ScalarSqrt2)) { |
358 miterStroke = false; | 363 miterStroke = false; |
359 } | 364 } |
360 | 365 |
361 if (spare <= 0 && miterStroke) { | 366 if (spare <= 0 && miterStroke) { |
362 this->fillAARect(target, drawState, color, localMatrix, devOutside, SkMa
trix::I(), | 367 this->fillAARect(target, drawState, color, viewMatrix, devOutside, |
363 devOutside); | 368 devOutside); |
364 return; | 369 return; |
365 } | 370 } |
366 | 371 |
367 SkRect devInside(devRect); | 372 SkRect devInside(devRect); |
368 devInside.inset(rx, ry); | 373 devInside.inset(rx, ry); |
369 | 374 |
370 SkRect devOutsideAssist(devRect); | 375 SkRect devOutsideAssist(devRect); |
371 | 376 |
372 // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist) | 377 // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist) |
373 // to draw the outer of the rect. Because there are 8 vertices on the outer | 378 // to draw the outer of the rect. Because there are 8 vertices on the outer |
374 // edge, while vertex number of inner edge is 4, the same as miter-stroke. | 379 // edge, while vertex number of inner edge is 4, the same as miter-stroke. |
375 if (!miterStroke) { | 380 if (!miterStroke) { |
376 devOutside.inset(0, ry); | 381 devOutside.inset(0, ry); |
377 devOutsideAssist.outset(0, ry); | 382 devOutsideAssist.outset(0, ry); |
378 } | 383 } |
379 | 384 |
380 this->geometryStrokeAARect(target, drawState, color, localMatrix, devOutside
, devOutsideAssist, | 385 this->geometryStrokeAARect(target, drawState, color, viewMatrix, devOutside,
devOutsideAssist, |
381 devInside, miterStroke); | 386 devInside, miterStroke); |
382 } | 387 } |
383 | 388 |
384 void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target, | 389 void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target, |
385 GrDrawState* drawState, | 390 GrDrawState* drawState, |
386 GrColor color, | 391 GrColor color, |
387 const SkMatrix& localMatrix, | 392 const SkMatrix& viewMatrix, |
388 const SkRect& devOutside, | 393 const SkRect& devOutside, |
389 const SkRect& devOutsideAssist, | 394 const SkRect& devOutsideAssist, |
390 const SkRect& devInside, | 395 const SkRect& devInside, |
391 bool miterStroke) { | 396 bool miterStroke) { |
392 GrDrawState::AutoRestoreEffects are(drawState); | 397 GrDrawState::AutoRestoreEffects are(drawState); |
393 | 398 |
| 399 SkMatrix localMatrix; |
| 400 if (!viewMatrix.invert(&localMatrix)) { |
| 401 SkDebugf("Cannot invert\n"); |
| 402 return; |
| 403 } |
| 404 |
394 CoverageAttribType type; | 405 CoverageAttribType type; |
395 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color,
&type, | 406 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color,
&type, |
396 localMatrix)); | 407 localMatrix)); |
397 | 408 |
398 int innerVertexNum = 4; | 409 int innerVertexNum = 4; |
399 int outerVertexNum = miterStroke ? 4 : 8; | 410 int outerVertexNum = miterStroke ? 4 : 8; |
400 int totalVertexNum = (outerVertexNum + innerVertexNum) * 2; | 411 int totalVertexNum = (outerVertexNum + innerVertexNum) * 2; |
401 | 412 |
402 size_t vstride = gp->getVertexStride(); | 413 size_t vstride = gp->getVertexStride(); |
403 GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, vstride, 0); | 414 GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, vstride, 0); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 kTriangles_GrPrimitiveType, | 522 kTriangles_GrPrimitiveType, |
512 1, | 523 1, |
513 totalVertexNum, | 524 totalVertexNum, |
514 aa_stroke_rect_index_count(miterStroke)); | 525 aa_stroke_rect_index_count(miterStroke)); |
515 target->resetIndexSource(); | 526 target->resetIndexSource(); |
516 } | 527 } |
517 | 528 |
518 void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target, | 529 void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target, |
519 GrDrawState* drawState, | 530 GrDrawState* drawState, |
520 GrColor color, | 531 GrColor color, |
521 const SkMatrix& localMatrix, | 532 const SkMatrix& viewMatrix, |
522 const SkRect rects[2], | 533 const SkRect rects[2]) { |
523 const SkMatrix& combinedMatrix) { | 534 SkASSERT(viewMatrix.rectStaysRect()); |
524 SkASSERT(combinedMatrix.rectStaysRect()); | |
525 SkASSERT(!rects[1].isEmpty()); | 535 SkASSERT(!rects[1].isEmpty()); |
526 | 536 |
527 SkRect devOutside, devOutsideAssist, devInside; | 537 SkRect devOutside, devOutsideAssist, devInside; |
528 combinedMatrix.mapRect(&devOutside, rects[0]); | 538 viewMatrix.mapRect(&devOutside, rects[0]); |
529 // can't call mapRect for devInside since it calls sort | 539 // can't call mapRect for devInside since it calls sort |
530 combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2)
; | 540 viewMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2); |
531 | 541 |
532 if (devInside.isEmpty()) { | 542 if (devInside.isEmpty()) { |
533 this->fillAARect(target, drawState, color, localMatrix, devOutside, SkMa
trix::I(), | 543 this->fillAARect(target, drawState, color, viewMatrix, devOutside, |
534 devOutside); | 544 devOutside); |
535 return; | 545 return; |
536 } | 546 } |
537 | 547 |
538 this->geometryStrokeAARect(target, drawState, color, localMatrix, devOutside
, devOutsideAssist, | 548 this->geometryStrokeAARect(target, drawState, color, viewMatrix, devOutside,
devOutsideAssist, |
539 devInside, true); | 549 devInside, true); |
540 } | 550 } |
OLD | NEW |