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