| 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, |
| 184 const SkMatrix& viewMatrix, |
| 183 const SkMatrix& localMatrix, | 185 const SkMatrix& localMatrix, |
| 184 const SkRect& rect, | 186 const SkRect& rect, |
| 185 const SkMatrix& combinedMatrix, | |
| 186 const SkRect& devRect) { | 187 const SkRect& devRect) { |
| 187 GrDrawState::AutoRestoreEffects are(drawState); | 188 GrDrawState::AutoRestoreEffects are(drawState); |
| 188 | 189 |
| 189 CoverageAttribType type; | 190 CoverageAttribType type; |
| 190 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color,
&type, | 191 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color,
&type, |
| 191 localMatrix)); | 192 localMatrix)); |
| 192 | 193 |
| 193 size_t vertexStride = gp->getVertexStride(); | 194 size_t vertexStride = gp->getVertexStride(); |
| 194 GrDrawTarget::AutoReleaseGeometry geo(target, 8, vertexStride, 0); | 195 GrDrawTarget::AutoReleaseGeometry geo(target, 8, vertexStride, 0); |
| 195 if (!geo.succeeded()) { | 196 if (!geo.succeeded()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 210 } | 211 } |
| 211 | 212 |
| 212 intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); | 213 intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); |
| 213 | 214 |
| 214 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); | 215 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); |
| 215 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); | 216 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); |
| 216 | 217 |
| 217 SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1); | 218 SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1); |
| 218 inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height()); | 219 inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height()); |
| 219 | 220 |
| 220 if (combinedMatrix.rectStaysRect()) { | 221 if (viewMatrix.rectStaysRect()) { |
| 221 // Temporarily #if'ed out. We don't want to pass in the devRect but | 222 // 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 | 223 // right now it is computed in GrContext::apply_aa_to_rect and we don't |
| 223 // want to throw away the work | 224 // want to throw away the work |
| 224 #if 0 | 225 #if 0 |
| 225 SkRect devRect; | 226 SkRect devRect; |
| 226 combinedMatrix.mapRect(&devRect, rect); | 227 combinedMatrix.mapRect(&devRect, rect); |
| 227 #endif | 228 #endif |
| 228 | 229 |
| 229 set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_Scalar
Half); | 230 set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_Scalar
Half); |
| 230 set_inset_fan(fan1Pos, vertexStride, devRect, inset, inset); | 231 set_inset_fan(fan1Pos, vertexStride, devRect, inset, inset); |
| 231 } else { | 232 } else { |
| 232 // compute transformed (1, 0) and (0, 1) vectors | 233 // compute transformed (1, 0) and (0, 1) vectors |
| 233 SkVector vec[2] = { | 234 SkVector vec[2] = { |
| 234 { combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY
] }, | 235 { viewMatrix[SkMatrix::kMScaleX], viewMatrix[SkMatrix::kMSkewY] }, |
| 235 { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix::kMScale
Y] } | 236 { viewMatrix[SkMatrix::kMSkewX], viewMatrix[SkMatrix::kMScaleY] } |
| 236 }; | 237 }; |
| 237 | 238 |
| 238 vec[0].normalize(); | 239 vec[0].normalize(); |
| 239 vec[0].scale(SK_ScalarHalf); | 240 vec[0].scale(SK_ScalarHalf); |
| 240 vec[1].normalize(); | 241 vec[1].normalize(); |
| 241 vec[1].scale(SK_ScalarHalf); | 242 vec[1].scale(SK_ScalarHalf); |
| 242 | 243 |
| 243 // create the rotated rect | 244 // create the rotated rect |
| 244 fan0Pos->setRectFan(rect.fLeft, rect.fTop, | 245 fan0Pos->setRectFan(rect.fLeft, rect.fTop, |
| 245 rect.fRight, rect.fBottom, vertexStride); | 246 rect.fRight, rect.fBottom, vertexStride); |
| 246 combinedMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4); | 247 viewMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4); |
| 247 | 248 |
| 248 // Now create the inset points and then outset the original | 249 // Now create the inset points and then outset the original |
| 249 // rotated points | 250 // rotated points |
| 250 | 251 |
| 251 // TL | 252 // TL |
| 252 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) = | 253 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) = |
| 253 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + vec[1
]; | 254 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + vec[1
]; |
| 254 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[1]; | 255 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[1]; |
| 255 // BL | 256 // BL |
| 256 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) = | 257 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) = |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 kTriangles_GrPrimitiveType, | 306 kTriangles_GrPrimitiveType, |
| 306 1, | 307 1, |
| 307 kVertsPerAAFillRect, | 308 kVertsPerAAFillRect, |
| 308 kIndicesPerAAFillRect); | 309 kIndicesPerAAFillRect); |
| 309 target->resetIndexSource(); | 310 target->resetIndexSource(); |
| 310 } | 311 } |
| 311 | 312 |
| 312 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, | 313 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, |
| 313 GrDrawState* drawState, | 314 GrDrawState* drawState, |
| 314 GrColor color, | 315 GrColor color, |
| 316 const SkMatrix& viewMatrix, |
| 315 const SkMatrix& localMatrix, | 317 const SkMatrix& localMatrix, |
| 316 const SkRect& rect, | 318 const SkRect& rect, |
| 317 const SkMatrix& combinedMatrix, | |
| 318 const SkRect& devRect, | 319 const SkRect& devRect, |
| 319 const SkStrokeRec& stroke) { | 320 const SkStrokeRec& stroke) { |
| 320 SkVector devStrokeSize; | 321 SkVector devStrokeSize; |
| 321 SkScalar width = stroke.getWidth(); | 322 SkScalar width = stroke.getWidth(); |
| 322 if (width > 0) { | 323 if (width > 0) { |
| 323 devStrokeSize.set(width, width); | 324 devStrokeSize.set(width, width); |
| 324 combinedMatrix.mapVectors(&devStrokeSize, 1); | 325 viewMatrix.mapVectors(&devStrokeSize, 1); |
| 325 devStrokeSize.setAbs(devStrokeSize); | 326 devStrokeSize.setAbs(devStrokeSize); |
| 326 } else { | 327 } else { |
| 327 devStrokeSize.set(SK_Scalar1, SK_Scalar1); | 328 devStrokeSize.set(SK_Scalar1, SK_Scalar1); |
| 328 } | 329 } |
| 329 | 330 |
| 330 const SkScalar dx = devStrokeSize.fX; | 331 const SkScalar dx = devStrokeSize.fX; |
| 331 const SkScalar dy = devStrokeSize.fY; | 332 const SkScalar dy = devStrokeSize.fY; |
| 332 const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); | 333 const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); |
| 333 const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf); | 334 const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf); |
| 334 | 335 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 352 | 353 |
| 353 bool miterStroke = true; | 354 bool miterStroke = true; |
| 354 // For hairlines, make bevel and round joins appear the same as mitered ones
. | 355 // For hairlines, make bevel and round joins appear the same as mitered ones
. |
| 355 // small miter limit means right angles show bevel... | 356 // small miter limit means right angles show bevel... |
| 356 if ((width > 0) && (stroke.getJoin() != SkPaint::kMiter_Join || | 357 if ((width > 0) && (stroke.getJoin() != SkPaint::kMiter_Join || |
| 357 stroke.getMiter() < SK_ScalarSqrt2)) { | 358 stroke.getMiter() < SK_ScalarSqrt2)) { |
| 358 miterStroke = false; | 359 miterStroke = false; |
| 359 } | 360 } |
| 360 | 361 |
| 361 if (spare <= 0 && miterStroke) { | 362 if (spare <= 0 && miterStroke) { |
| 362 this->fillAARect(target, drawState, color, localMatrix, devOutside, SkMa
trix::I(), | 363 this->fillAARect(target, drawState, color, SkMatrix::I(), localMatrix, d
evOutside, |
| 363 devOutside); | 364 devOutside); |
| 364 return; | 365 return; |
| 365 } | 366 } |
| 366 | 367 |
| 367 SkRect devInside(devRect); | 368 SkRect devInside(devRect); |
| 368 devInside.inset(rx, ry); | 369 devInside.inset(rx, ry); |
| 369 | 370 |
| 370 SkRect devOutsideAssist(devRect); | 371 SkRect devOutsideAssist(devRect); |
| 371 | 372 |
| 372 // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist) | 373 // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist) |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 kTriangles_GrPrimitiveType, | 512 kTriangles_GrPrimitiveType, |
| 512 1, | 513 1, |
| 513 totalVertexNum, | 514 totalVertexNum, |
| 514 aa_stroke_rect_index_count(miterStroke)); | 515 aa_stroke_rect_index_count(miterStroke)); |
| 515 target->resetIndexSource(); | 516 target->resetIndexSource(); |
| 516 } | 517 } |
| 517 | 518 |
| 518 void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target, | 519 void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target, |
| 519 GrDrawState* drawState, | 520 GrDrawState* drawState, |
| 520 GrColor color, | 521 GrColor color, |
| 522 const SkMatrix& viewMatrix, |
| 521 const SkMatrix& localMatrix, | 523 const SkMatrix& localMatrix, |
| 522 const SkRect rects[2], | 524 const SkRect rects[2]) { |
| 523 const SkMatrix& combinedMatrix) { | 525 SkASSERT(viewMatrix.rectStaysRect()); |
| 524 SkASSERT(combinedMatrix.rectStaysRect()); | |
| 525 SkASSERT(!rects[1].isEmpty()); | 526 SkASSERT(!rects[1].isEmpty()); |
| 526 | 527 |
| 527 SkRect devOutside, devOutsideAssist, devInside; | 528 SkRect devOutside, devOutsideAssist, devInside; |
| 528 combinedMatrix.mapRect(&devOutside, rects[0]); | 529 viewMatrix.mapRect(&devOutside, rects[0]); |
| 529 // can't call mapRect for devInside since it calls sort | 530 // can't call mapRect for devInside since it calls sort |
| 530 combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2)
; | 531 viewMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2); |
| 531 | 532 |
| 532 if (devInside.isEmpty()) { | 533 if (devInside.isEmpty()) { |
| 533 this->fillAARect(target, drawState, color, localMatrix, devOutside, SkMa
trix::I(), | 534 this->fillAARect(target, drawState, color, SkMatrix::I(), localMatrix, d
evOutside, |
| 534 devOutside); | 535 devOutside); |
| 535 return; | 536 return; |
| 536 } | 537 } |
| 537 | 538 |
| 538 this->geometryStrokeAARect(target, drawState, color, localMatrix, devOutside
, devOutsideAssist, | 539 this->geometryStrokeAARect(target, drawState, color, localMatrix, devOutside
, devOutsideAssist, |
| 539 devInside, true); | 540 devInside, true); |
| 540 } | 541 } |
| OLD | NEW |