| 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 |