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