| 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, GrColor color
) { | 28 static const GrGeometryProcessor* create_rect_gp(const GrDrawState& drawState, G
rColor color, |
| 29 CoverageAttribType* type) { |
| 29 uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; | 30 uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; |
| 30 if (drawState->canTweakAlphaForCoverage()) { | 31 const GrGeometryProcessor* gp; |
| 31 drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, f
lags))->unref(); | 32 if (drawState.canTweakAlphaForCoverage()) { |
| 32 SkASSERT(drawState->getGeometryProcessor()->getVertexStride() == | 33 gp = GrDefaultGeoProcFactory::Create(color, flags); |
| 33 sizeof(GrDefaultGeoProcFactory::PositionColorAttr)); | 34 SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::Positi
onColorAttr)); |
| 34 return kUseColor_CoverageAttribType; | 35 *type = kUseColor_CoverageAttribType; |
| 35 } else { | 36 } else { |
| 36 flags |= GrDefaultGeoProcFactory::kCoverage_GPType; | 37 flags |= GrDefaultGeoProcFactory::kCoverage_GPType; |
| 37 drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, f
lags))->unref(); | 38 gp = GrDefaultGeoProcFactory::Create(color, flags, GrColorIsOpaque(color
)); |
| 38 SkASSERT(drawState->getGeometryProcessor()->getVertexStride() == | 39 SkASSERT(gp->getVertexStride()==sizeof(GrDefaultGeoProcFactory::Position
ColorCoverageAttr)); |
| 39 sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr)); | 40 *type = kUseCoverage_CoverageAttribType; |
| 40 return kUseCoverage_CoverageAttribType; | |
| 41 } | 41 } |
| 42 return gp; |
| 42 } | 43 } |
| 43 | 44 |
| 44 static void set_inset_fan(SkPoint* pts, size_t stride, | 45 static void set_inset_fan(SkPoint* pts, size_t stride, |
| 45 const SkRect& r, SkScalar dx, SkScalar dy) { | 46 const SkRect& r, SkScalar dx, SkScalar dy) { |
| 46 pts->setRectFan(r.fLeft + dx, r.fTop + dy, | 47 pts->setRectFan(r.fLeft + dx, r.fTop + dy, |
| 47 r.fRight - dx, r.fBottom - dy, stride); | 48 r.fRight - dx, r.fBottom - dy, stride); |
| 48 } | 49 } |
| 49 | 50 |
| 50 void GrAARectRenderer::reset() { | 51 void GrAARectRenderer::reset() { |
| 51 SkSafeSetNull(fAAFillRectIndexBuffer); | 52 SkSafeSetNull(fAAFillRectIndexBuffer); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 } | 176 } |
| 176 | 177 |
| 177 void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target, | 178 void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target, |
| 178 GrDrawState* drawState, | 179 GrDrawState* drawState, |
| 179 GrColor color, | 180 GrColor color, |
| 180 const SkRect& rect, | 181 const SkRect& rect, |
| 181 const SkMatrix& combinedMatrix, | 182 const SkMatrix& combinedMatrix, |
| 182 const SkRect& devRect) { | 183 const SkRect& devRect) { |
| 183 GrDrawState::AutoRestoreEffects are(drawState); | 184 GrDrawState::AutoRestoreEffects are(drawState); |
| 184 | 185 |
| 185 CoverageAttribType covAttribType = set_rect_attribs(drawState, color); | 186 CoverageAttribType type; |
| 186 if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(colo
r)) { | 187 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color,
&type)); |
| 187 drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true); | |
| 188 } | |
| 189 | 188 |
| 190 size_t vstride = drawState->getGeometryProcessor()->getVertexStride(); | 189 size_t vertexStride = gp->getVertexStride(); |
| 191 GrDrawTarget::AutoReleaseGeometry geo(target, 8, vstride, 0); | 190 GrDrawTarget::AutoReleaseGeometry geo(target, 8, vertexStride, 0); |
| 192 if (!geo.succeeded()) { | 191 if (!geo.succeeded()) { |
| 193 SkDebugf("Failed to get space for vertices!\n"); | 192 SkDebugf("Failed to get space for vertices!\n"); |
| 194 return; | 193 return; |
| 195 } | 194 } |
| 196 | 195 |
| 197 if (NULL == fAAFillRectIndexBuffer) { | 196 if (NULL == fAAFillRectIndexBuffer) { |
| 198 fAAFillRectIndexBuffer = fGpu->createInstancedIndexBuffer(gFillAARectIdx
, | 197 fAAFillRectIndexBuffer = fGpu->createInstancedIndexBuffer(gFillAARectIdx
, |
| 199 kIndicesPerAAF
illRect, | 198 kIndicesPerAAF
illRect, |
| 200 kNumAAFillRect
sInIndexBuffer, | 199 kNumAAFillRect
sInIndexBuffer, |
| 201 kVertsPerAAFil
lRect); | 200 kVertsPerAAFil
lRect); |
| 202 } | 201 } |
| 203 GrIndexBuffer* indexBuffer = fAAFillRectIndexBuffer; | 202 GrIndexBuffer* indexBuffer = fAAFillRectIndexBuffer; |
| 204 if (NULL == indexBuffer) { | 203 if (NULL == indexBuffer) { |
| 205 SkDebugf("Failed to create index buffer!\n"); | 204 SkDebugf("Failed to create index buffer!\n"); |
| 206 return; | 205 return; |
| 207 } | 206 } |
| 208 | 207 |
| 209 intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); | 208 intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); |
| 210 | 209 |
| 211 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); | 210 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); |
| 212 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vstride); | 211 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); |
| 213 | 212 |
| 214 SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1); | 213 SkScalar inset = SkMinScalar(devRect.width(), SK_Scalar1); |
| 215 inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height()); | 214 inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height()); |
| 216 | 215 |
| 217 if (combinedMatrix.rectStaysRect()) { | 216 if (combinedMatrix.rectStaysRect()) { |
| 218 // Temporarily #if'ed out. We don't want to pass in the devRect but | 217 // Temporarily #if'ed out. We don't want to pass in the devRect but |
| 219 // right now it is computed in GrContext::apply_aa_to_rect and we don't | 218 // right now it is computed in GrContext::apply_aa_to_rect and we don't |
| 220 // want to throw away the work | 219 // want to throw away the work |
| 221 #if 0 | 220 #if 0 |
| 222 SkRect devRect; | 221 SkRect devRect; |
| 223 combinedMatrix.mapRect(&devRect, rect); | 222 combinedMatrix.mapRect(&devRect, rect); |
| 224 #endif | 223 #endif |
| 225 | 224 |
| 226 set_inset_fan(fan0Pos, vstride, devRect, -SK_ScalarHalf, -SK_ScalarHalf)
; | 225 set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_Scalar
Half); |
| 227 set_inset_fan(fan1Pos, vstride, devRect, inset, inset); | 226 set_inset_fan(fan1Pos, vertexStride, devRect, inset, inset); |
| 228 } else { | 227 } else { |
| 229 // compute transformed (1, 0) and (0, 1) vectors | 228 // compute transformed (1, 0) and (0, 1) vectors |
| 230 SkVector vec[2] = { | 229 SkVector vec[2] = { |
| 231 { combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY
] }, | 230 { combinedMatrix[SkMatrix::kMScaleX], combinedMatrix[SkMatrix::kMSkewY
] }, |
| 232 { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix::kMScale
Y] } | 231 { combinedMatrix[SkMatrix::kMSkewX], combinedMatrix[SkMatrix::kMScale
Y] } |
| 233 }; | 232 }; |
| 234 | 233 |
| 235 vec[0].normalize(); | 234 vec[0].normalize(); |
| 236 vec[0].scale(SK_ScalarHalf); | 235 vec[0].scale(SK_ScalarHalf); |
| 237 vec[1].normalize(); | 236 vec[1].normalize(); |
| 238 vec[1].scale(SK_ScalarHalf); | 237 vec[1].scale(SK_ScalarHalf); |
| 239 | 238 |
| 240 // create the rotated rect | 239 // create the rotated rect |
| 241 fan0Pos->setRectFan(rect.fLeft, rect.fTop, | 240 fan0Pos->setRectFan(rect.fLeft, rect.fTop, |
| 242 rect.fRight, rect.fBottom, vstride); | 241 rect.fRight, rect.fBottom, vertexStride); |
| 243 combinedMatrix.mapPointsWithStride(fan0Pos, vstride, 4); | 242 combinedMatrix.mapPointsWithStride(fan0Pos, vertexStride, 4); |
| 244 | 243 |
| 245 // Now create the inset points and then outset the original | 244 // Now create the inset points and then outset the original |
| 246 // rotated points | 245 // rotated points |
| 247 | 246 |
| 248 // TL | 247 // TL |
| 249 *((SkPoint*)((intptr_t)fan1Pos + 0 * vstride)) = | 248 *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) = |
| 250 *((SkPoint*)((intptr_t)fan0Pos + 0 * vstride)) + vec[0] + vec[1]; | 249 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + vec[1
]; |
| 251 *((SkPoint*)((intptr_t)fan0Pos + 0 * vstride)) -= vec[0] + vec[1]; | 250 *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[1]; |
| 252 // BL | 251 // BL |
| 253 *((SkPoint*)((intptr_t)fan1Pos + 1 * vstride)) = | 252 *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) = |
| 254 *((SkPoint*)((intptr_t)fan0Pos + 1 * vstride)) + vec[0] - vec[1]; | 253 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - vec[1
]; |
| 255 *((SkPoint*)((intptr_t)fan0Pos + 1 * vstride)) -= vec[0] - vec[1]; | 254 *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[1]; |
| 256 // BR | 255 // BR |
| 257 *((SkPoint*)((intptr_t)fan1Pos + 2 * vstride)) = | 256 *((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) = |
| 258 *((SkPoint*)((intptr_t)fan0Pos + 2 * vstride)) - vec[0] - vec[1]; | 257 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - vec[1
]; |
| 259 *((SkPoint*)((intptr_t)fan0Pos + 2 * vstride)) += vec[0] + vec[1]; | 258 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1]; |
| 260 // TR | 259 // TR |
| 261 *((SkPoint*)((intptr_t)fan1Pos + 3 * vstride)) = | 260 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) = |
| 262 *((SkPoint*)((intptr_t)fan0Pos + 3 * vstride)) - vec[0] + vec[1]; | 261 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1
]; |
| 263 *((SkPoint*)((intptr_t)fan0Pos + 3 * vstride)) += vec[0] - vec[1]; | 262 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1]; |
| 264 } | 263 } |
| 265 | 264 |
| 266 // Make verts point to vertex color and then set all the color and coverage
vertex attrs values. | 265 // Make verts point to vertex color and then set all the color and coverage
vertex attrs values. |
| 267 verts += sizeof(SkPoint); | 266 verts += sizeof(SkPoint); |
| 268 for (int i = 0; i < 4; ++i) { | 267 for (int i = 0; i < 4; ++i) { |
| 269 if (kUseCoverage_CoverageAttribType == covAttribType) { | 268 if (kUseCoverage_CoverageAttribType == type) { |
| 270 *reinterpret_cast<GrColor*>(verts + i * vstride) = color; | 269 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
| 271 *reinterpret_cast<float*>(verts + i * vstride + sizeof(GrColor)) = 0
; | 270 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)
) = 0; |
| 272 } else { | 271 } else { |
| 273 *reinterpret_cast<GrColor*>(verts + i * vstride) = 0; | 272 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0; |
| 274 } | 273 } |
| 275 } | 274 } |
| 276 | 275 |
| 277 int scale; | 276 int scale; |
| 278 if (inset < SK_ScalarHalf) { | 277 if (inset < SK_ScalarHalf) { |
| 279 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)); | 278 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)); |
| 280 SkASSERT(scale >= 0 && scale <= 255); | 279 SkASSERT(scale >= 0 && scale <= 255); |
| 281 } else { | 280 } else { |
| 282 scale = 0xff; | 281 scale = 0xff; |
| 283 } | 282 } |
| 284 | 283 |
| 285 verts += 4 * vstride; | 284 verts += 4 * vertexStride; |
| 286 | 285 |
| 287 float innerCoverage = GrNormalizeByteToFloat(scale); | 286 float innerCoverage = GrNormalizeByteToFloat(scale); |
| 288 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale); | 287 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale); |
| 289 | 288 |
| 290 for (int i = 0; i < 4; ++i) { | 289 for (int i = 0; i < 4; ++i) { |
| 291 if (kUseCoverage_CoverageAttribType == covAttribType) { | 290 if (kUseCoverage_CoverageAttribType == type) { |
| 292 *reinterpret_cast<GrColor*>(verts + i * vstride) = color; | 291 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
| 293 *reinterpret_cast<float*>(verts + i * vstride + sizeof(GrColor)) = i
nnerCoverage; | 292 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)
) = innerCoverage; |
| 294 } else { | 293 } else { |
| 295 *reinterpret_cast<GrColor*>(verts + i * vstride) = scaledColor; | 294 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; |
| 296 } | 295 } |
| 297 } | 296 } |
| 298 | 297 |
| 299 target->setIndexSourceToBuffer(indexBuffer); | 298 target->setIndexSourceToBuffer(indexBuffer); |
| 300 target->drawIndexedInstances(drawState, | 299 target->drawIndexedInstances(drawState, |
| 300 gp, |
| 301 kTriangles_GrPrimitiveType, | 301 kTriangles_GrPrimitiveType, |
| 302 1, | 302 1, |
| 303 kVertsPerAAFillRect, | 303 kVertsPerAAFillRect, |
| 304 kIndicesPerAAFillRect); | 304 kIndicesPerAAFillRect); |
| 305 target->resetIndexSource(); | 305 target->resetIndexSource(); |
| 306 } | 306 } |
| 307 | 307 |
| 308 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, | 308 void GrAARectRenderer::strokeAARect(GrDrawTarget* target, |
| 309 GrDrawState* drawState, | 309 GrDrawState* drawState, |
| 310 GrColor color, | 310 GrColor color, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 GrColor color, |
| 381 const SkRect& devOutside, | 381 const SkRect& devOutside, |
| 382 const SkRect& devOutsideAssist, | 382 const SkRect& devOutsideAssist, |
| 383 const SkRect& devInside, | 383 const SkRect& devInside, |
| 384 bool miterStroke) { | 384 bool miterStroke) { |
| 385 GrDrawState::AutoRestoreEffects are(drawState); | 385 GrDrawState::AutoRestoreEffects are(drawState); |
| 386 CoverageAttribType covAttribType = set_rect_attribs(drawState, color); | |
| 387 | 386 |
| 388 if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(colo
r)) { | 387 CoverageAttribType type; |
| 389 drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true); | 388 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(*drawState, color,
&type)); |
| 390 } | |
| 391 | 389 |
| 392 int innerVertexNum = 4; | 390 int innerVertexNum = 4; |
| 393 int outerVertexNum = miterStroke ? 4 : 8; | 391 int outerVertexNum = miterStroke ? 4 : 8; |
| 394 int totalVertexNum = (outerVertexNum + innerVertexNum) * 2; | 392 int totalVertexNum = (outerVertexNum + innerVertexNum) * 2; |
| 395 | 393 |
| 396 size_t vstride = drawState->getGeometryProcessor()->getVertexStride(); | 394 size_t vstride = gp->getVertexStride(); |
| 397 GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, vstride, 0); | 395 GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, vstride, 0); |
| 398 if (!geo.succeeded()) { | 396 if (!geo.succeeded()) { |
| 399 SkDebugf("Failed to get space for vertices!\n"); | 397 SkDebugf("Failed to get space for vertices!\n"); |
| 400 return; | 398 return; |
| 401 } | 399 } |
| 402 GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(miterStroke); | 400 GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(miterStroke); |
| 403 if (NULL == indexBuffer) { | 401 if (NULL == indexBuffer) { |
| 404 SkDebugf("Failed to create index buffer!\n"); | 402 SkDebugf("Failed to create index buffer!\n"); |
| 405 return; | 403 return; |
| 406 } | 404 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 // inner one of the inner two | 449 // inner one of the inner two |
| 452 set_inset_fan(fan2Pos, vstride, devInside, -inset, -inset); | 450 set_inset_fan(fan2Pos, vstride, devInside, -inset, -inset); |
| 453 // innermost | 451 // innermost |
| 454 set_inset_fan(fan3Pos, vstride, devInside, SK_ScalarHalf, SK_ScalarHa
lf); | 452 set_inset_fan(fan3Pos, vstride, devInside, SK_ScalarHalf, SK_ScalarHa
lf); |
| 455 } | 453 } |
| 456 | 454 |
| 457 // Make verts point to vertex color and then set all the color and coverage
vertex attrs values. | 455 // Make verts point to vertex color and then set all the color and coverage
vertex attrs values. |
| 458 // The outermost rect has 0 coverage | 456 // The outermost rect has 0 coverage |
| 459 verts += sizeof(SkPoint); | 457 verts += sizeof(SkPoint); |
| 460 for (int i = 0; i < outerVertexNum; ++i) { | 458 for (int i = 0; i < outerVertexNum; ++i) { |
| 461 if (kUseCoverage_CoverageAttribType == covAttribType) { | 459 if (kUseCoverage_CoverageAttribType == type) { |
| 462 *reinterpret_cast<GrColor*>(verts + i * vstride) = color; | 460 *reinterpret_cast<GrColor*>(verts + i * vstride) = color; |
| 463 *reinterpret_cast<float*>(verts + i * vstride + sizeof(GrColor)) = 0
; | 461 *reinterpret_cast<float*>(verts + i * vstride + sizeof(GrColor)) = 0
; |
| 464 } else { | 462 } else { |
| 465 *reinterpret_cast<GrColor*>(verts + i * vstride) = 0; | 463 *reinterpret_cast<GrColor*>(verts + i * vstride) = 0; |
| 466 } | 464 } |
| 467 } | 465 } |
| 468 | 466 |
| 469 // scale is the coverage for the the inner two rects. | 467 // scale is the coverage for the the inner two rects. |
| 470 int scale; | 468 int scale; |
| 471 if (inset < SK_ScalarHalf) { | 469 if (inset < SK_ScalarHalf) { |
| 472 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)); | 470 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)); |
| 473 SkASSERT(scale >= 0 && scale <= 255); | 471 SkASSERT(scale >= 0 && scale <= 255); |
| 474 } else { | 472 } else { |
| 475 scale = 0xff; | 473 scale = 0xff; |
| 476 } | 474 } |
| 477 | 475 |
| 478 float innerCoverage = GrNormalizeByteToFloat(scale); | 476 float innerCoverage = GrNormalizeByteToFloat(scale); |
| 479 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale); | 477 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale); |
| 480 | 478 |
| 481 verts += outerVertexNum * vstride; | 479 verts += outerVertexNum * vstride; |
| 482 for (int i = 0; i < outerVertexNum + innerVertexNum; ++i) { | 480 for (int i = 0; i < outerVertexNum + innerVertexNum; ++i) { |
| 483 if (kUseCoverage_CoverageAttribType == covAttribType) { | 481 if (kUseCoverage_CoverageAttribType == type) { |
| 484 *reinterpret_cast<GrColor*>(verts + i * vstride) = color; | 482 *reinterpret_cast<GrColor*>(verts + i * vstride) = color; |
| 485 *reinterpret_cast<float*>(verts + i * vstride + sizeof(GrColor)) = i
nnerCoverage; | 483 *reinterpret_cast<float*>(verts + i * vstride + sizeof(GrColor)) = i
nnerCoverage; |
| 486 } else { | 484 } else { |
| 487 *reinterpret_cast<GrColor*>(verts + i * vstride) = scaledColor; | 485 *reinterpret_cast<GrColor*>(verts + i * vstride) = scaledColor; |
| 488 } | 486 } |
| 489 } | 487 } |
| 490 | 488 |
| 491 // The innermost rect has 0 coverage | 489 // The innermost rect has 0 coverage |
| 492 verts += (outerVertexNum + innerVertexNum) * vstride; | 490 verts += (outerVertexNum + innerVertexNum) * vstride; |
| 493 for (int i = 0; i < innerVertexNum; ++i) { | 491 for (int i = 0; i < innerVertexNum; ++i) { |
| 494 if (kUseCoverage_CoverageAttribType == covAttribType) { | 492 if (kUseCoverage_CoverageAttribType == type) { |
| 495 *reinterpret_cast<GrColor*>(verts + i * vstride) = color; | 493 *reinterpret_cast<GrColor*>(verts + i * vstride) = color; |
| 496 *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) =
0; | 494 *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) =
0; |
| 497 } else { | 495 } else { |
| 498 *reinterpret_cast<GrColor*>(verts + i * vstride) = 0; | 496 *reinterpret_cast<GrColor*>(verts + i * vstride) = 0; |
| 499 } | 497 } |
| 500 } | 498 } |
| 501 | 499 |
| 502 target->setIndexSourceToBuffer(indexBuffer); | 500 target->setIndexSourceToBuffer(indexBuffer); |
| 503 target->drawIndexedInstances(drawState, | 501 target->drawIndexedInstances(drawState, |
| 502 gp, |
| 504 kTriangles_GrPrimitiveType, | 503 kTriangles_GrPrimitiveType, |
| 505 1, | 504 1, |
| 506 totalVertexNum, | 505 totalVertexNum, |
| 507 aa_stroke_rect_index_count(miterStroke)); | 506 aa_stroke_rect_index_count(miterStroke)); |
| 508 target->resetIndexSource(); | 507 target->resetIndexSource(); |
| 509 } | 508 } |
| 510 | 509 |
| 511 void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target, | 510 void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target, |
| 512 GrDrawState* drawState, | 511 GrDrawState* drawState, |
| 513 GrColor color, | 512 GrColor color, |
| 514 const SkRect rects[2], | 513 const SkRect rects[2], |
| 515 const SkMatrix& combinedMatrix) { | 514 const SkMatrix& combinedMatrix) { |
| 516 SkASSERT(combinedMatrix.rectStaysRect()); | 515 SkASSERT(combinedMatrix.rectStaysRect()); |
| 517 SkASSERT(!rects[1].isEmpty()); | 516 SkASSERT(!rects[1].isEmpty()); |
| 518 | 517 |
| 519 SkRect devOutside, devOutsideAssist, devInside; | 518 SkRect devOutside, devOutsideAssist, devInside; |
| 520 combinedMatrix.mapRect(&devOutside, rects[0]); | 519 combinedMatrix.mapRect(&devOutside, rects[0]); |
| 521 // can't call mapRect for devInside since it calls sort | 520 // can't call mapRect for devInside since it calls sort |
| 522 combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2)
; | 521 combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2)
; |
| 523 | 522 |
| 524 if (devInside.isEmpty()) { | 523 if (devInside.isEmpty()) { |
| 525 this->fillAARect(target, drawState, color, devOutside, SkMatrix::I(), de
vOutside); | 524 this->fillAARect(target, drawState, color, devOutside, SkMatrix::I(), de
vOutside); |
| 526 return; | 525 return; |
| 527 } | 526 } |
| 528 | 527 |
| 529 this->geometryStrokeAARect(target, drawState, color, devOutside, devOutsideA
ssist, devInside, | 528 this->geometryStrokeAARect(target, drawState, color, devOutside, devOutsideA
ssist, devInside, |
| 530 true); | 529 true); |
| 531 } | 530 } |
| OLD | NEW |