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