| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2010 Google Inc. | 2 * Copyright 2010 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrRenderTargetOpList.h" | 8 #include "GrRenderTargetOpList.h" |
| 9 | 9 |
| 10 #include "GrAppliedClip.h" | 10 #include "GrAppliedClip.h" |
| 11 #include "GrAuditTrail.h" | 11 #include "GrAuditTrail.h" |
| 12 #include "GrCaps.h" | 12 #include "GrCaps.h" |
| 13 #include "GrRenderTargetContext.h" | 13 #include "GrRenderTargetContext.h" |
| 14 #include "GrGpu.h" | 14 #include "GrGpu.h" |
| 15 #include "GrGpuCommandBuffer.h" | 15 #include "GrGpuCommandBuffer.h" |
| 16 #include "GrPath.h" | 16 #include "GrPath.h" |
| 17 #include "GrPipeline.h" | 17 #include "GrPipeline.h" |
| 18 #include "GrMemoryPool.h" | 18 #include "GrMemoryPool.h" |
| 19 #include "GrPipelineBuilder.h" | 19 #include "GrPipelineBuilder.h" |
| 20 #include "GrRenderTarget.h" | 20 #include "GrRenderTarget.h" |
| 21 #include "GrResourceProvider.h" | 21 #include "GrResourceProvider.h" |
| 22 #include "GrRenderTargetContextPriv.h" |
| 22 #include "GrRenderTargetPriv.h" | 23 #include "GrRenderTargetPriv.h" |
| 23 #include "GrStencilAttachment.h" | 24 #include "GrStencilAttachment.h" |
| 24 #include "GrSurfacePriv.h" | 25 #include "GrSurfacePriv.h" |
| 25 #include "GrTexture.h" | 26 #include "GrTexture.h" |
| 26 #include "gl/GrGLRenderTarget.h" | 27 #include "gl/GrGLRenderTarget.h" |
| 27 | 28 |
| 28 #include "SkStrokeRec.h" | 29 #include "SkStrokeRec.h" |
| 29 | 30 |
| 30 #include "batches/GrClearBatch.h" | 31 #include "batches/GrClearBatch.h" |
| 31 #include "batches/GrClearStencilClipBatch.h" | 32 #include "batches/GrClearStencilClipBatch.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 const SkRect& clippedBounds = fRecordedBatches[i].fClippedBounds; | 92 const SkRect& clippedBounds = fRecordedBatches[i].fClippedBounds; |
| 92 SkDebugf("ClippedBounds: [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", | 93 SkDebugf("ClippedBounds: [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", |
| 93 clippedBounds.fLeft, clippedBounds.fTop, clippedBounds.fRig
ht, | 94 clippedBounds.fLeft, clippedBounds.fTop, clippedBounds.fRig
ht, |
| 94 clippedBounds.fBottom); | 95 clippedBounds.fBottom); |
| 95 } | 96 } |
| 96 } | 97 } |
| 97 } | 98 } |
| 98 #endif | 99 #endif |
| 99 | 100 |
| 100 bool GrRenderTargetOpList::setupDstReadIfNecessary(const GrPipelineBuilder& pipe
lineBuilder, | 101 bool GrRenderTargetOpList::setupDstReadIfNecessary(const GrPipelineBuilder& pipe
lineBuilder, |
| 101 GrRenderTarget* rt, | 102 GrRenderTargetContext* rtc, |
| 102 const GrClip& clip, | 103 const GrClip& clip, |
| 103 const GrPipelineOptimizations
& optimizations, | 104 const GrPipelineOptimizations
& optimizations, |
| 104 GrXferProcessor::DstTexture*
dstTexture, | 105 GrXferProcessor::DstTexture*
dstTexture, |
| 105 const SkRect& batchBounds) { | 106 const SkRect& batchBounds) { |
| 106 SkRect bounds = batchBounds; | 107 SkRect bounds = batchBounds; |
| 107 bounds.outset(0.5f, 0.5f); | 108 bounds.outset(0.5f, 0.5f); |
| 108 | 109 |
| 109 if (!pipelineBuilder.willXPNeedDstTexture(*this->caps(), optimizations)) { | 110 if (!pipelineBuilder.willXPNeedDstTexture(*this->caps(), optimizations)) { |
| 110 return true; | 111 return true; |
| 111 } | 112 } |
| 112 | 113 |
| 114 GrContext* context = rtc->priv().context(); |
| 115 GrRenderTarget* rt = rtc->priv().accessRTP()->instantiate(context->texturePr
ovider()); |
| 116 if (!rt) { |
| 117 return false; |
| 118 } |
| 119 |
| 113 if (this->caps()->textureBarrierSupport()) { | 120 if (this->caps()->textureBarrierSupport()) { |
| 114 if (GrTexture* rtTex = rt->asTexture()) { | 121 if (GrTexture* rtTex = rt->asTexture()) { |
| 115 // The render target is a texture, so we can read from it directly i
n the shader. The XP | 122 // The render target is a texture, so we can read from it directly i
n the shader. The XP |
| 116 // will be responsible to detect this situation and request a textur
e barrier. | 123 // will be responsible to detect this situation and request a textur
e barrier. |
| 117 dstTexture->setTexture(sk_ref_sp(rtTex)); | 124 dstTexture->setTexture(sk_ref_sp(rtTex)); |
| 118 dstTexture->setOffset(0, 0); | 125 dstTexture->setOffset(0, 0); |
| 119 return true; | 126 return true; |
| 120 } | 127 } |
| 121 } | 128 } |
| 122 | 129 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 fInstancedRendering->beginFlush(flushState->resourceProvider()); | 184 fInstancedRendering->beginFlush(flushState->resourceProvider()); |
| 178 } | 185 } |
| 179 } | 186 } |
| 180 | 187 |
| 181 bool GrRenderTargetOpList::drawBatches(GrBatchFlushState* flushState) { | 188 bool GrRenderTargetOpList::drawBatches(GrBatchFlushState* flushState) { |
| 182 if (0 == fRecordedBatches.count()) { | 189 if (0 == fRecordedBatches.count()) { |
| 183 return false; | 190 return false; |
| 184 } | 191 } |
| 185 // Draw all the generated geometry. | 192 // Draw all the generated geometry. |
| 186 SkRandom random; | 193 SkRandom random; |
| 187 GrRenderTarget* currentRT = nullptr; | 194 GrRenderTargetProxy* currentRTP = nullptr; |
| 188 std::unique_ptr<GrGpuCommandBuffer> commandBuffer; | 195 std::unique_ptr<GrGpuCommandBuffer> commandBuffer; |
| 189 for (int i = 0; i < fRecordedBatches.count(); ++i) { | 196 for (int i = 0; i < fRecordedBatches.count(); ++i) { |
| 190 if (!fRecordedBatches[i].fBatch) { | 197 if (!fRecordedBatches[i].fBatch) { |
| 191 continue; | 198 continue; |
| 192 } | 199 } |
| 193 if (fRecordedBatches[i].fBatch->renderTarget() != currentRT) { | 200 if (fRecordedBatches[i].fBatch->rtp() != currentRTP) { |
| 194 if (commandBuffer) { | 201 if (commandBuffer) { |
| 195 commandBuffer->end(); | 202 commandBuffer->end(); |
| 196 commandBuffer->submit(); | 203 commandBuffer->submit(); |
| 197 commandBuffer.reset(); | 204 commandBuffer.reset(); |
| 198 } | 205 } |
| 199 currentRT = fRecordedBatches[i].fBatch->renderTarget(); | 206 currentRTP = fRecordedBatches[i].fBatch->rtp(); |
| 200 if (currentRT) { | 207 if (currentRTP) { |
| 201 static const GrGpuCommandBuffer::LoadAndStoreInfo kBasicLoadStor
eInfo | 208 static const GrGpuCommandBuffer::LoadAndStoreInfo kBasicLoadStor
eInfo |
| 202 { GrGpuCommandBuffer::LoadOp::kLoad,GrGpuCommandBuffer::Stor
eOp::kStore, | 209 { GrGpuCommandBuffer::LoadOp::kLoad,GrGpuCommandBuffer::Stor
eOp::kStore, |
| 203 GrColor_ILLEGAL }; | 210 GrColor_ILLEGAL }; |
| 204 commandBuffer.reset(fGpu->createCommandBuffer(currentRT, | 211 commandBuffer.reset(fGpu->createCommandBuffer(nullptr, //current
RT, |
| 205 kBasicLoadStoreInf
o, // Color | 212 kBasicLoadStoreInf
o, // Color |
| 206 kBasicLoadStoreInf
o)); // Stencil | 213 kBasicLoadStoreInf
o)); // Stencil |
| 207 } | 214 } |
| 208 flushState->setCommandBuffer(commandBuffer.get()); | 215 flushState->setCommandBuffer(commandBuffer.get()); |
| 209 } | 216 } |
| 210 if (fDrawBatchBounds) { | 217 if (fDrawBatchBounds) { |
| 211 const SkRect& bounds = fRecordedBatches[i].fClippedBounds; | 218 const SkRect& bounds = fRecordedBatches[i].fClippedBounds; |
| 212 SkIRect ibounds; | 219 SkIRect ibounds; |
| 213 bounds.roundOut(&ibounds); | 220 bounds.roundOut(&ibounds); |
| 221 #if 0 |
| 214 // In multi-draw buffer all the batches use the same render target a
nd we won't need to | 222 // In multi-draw buffer all the batches use the same render target a
nd we won't need to |
| 215 // get the batchs bounds. | 223 // get the batchs bounds. |
| 216 if (GrRenderTarget* rt = fRecordedBatches[i].fBatch->renderTarget())
{ | 224 if (GrRenderTarget* rt = fRecordedBatches[i].fBatch->renderTarget())
{ |
| 217 fGpu->drawDebugWireRect(rt, ibounds, 0xFF000000 | random.nextU()
); | 225 fGpu->drawDebugWireRect(rt, ibounds, 0xFF000000 | random.nextU()
); |
| 218 } | 226 } |
| 227 #endif |
| 219 } | 228 } |
| 220 fRecordedBatches[i].fBatch->draw(flushState, fRecordedBatches[i].fClippe
dBounds); | 229 fRecordedBatches[i].fBatch->draw(flushState, fRecordedBatches[i].fClippe
dBounds); |
| 221 } | 230 } |
| 222 if (commandBuffer) { | 231 if (commandBuffer) { |
| 223 commandBuffer->end(); | 232 commandBuffer->end(); |
| 224 commandBuffer->submit(); | 233 commandBuffer->submit(); |
| 225 flushState->setCommandBuffer(nullptr); | 234 flushState->setCommandBuffer(nullptr); |
| 226 } | 235 } |
| 227 | 236 |
| 228 fGpu->finishOpList(); | 237 fGpu->finishOpList(); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 } | 340 } |
| 332 args.fOpts.fColorPOI.completeCalculations( | 341 args.fOpts.fColorPOI.completeCalculations( |
| 333 sk_sp_address_as_pointer_address(pipelineBuilder.fColorFragmentProcessor
s.begin()), | 342 sk_sp_address_as_pointer_address(pipelineBuilder.fColorFragmentProcessor
s.begin()), |
| 334 pipelineBuilder.numColorFragmentProcessors()); | 343 pipelineBuilder.numColorFragmentProcessors()); |
| 335 args.fOpts.fCoveragePOI.completeCalculations( | 344 args.fOpts.fCoveragePOI.completeCalculations( |
| 336 sk_sp_address_as_pointer_address(pipelineBuilder.fCoverageFragmentProces
sors.begin()), | 345 sk_sp_address_as_pointer_address(pipelineBuilder.fCoverageFragmentProces
sors.begin()), |
| 337 pipelineBuilder.numCoverageFragmentProcessors()); | 346 pipelineBuilder.numCoverageFragmentProcessors()); |
| 338 args.fScissor = &appliedClip.scissorState(); | 347 args.fScissor = &appliedClip.scissorState(); |
| 339 args.fWindowRectsState = &appliedClip.windowRectsState(); | 348 args.fWindowRectsState = &appliedClip.windowRectsState(); |
| 340 args.fHasStencilClip = appliedClip.hasStencilClip(); | 349 args.fHasStencilClip = appliedClip.hasStencilClip(); |
| 341 if (!this->setupDstReadIfNecessary(pipelineBuilder, renderTargetContext->acc
essRenderTarget(), | 350 if (!this->setupDstReadIfNecessary(pipelineBuilder, renderTargetContext, |
| 342 clip, args.fOpts, | 351 clip, args.fOpts, |
| 343 &args.fDstTexture, batch->bounds())) { | 352 &args.fDstTexture, batch->bounds())) { |
| 344 return; | 353 return; |
| 345 } | 354 } |
| 346 | 355 |
| 347 if (!batch->installPipeline(args)) { | 356 if (!batch->installPipeline(args)) { |
| 348 return; | 357 return; |
| 349 } | 358 } |
| 350 | 359 |
| 351 #ifdef ENABLE_MDB | 360 #ifdef ENABLE_MDB |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 SkDebugf("ERROR creating stencil attachment. Draw skipped.\n"); | 394 SkDebugf("ERROR creating stencil attachment. Draw skipped.\n"); |
| 386 return; | 395 return; |
| 387 } | 396 } |
| 388 | 397 |
| 389 GrBatch* batch = GrStencilPathBatch::Create(viewMatrix, | 398 GrBatch* batch = GrStencilPathBatch::Create(viewMatrix, |
| 390 useHWAA, | 399 useHWAA, |
| 391 path->getFillType(), | 400 path->getFillType(), |
| 392 appliedClip.hasStencilClip(), | 401 appliedClip.hasStencilClip(), |
| 393 stencilAttachment->bits(), | 402 stencilAttachment->bits(), |
| 394 appliedClip.scissorState(), | 403 appliedClip.scissorState(), |
| 395 renderTargetContext->accessRende
rTarget(), | 404 fRenderTargetProxy, |
| 396 path); | 405 path); |
| 397 this->recordBatch(batch, appliedClip.clippedDrawBounds()); | 406 this->recordBatch(batch, appliedClip.clippedDrawBounds()); |
| 398 batch->unref(); | 407 batch->unref(); |
| 399 } | 408 } |
| 400 | 409 |
| 401 void GrRenderTargetOpList::addBatch(sk_sp<GrBatch> batch) { | 410 void GrRenderTargetOpList::addBatch(sk_sp<GrBatch> batch) { |
| 402 this->recordBatch(batch.get(), batch->bounds()); | 411 this->recordBatch(batch.get(), batch->bounds()); |
| 403 } | 412 } |
| 404 | 413 |
| 405 void GrRenderTargetOpList::fullClear(GrRenderTarget* renderTarget, GrColor color
) { | 414 void GrRenderTargetOpList::fullClear(GrRenderTargetProxy* rtp, GrColor color) { |
| 406 // Currently this just inserts or updates the last clear batch. However, onc
e in MDB this can | 415 // Currently this just inserts or updates the last clear batch. However, onc
e in MDB this can |
| 407 // remove all the previously recorded batches and change the load op to clea
r with supplied | 416 // remove all the previously recorded batches and change the load op to clea
r with supplied |
| 408 // color. | 417 // color. |
| 409 if (fLastFullClearBatch && | 418 if (fLastFullClearBatch && |
| 410 fLastFullClearBatch->renderTargetUniqueID() == renderTarget->uniqueID())
{ | 419 fLastFullClearBatch->renderTargetUniqueID() == rtp->uniqueID()) { |
| 411 // As currently implemented, fLastFullClearBatch should be the last batc
h because we would | 420 // As currently implemented, fLastFullClearBatch should be the last batc
h because we would |
| 412 // have cleared it when another batch was recorded. | 421 // have cleared it when another batch was recorded. |
| 413 SkASSERT(fRecordedBatches.back().fBatch.get() == fLastFullClearBatch); | 422 SkASSERT(fRecordedBatches.back().fBatch.get() == fLastFullClearBatch); |
| 414 fLastFullClearBatch->setColor(color); | 423 fLastFullClearBatch->setColor(color); |
| 415 return; | 424 return; |
| 416 } | 425 } |
| 417 sk_sp<GrClearBatch> batch(GrClearBatch::Make(GrFixedClip::Disabled(), color,
renderTarget)); | 426 sk_sp<GrClearBatch> batch(GrClearBatch::Make(GrFixedClip::Disabled(), color,
rtp)); |
| 418 if (batch.get() == this->recordBatch(batch.get(), batch->bounds())) { | 427 if (batch.get() == this->recordBatch(batch.get(), batch->bounds())) { |
| 419 fLastFullClearBatch = batch.get(); | 428 fLastFullClearBatch = batch.get(); |
| 420 } | 429 } |
| 421 } | 430 } |
| 422 | 431 |
| 423 void GrRenderTargetOpList::discard(GrRenderTarget* renderTarget) { | 432 void GrRenderTargetOpList::discard(GrRenderTargetProxy* rtp) { |
| 424 // Currently this just inserts a discard batch. However, once in MDB this ca
n remove all the | 433 // Currently this just inserts a discard batch. However, once in MDB this ca
n remove all the |
| 425 // previously recorded batches and change the load op to discard. | 434 // previously recorded batches and change the load op to discard. |
| 426 if (this->caps()->discardRenderTargetSupport()) { | 435 if (this->caps()->discardRenderTargetSupport()) { |
| 427 GrBatch* batch = new GrDiscardBatch(renderTarget); | 436 GrBatch* batch = new GrDiscardBatch(rtp); |
| 428 this->recordBatch(batch, batch->bounds()); | 437 this->recordBatch(batch, batch->bounds()); |
| 429 batch->unref(); | 438 batch->unref(); |
| 430 } | 439 } |
| 431 } | 440 } |
| 432 | 441 |
| 433 //////////////////////////////////////////////////////////////////////////////// | 442 //////////////////////////////////////////////////////////////////////////////// |
| 434 | 443 |
| 435 bool GrRenderTargetOpList::copySurface(GrSurface* dst, | 444 bool GrRenderTargetOpList::copySurface(GrSurface* dst, |
| 436 GrSurface* src, | 445 GrSurface* src, |
| 437 const SkIRect& srcRect, | 446 const SkIRect& srcRect, |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 break; | 576 break; |
| 568 } | 577 } |
| 569 } | 578 } |
| 570 } | 579 } |
| 571 } | 580 } |
| 572 | 581 |
| 573 /////////////////////////////////////////////////////////////////////////////// | 582 /////////////////////////////////////////////////////////////////////////////// |
| 574 | 583 |
| 575 void GrRenderTargetOpList::clearStencilClip(const GrFixedClip& clip, | 584 void GrRenderTargetOpList::clearStencilClip(const GrFixedClip& clip, |
| 576 bool insideStencilMask, | 585 bool insideStencilMask, |
| 577 GrRenderTarget* rt) { | 586 GrRenderTargetProxy* rtp) { |
| 578 GrBatch* batch = new GrClearStencilClipBatch(clip, insideStencilMask, rt); | 587 GrBatch* batch = new GrClearStencilClipBatch(clip, insideStencilMask, rtp); |
| 579 this->recordBatch(batch, batch->bounds()); | 588 this->recordBatch(batch, batch->bounds()); |
| 580 batch->unref(); | 589 batch->unref(); |
| 581 } | 590 } |
| OLD | NEW |