| 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 "GrGpu.h" | 9 #include "GrGpu.h" |
| 10 #include "gl/builders/GrGLProgramBuilder.h" | 10 #include "gl/builders/GrGLProgramBuilder.h" |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 1, 2, 6, 6, 5, 1, | 304 1, 2, 6, 6, 5, 1, |
| 305 2, 3, 7, 7, 6, 2, | 305 2, 3, 7, 7, 6, 2, |
| 306 3, 0, 4, 4, 7, 3, | 306 3, 0, 4, 4, 7, 3, |
| 307 4, 5, 6, 6, 7, 4, | 307 4, 5, 6, 6, 7, 4, |
| 308 }; | 308 }; |
| 309 | 309 |
| 310 static const int kIndicesPerAAFillRect = SK_ARRAY_COUNT(gFillAARectIdx); | 310 static const int kIndicesPerAAFillRect = SK_ARRAY_COUNT(gFillAARectIdx); |
| 311 static const int kVertsPerAAFillRect = 8; | 311 static const int kVertsPerAAFillRect = 8; |
| 312 static const int kNumAAFillRectsInIndexBuffer = 256; | 312 static const int kNumAAFillRectsInIndexBuffer = 256; |
| 313 | 313 |
| 314 GrIndexBuffer* GrAARectRenderer::aaFillRectIndexBuffer(GrGpu* gpu) { |
| 315 static const size_t kAAFillRectIndexBufferSize = kIndicesPerAAFillRect * |
| 316 sizeof(uint16_t) * |
| 317 kNumAAFillRectsInIndexBuffe
r; |
| 318 |
| 319 if (NULL == fAAFillRectIndexBuffer) { |
| 320 fAAFillRectIndexBuffer = gpu->createIndexBuffer(kAAFillRectIndexBufferSi
ze, false); |
| 321 if (fAAFillRectIndexBuffer) { |
| 322 uint16_t* data = (uint16_t*) fAAFillRectIndexBuffer->map(); |
| 323 bool useTempData = (NULL == data); |
| 324 if (useTempData) { |
| 325 data = SkNEW_ARRAY(uint16_t, kNumAAFillRectsInIndexBuffer * kInd
icesPerAAFillRect); |
| 326 } |
| 327 for (int i = 0; i < kNumAAFillRectsInIndexBuffer; ++i) { |
| 328 // Each AA filled rect is drawn with 8 vertices and 10 triangles
(8 around |
| 329 // the inner rect (for AA) and 2 for the inner rect. |
| 330 int baseIdx = i * kIndicesPerAAFillRect; |
| 331 uint16_t baseVert = (uint16_t)(i * kVertsPerAAFillRect); |
| 332 for (int j = 0; j < kIndicesPerAAFillRect; ++j) { |
| 333 data[baseIdx+j] = baseVert + gFillAARectIdx[j]; |
| 334 } |
| 335 } |
| 336 if (useTempData) { |
| 337 if (!fAAFillRectIndexBuffer->updateData(data, kAAFillRectIndexBu
fferSize)) { |
| 338 SkFAIL("Can't get AA Fill Rect indices into buffer!"); |
| 339 } |
| 340 SkDELETE_ARRAY(data); |
| 341 } else { |
| 342 fAAFillRectIndexBuffer->unmap(); |
| 343 } |
| 344 } |
| 345 } |
| 346 |
| 347 return fAAFillRectIndexBuffer; |
| 348 } |
| 349 |
| 314 static const uint16_t gMiterStrokeAARectIdx[] = { | 350 static const uint16_t gMiterStrokeAARectIdx[] = { |
| 315 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, | 351 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, |
| 316 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, | 352 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, |
| 317 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, | 353 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, |
| 318 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, | 354 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, |
| 319 | 355 |
| 320 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, | 356 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, |
| 321 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, | 357 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, |
| 322 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4, | 358 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4, |
| 323 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4, | 359 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4, |
| 324 | 360 |
| 325 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8, | 361 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8, |
| 326 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8, | 362 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8, |
| 327 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8, | 363 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8, |
| 328 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8, | 364 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8, |
| 329 }; | 365 }; |
| 330 | 366 |
| 331 static const int kIndicesPerMiterStrokeRect = SK_ARRAY_COUNT(gMiterStrokeAARectI
dx); | |
| 332 static const int kVertsPerMiterStrokeRect = 16; | |
| 333 static const int kNumMiterStrokeRectsInIndexBuffer = 256; | |
| 334 | |
| 335 /** | 367 /** |
| 336 * As in miter-stroke, index = a + b, and a is the current index, b is the shift | 368 * As in miter-stroke, index = a + b, and a is the current index, b is the shift |
| 337 * from the first index. The index layout: | 369 * from the first index. The index layout: |
| 338 * outer AA line: 0~3, 4~7 | 370 * outer AA line: 0~3, 4~7 |
| 339 * outer edge: 8~11, 12~15 | 371 * outer edge: 8~11, 12~15 |
| 340 * inner edge: 16~19 | 372 * inner edge: 16~19 |
| 341 * inner AA line: 20~23 | 373 * inner AA line: 20~23 |
| 342 * Following comes a bevel-stroke rect and its indices: | 374 * Following comes a bevel-stroke rect and its indices: |
| 343 * | 375 * |
| 344 * 4 7 | 376 * 4 7 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 7 + 8, 4 + 8, 8 + 8, 8 + 8, 11 + 8, 7 + 8, | 414 7 + 8, 4 + 8, 8 + 8, 8 + 8, 11 + 8, 7 + 8, |
| 383 4 + 8, 0 + 8, 8 + 8, | 415 4 + 8, 0 + 8, 8 + 8, |
| 384 | 416 |
| 385 // Draw the inner AA, from inner edge to inner AA line, shift is 16. | 417 // Draw the inner AA, from inner edge to inner AA line, shift is 16. |
| 386 0 + 16, 1 + 16, 5 + 16, 5 + 16, 4 + 16, 0 + 16, | 418 0 + 16, 1 + 16, 5 + 16, 5 + 16, 4 + 16, 0 + 16, |
| 387 1 + 16, 2 + 16, 6 + 16, 6 + 16, 5 + 16, 1 + 16, | 419 1 + 16, 2 + 16, 6 + 16, 6 + 16, 5 + 16, 1 + 16, |
| 388 2 + 16, 3 + 16, 7 + 16, 7 + 16, 6 + 16, 2 + 16, | 420 2 + 16, 3 + 16, 7 + 16, 7 + 16, 6 + 16, 2 + 16, |
| 389 3 + 16, 0 + 16, 4 + 16, 4 + 16, 7 + 16, 3 + 16, | 421 3 + 16, 0 + 16, 4 + 16, 4 + 16, 7 + 16, 3 + 16, |
| 390 }; | 422 }; |
| 391 | 423 |
| 392 static const int kIndicesPerBevelStrokeRect = SK_ARRAY_COUNT(gBevelStrokeAARectI
dx); | |
| 393 static const int kVertsPerBevelStrokeRect = 24; | |
| 394 static const int kNumBevelStrokeRectsInIndexBuffer = 256; | |
| 395 | |
| 396 int GrAARectRenderer::aaStrokeRectIndexCount(bool miterStroke) { | 424 int GrAARectRenderer::aaStrokeRectIndexCount(bool miterStroke) { |
| 397 return miterStroke ? SK_ARRAY_COUNT(gMiterStrokeAARectIdx) : | 425 return miterStroke ? SK_ARRAY_COUNT(gMiterStrokeAARectIdx) : |
| 398 SK_ARRAY_COUNT(gBevelStrokeAARectIdx); | 426 SK_ARRAY_COUNT(gBevelStrokeAARectIdx); |
| 399 } | 427 } |
| 400 | 428 |
| 401 GrIndexBuffer* GrAARectRenderer::aaStrokeRectIndexBuffer(GrGpu* gpu, bool miterS
troke) { | 429 GrIndexBuffer* GrAARectRenderer::aaStrokeRectIndexBuffer(GrGpu* gpu, bool miterS
troke) { |
| 402 if (miterStroke) { | 430 if (miterStroke) { |
| 403 if (NULL == fAAMiterStrokeRectIndexBuffer) { | 431 if (NULL == fAAMiterStrokeRectIndexBuffer) { |
| 404 fAAMiterStrokeRectIndexBuffer = | 432 fAAMiterStrokeRectIndexBuffer = |
| 405 gpu->createInstancedIndexBuffer(gMiterStrokeAARectIdx, | 433 gpu->createIndexBuffer(sizeof(gMiterStrokeAARectIdx), false); |
| 406 kIndicesPerMiterStrokeRect, | 434 if (fAAMiterStrokeRectIndexBuffer) { |
| 407 kNumMiterStrokeRectsInIndexB
uffer, | 435 #ifdef SK_DEBUG |
| 408 kVertsPerMiterStrokeRect); | 436 bool updated = |
| 437 #endif |
| 438 fAAMiterStrokeRectIndexBuffer->updateData(gMiterStrokeAARectIdx, |
| 439 sizeof(gMiterStrokeAAR
ectIdx)); |
| 440 GR_DEBUGASSERT(updated); |
| 441 } |
| 409 } | 442 } |
| 410 return fAAMiterStrokeRectIndexBuffer; | 443 return fAAMiterStrokeRectIndexBuffer; |
| 411 } else { | 444 } else { |
| 412 if (NULL == fAABevelStrokeRectIndexBuffer) { | 445 if (NULL == fAABevelStrokeRectIndexBuffer) { |
| 413 fAABevelStrokeRectIndexBuffer = | 446 fAABevelStrokeRectIndexBuffer = |
| 414 gpu->createInstancedIndexBuffer(gBevelStrokeAARectIdx, | 447 gpu->createIndexBuffer(sizeof(gBevelStrokeAARectIdx), false); |
| 415 kIndicesPerBevelStrokeRect, | 448 if (fAABevelStrokeRectIndexBuffer) { |
| 416 kNumBevelStrokeRectsInIndexB
uffer, | 449 #ifdef SK_DEBUG |
| 417 kVertsPerBevelStrokeRect); | 450 bool updated = |
| 451 #endif |
| 452 fAABevelStrokeRectIndexBuffer->updateData(gBevelStrokeAARectIdx, |
| 453 sizeof(gBevelStrokeAAR
ectIdx)); |
| 454 GR_DEBUGASSERT(updated); |
| 455 } |
| 418 } | 456 } |
| 419 return fAABevelStrokeRectIndexBuffer; | 457 return fAABevelStrokeRectIndexBuffer; |
| 420 } | 458 } |
| 421 } | 459 } |
| 422 | 460 |
| 423 void GrAARectRenderer::geometryFillAARect(GrGpu* gpu, | 461 void GrAARectRenderer::geometryFillAARect(GrGpu* gpu, |
| 424 GrDrawTarget* target, | 462 GrDrawTarget* target, |
| 425 const SkRect& rect, | 463 const SkRect& rect, |
| 426 const SkMatrix& combinedMatrix, | 464 const SkMatrix& combinedMatrix, |
| 427 const SkRect& devRect) { | 465 const SkRect& devRect) { |
| 428 GrDrawState* drawState = target->drawState(); | 466 GrDrawState* drawState = target->drawState(); |
| 429 | 467 |
| 430 GrColor color = drawState->getColor(); | 468 GrColor color = drawState->getColor(); |
| 431 | 469 |
| 432 CoverageAttribType covAttribType = set_rect_attribs(drawState); | 470 CoverageAttribType covAttribType = set_rect_attribs(drawState); |
| 433 if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(colo
r)) { | 471 if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(colo
r)) { |
| 434 drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true); | 472 drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true); |
| 435 } | 473 } |
| 436 | 474 |
| 437 GrDrawTarget::AutoReleaseGeometry geo(target, 8, 0); | 475 GrDrawTarget::AutoReleaseGeometry geo(target, 8, 0); |
| 438 if (!geo.succeeded()) { | 476 if (!geo.succeeded()) { |
| 439 GrPrintf("Failed to get space for vertices!\n"); | 477 GrPrintf("Failed to get space for vertices!\n"); |
| 440 return; | 478 return; |
| 441 } | 479 } |
| 442 | 480 |
| 443 if (NULL == fAAFillRectIndexBuffer) { | 481 GrIndexBuffer* indexBuffer = this->aaFillRectIndexBuffer(gpu); |
| 444 fAAFillRectIndexBuffer = gpu->createInstancedIndexBuffer(gFillAARectIdx, | |
| 445 kIndicesPerAAFi
llRect, | |
| 446 kNumAAFillRects
InIndexBuffer, | |
| 447 kVertsPerAAFill
Rect); | |
| 448 } | |
| 449 GrIndexBuffer* indexBuffer = fAAFillRectIndexBuffer; | |
| 450 if (NULL == indexBuffer) { | 482 if (NULL == indexBuffer) { |
| 451 GrPrintf("Failed to create index buffer!\n"); | 483 GrPrintf("Failed to create index buffer!\n"); |
| 452 return; | 484 return; |
| 453 } | 485 } |
| 454 | 486 |
| 455 intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); | 487 intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); |
| 456 size_t vstride = drawState->getVertexStride(); | 488 size_t vstride = drawState->getVertexStride(); |
| 457 | 489 |
| 458 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); | 490 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); |
| 459 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vstride); | 491 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vstride); |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 for (int i = 0; i < innerVertexNum; ++i) { | 926 for (int i = 0; i < innerVertexNum; ++i) { |
| 895 if (kUseCoverage_CoverageAttribType == covAttribType) { | 927 if (kUseCoverage_CoverageAttribType == covAttribType) { |
| 896 *reinterpret_cast<GrColor*>(verts + i * vstride) = color; | 928 *reinterpret_cast<GrColor*>(verts + i * vstride) = color; |
| 897 *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) =
0; | 929 *reinterpret_cast<GrColor*>(verts + i * vstride + sizeof(GrColor)) =
0; |
| 898 } else { | 930 } else { |
| 899 *reinterpret_cast<GrColor*>(verts + i * vstride) = 0; | 931 *reinterpret_cast<GrColor*>(verts + i * vstride) = 0; |
| 900 } | 932 } |
| 901 } | 933 } |
| 902 | 934 |
| 903 target->setIndexSourceToBuffer(indexBuffer); | 935 target->setIndexSourceToBuffer(indexBuffer); |
| 904 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, | 936 target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, |
| 905 totalVertexNum, aaStrokeRectIndexCount(miterStr
oke)); | 937 totalVertexNum, aaStrokeRectIndexCount(miterStroke)); |
| 906 target->resetIndexSource(); | |
| 907 } | 938 } |
| 908 | 939 |
| 909 void GrAARectRenderer::fillAANestedRects(GrGpu* gpu, | 940 void GrAARectRenderer::fillAANestedRects(GrGpu* gpu, |
| 910 GrDrawTarget* target, | 941 GrDrawTarget* target, |
| 911 const SkRect rects[2], | 942 const SkRect rects[2], |
| 912 const SkMatrix& combinedMatrix) { | 943 const SkMatrix& combinedMatrix) { |
| 913 SkASSERT(combinedMatrix.rectStaysRect()); | 944 SkASSERT(combinedMatrix.rectStaysRect()); |
| 914 SkASSERT(!rects[1].isEmpty()); | 945 SkASSERT(!rects[1].isEmpty()); |
| 915 | 946 |
| 916 SkRect devOutside, devOutsideAssist, devInside; | 947 SkRect devOutside, devOutsideAssist, devInside; |
| 917 combinedMatrix.mapRect(&devOutside, rects[0]); | 948 combinedMatrix.mapRect(&devOutside, rects[0]); |
| 918 // can't call mapRect for devInside since it calls sort | 949 // can't call mapRect for devInside since it calls sort |
| 919 combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2)
; | 950 combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2)
; |
| 920 | 951 |
| 921 if (devInside.isEmpty()) { | 952 if (devInside.isEmpty()) { |
| 922 this->fillAARect(gpu, target, devOutside, SkMatrix::I(), devOutside); | 953 this->fillAARect(gpu, target, devOutside, SkMatrix::I(), devOutside); |
| 923 return; | 954 return; |
| 924 } | 955 } |
| 925 | 956 |
| 926 this->geometryStrokeAARect(gpu, target, devOutside, devOutsideAssist, devIns
ide, true); | 957 this->geometryStrokeAARect(gpu, target, devOutside, devOutsideAssist, devIns
ide, true); |
| 927 } | 958 } |
| OLD | NEW |