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, G
rColor color, |
29 CoverageAttribType* type) { | 29 CoverageAttribType* type, |
| 30 const SkMatrix& localMatrix) { |
30 uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; | 31 uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; |
31 const GrGeometryProcessor* gp; | 32 const GrGeometryProcessor* gp; |
32 if (drawState.canTweakAlphaForCoverage()) { | 33 if (drawState.canTweakAlphaForCoverage()) { |
33 gp = GrDefaultGeoProcFactory::Create(color, flags); | 34 gp = GrDefaultGeoProcFactory::Create(color, flags, localMatrix); |
34 SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::Positi
onColorAttr)); | 35 SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::Positi
onColorAttr)); |
35 *type = kUseColor_CoverageAttribType; | 36 *type = kUseColor_CoverageAttribType; |
36 } else { | 37 } else { |
37 flags |= GrDefaultGeoProcFactory::kCoverage_GPType; | 38 flags |= GrDefaultGeoProcFactory::kCoverage_GPType; |
38 gp = GrDefaultGeoProcFactory::Create(color, flags, GrColorIsOpaque(color
)); | 39 gp = GrDefaultGeoProcFactory::Create(color, flags, GrColorIsOpaque(color
), 0xff, |
| 40 localMatrix); |
39 SkASSERT(gp->getVertexStride()==sizeof(GrDefaultGeoProcFactory::Position
ColorCoverageAttr)); | 41 SkASSERT(gp->getVertexStride()==sizeof(GrDefaultGeoProcFactory::Position
ColorCoverageAttr)); |
40 *type = kUseCoverage_CoverageAttribType; | 42 *type = kUseCoverage_CoverageAttribType; |
41 } | 43 } |
42 return gp; | 44 return gp; |
43 } | 45 } |
44 | 46 |
45 static void set_inset_fan(SkPoint* pts, size_t stride, | 47 static void set_inset_fan(SkPoint* pts, size_t stride, |
46 const SkRect& r, SkScalar dx, SkScalar dy) { | 48 const SkRect& r, SkScalar dx, SkScalar dy) { |
47 pts->setRectFan(r.fLeft + dx, r.fTop + dy, | 49 pts->setRectFan(r.fLeft + dx, r.fTop + dy, |
48 r.fRight - dx, r.fBottom - dy, stride); | 50 r.fRight - dx, r.fBottom - dy, stride); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 kNumBevelStrokeRectsInIndex
Buffer, | 173 kNumBevelStrokeRectsInIndex
Buffer, |
172 kVertsPerBevelStrokeRect); | 174 kVertsPerBevelStrokeRect); |
173 } | 175 } |
174 return fAABevelStrokeRectIndexBuffer; | 176 return fAABevelStrokeRectIndexBuffer; |
175 } | 177 } |
176 } | 178 } |
177 | 179 |
178 void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target, | 180 void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target, |
179 GrDrawState* drawState, | 181 GrDrawState* drawState, |
180 GrColor color, | 182 GrColor color, |
| 183 const SkMatrix& localMatrix, |
181 const SkRect& rect, | 184 const SkRect& rect, |
182 const SkMatrix& combinedMatrix, | 185 const SkMatrix& combinedMatrix, |
183 const SkRect& devRect) { | 186 const SkRect& devRect) { |
184 GrDrawState::AutoRestoreEffects are(drawState); | 187 GrDrawState::AutoRestoreEffects are(drawState); |
185 | 188 |
186 CoverageAttribType type; | 189 CoverageAttribType type; |
187 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color,
&type)); | 190 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color,
&type, |
| 191 localMatrix)); |
188 | 192 |
189 size_t vertexStride = gp->getVertexStride(); | 193 size_t vertexStride = gp->getVertexStride(); |
190 GrDrawTarget::AutoReleaseGeometry geo(target, 8, vertexStride, 0); | 194 GrDrawTarget::AutoReleaseGeometry geo(target, 8, vertexStride, 0); |
191 if (!geo.succeeded()) { | 195 if (!geo.succeeded()) { |
192 SkDebugf("Failed to get space for vertices!\n"); | 196 SkDebugf("Failed to get space for vertices!\n"); |
193 return; | 197 return; |
194 } | 198 } |
195 | 199 |
196 if (NULL == fAAFillRectIndexBuffer) { | 200 if (NULL == fAAFillRectIndexBuffer) { |
197 fAAFillRectIndexBuffer = fGpu->createInstancedIndexBuffer(gFillAARectIdx
, | 201 fAAFillRectIndexBuffer = fGpu->createInstancedIndexBuffer(gFillAARectIdx
, |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 kTriangles_GrPrimitiveType, | 305 kTriangles_GrPrimitiveType, |
302 1, | 306 1, |
303 kVertsPerAAFillRect, | 307 kVertsPerAAFillRect, |
304 kIndicesPerAAFillRect); | 308 kIndicesPerAAFillRect); |
305 target->resetIndexSource(); | 309 target->resetIndexSource(); |
306 } | 310 } |
307 | 311 |
308 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, | 312 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, |
309 GrDrawState* drawState, | 313 GrDrawState* drawState, |
310 GrColor color, | 314 GrColor color, |
| 315 const SkMatrix& localMatrix, |
311 const SkRect& rect, | 316 const SkRect& rect, |
312 const SkMatrix& combinedMatrix, | 317 const SkMatrix& combinedMatrix, |
313 const SkRect& devRect, | 318 const SkRect& devRect, |
314 const SkStrokeRec& stroke) { | 319 const SkStrokeRec& stroke) { |
315 SkVector devStrokeSize; | 320 SkVector devStrokeSize; |
316 SkScalar width = stroke.getWidth(); | 321 SkScalar width = stroke.getWidth(); |
317 if (width > 0) { | 322 if (width > 0) { |
318 devStrokeSize.set(width, width); | 323 devStrokeSize.set(width, width); |
319 combinedMatrix.mapVectors(&devStrokeSize, 1); | 324 combinedMatrix.mapVectors(&devStrokeSize, 1); |
320 devStrokeSize.setAbs(devStrokeSize); | 325 devStrokeSize.setAbs(devStrokeSize); |
(...skipping 26 matching lines...) Expand all Loading... |
347 | 352 |
348 bool miterStroke = true; | 353 bool miterStroke = true; |
349 // For hairlines, make bevel and round joins appear the same as mitered ones
. | 354 // For hairlines, make bevel and round joins appear the same as mitered ones
. |
350 // small miter limit means right angles show bevel... | 355 // small miter limit means right angles show bevel... |
351 if ((width > 0) && (stroke.getJoin() != SkPaint::kMiter_Join || | 356 if ((width > 0) && (stroke.getJoin() != SkPaint::kMiter_Join || |
352 stroke.getMiter() < SK_ScalarSqrt2)) { | 357 stroke.getMiter() < SK_ScalarSqrt2)) { |
353 miterStroke = false; | 358 miterStroke = false; |
354 } | 359 } |
355 | 360 |
356 if (spare <= 0 && miterStroke) { | 361 if (spare <= 0 && miterStroke) { |
357 this->fillAARect(target, drawState, color, devOutside, SkMatrix::I(), de
vOutside); | 362 this->fillAARect(target, drawState, color, localMatrix, devOutside, SkMa
trix::I(), |
| 363 devOutside); |
358 return; | 364 return; |
359 } | 365 } |
360 | 366 |
361 SkRect devInside(devRect); | 367 SkRect devInside(devRect); |
362 devInside.inset(rx, ry); | 368 devInside.inset(rx, ry); |
363 | 369 |
364 SkRect devOutsideAssist(devRect); | 370 SkRect devOutsideAssist(devRect); |
365 | 371 |
366 // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist) | 372 // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist) |
367 // to draw the outer of the rect. Because there are 8 vertices on the outer | 373 // to draw the outer of the rect. Because there are 8 vertices on the outer |
368 // edge, while vertex number of inner edge is 4, the same as miter-stroke. | 374 // edge, while vertex number of inner edge is 4, the same as miter-stroke. |
369 if (!miterStroke) { | 375 if (!miterStroke) { |
370 devOutside.inset(0, ry); | 376 devOutside.inset(0, ry); |
371 devOutsideAssist.outset(0, ry); | 377 devOutsideAssist.outset(0, ry); |
372 } | 378 } |
373 | 379 |
374 this->geometryStrokeAARect(target, drawState, color, devOutside, devOutsideA
ssist, devInside, | 380 this->geometryStrokeAARect(target, drawState, color, localMatrix, devOutside
, devOutsideAssist, |
375 miterStroke); | 381 devInside, miterStroke); |
376 } | 382 } |
377 | 383 |
378 void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target, | 384 void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target, |
379 GrDrawState* drawState, | 385 GrDrawState* drawState, |
380 GrColor color, | 386 GrColor color, |
| 387 const SkMatrix& localMatrix, |
381 const SkRect& devOutside, | 388 const SkRect& devOutside, |
382 const SkRect& devOutsideAssist, | 389 const SkRect& devOutsideAssist, |
383 const SkRect& devInside, | 390 const SkRect& devInside, |
384 bool miterStroke) { | 391 bool miterStroke) { |
385 GrDrawState::AutoRestoreEffects are(drawState); | 392 GrDrawState::AutoRestoreEffects are(drawState); |
386 | 393 |
387 CoverageAttribType type; | 394 CoverageAttribType type; |
388 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color,
&type)); | 395 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color,
&type, |
| 396 localMatrix)); |
389 | 397 |
390 int innerVertexNum = 4; | 398 int innerVertexNum = 4; |
391 int outerVertexNum = miterStroke ? 4 : 8; | 399 int outerVertexNum = miterStroke ? 4 : 8; |
392 int totalVertexNum = (outerVertexNum + innerVertexNum) * 2; | 400 int totalVertexNum = (outerVertexNum + innerVertexNum) * 2; |
393 | 401 |
394 size_t vstride = gp->getVertexStride(); | 402 size_t vstride = gp->getVertexStride(); |
395 GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, vstride, 0); | 403 GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, vstride, 0); |
396 if (!geo.succeeded()) { | 404 if (!geo.succeeded()) { |
397 SkDebugf("Failed to get space for vertices!\n"); | 405 SkDebugf("Failed to get space for vertices!\n"); |
398 return; | 406 return; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 kTriangles_GrPrimitiveType, | 511 kTriangles_GrPrimitiveType, |
504 1, | 512 1, |
505 totalVertexNum, | 513 totalVertexNum, |
506 aa_stroke_rect_index_count(miterStroke)); | 514 aa_stroke_rect_index_count(miterStroke)); |
507 target->resetIndexSource(); | 515 target->resetIndexSource(); |
508 } | 516 } |
509 | 517 |
510 void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target, | 518 void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target, |
511 GrDrawState* drawState, | 519 GrDrawState* drawState, |
512 GrColor color, | 520 GrColor color, |
| 521 const SkMatrix& localMatrix, |
513 const SkRect rects[2], | 522 const SkRect rects[2], |
514 const SkMatrix& combinedMatrix) { | 523 const SkMatrix& combinedMatrix) { |
515 SkASSERT(combinedMatrix.rectStaysRect()); | 524 SkASSERT(combinedMatrix.rectStaysRect()); |
516 SkASSERT(!rects[1].isEmpty()); | 525 SkASSERT(!rects[1].isEmpty()); |
517 | 526 |
518 SkRect devOutside, devOutsideAssist, devInside; | 527 SkRect devOutside, devOutsideAssist, devInside; |
519 combinedMatrix.mapRect(&devOutside, rects[0]); | 528 combinedMatrix.mapRect(&devOutside, rects[0]); |
520 // can't call mapRect for devInside since it calls sort | 529 // can't call mapRect for devInside since it calls sort |
521 combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2)
; | 530 combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2)
; |
522 | 531 |
523 if (devInside.isEmpty()) { | 532 if (devInside.isEmpty()) { |
524 this->fillAARect(target, drawState, color, devOutside, SkMatrix::I(), de
vOutside); | 533 this->fillAARect(target, drawState, color, localMatrix, devOutside, SkMa
trix::I(), |
| 534 devOutside); |
525 return; | 535 return; |
526 } | 536 } |
527 | 537 |
528 this->geometryStrokeAARect(target, drawState, color, devOutside, devOutsideA
ssist, devInside, | 538 this->geometryStrokeAARect(target, drawState, color, localMatrix, devOutside
, devOutsideAssist, |
529 true); | 539 devInside, true); |
530 } | 540 } |
OLD | NEW |