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