GrDrawTarget.cpp revision c0bd6484f621e4a1033be318b1947a5d32157c13
1
2/*
3 * Copyright 2010 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 "GrDrawTarget.h"
12#include "GrContext.h"
13#include "GrDrawTargetCaps.h"
14#include "GrPath.h"
15#include "GrRenderTarget.h"
16#include "GrSurfacePriv.h"
17#include "GrTemplates.h"
18#include "GrTexture.h"
19#include "GrVertexBuffer.h"
20
21#include "SkStrokeRec.h"
22
23////////////////////////////////////////////////////////////////////////////////
24
25GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) {
26    fPrimitiveType  = di.fPrimitiveType;
27    fStartVertex    = di.fStartVertex;
28    fStartIndex     = di.fStartIndex;
29    fVertexCount    = di.fVertexCount;
30    fIndexCount     = di.fIndexCount;
31
32    fInstanceCount          = di.fInstanceCount;
33    fVerticesPerInstance    = di.fVerticesPerInstance;
34    fIndicesPerInstance     = di.fIndicesPerInstance;
35
36    if (di.fDevBounds) {
37        SkASSERT(di.fDevBounds == &di.fDevBoundsStorage);
38        fDevBoundsStorage = di.fDevBoundsStorage;
39        fDevBounds = &fDevBoundsStorage;
40    } else {
41        fDevBounds = NULL;
42    }
43
44    this->setVertexBuffer(di.vertexBuffer());
45    this->setIndexBuffer(di.indexBuffer());
46
47    return *this;
48}
49
50#ifdef SK_DEBUG
51bool GrDrawTarget::DrawInfo::isInstanced() const {
52    if (fInstanceCount > 0) {
53        SkASSERT(0 == fIndexCount % fIndicesPerInstance);
54        SkASSERT(0 == fVertexCount % fVerticesPerInstance);
55        SkASSERT(fIndexCount / fIndicesPerInstance == fInstanceCount);
56        SkASSERT(fVertexCount / fVerticesPerInstance == fInstanceCount);
57        // there is no way to specify a non-zero start index to drawIndexedInstances().
58        SkASSERT(0 == fStartIndex);
59        return true;
60    } else {
61        SkASSERT(!fVerticesPerInstance);
62        SkASSERT(!fIndicesPerInstance);
63        return false;
64    }
65}
66#endif
67
68void GrDrawTarget::DrawInfo::adjustInstanceCount(int instanceOffset) {
69    SkASSERT(this->isInstanced());
70    SkASSERT(instanceOffset + fInstanceCount >= 0);
71    fInstanceCount += instanceOffset;
72    fVertexCount = fVerticesPerInstance * fInstanceCount;
73    fIndexCount = fIndicesPerInstance * fInstanceCount;
74}
75
76void GrDrawTarget::DrawInfo::adjustStartVertex(int vertexOffset) {
77    fStartVertex += vertexOffset;
78    SkASSERT(fStartVertex >= 0);
79}
80
81void GrDrawTarget::DrawInfo::adjustStartIndex(int indexOffset) {
82    SkASSERT(this->isIndexed());
83    fStartIndex += indexOffset;
84    SkASSERT(fStartIndex >= 0);
85}
86
87////////////////////////////////////////////////////////////////////////////////
88
89#define DEBUG_INVAL_BUFFER 0xdeadcafe
90#define DEBUG_INVAL_START_IDX -1
91
92GrDrawTarget::GrDrawTarget(GrContext* context)
93    : fClip(NULL)
94    , fContext(context)
95    , fGpuTraceMarkerCount(0) {
96    SkASSERT(context);
97    GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
98#ifdef SK_DEBUG
99    geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
100    geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
101    geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
102    geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
103#endif
104    geoSrc.fVertexSrc = kNone_GeometrySrcType;
105    geoSrc.fIndexSrc  = kNone_GeometrySrcType;
106}
107
108GrDrawTarget::~GrDrawTarget() {
109    SkASSERT(1 == fGeoSrcStateStack.count());
110    SkDEBUGCODE(GeometrySrcState& geoSrc = fGeoSrcStateStack.back());
111    SkASSERT(kNone_GeometrySrcType == geoSrc.fIndexSrc);
112    SkASSERT(kNone_GeometrySrcType == geoSrc.fVertexSrc);
113}
114
115void GrDrawTarget::releaseGeometry() {
116    int popCnt = fGeoSrcStateStack.count() - 1;
117    while (popCnt) {
118        this->popGeometrySource();
119        --popCnt;
120    }
121    this->resetVertexSource();
122    this->resetIndexSource();
123}
124
125void GrDrawTarget::setClip(const GrClipData* clip) {
126    fClip = clip;
127}
128
129const GrClipData* GrDrawTarget::getClip() const {
130    return fClip;
131}
132
133bool GrDrawTarget::reserveVertexSpace(size_t vertexSize,
134                                      int vertexCount,
135                                      void** vertices) {
136    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
137    bool acquired = false;
138    if (vertexCount > 0) {
139        SkASSERT(vertices);
140        this->releasePreviousVertexSource();
141        geoSrc.fVertexSrc = kNone_GeometrySrcType;
142
143        acquired = this->onReserveVertexSpace(vertexSize,
144                                              vertexCount,
145                                              vertices);
146    }
147    if (acquired) {
148        geoSrc.fVertexSrc = kReserved_GeometrySrcType;
149        geoSrc.fVertexCount = vertexCount;
150        geoSrc.fVertexSize = vertexSize;
151    } else if (vertices) {
152        *vertices = NULL;
153    }
154    return acquired;
155}
156
157bool GrDrawTarget::reserveIndexSpace(int indexCount,
158                                     void** indices) {
159    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
160    bool acquired = false;
161    if (indexCount > 0) {
162        SkASSERT(indices);
163        this->releasePreviousIndexSource();
164        geoSrc.fIndexSrc = kNone_GeometrySrcType;
165
166        acquired = this->onReserveIndexSpace(indexCount, indices);
167    }
168    if (acquired) {
169        geoSrc.fIndexSrc = kReserved_GeometrySrcType;
170        geoSrc.fIndexCount = indexCount;
171    } else if (indices) {
172        *indices = NULL;
173    }
174    return acquired;
175
176}
177
178bool GrDrawTarget::reserveVertexAndIndexSpace(int vertexCount,
179                                              size_t vertexStride,
180                                              int indexCount,
181                                              void** vertices,
182                                              void** indices) {
183    this->willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount);
184    if (vertexCount) {
185        if (!this->reserveVertexSpace(vertexStride, vertexCount, vertices)) {
186            if (indexCount) {
187                this->resetIndexSource();
188            }
189            return false;
190        }
191    }
192    if (indexCount) {
193        if (!this->reserveIndexSpace(indexCount, indices)) {
194            if (vertexCount) {
195                this->resetVertexSource();
196            }
197            return false;
198        }
199    }
200    return true;
201}
202
203bool GrDrawTarget::geometryHints(size_t vertexStride,
204                                 int32_t* vertexCount,
205                                 int32_t* indexCount) const {
206    if (vertexCount) {
207        *vertexCount = -1;
208    }
209    if (indexCount) {
210        *indexCount = -1;
211    }
212    return false;
213}
214
215void GrDrawTarget::releasePreviousVertexSource() {
216    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
217    switch (geoSrc.fVertexSrc) {
218        case kNone_GeometrySrcType:
219            break;
220        case kReserved_GeometrySrcType:
221            this->releaseReservedVertexSpace();
222            break;
223        case kBuffer_GeometrySrcType:
224            geoSrc.fVertexBuffer->unref();
225#ifdef SK_DEBUG
226            geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
227#endif
228            break;
229        default:
230            SkFAIL("Unknown Vertex Source Type.");
231            break;
232    }
233}
234
235void GrDrawTarget::releasePreviousIndexSource() {
236    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
237    switch (geoSrc.fIndexSrc) {
238        case kNone_GeometrySrcType:   // these two don't require
239            break;
240        case kReserved_GeometrySrcType:
241            this->releaseReservedIndexSpace();
242            break;
243        case kBuffer_GeometrySrcType:
244            geoSrc.fIndexBuffer->unref();
245#ifdef SK_DEBUG
246            geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
247#endif
248            break;
249        default:
250            SkFAIL("Unknown Index Source Type.");
251            break;
252    }
253}
254
255void GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer, size_t vertexStride) {
256    this->releasePreviousVertexSource();
257    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
258    geoSrc.fVertexSrc    = kBuffer_GeometrySrcType;
259    geoSrc.fVertexBuffer = buffer;
260    buffer->ref();
261    geoSrc.fVertexSize = vertexStride;
262}
263
264void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
265    this->releasePreviousIndexSource();
266    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
267    geoSrc.fIndexSrc     = kBuffer_GeometrySrcType;
268    geoSrc.fIndexBuffer  = buffer;
269    buffer->ref();
270}
271
272void GrDrawTarget::resetVertexSource() {
273    this->releasePreviousVertexSource();
274    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
275    geoSrc.fVertexSrc = kNone_GeometrySrcType;
276}
277
278void GrDrawTarget::resetIndexSource() {
279    this->releasePreviousIndexSource();
280    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
281    geoSrc.fIndexSrc = kNone_GeometrySrcType;
282}
283
284void GrDrawTarget::pushGeometrySource() {
285    this->geometrySourceWillPush();
286    GeometrySrcState& newState = fGeoSrcStateStack.push_back();
287    newState.fIndexSrc = kNone_GeometrySrcType;
288    newState.fVertexSrc = kNone_GeometrySrcType;
289#ifdef SK_DEBUG
290    newState.fVertexCount  = ~0;
291    newState.fVertexBuffer = (GrVertexBuffer*)~0;
292    newState.fIndexCount   = ~0;
293    newState.fIndexBuffer = (GrIndexBuffer*)~0;
294#endif
295}
296
297void GrDrawTarget::popGeometrySource() {
298    // if popping last element then pops are unbalanced with pushes
299    SkASSERT(fGeoSrcStateStack.count() > 1);
300
301    this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
302    this->releasePreviousVertexSource();
303    this->releasePreviousIndexSource();
304    fGeoSrcStateStack.pop_back();
305}
306
307////////////////////////////////////////////////////////////////////////////////
308
309bool GrDrawTarget::checkDraw(const GrDrawState& drawState,
310                             GrPrimitiveType type,
311                             int startVertex,
312                             int startIndex,
313                             int vertexCount,
314                             int indexCount) const {
315#ifdef SK_DEBUG
316    const GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
317    int maxVertex = startVertex + vertexCount;
318    int maxValidVertex;
319    switch (geoSrc.fVertexSrc) {
320        case kNone_GeometrySrcType:
321            SkFAIL("Attempting to draw without vertex src.");
322        case kReserved_GeometrySrcType: // fallthrough
323            maxValidVertex = geoSrc.fVertexCount;
324            break;
325        case kBuffer_GeometrySrcType:
326            maxValidVertex = static_cast<int>(geoSrc.fVertexBuffer->gpuMemorySize() / geoSrc.fVertexSize);
327            break;
328    }
329    if (maxVertex > maxValidVertex) {
330        SkFAIL("Drawing outside valid vertex range.");
331    }
332    if (indexCount > 0) {
333        int maxIndex = startIndex + indexCount;
334        int maxValidIndex;
335        switch (geoSrc.fIndexSrc) {
336            case kNone_GeometrySrcType:
337                SkFAIL("Attempting to draw indexed geom without index src.");
338            case kReserved_GeometrySrcType: // fallthrough
339                maxValidIndex = geoSrc.fIndexCount;
340                break;
341            case kBuffer_GeometrySrcType:
342                maxValidIndex = static_cast<int>(geoSrc.fIndexBuffer->gpuMemorySize() / sizeof(uint16_t));
343                break;
344        }
345        if (maxIndex > maxValidIndex) {
346            SkFAIL("Index reads outside valid index range.");
347        }
348    }
349
350    SkASSERT(drawState.getRenderTarget());
351
352    if (drawState.hasGeometryProcessor()) {
353        const GrGeometryProcessor* gp = drawState.getGeometryProcessor();
354        int numTextures = gp->numTextures();
355        for (int t = 0; t < numTextures; ++t) {
356            GrTexture* texture = gp->texture(t);
357            SkASSERT(texture->asRenderTarget() != drawState.getRenderTarget());
358        }
359    }
360
361    for (int s = 0; s < drawState.numColorStages(); ++s) {
362        const GrProcessor* effect = drawState.getColorStage(s).getProcessor();
363        int numTextures = effect->numTextures();
364        for (int t = 0; t < numTextures; ++t) {
365            GrTexture* texture = effect->texture(t);
366            SkASSERT(texture->asRenderTarget() != drawState.getRenderTarget());
367        }
368    }
369    for (int s = 0; s < drawState.numCoverageStages(); ++s) {
370        const GrProcessor* effect = drawState.getCoverageStage(s).getProcessor();
371        int numTextures = effect->numTextures();
372        for (int t = 0; t < numTextures; ++t) {
373            GrTexture* texture = effect->texture(t);
374            SkASSERT(texture->asRenderTarget() != drawState.getRenderTarget());
375        }
376    }
377
378#endif
379    if (NULL == drawState.getRenderTarget()) {
380        return false;
381    }
382    return true;
383}
384
385bool GrDrawTarget::setupDstReadIfNecessary(GrDrawState* ds,
386                                           GrDeviceCoordTexture* dstCopy,
387                                           const SkRect* drawBounds) {
388    if (this->caps()->dstReadInShaderSupport() || !ds->willEffectReadDstColor()) {
389        return true;
390    }
391    SkIRect copyRect;
392    const GrClipData* clip = this->getClip();
393    GrRenderTarget* rt = ds->getRenderTarget();
394    clip->getConservativeBounds(rt, &copyRect);
395
396    if (drawBounds) {
397        SkIRect drawIBounds;
398        drawBounds->roundOut(&drawIBounds);
399        if (!copyRect.intersect(drawIBounds)) {
400#ifdef SK_DEBUG
401            SkDebugf("Missed an early reject. Bailing on draw from setupDstReadIfNecessary.\n");
402#endif
403            return false;
404        }
405    } else {
406#ifdef SK_DEBUG
407        //SkDebugf("No dev bounds when dst copy is made.\n");
408#endif
409    }
410
411    // MSAA consideration: When there is support for reading MSAA samples in the shader we could
412    // have per-sample dst values by making the copy multisampled.
413    GrSurfaceDesc desc;
414    this->initCopySurfaceDstDesc(rt, &desc);
415    desc.fWidth = copyRect.width();
416    desc.fHeight = copyRect.height();
417
418    SkAutoTUnref<GrTexture> copy(
419        fContext->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch));
420
421    if (!copy) {
422        SkDebugf("Failed to create temporary copy of destination texture.\n");
423        return false;
424    }
425    SkIPoint dstPoint = {0, 0};
426    if (this->copySurface(copy, rt, copyRect, dstPoint)) {
427        dstCopy->setTexture(copy);
428        dstCopy->setOffset(copyRect.fLeft, copyRect.fTop);
429        return true;
430    } else {
431        return false;
432    }
433}
434
435void GrDrawTarget::drawIndexed(GrDrawState* ds,
436                               GrPrimitiveType type,
437                               int startVertex,
438                               int startIndex,
439                               int vertexCount,
440                               int indexCount,
441                               const SkRect* devBounds) {
442    SkASSERT(ds);
443    if (indexCount > 0 &&
444        this->checkDraw(*ds, type, startVertex, startIndex, vertexCount, indexCount)) {
445
446        // Setup clip
447        GrClipMaskManager::ScissorState scissorState;
448        GrDrawState::AutoRestoreEffects are;
449        GrDrawState::AutoRestoreStencil ars;
450        if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) {
451            return;
452        }
453
454        DrawInfo info;
455        info.fPrimitiveType = type;
456        info.fStartVertex   = startVertex;
457        info.fStartIndex    = startIndex;
458        info.fVertexCount   = vertexCount;
459        info.fIndexCount    = indexCount;
460
461        info.fInstanceCount         = 0;
462        info.fVerticesPerInstance   = 0;
463        info.fIndicesPerInstance    = 0;
464
465        if (devBounds) {
466            info.setDevBounds(*devBounds);
467        }
468
469        // TODO: We should continue with incorrect blending.
470        GrDeviceCoordTexture dstCopy;
471        if (!this->setupDstReadIfNecessary(ds, &dstCopy, devBounds)) {
472            return;
473        }
474        this->setDrawBuffers(&info, ds->getGeometryProcessor()->getVertexStride());
475
476        this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
477    }
478}
479
480void GrDrawTarget::drawNonIndexed(GrDrawState* ds,
481                                  GrPrimitiveType type,
482                                  int startVertex,
483                                  int vertexCount,
484                                  const SkRect* devBounds) {
485    SkASSERT(ds);
486    if (vertexCount > 0 && this->checkDraw(*ds, type, startVertex, -1, vertexCount, -1)) {
487
488        // Setup clip
489        GrClipMaskManager::ScissorState scissorState;
490        GrDrawState::AutoRestoreEffects are;
491        GrDrawState::AutoRestoreStencil ars;
492        if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) {
493            return;
494        }
495
496        DrawInfo info;
497        info.fPrimitiveType = type;
498        info.fStartVertex   = startVertex;
499        info.fStartIndex    = 0;
500        info.fVertexCount   = vertexCount;
501        info.fIndexCount    = 0;
502
503        info.fInstanceCount         = 0;
504        info.fVerticesPerInstance   = 0;
505        info.fIndicesPerInstance    = 0;
506
507        if (devBounds) {
508            info.setDevBounds(*devBounds);
509        }
510
511        // TODO: We should continue with incorrect blending.
512        GrDeviceCoordTexture dstCopy;
513        if (!this->setupDstReadIfNecessary(ds, &dstCopy, devBounds)) {
514            return;
515        }
516
517        this->setDrawBuffers(&info, ds->getGeometryProcessor()->getVertexStride());
518
519        this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
520    }
521}
522
523static const GrStencilSettings& winding_path_stencil_settings() {
524    GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
525        kIncClamp_StencilOp,
526        kIncClamp_StencilOp,
527        kAlwaysIfInClip_StencilFunc,
528        0xFFFF, 0xFFFF, 0xFFFF);
529    return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
530}
531
532static const GrStencilSettings& even_odd_path_stencil_settings() {
533    GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
534        kInvert_StencilOp,
535        kInvert_StencilOp,
536        kAlwaysIfInClip_StencilFunc,
537        0xFFFF, 0xFFFF, 0xFFFF);
538    return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
539}
540
541void GrDrawTarget::getPathStencilSettingsForFilltype(GrPathRendering::FillType fill,
542                                                     const GrStencilBuffer* sb,
543                                                     GrStencilSettings* outStencilSettings) {
544
545    switch (fill) {
546        default:
547            SkFAIL("Unexpected path fill.");
548        case GrPathRendering::kWinding_FillType:
549            *outStencilSettings = winding_path_stencil_settings();
550            break;
551        case GrPathRendering::kEvenOdd_FillType:
552            *outStencilSettings = even_odd_path_stencil_settings();
553            break;
554    }
555    this->clipMaskManager()->adjustPathStencilParams(sb, outStencilSettings);
556}
557
558void GrDrawTarget::stencilPath(GrDrawState* ds,
559                               const GrPath* path,
560                               GrPathRendering::FillType fill) {
561    // TODO: extract portions of checkDraw that are relevant to path stenciling.
562    SkASSERT(path);
563    SkASSERT(this->caps()->pathRenderingSupport());
564    SkASSERT(ds);
565
566    // Setup clip
567    GrClipMaskManager::ScissorState scissorState;
568    GrDrawState::AutoRestoreEffects are;
569    GrDrawState::AutoRestoreStencil ars;
570    if (!this->setupClip(NULL, &are, &ars, ds, &scissorState)) {
571        return;
572    }
573
574    // set stencil settings for path
575    GrStencilSettings stencilSettings;
576    this->getPathStencilSettingsForFilltype(fill,
577                                            ds->getRenderTarget()->getStencilBuffer(),
578                                            &stencilSettings);
579
580    this->onStencilPath(*ds, path, scissorState, stencilSettings);
581}
582
583void GrDrawTarget::drawPath(GrDrawState* ds,
584                            const GrPath* path,
585                            GrPathRendering::FillType fill) {
586    // TODO: extract portions of checkDraw that are relevant to path rendering.
587    SkASSERT(path);
588    SkASSERT(this->caps()->pathRenderingSupport());
589    SkASSERT(ds);
590
591    SkRect devBounds = path->getBounds();
592    SkMatrix viewM = ds->getViewMatrix();
593    viewM.mapRect(&devBounds);
594
595    // Setup clip
596    GrClipMaskManager::ScissorState scissorState;
597    GrDrawState::AutoRestoreEffects are;
598    GrDrawState::AutoRestoreStencil ars;
599    if (!this->setupClip(&devBounds, &are, &ars, ds, &scissorState)) {
600       return;
601    }
602
603    // set stencil settings for path
604    GrStencilSettings stencilSettings;
605    this->getPathStencilSettingsForFilltype(fill,
606                                            ds->getRenderTarget()->getStencilBuffer(),
607                                            &stencilSettings);
608
609    GrDeviceCoordTexture dstCopy;
610    if (!this->setupDstReadIfNecessary(ds, &dstCopy, &devBounds)) {
611        return;
612    }
613
614    this->onDrawPath(*ds, path, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
615}
616
617void GrDrawTarget::drawPaths(GrDrawState* ds,
618                             const GrPathRange* pathRange,
619                             const void* indices,
620                             PathIndexType indexType,
621                             const float transformValues[],
622                             PathTransformType transformType,
623                             int count,
624                             GrPathRendering::FillType fill) {
625    SkASSERT(this->caps()->pathRenderingSupport());
626    SkASSERT(pathRange);
627    SkASSERT(indices);
628    SkASSERT(0 == reinterpret_cast<long>(indices) % GrPathRange::PathIndexSizeInBytes(indexType));
629    SkASSERT(transformValues);
630    SkASSERT(ds);
631
632    // Setup clip
633    GrClipMaskManager::ScissorState scissorState;
634    GrDrawState::AutoRestoreEffects are;
635    GrDrawState::AutoRestoreStencil ars;
636
637    if (!this->setupClip(NULL, &are, &ars, ds, &scissorState)) {
638        return;
639    }
640
641    // set stencil settings for path
642    GrStencilSettings stencilSettings;
643    this->getPathStencilSettingsForFilltype(fill,
644                                            ds->getRenderTarget()->getStencilBuffer(),
645                                            &stencilSettings);
646
647    // Don't compute a bounding box for setupDstReadIfNecessary(), we'll opt
648    // instead for it to just copy the entire dst. Realistically this is a moot
649    // point, because any context that supports NV_path_rendering will also
650    // support NV_blend_equation_advanced.
651    GrDeviceCoordTexture dstCopy;
652    if (!this->setupDstReadIfNecessary(ds, &dstCopy, NULL)) {
653        return;
654    }
655
656    this->onDrawPaths(*ds, pathRange, indices, indexType, transformValues, transformType, count,
657                      scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
658}
659
660void GrDrawTarget::clear(const SkIRect* rect,
661                         GrColor color,
662                         bool canIgnoreRect,
663                         GrRenderTarget* renderTarget) {
664    if (fCaps->useDrawInsteadOfClear()) {
665        // This works around a driver bug with clear by drawing a rect instead.
666        // The driver will ignore a clear if it is the only thing rendered to a
667        // target before the target is read.
668        SkIRect rtRect = SkIRect::MakeWH(renderTarget->width(), renderTarget->height());
669        if (NULL == rect || canIgnoreRect || rect->contains(rtRect)) {
670            rect = &rtRect;
671            // We first issue a discard() since that may help tilers.
672            this->discard(renderTarget);
673        }
674
675        GrDrawState drawState;
676
677        drawState.setColor(color);
678        drawState.setRenderTarget(renderTarget);
679
680        this->drawSimpleRect(&drawState, *rect);
681    } else {
682        this->onClear(rect, color, canIgnoreRect, renderTarget);
683    }
684}
685
686typedef GrTraceMarkerSet::Iter TMIter;
687void GrDrawTarget::saveActiveTraceMarkers() {
688    if (this->caps()->gpuTracingSupport()) {
689        SkASSERT(0 == fStoredTraceMarkers.count());
690        fStoredTraceMarkers.addSet(fActiveTraceMarkers);
691        for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
692            this->removeGpuTraceMarker(&(*iter));
693        }
694    }
695}
696
697void GrDrawTarget::restoreActiveTraceMarkers() {
698    if (this->caps()->gpuTracingSupport()) {
699        SkASSERT(0 == fActiveTraceMarkers.count());
700        for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
701            this->addGpuTraceMarker(&(*iter));
702        }
703        for (TMIter iter = fActiveTraceMarkers.begin(); iter != fActiveTraceMarkers.end(); ++iter) {
704            this->fStoredTraceMarkers.remove(*iter);
705        }
706    }
707}
708
709void GrDrawTarget::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
710    if (this->caps()->gpuTracingSupport()) {
711        SkASSERT(fGpuTraceMarkerCount >= 0);
712        this->fActiveTraceMarkers.add(*marker);
713        ++fGpuTraceMarkerCount;
714    }
715}
716
717void GrDrawTarget::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
718    if (this->caps()->gpuTracingSupport()) {
719        SkASSERT(fGpuTraceMarkerCount >= 1);
720        this->fActiveTraceMarkers.remove(*marker);
721        --fGpuTraceMarkerCount;
722    }
723}
724
725////////////////////////////////////////////////////////////////////////////////
726
727void GrDrawTarget::drawIndexedInstances(GrDrawState* ds,
728                                        GrPrimitiveType type,
729                                        int instanceCount,
730                                        int verticesPerInstance,
731                                        int indicesPerInstance,
732                                        const SkRect* devBounds) {
733    SkASSERT(ds);
734
735    if (!verticesPerInstance || !indicesPerInstance) {
736        return;
737    }
738
739    int maxInstancesPerDraw = this->indexCountInCurrentSource() / indicesPerInstance;
740    if (!maxInstancesPerDraw) {
741        return;
742    }
743
744    // Setup clip
745    GrClipMaskManager::ScissorState scissorState;
746    GrDrawState::AutoRestoreEffects are;
747    GrDrawState::AutoRestoreStencil ars;
748    if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) {
749        return;
750    }
751
752    DrawInfo info;
753    info.fPrimitiveType = type;
754    info.fStartIndex = 0;
755    info.fStartVertex = 0;
756    info.fIndicesPerInstance = indicesPerInstance;
757    info.fVerticesPerInstance = verticesPerInstance;
758
759    // Set the same bounds for all the draws.
760    if (devBounds) {
761        info.setDevBounds(*devBounds);
762    }
763
764    // TODO: We should continue with incorrect blending.
765    GrDeviceCoordTexture dstCopy;
766    if (!this->setupDstReadIfNecessary(ds, &dstCopy, devBounds)) {
767        return;
768    }
769
770    while (instanceCount) {
771        info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw);
772        info.fVertexCount = info.fInstanceCount * verticesPerInstance;
773        info.fIndexCount = info.fInstanceCount * indicesPerInstance;
774
775        if (this->checkDraw(*ds,
776                            type,
777                            info.fStartVertex,
778                            info.fStartIndex,
779                            info.fVertexCount,
780                            info.fIndexCount)) {
781            this->setDrawBuffers(&info, ds->getGeometryProcessor()->getVertexStride());
782            this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
783        }
784        info.fStartVertex += info.fVertexCount;
785        instanceCount -= info.fInstanceCount;
786    }
787}
788
789////////////////////////////////////////////////////////////////////////////////
790
791GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
792                                         GrDrawTarget*  target,
793                                         int vertexCount,
794                                         size_t vertexStride,
795                                         int indexCount) {
796    fTarget = NULL;
797    this->set(target, vertexCount, vertexStride, indexCount);
798}
799
800GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
801    fTarget = NULL;
802}
803
804GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
805    this->reset();
806}
807
808bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget*  target,
809                                            int vertexCount,
810                                            size_t vertexStride,
811                                            int indexCount) {
812    this->reset();
813    fTarget = target;
814    bool success = true;
815    if (fTarget) {
816        success = target->reserveVertexAndIndexSpace(vertexCount,
817                                                     vertexStride,
818                                                     indexCount,
819                                                     &fVertices,
820                                                     &fIndices);
821        if (!success) {
822            fTarget = NULL;
823            this->reset();
824        }
825    }
826    SkASSERT(success == SkToBool(fTarget));
827    return success;
828}
829
830void GrDrawTarget::AutoReleaseGeometry::reset() {
831    if (fTarget) {
832        if (fVertices) {
833            fTarget->resetVertexSource();
834        }
835        if (fIndices) {
836            fTarget->resetIndexSource();
837        }
838        fTarget = NULL;
839    }
840    fVertices = NULL;
841    fIndices = NULL;
842}
843
844GrDrawTarget::AutoClipRestore::AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip) {
845    fTarget = target;
846    fClip = fTarget->getClip();
847    fStack.init();
848    fStack.get()->clipDevRect(newClip, SkRegion::kReplace_Op);
849    fReplacementClip.fClipStack = fStack.get();
850    target->setClip(&fReplacementClip);
851}
852
853namespace {
854// returns true if the read/written rect intersects the src/dst and false if not.
855bool clip_srcrect_and_dstpoint(const GrSurface* dst,
856                               const GrSurface* src,
857                               const SkIRect& srcRect,
858                               const SkIPoint& dstPoint,
859                               SkIRect* clippedSrcRect,
860                               SkIPoint* clippedDstPoint) {
861    *clippedSrcRect = srcRect;
862    *clippedDstPoint = dstPoint;
863
864    // clip the left edge to src and dst bounds, adjusting dstPoint if necessary
865    if (clippedSrcRect->fLeft < 0) {
866        clippedDstPoint->fX -= clippedSrcRect->fLeft;
867        clippedSrcRect->fLeft = 0;
868    }
869    if (clippedDstPoint->fX < 0) {
870        clippedSrcRect->fLeft -= clippedDstPoint->fX;
871        clippedDstPoint->fX = 0;
872    }
873
874    // clip the top edge to src and dst bounds, adjusting dstPoint if necessary
875    if (clippedSrcRect->fTop < 0) {
876        clippedDstPoint->fY -= clippedSrcRect->fTop;
877        clippedSrcRect->fTop = 0;
878    }
879    if (clippedDstPoint->fY < 0) {
880        clippedSrcRect->fTop -= clippedDstPoint->fY;
881        clippedDstPoint->fY = 0;
882    }
883
884    // clip the right edge to the src and dst bounds.
885    if (clippedSrcRect->fRight > src->width()) {
886        clippedSrcRect->fRight = src->width();
887    }
888    if (clippedDstPoint->fX + clippedSrcRect->width() > dst->width()) {
889        clippedSrcRect->fRight = clippedSrcRect->fLeft + dst->width() - clippedDstPoint->fX;
890    }
891
892    // clip the bottom edge to the src and dst bounds.
893    if (clippedSrcRect->fBottom > src->height()) {
894        clippedSrcRect->fBottom = src->height();
895    }
896    if (clippedDstPoint->fY + clippedSrcRect->height() > dst->height()) {
897        clippedSrcRect->fBottom = clippedSrcRect->fTop + dst->height() - clippedDstPoint->fY;
898    }
899
900    // The above clipping steps may have inverted the rect if it didn't intersect either the src or
901    // dst bounds.
902    return !clippedSrcRect->isEmpty();
903}
904}
905
906bool GrDrawTarget::copySurface(GrSurface* dst,
907                               GrSurface* src,
908                               const SkIRect& srcRect,
909                               const SkIPoint& dstPoint) {
910    SkASSERT(dst);
911    SkASSERT(src);
912
913    SkIRect clippedSrcRect;
914    SkIPoint clippedDstPoint;
915    // If the rect is outside the src or dst then we've already succeeded.
916    if (!clip_srcrect_and_dstpoint(dst,
917                                   src,
918                                   srcRect,
919                                   dstPoint,
920                                   &clippedSrcRect,
921                                   &clippedDstPoint)) {
922        return true;
923    }
924
925    if (this->onCopySurface(dst, src, clippedSrcRect, clippedDstPoint)) {
926        return true;
927    }
928
929    GrRenderTarget* rt = dst->asRenderTarget();
930    GrTexture* tex = src->asTexture();
931
932    if ((dst == src) || !rt || !tex) {
933        return false;
934    }
935
936    GrDrawState drawState;
937    drawState.setRenderTarget(rt);
938    SkMatrix matrix;
939    matrix.setTranslate(SkIntToScalar(clippedSrcRect.fLeft - clippedDstPoint.fX),
940                        SkIntToScalar(clippedSrcRect.fTop - clippedDstPoint.fY));
941    matrix.postIDiv(tex->width(), tex->height());
942    drawState.addColorTextureProcessor(tex, matrix);
943    SkIRect dstRect = SkIRect::MakeXYWH(clippedDstPoint.fX,
944                                        clippedDstPoint.fY,
945                                        clippedSrcRect.width(),
946                                        clippedSrcRect.height());
947    this->drawSimpleRect(&drawState, dstRect);
948    return true;
949}
950
951bool GrDrawTarget::canCopySurface(const GrSurface* dst,
952                                  const GrSurface* src,
953                                  const SkIRect& srcRect,
954                                  const SkIPoint& dstPoint) {
955    SkASSERT(dst);
956    SkASSERT(src);
957
958    SkIRect clippedSrcRect;
959    SkIPoint clippedDstPoint;
960    // If the rect is outside the src or dst then we're guaranteed success
961    if (!clip_srcrect_and_dstpoint(dst,
962                                   src,
963                                   srcRect,
964                                   dstPoint,
965                                   &clippedSrcRect,
966                                   &clippedDstPoint)) {
967        return true;
968    }
969    return this->internalCanCopySurface(dst, src, clippedSrcRect, clippedDstPoint);
970}
971
972bool GrDrawTarget::internalCanCopySurface(const GrSurface* dst,
973                                          const GrSurface* src,
974                                          const SkIRect& clippedSrcRect,
975                                          const SkIPoint& clippedDstPoint) {
976    // Check that the read/write rects are contained within the src/dst bounds.
977    SkASSERT(!clippedSrcRect.isEmpty());
978    SkASSERT(SkIRect::MakeWH(src->width(), src->height()).contains(clippedSrcRect));
979    SkASSERT(clippedDstPoint.fX >= 0 && clippedDstPoint.fY >= 0);
980    SkASSERT(clippedDstPoint.fX + clippedSrcRect.width() <= dst->width() &&
981             clippedDstPoint.fY + clippedSrcRect.height() <= dst->height());
982
983    // The base class can do it as a draw or the subclass may be able to handle it.
984    return ((dst != src) && dst->asRenderTarget() && src->asTexture()) ||
985           this->onCanCopySurface(dst, src, clippedSrcRect, clippedDstPoint);
986}
987
988///////////////////////////////////////////////////////////////////////////////
989
990void GrDrawTargetCaps::reset() {
991    fMipMapSupport = false;
992    fNPOTTextureTileSupport = false;
993    fTwoSidedStencilSupport = false;
994    fStencilWrapOpsSupport = false;
995    fHWAALineSupport = false;
996    fShaderDerivativeSupport = false;
997    fGeometryShaderSupport = false;
998    fDualSourceBlendingSupport = false;
999    fPathRenderingSupport = false;
1000    fDstReadInShaderSupport = false;
1001    fDiscardRenderTargetSupport = false;
1002    fReuseScratchTextures = true;
1003    fGpuTracingSupport = false;
1004    fCompressedTexSubImageSupport = false;
1005
1006    fUseDrawInsteadOfClear = false;
1007
1008    fMapBufferFlags = kNone_MapFlags;
1009
1010    fMaxRenderTargetSize = 0;
1011    fMaxTextureSize = 0;
1012    fMaxSampleCount = 0;
1013
1014    fShaderPrecisionVaries = false;
1015
1016    memset(fConfigRenderSupport, 0, sizeof(fConfigRenderSupport));
1017    memset(fConfigTextureSupport, 0, sizeof(fConfigTextureSupport));
1018}
1019
1020GrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) {
1021    fMipMapSupport = other.fMipMapSupport;
1022    fNPOTTextureTileSupport = other.fNPOTTextureTileSupport;
1023    fTwoSidedStencilSupport = other.fTwoSidedStencilSupport;
1024    fStencilWrapOpsSupport = other.fStencilWrapOpsSupport;
1025    fHWAALineSupport = other.fHWAALineSupport;
1026    fShaderDerivativeSupport = other.fShaderDerivativeSupport;
1027    fGeometryShaderSupport = other.fGeometryShaderSupport;
1028    fDualSourceBlendingSupport = other.fDualSourceBlendingSupport;
1029    fPathRenderingSupport = other.fPathRenderingSupport;
1030    fDstReadInShaderSupport = other.fDstReadInShaderSupport;
1031    fDiscardRenderTargetSupport = other.fDiscardRenderTargetSupport;
1032    fReuseScratchTextures = other.fReuseScratchTextures;
1033    fGpuTracingSupport = other.fGpuTracingSupport;
1034    fCompressedTexSubImageSupport = other.fCompressedTexSubImageSupport;
1035
1036    fUseDrawInsteadOfClear = other.fUseDrawInsteadOfClear;
1037
1038    fMapBufferFlags = other.fMapBufferFlags;
1039
1040    fMaxRenderTargetSize = other.fMaxRenderTargetSize;
1041    fMaxTextureSize = other.fMaxTextureSize;
1042    fMaxSampleCount = other.fMaxSampleCount;
1043
1044    memcpy(fConfigRenderSupport, other.fConfigRenderSupport, sizeof(fConfigRenderSupport));
1045    memcpy(fConfigTextureSupport, other.fConfigTextureSupport, sizeof(fConfigTextureSupport));
1046
1047    fShaderPrecisionVaries = other.fShaderPrecisionVaries;
1048    for (int s = 0; s < kGrShaderTypeCount; ++s) {
1049        for (int p = 0; p < kGrSLPrecisionCount; ++p) {
1050            fFloatPrecisions[s][p] = other.fFloatPrecisions[s][p];
1051        }
1052    }
1053    return *this;
1054}
1055
1056static SkString map_flags_to_string(uint32_t flags) {
1057    SkString str;
1058    if (GrDrawTargetCaps::kNone_MapFlags == flags) {
1059        str = "none";
1060    } else {
1061        SkASSERT(GrDrawTargetCaps::kCanMap_MapFlag & flags);
1062        SkDEBUGCODE(flags &= ~GrDrawTargetCaps::kCanMap_MapFlag);
1063        str = "can_map";
1064
1065        if (GrDrawTargetCaps::kSubset_MapFlag & flags) {
1066            str.append(" partial");
1067        } else {
1068            str.append(" full");
1069        }
1070        SkDEBUGCODE(flags &= ~GrDrawTargetCaps::kSubset_MapFlag);
1071    }
1072    SkASSERT(0 == flags); // Make sure we handled all the flags.
1073    return str;
1074}
1075
1076static const char* shader_type_to_string(GrShaderType type) {
1077    switch (type) {
1078        case kVertex_GrShaderType:
1079            return "vertex";
1080        case kGeometry_GrShaderType:
1081            return "geometry";
1082        case kFragment_GrShaderType:
1083            return "fragment";
1084    }
1085    return "";
1086}
1087
1088static const char* precision_to_string(GrSLPrecision p) {
1089    switch (p) {
1090        case kLow_GrSLPrecision:
1091            return "low";
1092        case kMedium_GrSLPrecision:
1093            return "medium";
1094        case kHigh_GrSLPrecision:
1095            return "high";
1096    }
1097    return "";
1098}
1099
1100SkString GrDrawTargetCaps::dump() const {
1101    SkString r;
1102    static const char* gNY[] = {"NO", "YES"};
1103    r.appendf("MIP Map Support                    : %s\n", gNY[fMipMapSupport]);
1104    r.appendf("NPOT Texture Tile Support          : %s\n", gNY[fNPOTTextureTileSupport]);
1105    r.appendf("Two Sided Stencil Support          : %s\n", gNY[fTwoSidedStencilSupport]);
1106    r.appendf("Stencil Wrap Ops  Support          : %s\n", gNY[fStencilWrapOpsSupport]);
1107    r.appendf("HW AA Lines Support                : %s\n", gNY[fHWAALineSupport]);
1108    r.appendf("Shader Derivative Support          : %s\n", gNY[fShaderDerivativeSupport]);
1109    r.appendf("Geometry Shader Support            : %s\n", gNY[fGeometryShaderSupport]);
1110    r.appendf("Dual Source Blending Support       : %s\n", gNY[fDualSourceBlendingSupport]);
1111    r.appendf("Path Rendering Support             : %s\n", gNY[fPathRenderingSupport]);
1112    r.appendf("Dst Read In Shader Support         : %s\n", gNY[fDstReadInShaderSupport]);
1113    r.appendf("Discard Render Target Support      : %s\n", gNY[fDiscardRenderTargetSupport]);
1114    r.appendf("Reuse Scratch Textures             : %s\n", gNY[fReuseScratchTextures]);
1115    r.appendf("Gpu Tracing Support                : %s\n", gNY[fGpuTracingSupport]);
1116    r.appendf("Compressed Update Support          : %s\n", gNY[fCompressedTexSubImageSupport]);
1117
1118    r.appendf("Draw Instead of Clear [workaround] : %s\n", gNY[fUseDrawInsteadOfClear]);
1119
1120    r.appendf("Max Texture Size                   : %d\n", fMaxTextureSize);
1121    r.appendf("Max Render Target Size             : %d\n", fMaxRenderTargetSize);
1122    r.appendf("Max Sample Count                   : %d\n", fMaxSampleCount);
1123
1124    r.appendf("Map Buffer Support                 : %s\n",
1125              map_flags_to_string(fMapBufferFlags).c_str());
1126
1127    static const char* kConfigNames[] = {
1128        "Unknown",  // kUnknown_GrPixelConfig
1129        "Alpha8",   // kAlpha_8_GrPixelConfig,
1130        "Index8",   // kIndex_8_GrPixelConfig,
1131        "RGB565",   // kRGB_565_GrPixelConfig,
1132        "RGBA444",  // kRGBA_4444_GrPixelConfig,
1133        "RGBA8888", // kRGBA_8888_GrPixelConfig,
1134        "BGRA8888", // kBGRA_8888_GrPixelConfig,
1135        "ETC1",     // kETC1_GrPixelConfig,
1136        "LATC",     // kLATC_GrPixelConfig,
1137        "R11EAC",   // kR11_EAC_GrPixelConfig,
1138        "ASTC12x12",// kASTC_12x12_GrPixelConfig,
1139        "RGBAFloat",// kRGBA_float_GrPixelConfig
1140        "AlphaHalf",// kAlpha_half_GrPixelConfig
1141    };
1142    GR_STATIC_ASSERT(0  == kUnknown_GrPixelConfig);
1143    GR_STATIC_ASSERT(1  == kAlpha_8_GrPixelConfig);
1144    GR_STATIC_ASSERT(2  == kIndex_8_GrPixelConfig);
1145    GR_STATIC_ASSERT(3  == kRGB_565_GrPixelConfig);
1146    GR_STATIC_ASSERT(4  == kRGBA_4444_GrPixelConfig);
1147    GR_STATIC_ASSERT(5  == kRGBA_8888_GrPixelConfig);
1148    GR_STATIC_ASSERT(6  == kBGRA_8888_GrPixelConfig);
1149    GR_STATIC_ASSERT(7  == kETC1_GrPixelConfig);
1150    GR_STATIC_ASSERT(8  == kLATC_GrPixelConfig);
1151    GR_STATIC_ASSERT(9  == kR11_EAC_GrPixelConfig);
1152    GR_STATIC_ASSERT(10 == kASTC_12x12_GrPixelConfig);
1153    GR_STATIC_ASSERT(11 == kRGBA_float_GrPixelConfig);
1154    GR_STATIC_ASSERT(12 == kAlpha_half_GrPixelConfig);
1155    GR_STATIC_ASSERT(SK_ARRAY_COUNT(kConfigNames) == kGrPixelConfigCnt);
1156
1157    SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][0]);
1158    SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][1]);
1159
1160    for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i)  {
1161        r.appendf("%s is renderable: %s, with MSAA: %s\n",
1162                  kConfigNames[i],
1163                  gNY[fConfigRenderSupport[i][0]],
1164                  gNY[fConfigRenderSupport[i][1]]);
1165    }
1166
1167    SkASSERT(!fConfigTextureSupport[kUnknown_GrPixelConfig]);
1168
1169    for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i)  {
1170        r.appendf("%s is uploadable to a texture: %s\n",
1171                  kConfigNames[i],
1172                  gNY[fConfigTextureSupport[i]]);
1173    }
1174
1175    r.appendf("Shader Float Precisions (varies: %s):\n", gNY[fShaderPrecisionVaries]);
1176
1177    for (int s = 0; s < kGrShaderTypeCount; ++s) {
1178        GrShaderType shaderType = static_cast<GrShaderType>(s);
1179        r.appendf("\t%s:\n", shader_type_to_string(shaderType));
1180        for (int p = 0; p < kGrSLPrecisionCount; ++p) {
1181            if (fFloatPrecisions[s][p].supported()) {
1182                GrSLPrecision precision = static_cast<GrSLPrecision>(p);
1183                r.appendf("\t\t%s: log_low: %d log_high: %d bits: %d\n",
1184                          precision_to_string(precision),
1185                          fFloatPrecisions[s][p].fLogRangeLow,
1186                          fFloatPrecisions[s][p].fLogRangeHigh,
1187                          fFloatPrecisions[s][p].fBits);
1188            }
1189        }
1190    }
1191
1192    return r;
1193}
1194
1195uint32_t GrDrawTargetCaps::CreateUniqueID() {
1196    static int32_t gUniqueID = SK_InvalidUniqueID;
1197    uint32_t id;
1198    do {
1199        id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
1200    } while (id == SK_InvalidUniqueID);
1201    return id;
1202}
1203
1204///////////////////////////////////////////////////////////////////////////////////////////////////
1205
1206bool GrClipTarget::setupClip(const SkRect* devBounds,
1207                             GrDrawState::AutoRestoreEffects* are,
1208                             GrDrawState::AutoRestoreStencil* ars,
1209                             GrDrawState* ds,
1210                             GrClipMaskManager::ScissorState* scissorState) {
1211    return fClipMaskManager.setupClipping(ds,
1212                                          are,
1213                                          ars,
1214                                          scissorState,
1215                                          this->getClip(),
1216                                          devBounds);
1217}
1218