GrInOrderDrawBuffer.cpp revision 1cab2921ab279367f8206cdadc9259d12e603548
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
19GrInOrderDrawBuffer::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
46GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
47    this->reset();
48    // This must be called by before the GrDrawTarget destructor
49    this->releaseGeometry();
50    GrSafeUnref(fQuadIndexBuffer);
51}
52
53void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
54    this->copyDrawState(target);
55    this->setClip(target.getClip());
56}
57
58void 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
72void 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
188void 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.fPoolStartVertex;
250        break;
251    }
252    default:
253        GrCrash("unknown geom src type");
254    }
255    draw.fIndexBuffer->ref();
256}
257
258void 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
308void 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
325void 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
357void 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
421bool 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
451bool 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
466bool 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
478void 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
492void 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
504void 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
520void 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
534void 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
546void 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
557void 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
567void 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
588bool 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
597void 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
606bool 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
615void GrInOrderDrawBuffer::pushClip() {
616    fClips.push_back() = fClip;
617    fClipSet = false;
618}
619
620void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
621    INHERITED::clipWillBeSet(newClip);
622    fClipSet = true;
623}
624