| 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 |