OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrContext.h" | 9 #include "GrContext.h" |
10 | 10 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 static const size_t MAX_RESOURCE_CACHE_BYTES = GR_DEFAULT_RESOURCE_CACHE_MB_LIMI
T * 1024 * 1024; | 55 static const size_t MAX_RESOURCE_CACHE_BYTES = GR_DEFAULT_RESOURCE_CACHE_MB_LIMI
T * 1024 * 1024; |
56 | 56 |
57 static const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 15; | 57 static const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 15; |
58 static const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4; | 58 static const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4; |
59 | 59 |
60 static const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 1 << 11; | 60 static const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 1 << 11; |
61 static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 4; | 61 static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 4; |
62 | 62 |
63 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) | 63 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) |
64 | 64 |
65 // Glorified typedef to avoid including GrDrawState.h in GrContext.h | |
66 class GrContext::AutoRestoreEffects : public GrDrawState::AutoRestoreEffects {}; | |
67 | |
68 class GrContext::AutoCheckFlush { | 65 class GrContext::AutoCheckFlush { |
69 public: | 66 public: |
70 AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context);
} | 67 AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context);
} |
71 | 68 |
72 ~AutoCheckFlush() { | 69 ~AutoCheckFlush() { |
73 if (fContext->fFlushToReduceCacheSize) { | 70 if (fContext->fFlushToReduceCacheSize) { |
74 fContext->flush(); | 71 fContext->flush(); |
75 } | 72 } |
76 } | 73 } |
77 | 74 |
(...skipping 12 matching lines...) Expand all Loading... |
90 | 87 |
91 if (context->init(backend, backendContext)) { | 88 if (context->init(backend, backendContext)) { |
92 return context; | 89 return context; |
93 } else { | 90 } else { |
94 context->unref(); | 91 context->unref(); |
95 return NULL; | 92 return NULL; |
96 } | 93 } |
97 } | 94 } |
98 | 95 |
99 GrContext::GrContext(const Options& opts) : fOptions(opts) { | 96 GrContext::GrContext(const Options& opts) : fOptions(opts) { |
100 fDrawState = NULL; | |
101 fGpu = NULL; | 97 fGpu = NULL; |
102 fClip = NULL; | 98 fClip = NULL; |
103 fPathRendererChain = NULL; | 99 fPathRendererChain = NULL; |
104 fSoftwarePathRenderer = NULL; | 100 fSoftwarePathRenderer = NULL; |
105 fResourceCache = NULL; | 101 fResourceCache = NULL; |
106 fResourceCache2 = NULL; | 102 fResourceCache2 = NULL; |
107 fFontCache = NULL; | 103 fFontCache = NULL; |
108 fDrawBuffer = NULL; | 104 fDrawBuffer = NULL; |
109 fDrawBufferVBAllocPool = NULL; | 105 fDrawBufferVBAllocPool = NULL; |
110 fDrawBufferIBAllocPool = NULL; | 106 fDrawBufferIBAllocPool = NULL; |
111 fFlushToReduceCacheSize = false; | 107 fFlushToReduceCacheSize = false; |
112 fAARectRenderer = NULL; | 108 fAARectRenderer = NULL; |
113 fOvalRenderer = NULL; | 109 fOvalRenderer = NULL; |
114 fViewMatrix.reset(); | 110 fViewMatrix.reset(); |
115 fMaxTextureSizeOverride = 1 << 20; | 111 fMaxTextureSizeOverride = 1 << 20; |
116 } | 112 } |
117 | 113 |
118 bool GrContext::init(GrBackend backend, GrBackendContext backendContext) { | 114 bool GrContext::init(GrBackend backend, GrBackendContext backendContext) { |
119 SkASSERT(NULL == fGpu); | 115 SkASSERT(NULL == fGpu); |
120 | 116 |
121 fGpu = GrGpu::Create(backend, backendContext, this); | 117 fGpu = GrGpu::Create(backend, backendContext, this); |
122 if (NULL == fGpu) { | 118 if (NULL == fGpu) { |
123 return false; | 119 return false; |
124 } | 120 } |
125 this->initCommon(); | 121 this->initCommon(); |
126 return true; | 122 return true; |
127 } | 123 } |
128 | 124 |
129 void GrContext::initCommon() { | 125 void GrContext::initCommon() { |
130 fDrawState = SkNEW(GrDrawState); | |
131 | |
132 fResourceCache = SkNEW_ARGS(GrResourceCache, (fGpu->caps(), | 126 fResourceCache = SkNEW_ARGS(GrResourceCache, (fGpu->caps(), |
133 MAX_RESOURCE_CACHE_COUNT, | 127 MAX_RESOURCE_CACHE_COUNT, |
134 MAX_RESOURCE_CACHE_BYTES)); | 128 MAX_RESOURCE_CACHE_BYTES)); |
135 fResourceCache->setOverbudgetCallback(OverbudgetCB, this); | 129 fResourceCache->setOverbudgetCallback(OverbudgetCB, this); |
136 fResourceCache2 = SkNEW(GrResourceCache2); | 130 fResourceCache2 = SkNEW(GrResourceCache2); |
137 | 131 |
138 fFontCache = SkNEW_ARGS(GrFontCache, (fGpu)); | 132 fFontCache = SkNEW_ARGS(GrFontCache, (fGpu)); |
139 | 133 |
140 fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (this))); | 134 fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (this))); |
141 | 135 |
(...skipping 24 matching lines...) Expand all Loading... |
166 SkDELETE(fDrawBuffer); | 160 SkDELETE(fDrawBuffer); |
167 SkDELETE(fDrawBufferVBAllocPool); | 161 SkDELETE(fDrawBufferVBAllocPool); |
168 SkDELETE(fDrawBufferIBAllocPool); | 162 SkDELETE(fDrawBufferIBAllocPool); |
169 | 163 |
170 fAARectRenderer->unref(); | 164 fAARectRenderer->unref(); |
171 fOvalRenderer->unref(); | 165 fOvalRenderer->unref(); |
172 | 166 |
173 fGpu->unref(); | 167 fGpu->unref(); |
174 SkSafeUnref(fPathRendererChain); | 168 SkSafeUnref(fPathRendererChain); |
175 SkSafeUnref(fSoftwarePathRenderer); | 169 SkSafeUnref(fSoftwarePathRenderer); |
176 fDrawState->unref(); | |
177 } | 170 } |
178 | 171 |
179 void GrContext::abandonContext() { | 172 void GrContext::abandonContext() { |
180 // abandon first to so destructors | 173 // abandon first to so destructors |
181 // don't try to free the resources in the API. | 174 // don't try to free the resources in the API. |
182 fResourceCache2->abandonAll(); | 175 fResourceCache2->abandonAll(); |
183 | 176 |
184 fGpu->contextAbandoned(); | 177 fGpu->contextAbandoned(); |
185 | 178 |
186 // a path renderer may be holding onto resources that | 179 // a path renderer may be holding onto resources that |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 GrSurfaceDesc rtDesc = desc; | 323 GrSurfaceDesc rtDesc = desc; |
331 rtDesc.fFlags = rtDesc.fFlags | | 324 rtDesc.fFlags = rtDesc.fFlags | |
332 kRenderTarget_GrSurfaceFlag | | 325 kRenderTarget_GrSurfaceFlag | |
333 kNoStencil_GrSurfaceFlag; | 326 kNoStencil_GrSurfaceFlag; |
334 rtDesc.fWidth = GrNextPow2(desc.fWidth); | 327 rtDesc.fWidth = GrNextPow2(desc.fWidth); |
335 rtDesc.fHeight = GrNextPow2(desc.fHeight); | 328 rtDesc.fHeight = GrNextPow2(desc.fHeight); |
336 | 329 |
337 GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); | 330 GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); |
338 | 331 |
339 if (texture) { | 332 if (texture) { |
340 GrDrawTarget::AutoStateRestore asr(fDrawBuffer, GrDrawTarget::kReset_ASR
Init); | 333 GrDrawState drawState; |
341 GrDrawState* drawState = fDrawBuffer->drawState(); | 334 drawState.setRenderTarget(texture->asRenderTarget()); |
342 drawState->setRenderTarget(texture->asRenderTarget()); | |
343 | 335 |
344 // if filtering is not desired then we want to ensure all | 336 // if filtering is not desired then we want to ensure all |
345 // texels in the resampled image are copies of texels from | 337 // texels in the resampled image are copies of texels from |
346 // the original. | 338 // the original. |
347 GrTextureParams params(SkShader::kClamp_TileMode, | 339 GrTextureParams params(SkShader::kClamp_TileMode, |
348 filter ? GrTextureParams::kBilerp_FilterMode : | 340 filter ? GrTextureParams::kBilerp_FilterMode : |
349 GrTextureParams::kNone_FilterMode); | 341 GrTextureParams::kNone_FilterMode); |
350 drawState->addColorTextureProcessor(clampedTexture, SkMatrix::I(), param
s); | 342 drawState.addColorTextureProcessor(clampedTexture, SkMatrix::I(), params
); |
351 | 343 |
352 drawState->setGeometryProcessor( | 344 drawState.setGeometryProcessor( |
353 GrDefaultGeoProcFactory::CreateAndSetAttribs( | 345 GrDefaultGeoProcFactory::CreateAndSetAttribs( |
354 drawState, | 346 &drawState, |
355 GrDefaultGeoProcFactory::kPosition_GPType | | 347 GrDefaultGeoProcFactory::kPosition_GPType | |
356 GrDefaultGeoProcFactory::kLocalCoord_GPType))->unref(); | 348 GrDefaultGeoProcFactory::kLocalCoord_GPType))->unref(); |
357 | 349 |
358 GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, 0); | 350 GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, drawState.getVerte
xStride(), 0); |
359 | 351 |
360 if (arg.succeeded()) { | 352 if (arg.succeeded()) { |
361 SkPoint* verts = (SkPoint*) arg.vertices(); | 353 SkPoint* verts = (SkPoint*) arg.vertices(); |
362 verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 *
sizeof(SkPoint)); | 354 verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 *
sizeof(SkPoint)); |
363 verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(SkPoint)); | 355 verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(SkPoint)); |
364 fDrawBuffer->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); | 356 fDrawBuffer->drawNonIndexed(&drawState, kTriangleFan_GrPrimitiveType
, 0, 4); |
365 } | 357 } |
366 } else { | 358 } else { |
367 // TODO: Our CPU stretch doesn't filter. But we create separate | 359 // TODO: Our CPU stretch doesn't filter. But we create separate |
368 // stretched textures when the texture params is either filtered or | 360 // stretched textures when the texture params is either filtered or |
369 // not. Either implement filtered stretch blit on CPU or just create | 361 // not. Either implement filtered stretch blit on CPU or just create |
370 // one when FBO case fails. | 362 // one when FBO case fails. |
371 | 363 |
372 rtDesc.fFlags = kNone_GrSurfaceFlags; | 364 rtDesc.fFlags = kNone_GrSurfaceFlags; |
373 // no longer need to clamp at min RT size. | 365 // no longer need to clamp at min RT size. |
374 rtDesc.fWidth = GrNextPow2(desc.fWidth); | 366 rtDesc.fWidth = GrNextPow2(desc.fWidth); |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 | 558 |
567 //////////////////////////////////////////////////////////////////////////////// | 559 //////////////////////////////////////////////////////////////////////////////// |
568 | 560 |
569 void GrContext::clear(const SkIRect* rect, | 561 void GrContext::clear(const SkIRect* rect, |
570 const GrColor color, | 562 const GrColor color, |
571 bool canIgnoreRect, | 563 bool canIgnoreRect, |
572 GrRenderTarget* renderTarget) { | 564 GrRenderTarget* renderTarget) { |
573 ASSERT_OWNED_RESOURCE(renderTarget); | 565 ASSERT_OWNED_RESOURCE(renderTarget); |
574 SkASSERT(renderTarget); | 566 SkASSERT(renderTarget); |
575 | 567 |
576 AutoRestoreEffects are; | |
577 AutoCheckFlush acf(this); | 568 AutoCheckFlush acf(this); |
578 GR_CREATE_TRACE_MARKER_CONTEXT("GrContext::clear", this); | 569 GR_CREATE_TRACE_MARKER_CONTEXT("GrContext::clear", this); |
579 GrDrawTarget* target = this->prepareToDraw(NULL, &are, &acf); | 570 GrDrawTarget* target = this->prepareToDraw(NULL, NULL, &acf); |
580 if (NULL == target) { | 571 if (NULL == target) { |
581 return; | 572 return; |
582 } | 573 } |
583 target->clear(rect, color, canIgnoreRect, renderTarget); | 574 target->clear(rect, color, canIgnoreRect, renderTarget); |
584 } | 575 } |
585 | 576 |
586 void GrContext::drawPaint(const GrPaint& origPaint) { | 577 void GrContext::drawPaint(const GrPaint& origPaint) { |
587 // set rect to be big enough to fill the space, but not super-huge, so we | 578 // set rect to be big enough to fill the space, but not super-huge, so we |
588 // don't overflow fixed-point implementations | 579 // don't overflow fixed-point implementations |
589 SkRect r; | 580 SkRect r; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 verts[8] = verts[0]; | 637 verts[8] = verts[0]; |
647 verts[9] = verts[1]; | 638 verts[9] = verts[1]; |
648 } | 639 } |
649 | 640 |
650 static inline bool is_irect(const SkRect& r) { | 641 static inline bool is_irect(const SkRect& r) { |
651 return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) && | 642 return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) && |
652 SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom); | 643 SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom); |
653 } | 644 } |
654 | 645 |
655 static bool apply_aa_to_rect(GrDrawTarget* target, | 646 static bool apply_aa_to_rect(GrDrawTarget* target, |
| 647 GrDrawState* ds, |
| 648 SkRect* devBoundRect, |
656 const SkRect& rect, | 649 const SkRect& rect, |
657 SkScalar strokeWidth, | 650 SkScalar strokeWidth, |
658 const SkMatrix& combinedMatrix, | 651 const SkMatrix& combinedMatrix) { |
659 SkRect* devBoundRect) { | 652 if (!ds->canTweakAlphaForCoverage() && !ds->couldApplyCoverage(*target->caps
())) { |
660 if (!target->getDrawState().canTweakAlphaForCoverage() && | |
661 target->shouldDisableCoverageAAForBlend()) { | |
662 #ifdef SK_DEBUG | 653 #ifdef SK_DEBUG |
663 //SkDebugf("Turning off AA to correctly apply blend.\n"); | 654 //SkDebugf("Turning off AA to correctly apply blend.\n"); |
664 #endif | 655 #endif |
665 return false; | 656 return false; |
666 } | 657 } |
667 const GrDrawState& drawState = target->getDrawState(); | 658 |
668 if (drawState.getRenderTarget()->isMultisampled()) { | 659 if (ds->getRenderTarget()->isMultisampled()) { |
669 return false; | 660 return false; |
670 } | 661 } |
671 | 662 |
672 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) | 663 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) |
673 if (strokeWidth >= 0) { | 664 if (strokeWidth >= 0) { |
674 #endif | 665 #endif |
675 if (!combinedMatrix.preservesAxisAlignment()) { | 666 if (!combinedMatrix.preservesAxisAlignment()) { |
676 return false; | 667 return false; |
677 } | 668 } |
678 | 669 |
(...skipping 21 matching lines...) Expand all Loading... |
700 void GrContext::drawRect(const GrPaint& paint, | 691 void GrContext::drawRect(const GrPaint& paint, |
701 const SkRect& rect, | 692 const SkRect& rect, |
702 const GrStrokeInfo* strokeInfo) { | 693 const GrStrokeInfo* strokeInfo) { |
703 if (strokeInfo && strokeInfo->isDashed()) { | 694 if (strokeInfo && strokeInfo->isDashed()) { |
704 SkPath path; | 695 SkPath path; |
705 path.addRect(rect); | 696 path.addRect(rect); |
706 this->drawPath(paint, path, *strokeInfo); | 697 this->drawPath(paint, path, *strokeInfo); |
707 return; | 698 return; |
708 } | 699 } |
709 | 700 |
710 AutoRestoreEffects are; | |
711 AutoCheckFlush acf(this); | 701 AutoCheckFlush acf(this); |
712 GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf); | 702 GrDrawState drawState; |
| 703 GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf); |
713 if (NULL == target) { | 704 if (NULL == target) { |
714 return; | 705 return; |
715 } | 706 } |
716 | 707 |
717 GR_CREATE_TRACE_MARKER("GrContext::drawRect", target); | 708 GR_CREATE_TRACE_MARKER("GrContext::drawRect", target); |
718 SkScalar width = NULL == strokeInfo ? -1 : strokeInfo->getStrokeRec().getWid
th(); | 709 SkScalar width = NULL == strokeInfo ? -1 : strokeInfo->getStrokeRec().getWid
th(); |
719 SkMatrix matrix = target->drawState()->getViewMatrix(); | 710 SkMatrix matrix = drawState.getViewMatrix(); |
720 | 711 |
721 // Check if this is a full RT draw and can be replaced with a clear. We don'
t bother checking | 712 // Check if this is a full RT draw and can be replaced with a clear. We don'
t bother checking |
722 // cases where the RT is fully inside a stroke. | 713 // cases where the RT is fully inside a stroke. |
723 if (width < 0) { | 714 if (width < 0) { |
724 SkRect rtRect; | 715 SkRect rtRect; |
725 target->getDrawState().getRenderTarget()->getBoundsRect(&rtRect); | 716 drawState.getRenderTarget()->getBoundsRect(&rtRect); |
726 SkRect clipSpaceRTRect = rtRect; | 717 SkRect clipSpaceRTRect = rtRect; |
727 bool checkClip = false; | 718 bool checkClip = false; |
728 if (this->getClip()) { | 719 if (this->getClip()) { |
729 checkClip = true; | 720 checkClip = true; |
730 clipSpaceRTRect.offset(SkIntToScalar(this->getClip()->fOrigin.fX), | 721 clipSpaceRTRect.offset(SkIntToScalar(this->getClip()->fOrigin.fX), |
731 SkIntToScalar(this->getClip()->fOrigin.fY)); | 722 SkIntToScalar(this->getClip()->fOrigin.fY)); |
732 } | 723 } |
733 // Does the clip contain the entire RT? | 724 // Does the clip contain the entire RT? |
734 if (!checkClip || target->getClip()->fClipStack->quickContains(clipSpace
RTRect)) { | 725 if (!checkClip || target->getClip()->fClipStack->quickContains(clipSpace
RTRect)) { |
735 SkMatrix invM; | 726 SkMatrix invM; |
(...skipping 11 matching lines...) Expand all Loading... |
747 GrColor clearColor; | 738 GrColor clearColor; |
748 if (paint.isOpaqueAndConstantColor(&clearColor)) { | 739 if (paint.isOpaqueAndConstantColor(&clearColor)) { |
749 target->clear(NULL, clearColor, true, fRenderTarget); | 740 target->clear(NULL, clearColor, true, fRenderTarget); |
750 return; | 741 return; |
751 } | 742 } |
752 } | 743 } |
753 } | 744 } |
754 } | 745 } |
755 | 746 |
756 SkRect devBoundRect; | 747 SkRect devBoundRect; |
757 bool needAA = paint.isAntiAlias() && | 748 bool needAA = paint.isAntiAlias() && !drawState.getRenderTarget()->isMultisa
mpled(); |
758 !target->getDrawState().getRenderTarget()->isMultisampled(); | 749 bool doAA = needAA && apply_aa_to_rect(target, &drawState, &devBoundRect, re
ct, width, matrix); |
759 bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, &devBoun
dRect); | |
760 | 750 |
761 const SkStrokeRec& strokeRec = strokeInfo->getStrokeRec(); | 751 const SkStrokeRec& strokeRec = strokeInfo->getStrokeRec(); |
762 | 752 |
763 if (doAA) { | 753 if (doAA) { |
764 GrDrawState::AutoViewMatrixRestore avmr; | 754 GrDrawState::AutoViewMatrixRestore avmr; |
765 if (!avmr.setIdentity(target->drawState())) { | 755 if (!avmr.setIdentity(&drawState)) { |
766 return; | 756 return; |
767 } | 757 } |
| 758 |
768 if (width >= 0) { | 759 if (width >= 0) { |
769 fAARectRenderer->strokeAARect(target, rect, | 760 fAARectRenderer->strokeAARect(target, |
770 matrix, devBoundRect, | 761 &drawState, |
| 762 rect, |
| 763 matrix, |
| 764 devBoundRect, |
771 strokeRec); | 765 strokeRec); |
772 } else { | 766 } else { |
773 // filled AA rect | 767 // filled AA rect |
774 fAARectRenderer->fillAARect(target, | 768 fAARectRenderer->fillAARect(target, &drawState, rect, matrix, devBou
ndRect); |
775 rect, matrix, devBoundRect); | |
776 } | 769 } |
777 return; | 770 return; |
778 } | 771 } |
779 | 772 |
780 if (width >= 0) { | 773 if (width >= 0) { |
781 // TODO: consider making static vertex buffers for these cases. | 774 // TODO: consider making static vertex buffers for these cases. |
782 // Hairline could be done by just adding closing vertex to | 775 // Hairline could be done by just adding closing vertex to |
783 // unitSquareVertexBuffer() | 776 // unitSquareVertexBuffer() |
784 | 777 |
785 static const int worstCaseVertCount = 10; | 778 static const int worstCaseVertCount = 10; |
786 target->drawState()->setDefaultVertexAttribs(); | 779 drawState.setDefaultVertexAttribs(); |
787 target->drawState()->setGeometryProcessor(GrDefaultGeoProcFactory::Creat
e(false))->unref(); | 780 drawState.setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->
unref(); |
788 GrDrawTarget::AutoReleaseGeometry geo(target, worstCaseVertCount, 0); | 781 GrDrawTarget::AutoReleaseGeometry geo(target, |
| 782 worstCaseVertCount, |
| 783 drawState.getVertexStride(), |
| 784 0); |
789 | 785 |
790 if (!geo.succeeded()) { | 786 if (!geo.succeeded()) { |
791 SkDebugf("Failed to get space for vertices!\n"); | 787 SkDebugf("Failed to get space for vertices!\n"); |
792 return; | 788 return; |
793 } | 789 } |
794 | 790 |
795 GrPrimitiveType primType; | 791 GrPrimitiveType primType; |
796 int vertCount; | 792 int vertCount; |
797 SkPoint* vertex = geo.positions(); | 793 SkPoint* vertex = geo.positions(); |
798 | 794 |
799 if (width > 0) { | 795 if (width > 0) { |
800 vertCount = 10; | 796 vertCount = 10; |
801 primType = kTriangleStrip_GrPrimitiveType; | 797 primType = kTriangleStrip_GrPrimitiveType; |
802 setStrokeRectStrip(vertex, rect, width); | 798 setStrokeRectStrip(vertex, rect, width); |
803 } else { | 799 } else { |
804 // hairline | 800 // hairline |
805 vertCount = 5; | 801 vertCount = 5; |
806 primType = kLineStrip_GrPrimitiveType; | 802 primType = kLineStrip_GrPrimitiveType; |
807 vertex[0].set(rect.fLeft, rect.fTop); | 803 vertex[0].set(rect.fLeft, rect.fTop); |
808 vertex[1].set(rect.fRight, rect.fTop); | 804 vertex[1].set(rect.fRight, rect.fTop); |
809 vertex[2].set(rect.fRight, rect.fBottom); | 805 vertex[2].set(rect.fRight, rect.fBottom); |
810 vertex[3].set(rect.fLeft, rect.fBottom); | 806 vertex[3].set(rect.fLeft, rect.fBottom); |
811 vertex[4].set(rect.fLeft, rect.fTop); | 807 vertex[4].set(rect.fLeft, rect.fTop); |
812 } | 808 } |
813 | 809 |
814 target->drawNonIndexed(primType, 0, vertCount); | 810 target->drawNonIndexed(&drawState, primType, 0, vertCount); |
815 } else { | 811 } else { |
816 // filled BW rect | 812 // filled BW rect |
817 target->drawSimpleRect(rect); | 813 target->drawSimpleRect(&drawState, rect); |
818 } | 814 } |
819 } | 815 } |
820 | 816 |
821 void GrContext::drawRectToRect(const GrPaint& paint, | 817 void GrContext::drawRectToRect(const GrPaint& paint, |
822 const SkRect& dstRect, | 818 const SkRect& dstRect, |
823 const SkRect& localRect, | 819 const SkRect& localRect, |
824 const SkMatrix* localMatrix) { | 820 const SkMatrix* localMatrix) { |
825 AutoRestoreEffects are; | |
826 AutoCheckFlush acf(this); | 821 AutoCheckFlush acf(this); |
827 GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf); | 822 GrDrawState drawState; |
| 823 GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf); |
828 if (NULL == target) { | 824 if (NULL == target) { |
829 return; | 825 return; |
830 } | 826 } |
831 | 827 |
832 GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target); | 828 GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target); |
833 | 829 |
834 target->drawRect(dstRect, &localRect, localMatrix); | 830 target->drawRect(&drawState, dstRect, &localRect, localMatrix); |
835 } | 831 } |
836 | 832 |
837 static void set_vertex_attributes(GrDrawState* drawState, | 833 static void set_vertex_attributes(GrDrawState* drawState, |
838 const SkPoint* texCoords, | 834 const SkPoint* texCoords, |
839 const GrColor* colors, | 835 const GrColor* colors, |
840 int* colorOffset, | 836 int* colorOffset, |
841 int* texOffset) { | 837 int* texOffset) { |
842 *texOffset = -1; | 838 *texOffset = -1; |
843 *colorOffset = -1; | 839 *colorOffset = -1; |
844 | 840 |
(...skipping 15 matching lines...) Expand all Loading... |
860 } | 856 } |
861 | 857 |
862 void GrContext::drawVertices(const GrPaint& paint, | 858 void GrContext::drawVertices(const GrPaint& paint, |
863 GrPrimitiveType primitiveType, | 859 GrPrimitiveType primitiveType, |
864 int vertexCount, | 860 int vertexCount, |
865 const SkPoint positions[], | 861 const SkPoint positions[], |
866 const SkPoint texCoords[], | 862 const SkPoint texCoords[], |
867 const GrColor colors[], | 863 const GrColor colors[], |
868 const uint16_t indices[], | 864 const uint16_t indices[], |
869 int indexCount) { | 865 int indexCount) { |
870 AutoRestoreEffects are; | |
871 AutoCheckFlush acf(this); | 866 AutoCheckFlush acf(this); |
| 867 GrDrawState drawState; |
872 GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scop
e | 868 GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scop
e |
873 | 869 |
874 GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf); | 870 GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf); |
875 if (NULL == target) { | 871 if (NULL == target) { |
876 return; | 872 return; |
877 } | 873 } |
878 GrDrawState* drawState = target->drawState(); | |
879 | 874 |
880 GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target); | 875 GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target); |
881 | 876 |
882 int colorOffset = -1, texOffset = -1; | 877 int colorOffset = -1, texOffset = -1; |
883 set_vertex_attributes(drawState, texCoords, colors, &colorOffset, &texOffset
); | 878 set_vertex_attributes(&drawState, texCoords, colors, &colorOffset, &texOffse
t); |
884 | 879 |
885 size_t VertexStride = drawState->getVertexStride(); | 880 size_t vertexStride = drawState.getVertexStride(); |
886 if (!geo.set(target, vertexCount, indexCount)) { | 881 if (!geo.set(target, vertexCount, vertexStride, indexCount)) { |
887 SkDebugf("Failed to get space for vertices!\n"); | 882 SkDebugf("Failed to get space for vertices!\n"); |
888 return; | 883 return; |
889 } | 884 } |
890 void* curVertex = geo.vertices(); | 885 void* curVertex = geo.vertices(); |
891 | 886 |
892 for (int i = 0; i < vertexCount; ++i) { | 887 for (int i = 0; i < vertexCount; ++i) { |
893 *((SkPoint*)curVertex) = positions[i]; | 888 *((SkPoint*)curVertex) = positions[i]; |
894 | 889 |
895 if (texOffset >= 0) { | 890 if (texOffset >= 0) { |
896 *(SkPoint*)((intptr_t)curVertex + texOffset) = texCoords[i]; | 891 *(SkPoint*)((intptr_t)curVertex + texOffset) = texCoords[i]; |
897 } | 892 } |
898 if (colorOffset >= 0) { | 893 if (colorOffset >= 0) { |
899 *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; | 894 *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; |
900 } | 895 } |
901 curVertex = (void*)((intptr_t)curVertex + VertexStride); | 896 curVertex = (void*)((intptr_t)curVertex + vertexStride); |
902 } | 897 } |
903 | 898 |
904 // we don't currently apply offscreen AA to this path. Need improved | 899 // we don't currently apply offscreen AA to this path. Need improved |
905 // management of GrDrawTarget's geometry to avoid copying points per-tile. | 900 // management of GrDrawTarget's geometry to avoid copying points per-tile. |
906 if (indices) { | 901 if (indices) { |
907 uint16_t* curIndex = (uint16_t*)geo.indices(); | 902 uint16_t* curIndex = (uint16_t*)geo.indices(); |
908 for (int i = 0; i < indexCount; ++i) { | 903 for (int i = 0; i < indexCount; ++i) { |
909 curIndex[i] = indices[i]; | 904 curIndex[i] = indices[i]; |
910 } | 905 } |
911 target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); | 906 target->drawIndexed(&drawState, primitiveType, 0, 0, vertexCount, indexC
ount); |
912 } else { | 907 } else { |
913 target->drawNonIndexed(primitiveType, 0, vertexCount); | 908 target->drawNonIndexed(&drawState, primitiveType, 0, vertexCount); |
914 } | 909 } |
915 } | 910 } |
916 | 911 |
917 /////////////////////////////////////////////////////////////////////////////// | 912 /////////////////////////////////////////////////////////////////////////////// |
918 | 913 |
919 void GrContext::drawRRect(const GrPaint& paint, | 914 void GrContext::drawRRect(const GrPaint& paint, |
920 const SkRRect& rrect, | 915 const SkRRect& rrect, |
921 const GrStrokeInfo& strokeInfo) { | 916 const GrStrokeInfo& strokeInfo) { |
922 if (rrect.isEmpty()) { | 917 if (rrect.isEmpty()) { |
923 return; | 918 return; |
924 } | 919 } |
925 | 920 |
926 if (strokeInfo.isDashed()) { | 921 if (strokeInfo.isDashed()) { |
927 SkPath path; | 922 SkPath path; |
928 path.addRRect(rrect); | 923 path.addRRect(rrect); |
929 this->drawPath(paint, path, strokeInfo); | 924 this->drawPath(paint, path, strokeInfo); |
930 return; | 925 return; |
931 } | 926 } |
932 | 927 |
933 AutoRestoreEffects are; | |
934 AutoCheckFlush acf(this); | 928 AutoCheckFlush acf(this); |
935 GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf); | 929 GrDrawState drawState; |
| 930 GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf); |
936 if (NULL == target) { | 931 if (NULL == target) { |
937 return; | 932 return; |
938 } | 933 } |
939 | 934 |
940 GR_CREATE_TRACE_MARKER("GrContext::drawRRect", target); | 935 GR_CREATE_TRACE_MARKER("GrContext::drawRRect", target); |
941 | 936 |
942 const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); | 937 const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); |
943 | 938 |
944 if (!fOvalRenderer->drawRRect(target, this, paint.isAntiAlias(), rrect, stro
keRec)) { | 939 if (!fOvalRenderer->drawRRect(target, &drawState, this, paint.isAntiAlias(),
rrect, strokeRec)) { |
945 SkPath path; | 940 SkPath path; |
946 path.addRRect(rrect); | 941 path.addRRect(rrect); |
947 this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo); | 942 this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, st
rokeInfo); |
948 } | 943 } |
949 } | 944 } |
950 | 945 |
951 /////////////////////////////////////////////////////////////////////////////// | 946 /////////////////////////////////////////////////////////////////////////////// |
952 | 947 |
953 void GrContext::drawDRRect(const GrPaint& paint, | 948 void GrContext::drawDRRect(const GrPaint& paint, |
954 const SkRRect& outer, | 949 const SkRRect& outer, |
955 const SkRRect& inner) { | 950 const SkRRect& inner) { |
956 if (outer.isEmpty()) { | 951 if (outer.isEmpty()) { |
957 return; | 952 return; |
958 } | 953 } |
959 | 954 |
960 AutoRestoreEffects are; | |
961 AutoCheckFlush acf(this); | 955 AutoCheckFlush acf(this); |
962 GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf); | 956 GrDrawState drawState; |
| 957 GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf); |
963 | 958 |
964 GR_CREATE_TRACE_MARKER("GrContext::drawDRRect", target); | 959 GR_CREATE_TRACE_MARKER("GrContext::drawDRRect", target); |
965 | 960 |
966 if (!fOvalRenderer->drawDRRect(target, this, paint.isAntiAlias(), outer, inn
er)) { | 961 if (!fOvalRenderer->drawDRRect(target, &drawState, this, paint.isAntiAlias()
, outer, inner)) { |
967 SkPath path; | 962 SkPath path; |
968 path.addRRect(inner); | 963 path.addRRect(inner); |
969 path.addRRect(outer); | 964 path.addRRect(outer); |
970 path.setFillType(SkPath::kEvenOdd_FillType); | 965 path.setFillType(SkPath::kEvenOdd_FillType); |
971 | 966 |
972 GrStrokeInfo fillRec(SkStrokeRec::kFill_InitStyle); | 967 GrStrokeInfo fillRec(SkStrokeRec::kFill_InitStyle); |
973 this->internalDrawPath(target, paint.isAntiAlias(), path, fillRec); | 968 this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, fi
llRec); |
974 } | 969 } |
975 } | 970 } |
976 | 971 |
977 /////////////////////////////////////////////////////////////////////////////// | 972 /////////////////////////////////////////////////////////////////////////////// |
978 | 973 |
979 void GrContext::drawOval(const GrPaint& paint, | 974 void GrContext::drawOval(const GrPaint& paint, |
980 const SkRect& oval, | 975 const SkRect& oval, |
981 const GrStrokeInfo& strokeInfo) { | 976 const GrStrokeInfo& strokeInfo) { |
982 if (oval.isEmpty()) { | 977 if (oval.isEmpty()) { |
983 return; | 978 return; |
984 } | 979 } |
985 | 980 |
986 if (strokeInfo.isDashed()) { | 981 if (strokeInfo.isDashed()) { |
987 SkPath path; | 982 SkPath path; |
988 path.addOval(oval); | 983 path.addOval(oval); |
989 this->drawPath(paint, path, strokeInfo); | 984 this->drawPath(paint, path, strokeInfo); |
990 return; | 985 return; |
991 } | 986 } |
992 | 987 |
993 AutoRestoreEffects are; | |
994 AutoCheckFlush acf(this); | 988 AutoCheckFlush acf(this); |
995 GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf); | 989 GrDrawState drawState; |
| 990 GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf); |
996 if (NULL == target) { | 991 if (NULL == target) { |
997 return; | 992 return; |
998 } | 993 } |
999 | 994 |
1000 GR_CREATE_TRACE_MARKER("GrContext::drawOval", target); | 995 GR_CREATE_TRACE_MARKER("GrContext::drawOval", target); |
1001 | 996 |
1002 const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); | 997 const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); |
1003 | 998 |
1004 | 999 |
1005 if (!fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), oval, stroke
Rec)) { | 1000 if (!fOvalRenderer->drawOval(target, &drawState, this, paint.isAntiAlias(),
oval, strokeRec)) { |
1006 SkPath path; | 1001 SkPath path; |
1007 path.addOval(oval); | 1002 path.addOval(oval); |
1008 this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo); | 1003 this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, st
rokeInfo); |
1009 } | 1004 } |
1010 } | 1005 } |
1011 | 1006 |
1012 // Can 'path' be drawn as a pair of filled nested rectangles? | 1007 // Can 'path' be drawn as a pair of filled nested rectangles? |
1013 static bool is_nested_rects(GrDrawTarget* target, | 1008 static bool is_nested_rects(GrDrawTarget* target, |
| 1009 GrDrawState* drawState, |
1014 const SkPath& path, | 1010 const SkPath& path, |
1015 const SkStrokeRec& stroke, | 1011 const SkStrokeRec& stroke, |
1016 SkRect rects[2]) { | 1012 SkRect rects[2]) { |
1017 SkASSERT(stroke.isFillStyle()); | 1013 SkASSERT(stroke.isFillStyle()); |
1018 | 1014 |
1019 if (path.isInverseFillType()) { | 1015 if (path.isInverseFillType()) { |
1020 return false; | 1016 return false; |
1021 } | 1017 } |
1022 | 1018 |
1023 const GrDrawState& drawState = target->getDrawState(); | |
1024 | |
1025 // TODO: this restriction could be lifted if we were willing to apply | 1019 // TODO: this restriction could be lifted if we were willing to apply |
1026 // the matrix to all the points individually rather than just to the rect | 1020 // the matrix to all the points individually rather than just to the rect |
1027 if (!drawState.getViewMatrix().preservesAxisAlignment()) { | 1021 if (!drawState->getViewMatrix().preservesAxisAlignment()) { |
1028 return false; | 1022 return false; |
1029 } | 1023 } |
1030 | 1024 |
1031 if (!target->getDrawState().canTweakAlphaForCoverage() && | 1025 if (!drawState->canTweakAlphaForCoverage() && !drawState->couldApplyCoverage
(*target->caps())) { |
1032 target->shouldDisableCoverageAAForBlend()) { | |
1033 return false; | 1026 return false; |
1034 } | 1027 } |
1035 | 1028 |
1036 SkPath::Direction dirs[2]; | 1029 SkPath::Direction dirs[2]; |
1037 if (!path.isNestedRects(rects, dirs)) { | 1030 if (!path.isNestedRects(rects, dirs)) { |
1038 return false; | 1031 return false; |
1039 } | 1032 } |
1040 | 1033 |
1041 if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) { | 1034 if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) { |
1042 // The two rects need to be wound opposite to each other | 1035 // The two rects need to be wound opposite to each other |
(...skipping 28 matching lines...) Expand all Loading... |
1071 if (path.isEmpty()) { | 1064 if (path.isEmpty()) { |
1072 if (path.isInverseFillType()) { | 1065 if (path.isInverseFillType()) { |
1073 this->drawPaint(paint); | 1066 this->drawPaint(paint); |
1074 } | 1067 } |
1075 return; | 1068 return; |
1076 } | 1069 } |
1077 | 1070 |
1078 if (strokeInfo.isDashed()) { | 1071 if (strokeInfo.isDashed()) { |
1079 SkPoint pts[2]; | 1072 SkPoint pts[2]; |
1080 if (path.isLine(pts)) { | 1073 if (path.isLine(pts)) { |
1081 AutoRestoreEffects are; | |
1082 AutoCheckFlush acf(this); | 1074 AutoCheckFlush acf(this); |
1083 GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf); | 1075 GrDrawState drawState; |
| 1076 GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf)
; |
1084 if (NULL == target) { | 1077 if (NULL == target) { |
1085 return; | 1078 return; |
1086 } | 1079 }; |
1087 GrDrawState* drawState = target->drawState(); | |
1088 | 1080 |
1089 SkMatrix origViewMatrix = drawState->getViewMatrix(); | 1081 SkMatrix origViewMatrix = drawState.getViewMatrix(); |
1090 GrDrawState::AutoViewMatrixRestore avmr; | 1082 GrDrawState::AutoViewMatrixRestore avmr; |
1091 if (avmr.setIdentity(target->drawState())) { | 1083 if (avmr.setIdentity(&drawState)) { |
1092 if (GrDashingEffect::DrawDashLine(pts, paint, strokeInfo, fGpu,
target, | 1084 if (GrDashingEffect::DrawDashLine(fGpu, target, &drawState, pts,
paint, |
1093 origViewMatrix)) { | 1085 strokeInfo, origViewMatrix)) { |
1094 return; | 1086 return; |
1095 } | 1087 } |
1096 } | 1088 } |
1097 } | 1089 } |
1098 | 1090 |
1099 // Filter dashed path into new path with the dashing applied | 1091 // Filter dashed path into new path with the dashing applied |
1100 const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); | 1092 const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); |
1101 SkTLazy<SkPath> effectPath; | 1093 SkTLazy<SkPath> effectPath; |
1102 GrStrokeInfo newStrokeInfo(strokeInfo, false); | 1094 GrStrokeInfo newStrokeInfo(strokeInfo, false); |
1103 SkStrokeRec* stroke = newStrokeInfo.getStrokeRecPtr(); | 1095 SkStrokeRec* stroke = newStrokeInfo.getStrokeRecPtr(); |
1104 if (SkDashPath::FilterDashPath(effectPath.init(), path, stroke, NULL, in
fo)) { | 1096 if (SkDashPath::FilterDashPath(effectPath.init(), path, stroke, NULL, in
fo)) { |
1105 this->drawPath(paint, *effectPath.get(), newStrokeInfo); | 1097 this->drawPath(paint, *effectPath.get(), newStrokeInfo); |
1106 return; | 1098 return; |
1107 } | 1099 } |
1108 | 1100 |
1109 this->drawPath(paint, path, newStrokeInfo); | 1101 this->drawPath(paint, path, newStrokeInfo); |
1110 return; | 1102 return; |
1111 } | 1103 } |
1112 | 1104 |
1113 // Note that internalDrawPath may sw-rasterize the path into a scratch textu
re. | 1105 // Note that internalDrawPath may sw-rasterize the path into a scratch textu
re. |
1114 // Scratch textures can be recycled after they are returned to the texture | 1106 // Scratch textures can be recycled after they are returned to the texture |
1115 // cache. This presents a potential hazard for buffered drawing. However, | 1107 // cache. This presents a potential hazard for buffered drawing. However, |
1116 // the writePixels that uploads to the scratch will perform a flush so we're | 1108 // the writePixels that uploads to the scratch will perform a flush so we're |
1117 // OK. | 1109 // OK. |
1118 AutoRestoreEffects are; | |
1119 AutoCheckFlush acf(this); | 1110 AutoCheckFlush acf(this); |
1120 GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf); | 1111 GrDrawState drawState; |
| 1112 GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf); |
1121 if (NULL == target) { | 1113 if (NULL == target) { |
1122 return; | 1114 return; |
1123 } | 1115 } |
1124 GrDrawState* drawState = target->drawState(); | |
1125 | 1116 |
1126 GR_CREATE_TRACE_MARKER1("GrContext::drawPath", target, "Is Convex", path.isC
onvex()); | 1117 GR_CREATE_TRACE_MARKER1("GrContext::drawPath", target, "Is Convex", path.isC
onvex()); |
1127 | 1118 |
1128 const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); | 1119 const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); |
1129 | 1120 |
1130 bool useCoverageAA = paint.isAntiAlias() && !drawState->getRenderTarget()->i
sMultisampled(); | 1121 bool useCoverageAA = paint.isAntiAlias() && !drawState.getRenderTarget()->is
Multisampled(); |
1131 | 1122 |
1132 if (useCoverageAA && strokeRec.getWidth() < 0 && !path.isConvex()) { | 1123 if (useCoverageAA && strokeRec.getWidth() < 0 && !path.isConvex()) { |
1133 // Concave AA paths are expensive - try to avoid them for special cases | 1124 // Concave AA paths are expensive - try to avoid them for special cases |
1134 SkRect rects[2]; | 1125 SkRect rects[2]; |
1135 | 1126 |
1136 if (is_nested_rects(target, path, strokeRec, rects)) { | 1127 if (is_nested_rects(target, &drawState, path, strokeRec, rects)) { |
1137 SkMatrix origViewMatrix = drawState->getViewMatrix(); | 1128 SkMatrix origViewMatrix = drawState.getViewMatrix(); |
1138 GrDrawState::AutoViewMatrixRestore avmr; | 1129 GrDrawState::AutoViewMatrixRestore avmr; |
1139 if (!avmr.setIdentity(target->drawState())) { | 1130 if (!avmr.setIdentity(&drawState)) { |
1140 return; | 1131 return; |
1141 } | 1132 } |
1142 | 1133 |
1143 fAARectRenderer->fillAANestedRects(target, rects, origViewMatrix); | 1134 fAARectRenderer->fillAANestedRects(target, &drawState, rects, origVi
ewMatrix); |
1144 return; | 1135 return; |
1145 } | 1136 } |
1146 } | 1137 } |
1147 | 1138 |
1148 SkRect ovalRect; | 1139 SkRect ovalRect; |
1149 bool isOval = path.isOval(&ovalRect); | 1140 bool isOval = path.isOval(&ovalRect); |
1150 | 1141 |
1151 if (!isOval || path.isInverseFillType() | 1142 if (!isOval || path.isInverseFillType() |
1152 || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect,
strokeRec)) { | 1143 || !fOvalRenderer->drawOval(target, &drawState, this, paint.isAntiAlias(
), ovalRect, strokeRec)) { |
1153 this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo); | 1144 this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, st
rokeInfo); |
1154 } | 1145 } |
1155 } | 1146 } |
1156 | 1147 |
1157 void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath&
path, | 1148 void GrContext::internalDrawPath(GrDrawTarget* target, |
| 1149 GrDrawState* drawState, |
| 1150 bool useAA, |
| 1151 const SkPath& path, |
1158 const GrStrokeInfo& strokeInfo) { | 1152 const GrStrokeInfo& strokeInfo) { |
1159 SkASSERT(!path.isEmpty()); | 1153 SkASSERT(!path.isEmpty()); |
1160 | 1154 |
1161 GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target); | 1155 GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target); |
1162 | 1156 |
1163 | 1157 |
1164 // An Assumption here is that path renderer would use some form of tweaking | 1158 // An Assumption here is that path renderer would use some form of tweaking |
1165 // the src color (either the input alpha or in the frag shader) to implement | 1159 // the src color (either the input alpha or in the frag shader) to implement |
1166 // aa. If we have some future driver-mojo path AA that can do the right | 1160 // aa. If we have some future driver-mojo path AA that can do the right |
1167 // thing WRT to the blend then we'll need some query on the PR. | 1161 // thing WRT to the blend then we'll need some query on the PR. |
1168 bool useCoverageAA = useAA && | 1162 bool useCoverageAA = useAA && |
1169 !target->getDrawState().getRenderTarget()->isMultisampled() && | 1163 !drawState->getRenderTarget()->isMultisampled() && |
1170 !target->shouldDisableCoverageAAForBlend(); | 1164 drawState->couldApplyCoverage(*target->caps()); |
1171 | 1165 |
1172 | 1166 |
1173 GrPathRendererChain::DrawType type = | 1167 GrPathRendererChain::DrawType type = |
1174 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType : | 1168 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType : |
1175 GrPathRendererChain::kColor_DrawType; | 1169 GrPathRendererChain::kColor_DrawType; |
1176 | 1170 |
1177 const SkPath* pathPtr = &path; | 1171 const SkPath* pathPtr = &path; |
1178 SkTLazy<SkPath> tmpPath; | 1172 SkTLazy<SkPath> tmpPath; |
1179 SkTCopyOnFirstWrite<SkStrokeRec> stroke(strokeInfo.getStrokeRec()); | 1173 SkTCopyOnFirstWrite<SkStrokeRec> stroke(strokeInfo.getStrokeRec()); |
1180 | 1174 |
1181 // Try a 1st time without stroking the path and without allowing the SW rend
erer | 1175 // Try a 1st time without stroking the path and without allowing the SW rend
erer |
1182 GrPathRenderer* pr = this->getPathRenderer(*pathPtr, *stroke, target, false,
type); | 1176 GrPathRenderer* pr = this->getPathRenderer(target, drawState, *pathPtr, *str
oke, false, type); |
1183 | 1177 |
1184 if (NULL == pr) { | 1178 if (NULL == pr) { |
1185 if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*stroke, this->getMatr
ix(), NULL)) { | 1179 if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*stroke, this->getMatr
ix(), NULL)) { |
1186 // It didn't work the 1st time, so try again with the stroked path | 1180 // It didn't work the 1st time, so try again with the stroked path |
1187 if (stroke->applyToPath(tmpPath.init(), *pathPtr)) { | 1181 if (stroke->applyToPath(tmpPath.init(), *pathPtr)) { |
1188 pathPtr = tmpPath.get(); | 1182 pathPtr = tmpPath.get(); |
1189 stroke.writable()->setFillStyle(); | 1183 stroke.writable()->setFillStyle(); |
1190 if (pathPtr->isEmpty()) { | 1184 if (pathPtr->isEmpty()) { |
1191 return; | 1185 return; |
1192 } | 1186 } |
1193 } | 1187 } |
1194 } | 1188 } |
1195 | 1189 |
1196 // This time, allow SW renderer | 1190 // This time, allow SW renderer |
1197 pr = this->getPathRenderer(*pathPtr, *stroke, target, true, type); | 1191 pr = this->getPathRenderer(target, drawState, *pathPtr, *stroke, true, t
ype); |
1198 } | 1192 } |
1199 | 1193 |
1200 if (NULL == pr) { | 1194 if (NULL == pr) { |
1201 #ifdef SK_DEBUG | 1195 #ifdef SK_DEBUG |
1202 SkDebugf("Unable to find path renderer compatible with path.\n"); | 1196 SkDebugf("Unable to find path renderer compatible with path.\n"); |
1203 #endif | 1197 #endif |
1204 return; | 1198 return; |
1205 } | 1199 } |
1206 | 1200 |
1207 pr->drawPath(*pathPtr, *stroke, target, useCoverageAA); | 1201 pr->drawPath(target, drawState, *pathPtr, *stroke, useCoverageAA); |
1208 } | 1202 } |
1209 | 1203 |
1210 //////////////////////////////////////////////////////////////////////////////// | 1204 //////////////////////////////////////////////////////////////////////////////// |
1211 | 1205 |
1212 void GrContext::flush(int flagsBitfield) { | 1206 void GrContext::flush(int flagsBitfield) { |
1213 if (NULL == fDrawBuffer) { | 1207 if (NULL == fDrawBuffer) { |
1214 return; | 1208 return; |
1215 } | 1209 } |
1216 | 1210 |
1217 if (kDiscard_FlushBit & flagsBitfield) { | 1211 if (kDiscard_FlushBit & flagsBitfield) { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1333 } | 1327 } |
1334 | 1328 |
1335 SkMatrix matrix; | 1329 SkMatrix matrix; |
1336 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); | 1330 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); |
1337 | 1331 |
1338 // This function can be called in the midst of drawing another object (e.g.,
when uploading a | 1332 // This function can be called in the midst of drawing another object (e.g.,
when uploading a |
1339 // SW-rasterized clip while issuing a draw). So we push the current geometry
state before | 1333 // SW-rasterized clip while issuing a draw). So we push the current geometry
state before |
1340 // drawing a rect to the render target. | 1334 // drawing a rect to the render target. |
1341 // The bracket ensures we pop the stack if we wind up flushing below. | 1335 // The bracket ensures we pop the stack if we wind up flushing below. |
1342 { | 1336 { |
1343 GrDrawTarget* drawTarget = this->prepareToDraw(NULL, NULL, NULL); | 1337 GrDrawState drawState; |
1344 GrDrawTarget::AutoGeometryAndStatePush agasp(drawTarget, GrDrawTarget::k
Reset_ASRInit, | 1338 GrDrawTarget* drawTarget = this->prepareToDraw(&drawState, NULL, NULL); |
1345 &matrix); | 1339 GrDrawTarget::AutoGeometryPush agp(drawTarget); |
1346 GrDrawState* drawState = drawTarget->drawState(); | 1340 |
1347 drawState->addColorProcessor(fp); | 1341 drawState.addColorProcessor(fp); |
1348 drawState->setRenderTarget(renderTarget); | 1342 drawState.setRenderTarget(renderTarget); |
1349 drawState->disableState(GrDrawState::kClip_StateBit); | 1343 drawTarget->drawSimpleRect(&drawState, SkRect::MakeWH(SkIntToScalar(widt
h), |
1350 drawTarget->drawSimpleRect(SkRect::MakeWH(SkIntToScalar(width), SkIntToS
calar(height))); | 1344 SkIntToScalar(heig
ht))); |
1351 } | 1345 } |
1352 | 1346 |
1353 if (kFlushWrites_PixelOp & pixelOpsFlags) { | 1347 if (kFlushWrites_PixelOp & pixelOpsFlags) { |
1354 this->flushSurfaceWrites(surface); | 1348 this->flushSurfaceWrites(surface); |
1355 } | 1349 } |
1356 | 1350 |
1357 return true; | 1351 return true; |
1358 } | 1352 } |
1359 | 1353 |
1360 // toggles between RGBA and BGRA | 1354 // toggles between RGBA and BGRA |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1452 fp.reset(GrConfigConversionEffect::Create( | 1446 fp.reset(GrConfigConversionEffect::Create( |
1453 src, swapRAndB, GrConfigConversionEffect::kNone_PMCo
nversion, | 1447 src, swapRAndB, GrConfigConversionEffect::kNone_PMCo
nversion, |
1454 textureMatrix)); | 1448 textureMatrix)); |
1455 } | 1449 } |
1456 swapRAndB = false; // we will handle the swap in the draw. | 1450 swapRAndB = false; // we will handle the swap in the draw. |
1457 | 1451 |
1458 // We protect the existing geometry here since it may not be | 1452 // We protect the existing geometry here since it may not be |
1459 // clear to the caller that a draw operation (i.e., drawSimpleRe
ct) | 1453 // clear to the caller that a draw operation (i.e., drawSimpleRe
ct) |
1460 // can be invoked in this method | 1454 // can be invoked in this method |
1461 { | 1455 { |
1462 GrDrawTarget::AutoGeometryAndStatePush agasp(fDrawBuffer, | 1456 GrDrawTarget::AutoGeometryPush agp(fDrawBuffer); |
1463 GrDrawTarget::k
Reset_ASRInit); | 1457 GrDrawState drawState; |
1464 GrDrawState* drawState = fDrawBuffer->drawState(); | |
1465 SkASSERT(fp); | 1458 SkASSERT(fp); |
1466 drawState->addColorProcessor(fp); | 1459 drawState.addColorProcessor(fp); |
| 1460 drawState.setRenderTarget(texture->asRenderTarget()); |
1467 | 1461 |
1468 drawState->setRenderTarget(texture->asRenderTarget()); | |
1469 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToSc
alar(height)); | 1462 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToSc
alar(height)); |
1470 fDrawBuffer->drawSimpleRect(rect); | 1463 fDrawBuffer->drawSimpleRect(&drawState, rect); |
1471 // we want to read back from the scratch's origin | 1464 // we want to read back from the scratch's origin |
1472 left = 0; | 1465 left = 0; |
1473 top = 0; | 1466 top = 0; |
1474 target = texture->asRenderTarget(); | 1467 target = texture->asRenderTarget(); |
1475 } | 1468 } |
1476 this->flushSurfaceWrites(target); | 1469 this->flushSurfaceWrites(target); |
1477 } | 1470 } |
1478 } | 1471 } |
1479 } | 1472 } |
1480 | 1473 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1512 } | 1505 } |
1513 GrRenderTarget* rt = surface->asRenderTarget(); | 1506 GrRenderTarget* rt = surface->asRenderTarget(); |
1514 if (fGpu && rt) { | 1507 if (fGpu && rt) { |
1515 fGpu->resolveRenderTarget(rt); | 1508 fGpu->resolveRenderTarget(rt); |
1516 } | 1509 } |
1517 } | 1510 } |
1518 | 1511 |
1519 void GrContext::discardRenderTarget(GrRenderTarget* renderTarget) { | 1512 void GrContext::discardRenderTarget(GrRenderTarget* renderTarget) { |
1520 SkASSERT(renderTarget); | 1513 SkASSERT(renderTarget); |
1521 ASSERT_OWNED_RESOURCE(renderTarget); | 1514 ASSERT_OWNED_RESOURCE(renderTarget); |
1522 AutoRestoreEffects are; | |
1523 AutoCheckFlush acf(this); | 1515 AutoCheckFlush acf(this); |
1524 GrDrawTarget* target = this->prepareToDraw(NULL, &are, &acf); | 1516 GrDrawTarget* target = this->prepareToDraw(NULL, NULL, &acf); |
1525 if (NULL == target) { | 1517 if (NULL == target) { |
1526 return; | 1518 return; |
1527 } | 1519 } |
1528 target->discard(renderTarget); | 1520 target->discard(renderTarget); |
1529 } | 1521 } |
1530 | 1522 |
1531 void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRe
ct, | 1523 void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRe
ct, |
1532 const SkIPoint& dstPoint, uint32_t pixelOpsFlags) { | 1524 const SkIPoint& dstPoint, uint32_t pixelOpsFlags) { |
1533 if (NULL == src || NULL == dst) { | 1525 if (NULL == src || NULL == dst) { |
1534 return; | 1526 return; |
(...skipping 14 matching lines...) Expand all Loading... |
1549 this->flush(); | 1541 this->flush(); |
1550 } | 1542 } |
1551 } | 1543 } |
1552 | 1544 |
1553 void GrContext::flushSurfaceWrites(GrSurface* surface) { | 1545 void GrContext::flushSurfaceWrites(GrSurface* surface) { |
1554 if (surface->surfacePriv().hasPendingWrite()) { | 1546 if (surface->surfacePriv().hasPendingWrite()) { |
1555 this->flush(); | 1547 this->flush(); |
1556 } | 1548 } |
1557 } | 1549 } |
1558 | 1550 |
1559 //////////////////////////////////////////////////////////////////////////////// | 1551 GrDrawTarget* GrContext::prepareToDraw(GrDrawState* ds, |
1560 | 1552 const GrPaint* paint, |
1561 GrDrawTarget* GrContext::prepareToDraw(const GrPaint* paint, | 1553 const AutoCheckFlush* acf) { |
1562 AutoRestoreEffects* are, | |
1563 AutoCheckFlush* acf) { | |
1564 // All users of this draw state should be freeing up all effects when they'r
e done. | |
1565 // Otherwise effects that own resources may keep those resources alive indef
initely. | |
1566 SkASSERT(0 == fDrawState->numColorStages() && 0 == fDrawState->numCoverageSt
ages() && | |
1567 !fDrawState->hasGeometryProcessor()); | |
1568 | |
1569 if (NULL == fGpu) { | 1554 if (NULL == fGpu) { |
1570 return NULL; | 1555 return NULL; |
1571 } | 1556 } |
1572 | 1557 |
1573 ASSERT_OWNED_RESOURCE(fRenderTarget.get()); | 1558 ASSERT_OWNED_RESOURCE(fRenderTarget.get()); |
1574 if (paint) { | 1559 if (ds) { |
1575 SkASSERT(are); | 1560 if (paint) { |
1576 SkASSERT(acf); | 1561 SkASSERT(acf); |
1577 are->set(fDrawState); | 1562 ds->setFromPaint(*paint, fViewMatrix, fRenderTarget.get()); |
1578 fDrawState->setFromPaint(*paint, fViewMatrix, fRenderTarget.get()); | |
1579 #if GR_DEBUG_PARTIAL_COVERAGE_CHECK | 1563 #if GR_DEBUG_PARTIAL_COVERAGE_CHECK |
1580 if ((paint->hasMask() || 0xff != paint->fCoverage) && | 1564 if ((paint->hasMask() || 0xff != paint->fCoverage) && |
1581 !fDrawState->couldApplyCoverage(fGpu->caps())) { | 1565 !fDrawState->couldApplyCoverage(fGpu->caps())) { |
1582 SkDebugf("Partial pixel coverage will be incorrectly blended.\n"); | 1566 SkDebugf("Partial pixel coverage will be incorrectly blended.\n"
); |
| 1567 } |
| 1568 #endif |
| 1569 // Clear any vertex attributes configured for the previous use of th
e |
| 1570 // GrDrawState which can effect which blend optimizations are in eff
ect. |
| 1571 ds->setDefaultVertexAttribs(); |
| 1572 } else { |
| 1573 ds->reset(fViewMatrix); |
| 1574 ds->setRenderTarget(fRenderTarget.get()); |
1583 } | 1575 } |
1584 #endif | 1576 ds->setState(GrDrawState::kClip_StateBit, fClip && !fClip->fClipStack->i
sWideOpen()); |
1585 // Clear any vertex attributes configured for the previous use of the | |
1586 // GrDrawState which can effect which blend optimizations are in effect. | |
1587 fDrawState->setDefaultVertexAttribs(); | |
1588 } else { | |
1589 fDrawState->reset(fViewMatrix); | |
1590 fDrawState->setRenderTarget(fRenderTarget.get()); | |
1591 } | 1577 } |
1592 fDrawState->setState(GrDrawState::kClip_StateBit, fClip && | |
1593 !fClip->fClipStack->isWideO
pen()); | |
1594 fDrawBuffer->setClip(fClip); | 1578 fDrawBuffer->setClip(fClip); |
1595 SkASSERT(fDrawState == fDrawBuffer->drawState()); | |
1596 return fDrawBuffer; | 1579 return fDrawBuffer; |
1597 } | 1580 } |
1598 | 1581 |
1599 /* | 1582 /* |
1600 * This method finds a path renderer that can draw the specified path on | 1583 * This method finds a path renderer that can draw the specified path on |
1601 * the provided target. | 1584 * the provided target. |
1602 * Due to its expense, the software path renderer has split out so it can | 1585 * Due to its expense, the software path renderer has split out so it can |
1603 * can be individually allowed/disallowed via the "allowSW" boolean. | 1586 * can be individually allowed/disallowed via the "allowSW" boolean. |
1604 */ | 1587 */ |
1605 GrPathRenderer* GrContext::getPathRenderer(const SkPath& path, | 1588 GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target, |
| 1589 const GrDrawState* drawState, |
| 1590 const SkPath& path, |
1606 const SkStrokeRec& stroke, | 1591 const SkStrokeRec& stroke, |
1607 const GrDrawTarget* target, | |
1608 bool allowSW, | 1592 bool allowSW, |
1609 GrPathRendererChain::DrawType drawTyp
e, | 1593 GrPathRendererChain::DrawType drawTyp
e, |
1610 GrPathRendererChain::StencilSupport*
stencilSupport) { | 1594 GrPathRendererChain::StencilSupport*
stencilSupport) { |
1611 | 1595 |
1612 if (NULL == fPathRendererChain) { | 1596 if (NULL == fPathRendererChain) { |
1613 fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this)); | 1597 fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this)); |
1614 } | 1598 } |
1615 | 1599 |
1616 GrPathRenderer* pr = fPathRendererChain->getPathRenderer(path, | 1600 GrPathRenderer* pr = fPathRendererChain->getPathRenderer(target, |
| 1601 drawState, |
| 1602 path, |
1617 stroke, | 1603 stroke, |
1618 target, | |
1619 drawType, | 1604 drawType, |
1620 stencilSupport); | 1605 stencilSupport); |
1621 | 1606 |
1622 if (NULL == pr && allowSW) { | 1607 if (NULL == pr && allowSW) { |
1623 if (NULL == fSoftwarePathRenderer) { | 1608 if (NULL == fSoftwarePathRenderer) { |
1624 fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this)); | 1609 fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this)); |
1625 } | 1610 } |
1626 pr = fSoftwarePathRenderer; | 1611 pr = fSoftwarePathRenderer; |
1627 } | 1612 } |
1628 | 1613 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1661 DRAW_BUFFER_VBPOOL_BUFFER_SIZE, | 1646 DRAW_BUFFER_VBPOOL_BUFFER_SIZE, |
1662 DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS)); | 1647 DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS)); |
1663 fDrawBufferIBAllocPool = | 1648 fDrawBufferIBAllocPool = |
1664 SkNEW_ARGS(GrIndexBufferAllocPool, (fGpu, false, | 1649 SkNEW_ARGS(GrIndexBufferAllocPool, (fGpu, false, |
1665 DRAW_BUFFER_IBPOOL_BUFFER_SIZE, | 1650 DRAW_BUFFER_IBPOOL_BUFFER_SIZE, |
1666 DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS)); | 1651 DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS)); |
1667 | 1652 |
1668 fDrawBuffer = SkNEW_ARGS(GrInOrderDrawBuffer, (fGpu, | 1653 fDrawBuffer = SkNEW_ARGS(GrInOrderDrawBuffer, (fGpu, |
1669 fDrawBufferVBAllocPool, | 1654 fDrawBufferVBAllocPool, |
1670 fDrawBufferIBAllocPool)); | 1655 fDrawBufferIBAllocPool)); |
1671 | |
1672 fDrawBuffer->setDrawState(fDrawState); | |
1673 } | 1656 } |
1674 | 1657 |
1675 GrDrawTarget* GrContext::getTextTarget() { | 1658 GrDrawTarget* GrContext::getTextTarget() { |
1676 return this->prepareToDraw(NULL, NULL, NULL); | 1659 return this->prepareToDraw(NULL, NULL, NULL); |
1677 } | 1660 } |
1678 | 1661 |
1679 const GrIndexBuffer* GrContext::getQuadIndexBuffer() const { | 1662 const GrIndexBuffer* GrContext::getQuadIndexBuffer() const { |
1680 return fGpu->getQuadIndexBuffer(); | 1663 return fGpu->getQuadIndexBuffer(); |
1681 } | 1664 } |
1682 | 1665 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1754 fResourceCache->printStats(); | 1737 fResourceCache->printStats(); |
1755 } | 1738 } |
1756 #endif | 1739 #endif |
1757 | 1740 |
1758 #if GR_GPU_STATS | 1741 #if GR_GPU_STATS |
1759 const GrContext::GPUStats* GrContext::gpuStats() const { | 1742 const GrContext::GPUStats* GrContext::gpuStats() const { |
1760 return fGpu->gpuStats(); | 1743 return fGpu->gpuStats(); |
1761 } | 1744 } |
1762 #endif | 1745 #endif |
1763 | 1746 |
OLD | NEW |