1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 11 #include "GrInOrderDrawBuffer.h" 12 #include "GrRenderTarget.h" 13 #include "GrTexture.h" 14 #include "GrBufferAllocPool.h" 15 #include "GrIndexBuffer.h" 16 #include "GrVertexBuffer.h" 17 #include "GrGpu.h" 18 19 GrInOrderDrawBuffer::GrInOrderDrawBuffer(const GrGpu* gpu, 20 GrVertexBufferAllocPool* vertexPool, 21 GrIndexBufferAllocPool* indexPool) 22 : fClipSet(true) 23 , fLastRectVertexLayout(0) 24 , fQuadIndexBuffer(NULL) 25 , fMaxQuads(0) 26 , fCurrQuad(0) 27 , fVertexPool(*vertexPool) 28 , fIndexPool(*indexPool) { 29 30 fCaps = gpu->getCaps(); 31 32 GrAssert(NULL != vertexPool); 33 GrAssert(NULL != indexPool); 34 35 GeometryPoolState& poolState = fGeoPoolStateStack.push_back(); 36 poolState.fUsedPoolVertexBytes = 0; 37 poolState.fUsedPoolIndexBytes = 0; 38 #if GR_DEBUG 39 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0; 40 poolState.fPoolStartVertex = ~0; 41 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0; 42 poolState.fPoolStartIndex = ~0; 43 #endif 44 } 45 46 GrInOrderDrawBuffer::~GrInOrderDrawBuffer() { 47 this->reset(); 48 // This must be called by before the GrDrawTarget destructor 49 this->releaseGeometry(); 50 GrSafeUnref(fQuadIndexBuffer); 51 } 52 53 void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) { 54 this->copyDrawState(target); 55 this->setClip(target.getClip()); 56 } 57 58 void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) { 59 bool newIdxBuffer = fQuadIndexBuffer != indexBuffer; 60 if (newIdxBuffer) { 61 GrSafeUnref(fQuadIndexBuffer); 62 fQuadIndexBuffer = indexBuffer; 63 GrSafeRef(fQuadIndexBuffer); 64 fCurrQuad = 0; 65 fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads(); 66 } else { 67 GrAssert((NULL == indexBuffer && 0 == fMaxQuads) || 68 (indexBuffer->maxQuads() == fMaxQuads)); 69 } 70 } 71 72 void GrInOrderDrawBuffer::drawRect(const GrRect& rect, 73 const GrMatrix* matrix, 74 StageMask stageMask, 75 const GrRect* srcRects[], 76 const GrMatrix* srcMatrices[]) { 77 78 GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad)); 79 GrAssert(!(fDraws.empty() && fCurrQuad)); 80 GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer)); 81 82 GrDrawState* drawState = this->drawState(); 83 84 // if we have a quad IB then either append to the previous run of 85 // rects or start a new run 86 if (fMaxQuads) { 87 88 bool appendToPreviousDraw = false; 89 GrVertexLayout layout = GetRectVertexLayout(stageMask, srcRects); 90 AutoReleaseGeometry geo(this, layout, 4, 0); 91 if (!geo.succeeded()) { 92 GrPrintf("Failed to get space for vertices!\n"); 93 return; 94 } 95 GrMatrix combinedMatrix = drawState->getViewMatrix(); 96 GrDrawState::AutoViewMatrixRestore avmr(drawState, GrMatrix::I()); 97 if (NULL != matrix) { 98 combinedMatrix.preConcat(*matrix); 99 } 100 101 SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices()); 102 103 // we don't want to miss an opportunity to batch rects together 104 // simply because the clip has changed if the clip doesn't affect 105 // the rect. 106 bool disabledClip = false; 107 if (drawState->isClipState() && fClip.isRect()) { 108 109 GrRect clipRect = fClip.getRect(0); 110 // If the clip rect touches the edge of the viewport, extended it 111 // out (close) to infinity to avoid bogus intersections. 112 // We might consider a more exact clip to viewport if this 113 // conservative test fails. 114 const GrRenderTarget* target = drawState->getRenderTarget(); 115 if (0 >= clipRect.fLeft) { 116 clipRect.fLeft = GR_ScalarMin; 117 } 118 if (target->width() <= clipRect.fRight) { 119 clipRect.fRight = GR_ScalarMax; 120 } 121 if (0 >= clipRect.top()) { 122 clipRect.fTop = GR_ScalarMin; 123 } 124 if (target->height() <= clipRect.fBottom) { 125 clipRect.fBottom = GR_ScalarMax; 126 } 127 int stride = VertexSize(layout); 128 bool insideClip = true; 129 for (int v = 0; v < 4; ++v) { 130 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride); 131 if (!clipRect.contains(p)) { 132 insideClip = false; 133 break; 134 } 135 } 136 if (insideClip) { 137 drawState->disableState(GrDrawState::kClip_StateBit); 138 disabledClip = true; 139 } 140 } 141 if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 && 142 fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) { 143 144 int vsize = VertexSize(layout); 145 146 Draw& lastDraw = fDraws.back(); 147 148 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer); 149 GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType); 150 GrAssert(0 == lastDraw.fVertexCount % 4); 151 GrAssert(0 == lastDraw.fIndexCount % 6); 152 GrAssert(0 == lastDraw.fStartIndex); 153 154 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 155 bool clearSinceLastDraw = 156 fClears.count() && 157 fClears.back().fBeforeDrawIdx == fDraws.count(); 158 159 appendToPreviousDraw = 160 !clearSinceLastDraw && 161 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer && 162 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex; 163 164 if (appendToPreviousDraw) { 165 lastDraw.fVertexCount += 4; 166 lastDraw.fIndexCount += 6; 167 fCurrQuad += 1; 168 // we reserved above, so we should be the first 169 // use of this vertex reserveation. 170 GrAssert(0 == poolState.fUsedPoolVertexBytes); 171 poolState.fUsedPoolVertexBytes = 4 * vsize; 172 } 173 } 174 if (!appendToPreviousDraw) { 175 this->setIndexSourceToBuffer(fQuadIndexBuffer); 176 drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6); 177 fCurrQuad = 1; 178 fLastRectVertexLayout = layout; 179 } 180 if (disabledClip) { 181 drawState->enableState(GrDrawState::kClip_StateBit); 182 } 183 } else { 184 INHERITED::drawRect(rect, matrix, stageMask, srcRects, srcMatrices); 185 } 186 } 187 188 void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType, 189 int startVertex, 190 int startIndex, 191 int vertexCount, 192 int indexCount) { 193 194 if (!vertexCount || !indexCount) { 195 return; 196 } 197 198 fCurrQuad = 0; 199 200 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 201 202 Draw& draw = fDraws.push_back(); 203 draw.fPrimitiveType = primitiveType; 204 draw.fStartVertex = startVertex; 205 draw.fStartIndex = startIndex; 206 draw.fVertexCount = vertexCount; 207 draw.fIndexCount = indexCount; 208 209 draw.fClipChanged = this->needsNewClip(); 210 if (draw.fClipChanged) { 211 this->pushClip(); 212 } 213 214 draw.fStateChanged = this->needsNewState(); 215 if (draw.fStateChanged) { 216 this->pushState(); 217 } 218 219 draw.fVertexLayout = this->getGeomSrc().fVertexLayout; 220 switch (this->getGeomSrc().fVertexSrc) { 221 case kBuffer_GeometrySrcType: 222 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer; 223 break; 224 case kReserved_GeometrySrcType: // fallthrough 225 case kArray_GeometrySrcType: { 226 size_t vertexBytes = (vertexCount + startVertex) * 227 VertexSize(this->getGeomSrc().fVertexLayout); 228 poolState.fUsedPoolVertexBytes = 229 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes); 230 draw.fVertexBuffer = poolState.fPoolVertexBuffer; 231 draw.fStartVertex += poolState.fPoolStartVertex; 232 break; 233 } 234 default: 235 GrCrash("unknown geom src type"); 236 } 237 draw.fVertexBuffer->ref(); 238 239 switch (this->getGeomSrc().fIndexSrc) { 240 case kBuffer_GeometrySrcType: 241 draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer; 242 break; 243 case kReserved_GeometrySrcType: // fallthrough 244 case kArray_GeometrySrcType: { 245 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t); 246 poolState.fUsedPoolIndexBytes = 247 GrMax(poolState.fUsedPoolIndexBytes, indexBytes); 248 draw.fIndexBuffer = poolState.fPoolIndexBuffer; 249 draw.fStartIndex += poolState.fPoolStartIndex; 250 break; 251 } 252 default: 253 GrCrash("unknown geom src type"); 254 } 255 draw.fIndexBuffer->ref(); 256 } 257 258 void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType, 259 int startVertex, 260 int vertexCount) { 261 if (!vertexCount) { 262 return; 263 } 264 265 fCurrQuad = 0; 266 267 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 268 269 Draw& draw = fDraws.push_back(); 270 draw.fPrimitiveType = primitiveType; 271 draw.fStartVertex = startVertex; 272 draw.fStartIndex = 0; 273 draw.fVertexCount = vertexCount; 274 draw.fIndexCount = 0; 275 276 draw.fClipChanged = this->needsNewClip(); 277 if (draw.fClipChanged) { 278 this->pushClip(); 279 } 280 281 draw.fStateChanged = this->needsNewState(); 282 if (draw.fStateChanged) { 283 this->pushState(); 284 } 285 286 draw.fVertexLayout = this->getGeomSrc().fVertexLayout; 287 switch (this->getGeomSrc().fVertexSrc) { 288 case kBuffer_GeometrySrcType: 289 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer; 290 break; 291 case kReserved_GeometrySrcType: // fallthrough 292 case kArray_GeometrySrcType: { 293 size_t vertexBytes = (vertexCount + startVertex) * 294 VertexSize(this->getGeomSrc().fVertexLayout); 295 poolState.fUsedPoolVertexBytes = 296 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes); 297 draw.fVertexBuffer = poolState.fPoolVertexBuffer; 298 draw.fStartVertex += poolState.fPoolStartVertex; 299 break; 300 } 301 default: 302 GrCrash("unknown geom src type"); 303 } 304 draw.fVertexBuffer->ref(); 305 draw.fIndexBuffer = NULL; 306 } 307 308 void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) { 309 GrIRect r; 310 if (NULL == rect) { 311 // We could do something smart and remove previous draws and clears to 312 // the current render target. If we get that smart we have to make sure 313 // those draws aren't read before this clear (render-to-texture). 314 r.setLTRB(0, 0, 315 this->getDrawState().getRenderTarget()->width(), 316 this->getDrawState().getRenderTarget()->height()); 317 rect = &r; 318 } 319 Clear& clr = fClears.push_back(); 320 clr.fColor = color; 321 clr.fBeforeDrawIdx = fDraws.count(); 322 clr.fRect = *rect; 323 } 324 325 void GrInOrderDrawBuffer::reset() { 326 GrAssert(1 == fGeoPoolStateStack.count()); 327 this->resetVertexSource(); 328 this->resetIndexSource(); 329 uint32_t numStates = fStates.count(); 330 for (uint32_t i = 0; i < numStates; ++i) { 331 const GrDrawState& dstate = this->accessSavedDrawState(fStates[i]); 332 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 333 GrSafeUnref(dstate.getTexture(s)); 334 } 335 GrSafeUnref(dstate.getRenderTarget()); 336 } 337 int numDraws = fDraws.count(); 338 for (int d = 0; d < numDraws; ++d) { 339 // we always have a VB, but not always an IB 340 GrAssert(NULL != fDraws[d].fVertexBuffer); 341 fDraws[d].fVertexBuffer->unref(); 342 GrSafeUnref(fDraws[d].fIndexBuffer); 343 } 344 fDraws.reset(); 345 fStates.reset(); 346 347 fClears.reset(); 348 349 fVertexPool.reset(); 350 fIndexPool.reset(); 351 352 fClips.reset(); 353 354 fCurrQuad = 0; 355 } 356 357 void GrInOrderDrawBuffer::playback(GrDrawTarget* target) { 358 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc); 359 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc); 360 GrAssert(NULL != target); 361 GrAssert(target != this); // not considered and why? 362 363 int numDraws = fDraws.count(); 364 if (!numDraws) { 365 return; 366 } 367 368 fVertexPool.unlock(); 369 fIndexPool.unlock(); 370 371 GrDrawTarget::AutoStateRestore asr(target); 372 GrDrawTarget::AutoClipRestore acr(target); 373 AutoGeometryPush agp(target); 374 375 int currState = ~0; 376 int currClip = ~0; 377 int currClear = 0; 378 379 for (int i = 0; i < numDraws; ++i) { 380 while (currClear < fClears.count() && 381 i == fClears[currClear].fBeforeDrawIdx) { 382 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor); 383 ++currClear; 384 } 385 386 const Draw& draw = fDraws[i]; 387 if (draw.fStateChanged) { 388 ++currState; 389 target->restoreDrawState(fStates[currState]); 390 } 391 if (draw.fClipChanged) { 392 ++currClip; 393 target->setClip(fClips[currClip]); 394 } 395 396 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer); 397 398 if (draw.fIndexCount) { 399 target->setIndexSourceToBuffer(draw.fIndexBuffer); 400 } 401 402 if (draw.fIndexCount) { 403 target->drawIndexed(draw.fPrimitiveType, 404 draw.fStartVertex, 405 draw.fStartIndex, 406 draw.fVertexCount, 407 draw.fIndexCount); 408 } else { 409 target->drawNonIndexed(draw.fPrimitiveType, 410 draw.fStartVertex, 411 draw.fVertexCount); 412 } 413 } 414 while (currClear < fClears.count()) { 415 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx); 416 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor); 417 ++currClear; 418 } 419 } 420 421 bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout, 422 int* vertexCount, 423 int* indexCount) const { 424 // we will recommend a flush if the data could fit in a single 425 // preallocated buffer but none are left and it can't fit 426 // in the current buffer (which may not be prealloced). 427 bool flush = false; 428 if (NULL != indexCount) { 429 int32_t currIndices = fIndexPool.currentBufferIndices(); 430 if (*indexCount > currIndices && 431 (!fIndexPool.preallocatedBuffersRemaining() && 432 *indexCount <= fIndexPool.preallocatedBufferIndices())) { 433 434 flush = true; 435 } 436 *indexCount = currIndices; 437 } 438 if (NULL != vertexCount) { 439 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout); 440 if (*vertexCount > currVertices && 441 (!fVertexPool.preallocatedBuffersRemaining() && 442 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) { 443 444 flush = true; 445 } 446 *vertexCount = currVertices; 447 } 448 return flush; 449 } 450 451 bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout, 452 int vertexCount, 453 void** vertices) { 454 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 455 GrAssert(vertexCount > 0); 456 GrAssert(NULL != vertices); 457 GrAssert(0 == poolState.fUsedPoolVertexBytes); 458 459 *vertices = fVertexPool.makeSpace(vertexLayout, 460 vertexCount, 461 &poolState.fPoolVertexBuffer, 462 &poolState.fPoolStartVertex); 463 return NULL != *vertices; 464 } 465 466 bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) { 467 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 468 GrAssert(indexCount > 0); 469 GrAssert(NULL != indices); 470 GrAssert(0 == poolState.fUsedPoolIndexBytes); 471 472 *indices = fIndexPool.makeSpace(indexCount, 473 &poolState.fPoolIndexBuffer, 474 &poolState.fPoolStartIndex); 475 return NULL != *indices; 476 } 477 478 void GrInOrderDrawBuffer::releaseReservedVertexSpace() { 479 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 480 const GeometrySrcState& geoSrc = this->getGeomSrc(); 481 482 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc); 483 484 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) * 485 geoSrc.fVertexCount; 486 fVertexPool.putBack(reservedVertexBytes - 487 poolState.fUsedPoolVertexBytes); 488 poolState.fUsedPoolVertexBytes = 0; 489 poolState.fPoolVertexBuffer = 0; 490 } 491 492 void GrInOrderDrawBuffer::releaseReservedIndexSpace() { 493 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 494 const GeometrySrcState& geoSrc = this->getGeomSrc(); 495 496 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc); 497 498 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount; 499 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes); 500 poolState.fUsedPoolIndexBytes = 0; 501 poolState.fPoolStartVertex = 0; 502 } 503 504 void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray, 505 int vertexCount) { 506 507 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 508 GrAssert(0 == poolState.fUsedPoolVertexBytes); 509 #if GR_DEBUG 510 bool success = 511 #endif 512 fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout, 513 vertexCount, 514 vertexArray, 515 &poolState.fPoolVertexBuffer, 516 &poolState.fPoolStartVertex); 517 GR_DEBUGASSERT(success); 518 } 519 520 void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray, 521 int indexCount) { 522 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 523 GrAssert(0 == poolState.fUsedPoolIndexBytes); 524 #if GR_DEBUG 525 bool success = 526 #endif 527 fIndexPool.appendIndices(indexCount, 528 indexArray, 529 &poolState.fPoolIndexBuffer, 530 &poolState.fPoolStartIndex); 531 GR_DEBUGASSERT(success); 532 } 533 534 void GrInOrderDrawBuffer::geometrySourceWillPush() { 535 GeometryPoolState& poolState = fGeoPoolStateStack.push_back(); 536 poolState.fUsedPoolVertexBytes = 0; 537 poolState.fUsedPoolIndexBytes = 0; 538 #if GR_DEBUG 539 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0; 540 poolState.fPoolStartVertex = ~0; 541 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0; 542 poolState.fPoolStartIndex = ~0; 543 #endif 544 } 545 546 void GrInOrderDrawBuffer::releaseVertexArray() { 547 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 548 const GeometrySrcState& geoSrc = this->getGeomSrc(); 549 550 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) * 551 geoSrc.fVertexCount; 552 fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes); 553 554 poolState.fUsedPoolVertexBytes = 0; 555 } 556 557 void GrInOrderDrawBuffer::releaseIndexArray() { 558 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 559 const GeometrySrcState& geoSrc = this->getGeomSrc(); 560 561 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount; 562 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes); 563 564 poolState.fUsedPoolIndexBytes = 0; 565 } 566 567 void GrInOrderDrawBuffer::geometrySourceWillPop( 568 const GeometrySrcState& restoredState) { 569 GrAssert(fGeoPoolStateStack.count() > 1); 570 fGeoPoolStateStack.pop_back(); 571 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 572 // we have to assume that any slack we had in our vertex/index data 573 // is now unreleasable because data may have been appended later in the 574 // pool. 575 if (kReserved_GeometrySrcType == restoredState.fVertexSrc || 576 kArray_GeometrySrcType == restoredState.fVertexSrc) { 577 poolState.fUsedPoolVertexBytes = 578 VertexSize(restoredState.fVertexLayout) * 579 restoredState.fVertexCount; 580 } 581 if (kReserved_GeometrySrcType == restoredState.fIndexSrc || 582 kArray_GeometrySrcType == restoredState.fIndexSrc) { 583 poolState.fUsedPoolVertexBytes = sizeof(uint16_t) * 584 restoredState.fIndexCount; 585 } 586 } 587 588 bool GrInOrderDrawBuffer::needsNewState() const { 589 if (fStates.empty()) { 590 return true; 591 } else { 592 const GrDrawState& old = this->accessSavedDrawState(fStates.back()); 593 return old != fCurrDrawState; 594 } 595 } 596 597 void GrInOrderDrawBuffer::pushState() { 598 const GrDrawState& drawState = this->getDrawState(); 599 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 600 GrSafeRef(drawState.getTexture(s)); 601 } 602 GrSafeRef(drawState.getRenderTarget()); 603 this->saveCurrentDrawState(&fStates.push_back()); 604 } 605 606 bool GrInOrderDrawBuffer::needsNewClip() const { 607 if (this->getDrawState().isClipState()) { 608 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) { 609 return true; 610 } 611 } 612 return false; 613 } 614 615 void GrInOrderDrawBuffer::pushClip() { 616 fClips.push_back() = fClip; 617 fClipSet = false; 618 } 619 620 void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) { 621 INHERITED::clipWillBeSet(newClip); 622 fClipSet = true; 623 } 624