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, | 28 static const GrGeometryProcessor* create_rect_gp(const GrPipelineBuilder& pipeli
neBuilder, |
29 GrColor color, | 29 GrColor color, |
30 CoverageAttribType* type, | 30 CoverageAttribType* type, |
31 const SkMatrix& localMatrix) { | 31 const SkMatrix& localMatrix) { |
32 uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; | 32 uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; |
33 const GrGeometryProcessor* gp; | 33 const GrGeometryProcessor* gp; |
34 if (drawState.canTweakAlphaForCoverage()) { | 34 if (pipelineBuilder.canTweakAlphaForCoverage()) { |
35 gp = GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), localM
atrix); | 35 gp = GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), localM
atrix); |
36 SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::Positi
onColorAttr)); | 36 SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::Positi
onColorAttr)); |
37 *type = kUseColor_CoverageAttribType; | 37 *type = kUseColor_CoverageAttribType; |
38 } else { | 38 } else { |
39 flags |= GrDefaultGeoProcFactory::kCoverage_GPType; | 39 flags |= GrDefaultGeoProcFactory::kCoverage_GPType; |
40 gp = GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), localM
atrix, | 40 gp = GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), localM
atrix, |
41 GrColorIsOpaque(color)); | 41 GrColorIsOpaque(color)); |
42 SkASSERT(gp->getVertexStride()==sizeof(GrDefaultGeoProcFactory::Position
ColorCoverageAttr)); | 42 SkASSERT(gp->getVertexStride()==sizeof(GrDefaultGeoProcFactory::Position
ColorCoverageAttr)); |
43 *type = kUseCoverage_CoverageAttribType; | 43 *type = kUseCoverage_CoverageAttribType; |
44 } | 44 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 fGpu->createInstancedIndexBuffer(gBevelStrokeAARectIdx, | 172 fGpu->createInstancedIndexBuffer(gBevelStrokeAARectIdx, |
173 kIndicesPerBevelStrokeRect, | 173 kIndicesPerBevelStrokeRect, |
174 kNumBevelStrokeRectsInIndex
Buffer, | 174 kNumBevelStrokeRectsInIndex
Buffer, |
175 kVertsPerBevelStrokeRect); | 175 kVertsPerBevelStrokeRect); |
176 } | 176 } |
177 return fAABevelStrokeRectIndexBuffer; | 177 return fAABevelStrokeRectIndexBuffer; |
178 } | 178 } |
179 } | 179 } |
180 | 180 |
181 void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target, | 181 void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target, |
182 GrDrawState* drawState, | 182 GrPipelineBuilder* pipelineBuilder, |
183 GrColor color, | 183 GrColor color, |
184 const SkMatrix& viewMatrix, | 184 const SkMatrix& viewMatrix, |
185 const SkRect& rect, | 185 const SkRect& rect, |
186 const SkRect& devRect) { | 186 const SkRect& devRect) { |
187 GrDrawState::AutoRestoreEffects are(drawState); | 187 GrPipelineBuilder::AutoRestoreEffects are(pipelineBuilder); |
188 | 188 |
189 SkMatrix localMatrix; | 189 SkMatrix localMatrix; |
190 if (!viewMatrix.invert(&localMatrix)) { | 190 if (!viewMatrix.invert(&localMatrix)) { |
191 SkDebugf("Cannot invert\n"); | 191 SkDebugf("Cannot invert\n"); |
192 return; | 192 return; |
193 } | 193 } |
194 | 194 |
195 CoverageAttribType type; | 195 CoverageAttribType type; |
196 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color,
&type, | 196 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*pipelineBuilder,
color, &type, |
197 localMatrix)); | 197 localMatrix)); |
198 | 198 |
199 size_t vertexStride = gp->getVertexStride(); | 199 size_t vertexStride = gp->getVertexStride(); |
200 GrDrawTarget::AutoReleaseGeometry geo(target, 8, vertexStride, 0); | 200 GrDrawTarget::AutoReleaseGeometry geo(target, 8, vertexStride, 0); |
201 if (!geo.succeeded()) { | 201 if (!geo.succeeded()) { |
202 SkDebugf("Failed to get space for vertices!\n"); | 202 SkDebugf("Failed to get space for vertices!\n"); |
203 return; | 203 return; |
204 } | 204 } |
205 | 205 |
206 if (NULL == fAAFillRectIndexBuffer) { | 206 if (NULL == fAAFillRectIndexBuffer) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 for (int i = 0; i < 4; ++i) { | 299 for (int i = 0; i < 4; ++i) { |
300 if (kUseCoverage_CoverageAttribType == type) { | 300 if (kUseCoverage_CoverageAttribType == type) { |
301 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; | 301 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
302 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)
) = innerCoverage; | 302 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)
) = innerCoverage; |
303 } else { | 303 } else { |
304 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; | 304 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; |
305 } | 305 } |
306 } | 306 } |
307 | 307 |
308 target->setIndexSourceToBuffer(indexBuffer); | 308 target->setIndexSourceToBuffer(indexBuffer); |
309 target->drawIndexedInstances(drawState, | 309 target->drawIndexedInstances(pipelineBuilder, |
310 gp, | 310 gp, |
311 kTriangles_GrPrimitiveType, | 311 kTriangles_GrPrimitiveType, |
312 1, | 312 1, |
313 kVertsPerAAFillRect, | 313 kVertsPerAAFillRect, |
314 kIndicesPerAAFillRect); | 314 kIndicesPerAAFillRect); |
315 target->resetIndexSource(); | 315 target->resetIndexSource(); |
316 } | 316 } |
317 | 317 |
318 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, | 318 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, |
319 GrDrawState* drawState, | 319 GrPipelineBuilder* pipelineBuilder, |
320 GrColor color, | 320 GrColor color, |
321 const SkMatrix& viewMatrix, | 321 const SkMatrix& viewMatrix, |
322 const SkRect& rect, | 322 const SkRect& rect, |
323 const SkRect& devRect, | 323 const SkRect& devRect, |
324 const SkStrokeRec& stroke) { | 324 const SkStrokeRec& stroke) { |
325 SkVector devStrokeSize; | 325 SkVector devStrokeSize; |
326 SkScalar width = stroke.getWidth(); | 326 SkScalar width = stroke.getWidth(); |
327 if (width > 0) { | 327 if (width > 0) { |
328 devStrokeSize.set(width, width); | 328 devStrokeSize.set(width, width); |
329 viewMatrix.mapVectors(&devStrokeSize, 1); | 329 viewMatrix.mapVectors(&devStrokeSize, 1); |
(...skipping 27 matching lines...) Expand all Loading... |
357 | 357 |
358 bool miterStroke = true; | 358 bool miterStroke = true; |
359 // 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
. |
360 // small miter limit means right angles show bevel... | 360 // small miter limit means right angles show bevel... |
361 if ((width > 0) && (stroke.getJoin() != SkPaint::kMiter_Join || | 361 if ((width > 0) && (stroke.getJoin() != SkPaint::kMiter_Join || |
362 stroke.getMiter() < SK_ScalarSqrt2)) { | 362 stroke.getMiter() < SK_ScalarSqrt2)) { |
363 miterStroke = false; | 363 miterStroke = false; |
364 } | 364 } |
365 | 365 |
366 if (spare <= 0 && miterStroke) { | 366 if (spare <= 0 && miterStroke) { |
367 this->fillAARect(target, drawState, color, viewMatrix, devOutside, | 367 this->fillAARect(target, pipelineBuilder, color, viewMatrix, devOutside, |
368 devOutside); | 368 devOutside); |
369 return; | 369 return; |
370 } | 370 } |
371 | 371 |
372 SkRect devInside(devRect); | 372 SkRect devInside(devRect); |
373 devInside.inset(rx, ry); | 373 devInside.inset(rx, ry); |
374 | 374 |
375 SkRect devOutsideAssist(devRect); | 375 SkRect devOutsideAssist(devRect); |
376 | 376 |
377 // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist) | 377 // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist) |
378 // 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 |
379 // 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. |
380 if (!miterStroke) { | 380 if (!miterStroke) { |
381 devOutside.inset(0, ry); | 381 devOutside.inset(0, ry); |
382 devOutsideAssist.outset(0, ry); | 382 devOutsideAssist.outset(0, ry); |
383 } | 383 } |
384 | 384 |
385 this->geometryStrokeAARect(target, drawState, color, viewMatrix, devOutside,
devOutsideAssist, | 385 this->geometryStrokeAARect(target, pipelineBuilder, color, viewMatrix, devOu
tside, devOutsideAssist, |
386 devInside, miterStroke); | 386 devInside, miterStroke); |
387 } | 387 } |
388 | 388 |
389 void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target, | 389 void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target, |
390 GrDrawState* drawState, | 390 GrPipelineBuilder* pipelineBuilder, |
391 GrColor color, | 391 GrColor color, |
392 const SkMatrix& viewMatrix, | 392 const SkMatrix& viewMatrix, |
393 const SkRect& devOutside, | 393 const SkRect& devOutside, |
394 const SkRect& devOutsideAssist, | 394 const SkRect& devOutsideAssist, |
395 const SkRect& devInside, | 395 const SkRect& devInside, |
396 bool miterStroke) { | 396 bool miterStroke) { |
397 GrDrawState::AutoRestoreEffects are(drawState); | 397 GrPipelineBuilder::AutoRestoreEffects are(pipelineBuilder); |
398 | 398 |
399 SkMatrix localMatrix; | 399 SkMatrix localMatrix; |
400 if (!viewMatrix.invert(&localMatrix)) { | 400 if (!viewMatrix.invert(&localMatrix)) { |
401 SkDebugf("Cannot invert\n"); | 401 SkDebugf("Cannot invert\n"); |
402 return; | 402 return; |
403 } | 403 } |
404 | 404 |
405 CoverageAttribType type; | 405 CoverageAttribType type; |
406 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color,
&type, | 406 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*pipelineBuilder,
color, &type, |
407 localMatrix)); | 407 localMatrix)); |
408 | 408 |
409 int innerVertexNum = 4; | 409 int innerVertexNum = 4; |
410 int outerVertexNum = miterStroke ? 4 : 8; | 410 int outerVertexNum = miterStroke ? 4 : 8; |
411 int totalVertexNum = (outerVertexNum + innerVertexNum) * 2; | 411 int totalVertexNum = (outerVertexNum + innerVertexNum) * 2; |
412 | 412 |
413 size_t vstride = gp->getVertexStride(); | 413 size_t vstride = gp->getVertexStride(); |
414 GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, vstride, 0); | 414 GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, vstride, 0); |
415 if (!geo.succeeded()) { | 415 if (!geo.succeeded()) { |
416 SkDebugf("Failed to get space for vertices!\n"); | 416 SkDebugf("Failed to get space for vertices!\n"); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 for (int i = 0; i < innerVertexNum; ++i) { | 510 for (int i = 0; i < innerVertexNum; ++i) { |
511 if (kUseCoverage_CoverageAttribType == type) { | 511 if (kUseCoverage_CoverageAttribType == type) { |
512 *reinterpret_cast<GrColor*>(verts + i * vstride) = color; | 512 *reinterpret_cast<GrColor*>(verts + i * vstride) = color; |
513 *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) =
0; | 513 *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) =
0; |
514 } else { | 514 } else { |
515 *reinterpret_cast<GrColor*>(verts + i * vstride) = 0; | 515 *reinterpret_cast<GrColor*>(verts + i * vstride) = 0; |
516 } | 516 } |
517 } | 517 } |
518 | 518 |
519 target->setIndexSourceToBuffer(indexBuffer); | 519 target->setIndexSourceToBuffer(indexBuffer); |
520 target->drawIndexedInstances(drawState, | 520 target->drawIndexedInstances(pipelineBuilder, |
521 gp, | 521 gp, |
522 kTriangles_GrPrimitiveType, | 522 kTriangles_GrPrimitiveType, |
523 1, | 523 1, |
524 totalVertexNum, | 524 totalVertexNum, |
525 aa_stroke_rect_index_count(miterStroke)); | 525 aa_stroke_rect_index_count(miterStroke)); |
526 target->resetIndexSource(); | 526 target->resetIndexSource(); |
527 } | 527 } |
528 | 528 |
529 void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target, | 529 void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target, |
530 GrDrawState* drawState, | 530 GrPipelineBuilder* pipelineBuilder, |
531 GrColor color, | 531 GrColor color, |
532 const SkMatrix& viewMatrix, | 532 const SkMatrix& viewMatrix, |
533 const SkRect rects[2]) { | 533 const SkRect rects[2]) { |
534 SkASSERT(viewMatrix.rectStaysRect()); | 534 SkASSERT(viewMatrix.rectStaysRect()); |
535 SkASSERT(!rects[1].isEmpty()); | 535 SkASSERT(!rects[1].isEmpty()); |
536 | 536 |
537 SkRect devOutside, devOutsideAssist, devInside; | 537 SkRect devOutside, devOutsideAssist, devInside; |
538 viewMatrix.mapRect(&devOutside, rects[0]); | 538 viewMatrix.mapRect(&devOutside, rects[0]); |
539 // can't call mapRect for devInside since it calls sort | 539 // can't call mapRect for devInside since it calls sort |
540 viewMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2); | 540 viewMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2); |
541 | 541 |
542 if (devInside.isEmpty()) { | 542 if (devInside.isEmpty()) { |
543 this->fillAARect(target, drawState, color, viewMatrix, devOutside, | 543 this->fillAARect(target, pipelineBuilder, color, viewMatrix, devOutside, |
544 devOutside); | 544 devOutside); |
545 return; | 545 return; |
546 } | 546 } |
547 | 547 |
548 this->geometryStrokeAARect(target, drawState, color, viewMatrix, devOutside,
devOutsideAssist, | 548 this->geometryStrokeAARect(target, pipelineBuilder, color, viewMatrix, devOu
tside, |
549 devInside, true); | 549 devOutsideAssist, devInside, true); |
550 } | 550 } |
OLD | NEW |