Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Side by Side Diff: src/gpu/GrDrawTarget.cpp

Issue 2137543002: Use clipped bounds for reordering decisions (Closed) Base URL: https://chromium.googlesource.com/skia.git@lessstencil
Patch Set: add comment Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/gpu/GrDrawTarget.h ('K') | « src/gpu/GrDrawTarget.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "GrDrawTarget.h" 8 #include "GrDrawTarget.h"
9 9
10 #include "GrAuditTrail.h" 10 #include "GrAuditTrail.h"
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 108
109 #ifdef SK_DEBUG 109 #ifdef SK_DEBUG
110 void GrDrawTarget::dump() const { 110 void GrDrawTarget::dump() const {
111 SkDebugf("--------------------------------------------------------------\n") ; 111 SkDebugf("--------------------------------------------------------------\n") ;
112 SkDebugf("node: %d -> RT: %d\n", fDebugID, fRenderTarget ? fRenderTarget->ge tUniqueID() : -1); 112 SkDebugf("node: %d -> RT: %d\n", fDebugID, fRenderTarget ? fRenderTarget->ge tUniqueID() : -1);
113 SkDebugf("relies On (%d): ", fDependencies.count()); 113 SkDebugf("relies On (%d): ", fDependencies.count());
114 for (int i = 0; i < fDependencies.count(); ++i) { 114 for (int i = 0; i < fDependencies.count(); ++i) {
115 SkDebugf("%d, ", fDependencies[i]->fDebugID); 115 SkDebugf("%d, ", fDependencies[i]->fDebugID);
116 } 116 }
117 SkDebugf("\n"); 117 SkDebugf("\n");
118 SkDebugf("batches (%d):\n", fBatches.count()); 118 SkDebugf("batches (%d):\n", fRecordedBatches.count());
119 for (int i = 0; i < fBatches.count(); ++i) { 119 for (int i = 0; i < fRecordedBatches.count(); ++i) {
120 SkDebugf("*******************************\n"); 120 SkDebugf("*******************************\n");
121 if (!fBatches[i]) { 121 if (!fRecordedBatches[i].fBatch) {
122 SkDebugf("%d: <combined forward>\n", i); 122 SkDebugf("%d: <combined forward>\n", i);
123 } else { 123 } else {
124 SkDebugf("%d: %s\n", i, fBatches[i]->name()); 124 SkDebugf("%d: %s\n", i, fRecordedBatches[i].fBatch->name());
125 SkString str = fBatches[i]->dumpInfo(); 125 SkString str = fRecordedBatches[i].fBatch->dumpInfo();
126 SkDebugf("%s\n", str.c_str()); 126 SkDebugf("%s\n", str.c_str());
127 const SkRect& clippedBounds = fRecordedBatches[i].fClippedBounds;
128 SkDebugf("ClippedBounds: [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n",
129 clippedBounds.fLeft, clippedBounds.fTop, clippedBounds.fRig ht,
130 clippedBounds.fBottom);
127 } 131 }
128 } 132 }
129 } 133 }
130 #endif 134 #endif
131 135
132 bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil der, 136 bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil der,
133 GrRenderTarget* rt, 137 GrRenderTarget* rt,
134 const GrClip& clip, 138 const GrClip& clip,
135 const GrPipelineOptimizations& optimi zations, 139 const GrPipelineOptimizations& optimi zations,
136 GrXferProcessor::DstTexture* dstTextu re, 140 GrXferProcessor::DstTexture* dstTextu re,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 } 196 }
193 197
194 void GrDrawTarget::prepareBatches(GrBatchFlushState* flushState) { 198 void GrDrawTarget::prepareBatches(GrBatchFlushState* flushState) {
195 // Semi-usually the drawTargets are already closed at this point, but someti mes Ganesh 199 // Semi-usually the drawTargets are already closed at this point, but someti mes Ganesh
196 // needs to flush mid-draw. In that case, the SkGpuDevice's drawTargets won' t be closed 200 // needs to flush mid-draw. In that case, the SkGpuDevice's drawTargets won' t be closed
197 // but need to be flushed anyway. Closing such drawTargets here will mean ne w 201 // but need to be flushed anyway. Closing such drawTargets here will mean ne w
198 // drawTargets will be created to replace them if the SkGpuDevice(s) write t o them again. 202 // drawTargets will be created to replace them if the SkGpuDevice(s) write t o them again.
199 this->makeClosed(); 203 this->makeClosed();
200 204
201 // Loop over the batches that haven't yet generated their geometry 205 // Loop over the batches that haven't yet generated their geometry
202 for (int i = 0; i < fBatches.count(); ++i) { 206 for (int i = 0; i < fRecordedBatches.count(); ++i) {
203 if (fBatches[i]) { 207 if (fRecordedBatches[i].fBatch) {
204 fBatches[i]->prepare(flushState); 208 fRecordedBatches[i].fBatch->prepare(flushState);
205 } 209 }
206 } 210 }
207 211
208 if (fInstancedRendering) { 212 if (fInstancedRendering) {
209 fInstancedRendering->beginFlush(flushState->resourceProvider()); 213 fInstancedRendering->beginFlush(flushState->resourceProvider());
210 } 214 }
211 } 215 }
212 216
213 void GrDrawTarget::drawBatches(GrBatchFlushState* flushState) { 217 void GrDrawTarget::drawBatches(GrBatchFlushState* flushState) {
214 // Draw all the generated geometry. 218 // Draw all the generated geometry.
215 SkRandom random; 219 SkRandom random;
216 GrRenderTarget* currentRT = nullptr; 220 GrRenderTarget* currentRT = nullptr;
217 SkAutoTDelete<GrGpuCommandBuffer> commandBuffer; 221 SkAutoTDelete<GrGpuCommandBuffer> commandBuffer;
218 SkRect bounds = SkRect::MakeEmpty(); 222 SkRect bounds = SkRect::MakeEmpty();
219 for (int i = 0; i < fBatches.count(); ++i) { 223 for (int i = 0; i < fRecordedBatches.count(); ++i) {
220 if (!fBatches[i]) { 224 if (!fRecordedBatches[i].fBatch) {
221 continue; 225 continue;
222 } 226 }
223 if (fBatches[i]->renderTarget() != currentRT) { 227 if (fRecordedBatches[i].fBatch->renderTarget() != currentRT) {
224 if (commandBuffer) { 228 if (commandBuffer) {
225 commandBuffer->end(); 229 commandBuffer->end();
226 if (bounds.intersect(0, 0, 230 if (bounds.intersect(0, 0,
227 SkIntToScalar(currentRT->width()), 231 SkIntToScalar(currentRT->width()),
228 SkIntToScalar(currentRT->height()))) { 232 SkIntToScalar(currentRT->height()))) {
229 SkIRect iBounds; 233 SkIRect iBounds;
230 bounds.roundOut(&iBounds); 234 bounds.roundOut(&iBounds);
231 commandBuffer->submit(iBounds); 235 commandBuffer->submit(iBounds);
232 } 236 }
233 commandBuffer.reset(); 237 commandBuffer.reset();
234 } 238 }
235 bounds.setEmpty(); 239 bounds.setEmpty();
236 currentRT = fBatches[i]->renderTarget(); 240 currentRT = fRecordedBatches[i].fBatch->renderTarget();
237 if (currentRT) { 241 if (currentRT) {
238 static const GrGpuCommandBuffer::LoadAndStoreInfo kBasicLoadStor eInfo 242 static const GrGpuCommandBuffer::LoadAndStoreInfo kBasicLoadStor eInfo
239 { GrGpuCommandBuffer::LoadOp::kLoad,GrGpuCommandBuffer::Stor eOp::kStore, 243 { GrGpuCommandBuffer::LoadOp::kLoad,GrGpuCommandBuffer::Stor eOp::kStore,
240 GrColor_ILLEGAL }; 244 GrColor_ILLEGAL };
241 commandBuffer.reset(fGpu->createCommandBuffer(currentRT, 245 commandBuffer.reset(fGpu->createCommandBuffer(currentRT,
242 kBasicLoadStoreInf o, // Color 246 kBasicLoadStoreInf o, // Color
243 kBasicLoadStoreInf o)); // Stencil 247 kBasicLoadStoreInf o)); // Stencil
244 } 248 }
245 flushState->setCommandBuffer(commandBuffer); 249 flushState->setCommandBuffer(commandBuffer);
246 } 250 }
247 if (commandBuffer) { 251 if (commandBuffer) {
248 bounds.join(fBatches[i]->bounds()); 252 bounds.join(fRecordedBatches[i].fClippedBounds);
249 } 253 }
250 if (fDrawBatchBounds) { 254 if (fDrawBatchBounds) {
251 const SkRect& batchBounds = fBatches[i]->bounds(); 255 const SkRect& bounds = fRecordedBatches[i].fClippedBounds;
252 SkIRect iBatchBounds; 256 SkIRect ibounds;
253 batchBounds.roundOut(&iBatchBounds); 257 bounds.roundOut(&ibounds);
254 // In multi-draw buffer all the batches use the same render target a nd we won't need to 258 // In multi-draw buffer all the batches use the same render target a nd we won't need to
255 // get the batchs bounds. 259 // get the batchs bounds.
256 if (GrRenderTarget* rt = fBatches[i]->renderTarget()) { 260 if (GrRenderTarget* rt = fRecordedBatches[i].fBatch->renderTarget()) {
257 fGpu->drawDebugWireRect(rt, iBatchBounds, 0xFF000000 | random.ne xtU()); 261 fGpu->drawDebugWireRect(rt, ibounds, 0xFF000000 | random.nextU() );
258 } 262 }
259 } 263 }
260 fBatches[i]->draw(flushState); 264 fRecordedBatches[i].fBatch->draw(flushState);
261 } 265 }
262 if (commandBuffer) { 266 if (commandBuffer) {
263 commandBuffer->end(); 267 commandBuffer->end();
264 if (bounds.intersect(0, 0, 268 if (bounds.intersect(0, 0,
265 SkIntToScalar(currentRT->width()), 269 SkIntToScalar(currentRT->width()),
266 SkIntToScalar(currentRT->height()))) { 270 SkIntToScalar(currentRT->height()))) {
267 SkIRect iBounds; 271 SkIRect iBounds;
268 bounds.roundOut(&iBounds); 272 bounds.roundOut(&iBounds);
269 commandBuffer->submit(iBounds); 273 commandBuffer->submit(iBounds);
270 } 274 }
271 flushState->setCommandBuffer(nullptr); 275 flushState->setCommandBuffer(nullptr);
272 } 276 }
273 277
274 fGpu->finishDrawTarget(); 278 fGpu->finishDrawTarget();
275 } 279 }
276 280
277 void GrDrawTarget::reset() { 281 void GrDrawTarget::reset() {
278 fBatches.reset(); 282 fRecordedBatches.reset();
279 if (fInstancedRendering) { 283 if (fInstancedRendering) {
280 fInstancedRendering->endFlush(); 284 fInstancedRendering->endFlush();
281 } 285 }
282 } 286 }
283 287
284 static void batch_bounds(SkRect* bounds, const GrBatch* batch) { 288 static void batch_bounds(SkRect* bounds, const GrBatch* batch) {
285 *bounds = batch->bounds(); 289 *bounds = batch->bounds();
286 if (batch->hasZeroArea()) { 290 if (batch->hasZeroArea()) {
287 if (batch->hasAABloat()) { 291 if (batch->hasAABloat()) {
288 bounds->outset(0.5f, 0.5f); 292 bounds->outset(0.5f, 0.5f);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 } 381 }
378 382
379 if (!batch->installPipeline(args)) { 383 if (!batch->installPipeline(args)) {
380 return; 384 return;
381 } 385 }
382 386
383 #ifdef ENABLE_MDB 387 #ifdef ENABLE_MDB
384 SkASSERT(fRenderTarget); 388 SkASSERT(fRenderTarget);
385 batch->pipeline()->addDependenciesTo(fRenderTarget); 389 batch->pipeline()->addDependenciesTo(fRenderTarget);
386 #endif 390 #endif
387 391 SkRect clippedBounds;
388 this->recordBatch(batch); 392 SkAssertResult(clippedBounds.intersect(bounds, appliedClip.deviceBounds()));
393 this->recordBatch(batch, clippedBounds);
389 } 394 }
390 395
391 void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder, 396 void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder,
392 GrDrawContext* drawContext, 397 GrDrawContext* drawContext,
393 const GrClip& clip, 398 const GrClip& clip,
394 const SkMatrix& viewMatrix, 399 const SkMatrix& viewMatrix,
395 const GrPath* path, 400 const GrPath* path,
396 GrPathRendering::FillType fill) { 401 GrPathRendering::FillType fill) {
397 // TODO: extract portions of checkDraw that are relevant to path stenciling. 402 // TODO: extract portions of checkDraw that are relevant to path stenciling.
398 SkASSERT(path); 403 SkASSERT(path);
(...skipping 18 matching lines...) Expand all
417 } 422 }
418 423
419 GrBatch* batch = GrStencilPathBatch::Create(viewMatrix, 424 GrBatch* batch = GrStencilPathBatch::Create(viewMatrix,
420 pipelineBuilder.isHWAntialias(), 425 pipelineBuilder.isHWAntialias(),
421 fill, 426 fill,
422 appliedClip.hasStencilClip(), 427 appliedClip.hasStencilClip(),
423 stencilAttachment->bits(), 428 stencilAttachment->bits(),
424 appliedClip.scissorState(), 429 appliedClip.scissorState(),
425 drawContext->accessRenderTarget( ), 430 drawContext->accessRenderTarget( ),
426 path); 431 path);
427 this->recordBatch(batch); 432 this->recordBatch(batch, appliedClip.deviceBounds());
428 batch->unref(); 433 batch->unref();
429 } 434 }
430 435
431 void GrDrawTarget::clear(const SkIRect* rect, 436 void GrDrawTarget::clear(const SkIRect* rect,
432 GrColor color, 437 GrColor color,
433 bool canIgnoreRect, 438 bool canIgnoreRect,
434 GrDrawContext* drawContext) { 439 GrDrawContext* drawContext) {
435 SkIRect rtRect = SkIRect::MakeWH(drawContext->width(), drawContext->height() ); 440 SkIRect rtRect = SkIRect::MakeWH(drawContext->width(), drawContext->height() );
436 SkIRect clippedRect; 441 SkIRect clippedRect;
437 if (!rect || 442 if (!rect ||
(...skipping 20 matching lines...) Expand all
458 GrPipelineBuilder pipelineBuilder; 463 GrPipelineBuilder pipelineBuilder;
459 pipelineBuilder.setXPFactory(GrPorterDuffXPFactory::Make(SkXfermode::kSr c_Mode)); 464 pipelineBuilder.setXPFactory(GrPorterDuffXPFactory::Make(SkXfermode::kSr c_Mode));
460 465
461 SkRect scalarRect = SkRect::Make(*rect); 466 SkRect scalarRect = SkRect::Make(*rect);
462 SkAutoTUnref<GrDrawBatch> batch( 467 SkAutoTUnref<GrDrawBatch> batch(
463 GrRectBatchFactory::CreateNonAAFill(color, SkMatrix::I(), scalar Rect, 468 GrRectBatchFactory::CreateNonAAFill(color, SkMatrix::I(), scalar Rect,
464 nullptr, nullptr)); 469 nullptr, nullptr));
465 this->drawBatch(pipelineBuilder, drawContext, GrNoClip(), batch); 470 this->drawBatch(pipelineBuilder, drawContext, GrNoClip(), batch);
466 } else { 471 } else {
467 GrBatch* batch = new GrClearBatch(*rect, color, drawContext->accessRende rTarget()); 472 GrBatch* batch = new GrClearBatch(*rect, color, drawContext->accessRende rTarget());
468 this->recordBatch(batch); 473 this->recordBatch(batch, batch->bounds());
469 batch->unref(); 474 batch->unref();
470 } 475 }
471 } 476 }
472 477
473 void GrDrawTarget::discard(GrRenderTarget* renderTarget) { 478 void GrDrawTarget::discard(GrRenderTarget* renderTarget) {
474 if (this->caps()->discardRenderTargetSupport()) { 479 if (this->caps()->discardRenderTargetSupport()) {
475 GrBatch* batch = new GrDiscardBatch(renderTarget); 480 GrBatch* batch = new GrDiscardBatch(renderTarget);
476 this->recordBatch(batch); 481 this->recordBatch(batch, batch->bounds());
477 batch->unref(); 482 batch->unref();
478 } 483 }
479 } 484 }
480 485
481 //////////////////////////////////////////////////////////////////////////////// 486 ////////////////////////////////////////////////////////////////////////////////
482 487
483 bool GrDrawTarget::copySurface(GrSurface* dst, 488 bool GrDrawTarget::copySurface(GrSurface* dst,
484 GrSurface* src, 489 GrSurface* src,
485 const SkIRect& srcRect, 490 const SkIRect& srcRect,
486 const SkIPoint& dstPoint) { 491 const SkIPoint& dstPoint) {
487 GrBatch* batch = GrCopySurfaceBatch::Create(dst, src, srcRect, dstPoint); 492 GrBatch* batch = GrCopySurfaceBatch::Create(dst, src, srcRect, dstPoint);
488 if (!batch) { 493 if (!batch) {
489 return false; 494 return false;
490 } 495 }
491 #ifdef ENABLE_MDB 496 #ifdef ENABLE_MDB
492 this->addDependency(src); 497 this->addDependency(src);
493 #endif 498 #endif
494 499
495 this->recordBatch(batch); 500 this->recordBatch(batch, batch->bounds());
496 batch->unref(); 501 batch->unref();
497 return true; 502 return true;
498 } 503 }
499 504
500 static inline bool exclusive_no_intersection(const SkRect& a, const SkRect& b) { 505 static inline bool can_reorder(const SkRect& a, const SkRect& b) {
501 return a.fRight <= b.fLeft || a.fBottom <= b.fTop || 506 return a.fRight <= b.fLeft || a.fBottom <= b.fTop ||
502 b.fRight <= a.fLeft || b.fBottom <= a.fTop; 507 b.fRight <= a.fLeft || b.fBottom <= a.fTop;
503 } 508 }
504 509
505 static inline bool can_reorder(const GrBatch* a, const GrBatch* b) { 510 void GrDrawTarget::recordBatch(GrBatch* batch, const SkRect& clippedBounds) {
506 SkRect ra;
507 SkRect rb;
508 batch_bounds(&ra, a);
509 batch_bounds(&rb, a);
510 return exclusive_no_intersection(ra, rb);
511 }
512
513 void GrDrawTarget::recordBatch(GrBatch* batch) {
514 // A closed drawTarget should never receive new/more batches 511 // A closed drawTarget should never receive new/more batches
515 SkASSERT(!this->isClosed()); 512 SkASSERT(!this->isClosed());
516 513
517 // Check if there is a Batch Draw we can batch with by linearly searching ba ck until we either 514 // Check if there is a Batch Draw we can batch with by linearly searching ba ck until we either
518 // 1) check every draw 515 // 1) check every draw
519 // 2) intersect with something 516 // 2) intersect with something
520 // 3) find a 'blocker' 517 // 3) find a 'blocker'
521 GR_AUDIT_TRAIL_ADDBATCH(fAuditTrail, batch); 518 GR_AUDIT_TRAIL_ADDBATCH(fAuditTrail, batch);
522 GrBATCH_INFO("Re-Recording (%s, B%u)\n" 519 GrBATCH_INFO("Re-Recording (%s, B%u)\n"
523 "\tBounds LRTB (%f, %f, %f, %f)\n", 520 "\tBounds LRTB (%f, %f, %f, %f)\n",
524 batch->name(), 521 batch->name(),
525 batch->uniqueID(), 522 batch->uniqueID(),
526 batch->bounds().fLeft, batch->bounds().fRight, 523 batch->bounds().fLeft, batch->bounds().fRight,
527 batch->bounds().fTop, batch->bounds().fBottom); 524 batch->bounds().fTop, batch->bounds().fBottom);
528 GrBATCH_INFO(SkTabString(batch->dumpInfo(), 1).c_str()); 525 GrBATCH_INFO(SkTabString(batch->dumpInfo(), 1).c_str());
526 GrBATCH_INFO("\tClipped Bounds: [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n",
527 clippedBounds.fLeft, clippedBounds.fTop, clippedBounds.fRight,
528 clippedBounds.fBottom);
529 GrBATCH_INFO("\tOutcome:\n"); 529 GrBATCH_INFO("\tOutcome:\n");
530 int maxCandidates = SkTMin(fMaxBatchLookback, fBatches.count()); 530 int maxCandidates = SkTMin(fMaxBatchLookback, fRecordedBatches.count());
531 if (maxCandidates) { 531 if (maxCandidates) {
532 int i = 0; 532 int i = 0;
533 while (true) { 533 while (true) {
534 GrBatch* candidate = fBatches.fromBack(i); 534 GrBatch* candidate = fRecordedBatches.fromBack(i).fBatch.get();
535 // We cannot continue to search backwards if the render target chang es 535 // We cannot continue to search backwards if the render target chang es
536 if (candidate->renderTargetUniqueID() != batch->renderTargetUniqueID ()) { 536 if (candidate->renderTargetUniqueID() != batch->renderTargetUniqueID ()) {
537 GrBATCH_INFO("\t\tBreaking because of (%s, B%u) Rendertarget\n", 537 GrBATCH_INFO("\t\tBreaking because of (%s, B%u) Rendertarget\n",
538 candidate->name(), candidate->uniqueID()); 538 candidate->name(), candidate->uniqueID());
539 break; 539 break;
540 } 540 }
541 if (candidate->combineIfPossible(batch, *this->caps())) { 541 if (candidate->combineIfPossible(batch, *this->caps())) {
542 GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name() , 542 GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name() ,
543 candidate->uniqueID()); 543 candidate->uniqueID());
544 GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, candidate, batch); 544 GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, candidate, batch);
545 fRecordedBatches.fromBack(i).fClippedBounds.joinNonEmptyArg(clip pedBounds);
545 return; 546 return;
546 } 547 }
547 // Stop going backwards if we would cause a painter's order violatio n. 548 // Stop going backwards if we would cause a painter's order violatio n.
548 // TODO: The bounds used here do not fully consider the clip. It may be advantageous 549 const SkRect& candidateBounds = fRecordedBatches.fromBack(i).fClippe dBounds;
549 // to clip each batch's bounds to the clip. 550 if (!can_reorder(candidateBounds, clippedBounds)) {
550 if (!can_reorder(candidate, batch)) {
551 GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name( ), 551 GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name( ),
552 candidate->uniqueID()); 552 candidate->uniqueID());
553 break; 553 break;
554 } 554 }
555 ++i; 555 ++i;
556 if (i == maxCandidates) { 556 if (i == maxCandidates) {
557 GrBATCH_INFO("\t\tReached max lookback or beginning of batch arr ay %d\n", i); 557 GrBATCH_INFO("\t\tReached max lookback or beginning of batch arr ay %d\n", i);
558 break; 558 break;
559 } 559 }
560 } 560 }
561 } else { 561 } else {
562 GrBATCH_INFO("\t\tFirstBatch\n"); 562 GrBATCH_INFO("\t\tFirstBatch\n");
563 } 563 }
564 GR_AUDIT_TRAIL_BATCHING_RESULT_NEW(fAuditTrail, batch); 564 GR_AUDIT_TRAIL_BATCHING_RESULT_NEW(fAuditTrail, batch);
565 fBatches.push_back().reset(SkRef(batch)); 565 fRecordedBatches.emplace_back(RecordedBatch{sk_ref_sp(batch), clippedBounds} );
566 } 566 }
567 567
568 void GrDrawTarget::forwardCombine() { 568 void GrDrawTarget::forwardCombine() {
569 for (int i = 0; i < fBatches.count() - 2; ++i) { 569 for (int i = 0; i < fRecordedBatches.count() - 2; ++i) {
570 GrBatch* batch = fBatches[i]; 570 GrBatch* batch = fRecordedBatches[i].fBatch.get();
571 int maxCandidateIdx = SkTMin(i + fMaxBatchLookahead, fBatches.count() - 1); 571 const SkRect& batchBounds = fRecordedBatches[i].fClippedBounds;
572 int maxCandidateIdx = SkTMin(i + fMaxBatchLookahead, fRecordedBatches.co unt() - 1);
572 int j = i + 1; 573 int j = i + 1;
573 while (true) { 574 while (true) {
574 GrBatch* candidate = fBatches[j]; 575 GrBatch* candidate = fRecordedBatches[j].fBatch.get();
575 // We cannot continue to search if the render target changes 576 // We cannot continue to search if the render target changes
576 if (candidate->renderTargetUniqueID() != batch->renderTargetUniqueID ()) { 577 if (candidate->renderTargetUniqueID() != batch->renderTargetUniqueID ()) {
577 GrBATCH_INFO("\t\tBreaking because of (%s, B%u) Rendertarget\n", 578 GrBATCH_INFO("\t\tBreaking because of (%s, B%u) Rendertarget\n",
578 candidate->name(), candidate->uniqueID()); 579 candidate->name(), candidate->uniqueID());
579 break; 580 break;
580 } 581 }
581 if (j == i +1) { 582 if (j == i +1) {
582 // We assume batch would have combined with candidate when the c andidate was added 583 // We assume batch would have combined with candidate when the c andidate was added
583 // via backwards combining in recordBatch. 584 // via backwards combining in recordBatch.
584 SkASSERT(!batch->combineIfPossible(candidate, *this->caps())); 585 SkASSERT(!batch->combineIfPossible(candidate, *this->caps()));
585 } else if (batch->combineIfPossible(candidate, *this->caps())) { 586 } else if (batch->combineIfPossible(candidate, *this->caps())) {
586 GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name() , 587 GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name() ,
587 candidate->uniqueID()); 588 candidate->uniqueID());
588 GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, batch, cand idate); 589 GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, batch, cand idate);
589 fBatches[j].reset(SkRef(batch)); 590 fRecordedBatches[j].fBatch = std::move(fRecordedBatches[i].fBatc h);
590 fBatches[i].reset(nullptr); 591 fRecordedBatches[j].fClippedBounds.join(batchBounds);
591 break; 592 break;
592 } 593 }
593 // Stop going traversing if we would cause a painter's order violati on. 594 // Stop going traversing if we would cause a painter's order violati on.
594 // TODO: The bounds used here do not fully consider the clip. It may be advantageous 595 const SkRect& candidateBounds = fRecordedBatches[j].fClippedBounds;
595 // to clip each batch's bounds to the clip. 596 if (!can_reorder(candidateBounds, batchBounds)) {
596 if (!can_reorder(candidate, batch)) {
597 GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name( ), 597 GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name( ),
598 candidate->uniqueID()); 598 candidate->uniqueID());
599 break; 599 break;
600 } 600 }
601 ++j; 601 ++j;
602 if (j > maxCandidateIdx) { 602 if (j > maxCandidateIdx) {
603 GrBATCH_INFO("\t\tReached max lookahead or end of batch array %d \n", i); 603 GrBATCH_INFO("\t\tReached max lookahead or end of batch array %d \n", i);
604 break; 604 break;
605 } 605 }
606 } 606 }
607 } 607 }
608 } 608 }
609 609
610 /////////////////////////////////////////////////////////////////////////////// 610 ///////////////////////////////////////////////////////////////////////////////
611 611
612 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend erTarget* rt) { 612 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend erTarget* rt) {
613 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); 613 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt);
614 this->recordBatch(batch); 614 this->recordBatch(batch, batch->bounds());
615 batch->unref(); 615 batch->unref();
616 } 616 }
OLDNEW
« src/gpu/GrDrawTarget.h ('K') | « src/gpu/GrDrawTarget.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698