OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 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 "GrDrawTarget.h" | 9 #include "GrDrawTarget.h" |
10 | 10 |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "batches/GrDrawPathBatch.h" | 27 #include "batches/GrDrawPathBatch.h" |
28 #include "batches/GrRectBatchFactory.h" | 28 #include "batches/GrRectBatchFactory.h" |
29 #include "batches/GrStencilPathBatch.h" | 29 #include "batches/GrStencilPathBatch.h" |
30 | 30 |
31 #include "SkStrokeRec.h" | 31 #include "SkStrokeRec.h" |
32 | 32 |
33 //////////////////////////////////////////////////////////////////////////////// | 33 //////////////////////////////////////////////////////////////////////////////// |
34 | 34 |
35 GrDrawTarget::GrDrawTarget(GrGpu* gpu, GrResourceProvider* resourceProvider) | 35 GrDrawTarget::GrDrawTarget(GrGpu* gpu, GrResourceProvider* resourceProvider) |
36 : fGpu(SkRef(gpu)) | 36 : fGpu(SkRef(gpu)) |
37 , fCaps(SkRef(gpu->caps())) | |
38 , fResourceProvider(resourceProvider) | 37 , fResourceProvider(resourceProvider) |
39 , fFlushing(false) | 38 , fFlushing(false) |
40 , fLastFlushToken(0) { | 39 , fLastFlushToken(0) { |
| 40 // TODO: Stop extracting the context (currently needed by GrClipMaskManager) |
| 41 fContext = fGpu->getContext(); |
41 } | 42 } |
42 | 43 |
43 GrDrawTarget::~GrDrawTarget() { | 44 GrDrawTarget::~GrDrawTarget() { |
44 fGpu->unref(); | 45 fGpu->unref(); |
45 fCaps->unref(); | |
46 } | 46 } |
47 | 47 |
48 //////////////////////////////////////////////////////////////////////////////// | 48 //////////////////////////////////////////////////////////////////////////////// |
49 | 49 |
50 bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil
der, | 50 bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil
der, |
51 const GrProcOptInfo& colorPOI, | 51 const GrProcOptInfo& colorPOI, |
52 const GrProcOptInfo& coveragePOI, | 52 const GrProcOptInfo& coveragePOI, |
53 GrXferProcessor::DstTexture* dstTextu
re, | 53 GrXferProcessor::DstTexture* dstTextu
re, |
54 const SkRect& batchBounds) { | 54 const SkRect& batchBounds) { |
55 SkRect bounds = batchBounds; | 55 SkRect bounds = batchBounds; |
(...skipping 15 matching lines...) Expand all Loading... |
71 } | 71 } |
72 } | 72 } |
73 | 73 |
74 SkIRect copyRect; | 74 SkIRect copyRect; |
75 pipelineBuilder.clip().getConservativeBounds(rt, ©Rect); | 75 pipelineBuilder.clip().getConservativeBounds(rt, ©Rect); |
76 | 76 |
77 SkIRect drawIBounds; | 77 SkIRect drawIBounds; |
78 bounds.roundOut(&drawIBounds); | 78 bounds.roundOut(&drawIBounds); |
79 if (!copyRect.intersect(drawIBounds)) { | 79 if (!copyRect.intersect(drawIBounds)) { |
80 #ifdef SK_DEBUG | 80 #ifdef SK_DEBUG |
81 GrCapsDebugf(fCaps, "Missed an early reject. " | 81 GrCapsDebugf(this->caps(), "Missed an early reject. " |
82 "Bailing on draw from setupDstReadIfNecessary.\n"); | 82 "Bailing on draw from setupDstReadIfNecessary
.\n"); |
83 #endif | 83 #endif |
84 return false; | 84 return false; |
85 } | 85 } |
86 | 86 |
87 // MSAA consideration: When there is support for reading MSAA samples in the
shader we could | 87 // MSAA consideration: When there is support for reading MSAA samples in the
shader we could |
88 // have per-sample dst values by making the copy multisampled. | 88 // have per-sample dst values by making the copy multisampled. |
89 GrSurfaceDesc desc; | 89 GrSurfaceDesc desc; |
90 if (!this->getGpu()->initCopySurfaceDstDesc(rt, &desc)) { | 90 if (!fGpu->initCopySurfaceDstDesc(rt, &desc)) { |
91 desc.fOrigin = kDefault_GrSurfaceOrigin; | 91 desc.fOrigin = kDefault_GrSurfaceOrigin; |
92 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 92 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
93 desc.fConfig = rt->config(); | 93 desc.fConfig = rt->config(); |
94 } | 94 } |
95 | 95 |
96 desc.fWidth = copyRect.width(); | 96 desc.fWidth = copyRect.width(); |
97 desc.fHeight = copyRect.height(); | 97 desc.fHeight = copyRect.height(); |
98 | 98 |
99 static const uint32_t kFlags = 0; | 99 static const uint32_t kFlags = 0; |
100 SkAutoTUnref<GrTexture> copy(fResourceProvider->createApproxTexture(desc, kF
lags)); | 100 SkAutoTUnref<GrTexture> copy(fResourceProvider->createApproxTexture(desc, kF
lags)); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 | 139 |
140 void GrDrawTarget::reset() { | 140 void GrDrawTarget::reset() { |
141 fBatches.reset(); | 141 fBatches.reset(); |
142 } | 142 } |
143 | 143 |
144 void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBat
ch* batch) { | 144 void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBat
ch* batch) { |
145 // Setup clip | 145 // Setup clip |
146 GrScissorState scissorState; | 146 GrScissorState scissorState; |
147 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; | 147 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; |
148 GrPipelineBuilder::AutoRestoreStencil ars; | 148 GrPipelineBuilder::AutoRestoreStencil ars; |
149 if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, &batch->b
ounds())) { | 149 if (!fClipMaskManager->setupClipping(pipelineBuilder, &arfps, &ars, &scissor
State, |
| 150 &batch->bounds())) { |
150 return; | 151 return; |
151 } | 152 } |
152 | 153 |
153 GrPipeline::CreateArgs args; | 154 GrPipeline::CreateArgs args; |
154 if (!this->installPipelineInDrawBatch(&pipelineBuilder, &scissorState, batch
)) { | 155 if (!this->installPipelineInDrawBatch(&pipelineBuilder, &scissorState, batch
)) { |
155 return; | 156 return; |
156 } | 157 } |
157 | 158 |
158 this->recordBatch(batch); | 159 this->recordBatch(batch); |
159 } | 160 } |
(...skipping 23 matching lines...) Expand all Loading... |
183 switch (fill) { | 184 switch (fill) { |
184 default: | 185 default: |
185 SkFAIL("Unexpected path fill."); | 186 SkFAIL("Unexpected path fill."); |
186 case GrPathRendering::kWinding_FillType: | 187 case GrPathRendering::kWinding_FillType: |
187 *outStencilSettings = winding_path_stencil_settings(); | 188 *outStencilSettings = winding_path_stencil_settings(); |
188 break; | 189 break; |
189 case GrPathRendering::kEvenOdd_FillType: | 190 case GrPathRendering::kEvenOdd_FillType: |
190 *outStencilSettings = even_odd_path_stencil_settings(); | 191 *outStencilSettings = even_odd_path_stencil_settings(); |
191 break; | 192 break; |
192 } | 193 } |
193 this->clipMaskManager()->adjustPathStencilParams(sb, outStencilSettings); | 194 fClipMaskManager->adjustPathStencilParams(sb, outStencilSettings); |
194 } | 195 } |
195 | 196 |
196 void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder, | 197 void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder, |
197 const SkMatrix& viewMatrix, | 198 const SkMatrix& viewMatrix, |
198 const GrPath* path, | 199 const GrPath* path, |
199 GrPathRendering::FillType fill) { | 200 GrPathRendering::FillType fill) { |
200 // TODO: extract portions of checkDraw that are relevant to path stenciling. | 201 // TODO: extract portions of checkDraw that are relevant to path stenciling. |
201 SkASSERT(path); | 202 SkASSERT(path); |
202 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); | 203 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); |
203 | 204 |
204 // Setup clip | 205 // Setup clip |
205 GrScissorState scissorState; | 206 GrScissorState scissorState; |
206 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; | 207 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; |
207 GrPipelineBuilder::AutoRestoreStencil ars; | 208 GrPipelineBuilder::AutoRestoreStencil ars; |
208 if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, nullptr))
{ | 209 |
| 210 if (!fClipMaskManager->setupClipping(pipelineBuilder, &arfps, &ars, &scissor
State, nullptr)) { |
209 return; | 211 return; |
210 } | 212 } |
211 | 213 |
212 // set stencil settings for path | 214 // set stencil settings for path |
213 GrStencilSettings stencilSettings; | 215 GrStencilSettings stencilSettings; |
214 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); | 216 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); |
215 GrStencilAttachment* sb = rt->renderTargetPriv().attachStencilAttachment(); | 217 GrStencilAttachment* sb = rt->renderTargetPriv().attachStencilAttachment(); |
216 this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings); | 218 this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings); |
217 | 219 |
218 GrBatch* batch = GrStencilPathBatch::Create(viewMatrix, | 220 GrBatch* batch = GrStencilPathBatch::Create(viewMatrix, |
(...skipping 26 matching lines...) Expand all Loading... |
245 GrPathRendering::FillType fill) { | 247 GrPathRendering::FillType fill) { |
246 GrDrawPathBatchBase* batch = GrDrawPathRangeBatch::Create(viewMatrix, localM
atrix, color, draw); | 248 GrDrawPathBatchBase* batch = GrDrawPathRangeBatch::Create(viewMatrix, localM
atrix, color, draw); |
247 this->drawPathBatch(pipelineBuilder, batch, fill); | 249 this->drawPathBatch(pipelineBuilder, batch, fill); |
248 batch->unref(); | 250 batch->unref(); |
249 } | 251 } |
250 | 252 |
251 void GrDrawTarget::drawPathBatch(const GrPipelineBuilder& pipelineBuilder, | 253 void GrDrawTarget::drawPathBatch(const GrPipelineBuilder& pipelineBuilder, |
252 GrDrawPathBatchBase* batch, | 254 GrDrawPathBatchBase* batch, |
253 GrPathRendering::FillType fill) { | 255 GrPathRendering::FillType fill) { |
254 // This looks like drawBatch() but there is an added wrinkle that stencil se
ttings get inserted | 256 // This looks like drawBatch() but there is an added wrinkle that stencil se
ttings get inserted |
255 // after setupClip() but before onDrawBatch(). TODO: Figure out a better mod
el for handling | 257 // after setting up clipping but before onDrawBatch(). TODO: Figure out a be
tter model for |
256 // stencil settings WRT interactions between pipeline(builder), clipmaskmana
ger, and batches. | 258 // handling stencil settings WRT interactions between pipeline(builder), cli
pmaskmanager, and |
| 259 // batches. |
257 | 260 |
258 GrScissorState scissorState; | 261 GrScissorState scissorState; |
259 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; | 262 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; |
260 GrPipelineBuilder::AutoRestoreStencil ars; | 263 GrPipelineBuilder::AutoRestoreStencil ars; |
261 if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, &batch->b
ounds())) { | 264 if (!fClipMaskManager->setupClipping(pipelineBuilder, &arfps, &ars, &scissor
State, |
| 265 &batch->bounds())) { |
262 return; | 266 return; |
263 } | 267 } |
264 | 268 |
265 // Ensure the render target has a stencil buffer and get the stencil setting
s. | 269 // Ensure the render target has a stencil buffer and get the stencil setting
s. |
266 GrStencilSettings stencilSettings; | 270 GrStencilSettings stencilSettings; |
267 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); | 271 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); |
268 GrStencilAttachment* sb = rt->renderTargetPriv().attachStencilAttachment(); | 272 GrStencilAttachment* sb = rt->renderTargetPriv().attachStencilAttachment(); |
269 this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings); | 273 this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings); |
270 batch->setStencilSettings(stencilSettings); | 274 batch->setStencilSettings(stencilSettings); |
271 | 275 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 rect->contains(rtRect)) { | 332 rect->contains(rtRect)) { |
329 rect = &rtRect; | 333 rect = &rtRect; |
330 } else { | 334 } else { |
331 clippedRect = *rect; | 335 clippedRect = *rect; |
332 if (!clippedRect.intersect(rtRect)) { | 336 if (!clippedRect.intersect(rtRect)) { |
333 return; | 337 return; |
334 } | 338 } |
335 rect = &clippedRect; | 339 rect = &clippedRect; |
336 } | 340 } |
337 | 341 |
338 if (fCaps->useDrawInsteadOfClear()) { | 342 if (this->caps()->useDrawInsteadOfClear()) { |
339 // This works around a driver bug with clear by drawing a rect instead. | 343 // This works around a driver bug with clear by drawing a rect instead. |
340 // The driver will ignore a clear if it is the only thing rendered to a | 344 // The driver will ignore a clear if it is the only thing rendered to a |
341 // target before the target is read. | 345 // target before the target is read. |
342 if (rect == &rtRect) { | 346 if (rect == &rtRect) { |
343 this->discard(renderTarget); | 347 this->discard(renderTarget); |
344 } | 348 } |
345 | 349 |
346 GrPipelineBuilder pipelineBuilder; | 350 GrPipelineBuilder pipelineBuilder; |
347 pipelineBuilder.setRenderTarget(renderTarget); | 351 pipelineBuilder.setRenderTarget(renderTarget); |
348 | 352 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 return false; | 452 return false; |
449 } | 453 } |
450 | 454 |
451 if (!batch->installPipeline(args)) { | 455 if (!batch->installPipeline(args)) { |
452 return false; | 456 return false; |
453 } | 457 } |
454 | 458 |
455 return true; | 459 return true; |
456 } | 460 } |
457 | 461 |
458 /////////////////////////////////////////////////////////////////////////////// | 462 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend
erTarget* rt) { |
459 GrClipTarget::GrClipTarget(GrContext* context) | |
460 : INHERITED(context->getGpu(), context->resourceProvider()) | |
461 , fContext(context) { | |
462 fClipMaskManager.reset(new GrClipMaskManager(this)); | |
463 } | |
464 | |
465 | |
466 bool GrClipTarget::setupClip(const GrPipelineBuilder& pipelineBuilder, | |
467 GrPipelineBuilder::AutoRestoreFragmentProcessorStat
e* arfps, | |
468 GrPipelineBuilder::AutoRestoreStencil* ars, | |
469 GrScissorState* scissorState, | |
470 const SkRect* devBounds) { | |
471 return fClipMaskManager->setupClipping(pipelineBuilder, | |
472 arfps, | |
473 ars, | |
474 scissorState, | |
475 devBounds); | |
476 } | |
477 | |
478 void GrClipTarget::purgeResources() { | |
479 // The clip mask manager can rebuild all its clip masks so just | |
480 // get rid of them all. | |
481 fClipMaskManager->purgeResources(); | |
482 }; | |
483 | |
484 void GrClipTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend
erTarget* rt) { | |
485 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); | 463 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); |
486 this->recordBatch(batch); | 464 this->recordBatch(batch); |
487 batch->unref(); | 465 batch->unref(); |
488 } | 466 } |
OLD | NEW |