
/*
 * Copyright 2010 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */



#include "GrDrawTarget.h"
#include "GrGpuVertex.h"
#include "GrIndexBuffer.h"
#include "GrRenderTarget.h"
#include "GrTexture.h"
#include "GrVertexBuffer.h"

namespace {

/**
 * This function generates some masks that we like to have known at compile
 * time. When the number of stages or tex coords is bumped or the way bits
 * are defined in GrDrawTarget.h changes this funcion should be rerun to
 * generate the new masks. (We attempted to force the compiler to generate the
 * masks using recursive templates but always wound up with static initializers
 * under gcc, even if they were just a series of immediate->memory moves.)
 * 
 */
void gen_mask_arrays(GrVertexLayout* stageTexCoordMasks,
                     GrVertexLayout* stageMasks,
                     GrVertexLayout* texCoordMasks) {
    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
        stageTexCoordMasks[s] = 0;
        for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
            stageTexCoordMasks[s] |= GrDrawTarget::StageTexCoordVertexLayoutBit(s, t);
        }
        stageMasks[s] = stageTexCoordMasks[s] | GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s);
    }
    for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
        texCoordMasks[t] = 0;
        for (int s = 0; s < GrDrawState::kNumStages; ++s) {
            texCoordMasks[t] |= GrDrawTarget::StageTexCoordVertexLayoutBit(s, t);
        }
    }
}

/** 
 * Run this function to generate the code that declares the global masks.
 */
void gen_globals() {
    GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages];
    GrVertexLayout stageMasks[GrDrawState::kNumStages];
    GrVertexLayout texCoordMasks[GrDrawState::kMaxTexCoords];
    gen_mask_arrays(stageTexCoordMasks, stageMasks, texCoordMasks);
    
    GrPrintf("const GrVertexLayout gStageTexCoordMasks[] = {\n");
    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
        GrPrintf("    0x%x,\n", stageTexCoordMasks[s]);
    }
    GrPrintf("};\n");
    GrPrintf("GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks));\n\n");
    GrPrintf("const GrVertexLayout gStageMasks[] = {\n");
    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
        GrPrintf("    0x%x,\n", stageMasks[s]);
    }
    GrPrintf("};\n");
    GrPrintf("GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageMasks));\n\n");
    GrPrintf("const GrVertexLayout gTexCoordMasks[] = {\n");
    for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
        GrPrintf("    0x%x,\n", texCoordMasks[t]);
    }
    GrPrintf("};\n");
    GrPrintf("GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks));\n");
}

/* These values were generated by the above function */
const GrVertexLayout gStageTexCoordMasks[] = {
    0x49,
    0x92,
    0x124
};

GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks));
const GrVertexLayout gStageMasks[] = {
    0x249,
    0x492,
    0x924
};

GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageMasks));
const GrVertexLayout gTexCoordMasks[] = {
    0x7,
    0x38,
    0x1c0,
};
GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks));

bool check_layout(GrVertexLayout layout) {
    // can only have 1 or 0 bits set for each stage.
    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
        int stageBits = layout & gStageMasks[s];
        if (stageBits && !GrIsPow2(stageBits)) {
            return false;
        }
    }
    return true;
}

int num_tex_coords(GrVertexLayout layout) {
    int cnt = 0;
    // figure out how many tex coordinates are present
    for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
        if (gTexCoordMasks[t] & layout) {
            ++cnt;
        }
    }
    return cnt;
}

} //unnamed namespace

size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
    GrAssert(check_layout(vertexLayout));

    size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
                        sizeof(GrGpuTextVertex) :
                        sizeof(GrPoint);

    size_t size = vecSize; // position
    size += num_tex_coords(vertexLayout) * vecSize;
    if (vertexLayout & kColor_VertexLayoutBit) {
        size += sizeof(GrColor);
    }
    if (vertexLayout & kCoverage_VertexLayoutBit) {
        size += sizeof(GrColor);
    }
    if (vertexLayout & kEdge_VertexLayoutBit) {
        size += 4 * sizeof(GrScalar);
    }
    return size;
}

////////////////////////////////////////////////////////////////////////////////

/**
 * Functions for computing offsets of various components from the layout
 * bitfield.
 * 
 * Order of vertex components:
 * Position
 * Tex Coord 0
 * ...
 * Tex Coord GrDrawState::kMaxTexCoords-1
 * Color
 * Coverage
 */

int GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) {
    GrAssert(check_layout(vertexLayout));
    if (StagePosAsTexCoordVertexLayoutBit(stage) & vertexLayout) {
        return 0;
    }
    int tcIdx = VertexTexCoordsForStage(stage, vertexLayout);
    if (tcIdx >= 0) {

        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
                                    sizeof(GrGpuTextVertex) :
                                    sizeof(GrPoint);
        int offset = vecSize; // position
        // figure out how many tex coordinates are present and precede this one.
        for (int t = 0; t < tcIdx; ++t) {
            if (gTexCoordMasks[t] & vertexLayout) {
                offset += vecSize;
            }
        }
        return offset;
    }

    return -1;
}

int GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) {
    GrAssert(check_layout(vertexLayout));

    if (vertexLayout & kColor_VertexLayoutBit) {
        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
                                    sizeof(GrGpuTextVertex) :
                                    sizeof(GrPoint);
        return vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos
    }
    return -1;
}

int GrDrawTarget::VertexCoverageOffset(GrVertexLayout vertexLayout) {
    GrAssert(check_layout(vertexLayout));

    if (vertexLayout & kCoverage_VertexLayoutBit) {
        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
                                    sizeof(GrGpuTextVertex) :
                                    sizeof(GrPoint);

        int offset = vecSize * (num_tex_coords(vertexLayout) + 1);
        if (vertexLayout & kColor_VertexLayoutBit) {
            offset += sizeof(GrColor);
        }
        return offset;
    }
    return -1;
}

int GrDrawTarget::VertexEdgeOffset(GrVertexLayout vertexLayout) {
    GrAssert(check_layout(vertexLayout));

    // edge pts are after the pos, tex coords, and color
    if (vertexLayout & kEdge_VertexLayoutBit) {
        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
                                    sizeof(GrGpuTextVertex) :
                                    sizeof(GrPoint);
        int offset = vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos
        if (vertexLayout & kColor_VertexLayoutBit) {
            offset += sizeof(GrColor);
        }
        if (vertexLayout & kCoverage_VertexLayoutBit) {
            offset += sizeof(GrColor);
        }
        return offset;
    }
    return -1;
}

int GrDrawTarget::VertexSizeAndOffsetsByIdx(
        GrVertexLayout vertexLayout,
        int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords],
        int* colorOffset,
        int* coverageOffset,
        int* edgeOffset) {
    GrAssert(check_layout(vertexLayout));

    int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
                                                    sizeof(GrGpuTextVertex) :
                                                    sizeof(GrPoint);
    int size = vecSize; // position

    for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
        if (gTexCoordMasks[t] & vertexLayout) {
            if (NULL != texCoordOffsetsByIdx) {
                texCoordOffsetsByIdx[t] = size;
            }
            size += vecSize;
        } else {
            if (NULL != texCoordOffsetsByIdx) {
                texCoordOffsetsByIdx[t] = -1;
            }
        }
    }
    if (kColor_VertexLayoutBit & vertexLayout) {
        if (NULL != colorOffset) {
            *colorOffset = size;
        }
        size += sizeof(GrColor);
    } else {
        if (NULL != colorOffset) {
            *colorOffset = -1;
        }
    }
    if (kCoverage_VertexLayoutBit & vertexLayout) {
        if (NULL != coverageOffset) {
            *coverageOffset = size;
        }
        size += sizeof(GrColor);
    } else {
        if (NULL != coverageOffset) {
            *coverageOffset = -1;
        }
    }
    if (kEdge_VertexLayoutBit & vertexLayout) {
        if (NULL != edgeOffset) {
            *edgeOffset = size;
        }
        size += 4 * sizeof(GrScalar);
    } else {
        if (NULL != edgeOffset) {
            *edgeOffset = -1;
        }
    }
    return size;
}

int GrDrawTarget::VertexSizeAndOffsetsByStage(
        GrVertexLayout vertexLayout,
        int texCoordOffsetsByStage[GrDrawState::kNumStages],
        int* colorOffset,
        int* coverageOffset,
        int* edgeOffset) {
    GrAssert(check_layout(vertexLayout));

    int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords];
    int size = VertexSizeAndOffsetsByIdx(vertexLayout,
                                         (NULL == texCoordOffsetsByStage) ?
                                               NULL :
                                               texCoordOffsetsByIdx,
                                         colorOffset,
                                         coverageOffset,
                                         edgeOffset);
    if (NULL != texCoordOffsetsByStage) {
        for (int s = 0; s < GrDrawState::kNumStages; ++s) {
            int tcIdx;
            if (StagePosAsTexCoordVertexLayoutBit(s) & vertexLayout) {
                texCoordOffsetsByStage[s] = 0;
            } else if ((tcIdx = VertexTexCoordsForStage(s, vertexLayout)) >= 0) {
                texCoordOffsetsByStage[s] = texCoordOffsetsByIdx[tcIdx];
            } else {
                texCoordOffsetsByStage[s] = -1;
            }
        }
    }
    return size;
}

////////////////////////////////////////////////////////////////////////////////

bool GrDrawTarget::VertexUsesStage(int stage, GrVertexLayout vertexLayout) {
    GrAssert(stage < GrDrawState::kNumStages);
    GrAssert(check_layout(vertexLayout));
    return !!(gStageMasks[stage] & vertexLayout);
}

bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex,
                                         GrVertexLayout vertexLayout) {
    GrAssert(coordIndex < GrDrawState::kMaxTexCoords);
    GrAssert(check_layout(vertexLayout));
    return !!(gTexCoordMasks[coordIndex] & vertexLayout);
}

int GrDrawTarget::VertexTexCoordsForStage(int stage,
                                          GrVertexLayout vertexLayout) {
    GrAssert(stage < GrDrawState::kNumStages);
    GrAssert(check_layout(vertexLayout));
    int bit = vertexLayout & gStageTexCoordMasks[stage];
    if (bit) {
        // figure out which set of texture coordates is used
        // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ...
        // and start at bit 0.
        GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t));
        return (32 - Gr_clz(bit) - 1) / GrDrawState::kNumStages;
    }
    return -1;
}

////////////////////////////////////////////////////////////////////////////////

void GrDrawTarget::VertexLayoutUnitTest() {
    // Ensure that our globals mask arrays are correct
    GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages];
    GrVertexLayout stageMasks[GrDrawState::kNumStages];
    GrVertexLayout texCoordMasks[GrDrawState::kMaxTexCoords];
    gen_mask_arrays(stageTexCoordMasks, stageMasks, texCoordMasks);
    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
        GrAssert(stageTexCoordMasks[s] == gStageTexCoordMasks[s]);
        GrAssert(stageMasks[s] == gStageMasks[s]);
    }
    for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
        GrAssert(texCoordMasks[t] == gTexCoordMasks[t]);
    }

    // not necessarily exhaustive
    static bool run;
    if (!run) {
        run = true;
        for (int s = 0; s < GrDrawState::kNumStages; ++s) {

            GrAssert(!VertexUsesStage(s, 0));
            GrAssert(-1 == VertexStageCoordOffset(s, 0));
            GrVertexLayout stageMask = 0;
            for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
                stageMask |= StageTexCoordVertexLayoutBit(s,t);
            }
            GrAssert(1 == GrDrawState::kMaxTexCoords ||
                     !check_layout(stageMask));
            GrAssert(gStageTexCoordMasks[s] == stageMask);
            stageMask |= StagePosAsTexCoordVertexLayoutBit(s);
            GrAssert(gStageMasks[s] == stageMask);
            GrAssert(!check_layout(stageMask));
        }
        for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
            GrVertexLayout tcMask = 0;
            GrAssert(!VertexUsesTexCoordIdx(t, 0));
            for (int s = 0; s < GrDrawState::kNumStages; ++s) {
                tcMask |= StageTexCoordVertexLayoutBit(s,t);
                GrAssert(VertexUsesStage(s, tcMask));
                GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
                GrAssert(VertexUsesTexCoordIdx(t, tcMask));
                GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
                GrAssert(t == VertexTexCoordsForStage(s, tcMask));
                for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) {
                    GrAssert(-1 == VertexStageCoordOffset(s2, tcMask));
                    GrAssert(!VertexUsesStage(s2, tcMask));
                    GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));

                #if GR_DEBUG
                    GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2);
                #endif
                    GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
                    GrAssert(VertexUsesStage(s2, posAsTex));
                    GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
                    GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex));
                    GrAssert(-1 == VertexEdgeOffset(posAsTex));
                }
                GrAssert(-1 == VertexEdgeOffset(tcMask));
                GrAssert(-1 == VertexColorOffset(tcMask));
                GrAssert(-1 == VertexCoverageOffset(tcMask));
            #if GR_DEBUG
                GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
            #endif
                GrAssert(-1 == VertexCoverageOffset(withColor));
                GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
                GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
            #if GR_DEBUG
                GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit;
            #endif
                GrAssert(-1 == VertexColorOffset(withEdge));
                GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge));
                GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge));
            #if GR_DEBUG
                GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit;
            #endif
                GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge));
                GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge));
                GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge));
            #if GR_DEBUG
                GrVertexLayout withCoverage = tcMask | kCoverage_VertexLayoutBit;
            #endif
                GrAssert(-1 == VertexColorOffset(withCoverage));
                GrAssert(2*sizeof(GrPoint) == VertexCoverageOffset(withCoverage));
                GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withCoverage));
            #if GR_DEBUG
                GrVertexLayout withCoverageAndColor = tcMask | kCoverage_VertexLayoutBit |
                                                      kColor_VertexLayoutBit;
            #endif
                GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withCoverageAndColor));
                GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexCoverageOffset(withCoverageAndColor));
                GrAssert(2*sizeof(GrPoint) + 2 * sizeof(GrColor) == VertexSize(withCoverageAndColor));
            }
            GrAssert(gTexCoordMasks[t] == tcMask);
            GrAssert(check_layout(tcMask));

            int stageOffsets[GrDrawState::kNumStages];
            int colorOffset;
            int edgeOffset;
            int coverageOffset;
            int size;
            size = VertexSizeAndOffsetsByStage(tcMask,
                                               stageOffsets, &colorOffset,
                                               &coverageOffset, &edgeOffset);
            GrAssert(2*sizeof(GrPoint) == size);
            GrAssert(-1 == colorOffset);
            GrAssert(-1 == coverageOffset);
            GrAssert(-1 == edgeOffset);
            for (int s = 0; s < GrDrawState::kNumStages; ++s) {
                GrAssert(VertexUsesStage(s, tcMask));
                GrAssert(sizeof(GrPoint) == stageOffsets[s]);
                GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
            }
        }
    }
}

////////////////////////////////////////////////////////////////////////////////

#define DEBUG_INVAL_BUFFER 0xdeadcafe
#define DEBUG_INVAL_START_IDX -1

GrDrawTarget::GrDrawTarget() {
#if GR_DEBUG
    VertexLayoutUnitTest();
#endif
    fDrawState = &fDefaultDrawState;
    // We assume that fDrawState always owns a ref to the object it points at.
    fDefaultDrawState.ref();
    GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
#if GR_DEBUG
    geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
    geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
    geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
    geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
#endif
    geoSrc.fVertexSrc = kNone_GeometrySrcType;
    geoSrc.fIndexSrc  = kNone_GeometrySrcType;
}

GrDrawTarget::~GrDrawTarget() {
    GrAssert(1 == fGeoSrcStateStack.count());
    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    GrAssert(kNone_GeometrySrcType == geoSrc.fIndexSrc);
    GrAssert(kNone_GeometrySrcType == geoSrc.fVertexSrc);
    fDrawState->unref();
}

void GrDrawTarget::releaseGeometry() {
    int popCnt = fGeoSrcStateStack.count() - 1;
    while (popCnt) {
        this->popGeometrySource();
        --popCnt;
    }
    this->resetVertexSource();
    this->resetIndexSource();
}

void GrDrawTarget::setClip(const GrClip& clip) {
    clipWillBeSet(clip);
    fClip = clip;
}

const GrClip& GrDrawTarget::getClip() const {
    return fClip;
}

void GrDrawTarget::setDrawState(GrDrawState*  drawState) {
    GrAssert(NULL != fDrawState);
    if (NULL == drawState) {
        drawState = &fDefaultDrawState;
    }
    if (fDrawState != drawState) {
        fDrawState->unref();
        drawState->ref();
        fDrawState = drawState;
    }
}

bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout,
                                      int vertexCount,
                                      void** vertices) {
    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    bool acquired = false;
    if (vertexCount > 0) {
        GrAssert(NULL != vertices);
        this->releasePreviousVertexSource();
        geoSrc.fVertexSrc = kNone_GeometrySrcType;

        acquired = this->onReserveVertexSpace(vertexLayout,
                                              vertexCount,
                                              vertices);
    }
    if (acquired) {
        geoSrc.fVertexSrc = kReserved_GeometrySrcType;
        geoSrc.fVertexCount = vertexCount;
        geoSrc.fVertexLayout = vertexLayout;
    } else if (NULL != vertices) {
        *vertices = NULL;
    }
    return acquired;
}

bool GrDrawTarget::reserveIndexSpace(int indexCount,
                                     void** indices) {
    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    bool acquired = false;
    if (indexCount > 0) {
        GrAssert(NULL != indices);
        this->releasePreviousIndexSource();
        geoSrc.fIndexSrc = kNone_GeometrySrcType;
        
        acquired = this->onReserveIndexSpace(indexCount, indices);
    }
    if (acquired) {
        geoSrc.fIndexSrc = kReserved_GeometrySrcType;
        geoSrc.fIndexCount = indexCount;
    } else if (NULL != indices) {
        *indices = NULL;
    }
    return acquired;
    
}

bool GrDrawTarget::reserveVertexAndIndexSpace(GrVertexLayout vertexLayout,
                                              int vertexCount,
                                              int indexCount,
                                              void** vertices,
                                              void** indices) {
    this->willReserveVertexAndIndexSpace(vertexLayout, vertexCount, indexCount);
    if (vertexCount) {
        if (!this->reserveVertexSpace(vertexLayout, vertexCount, vertices)) {
            if (indexCount) {
                this->resetIndexSource();
            }
            return false;
        }
    }
    if (indexCount) {
        if (!this->reserveIndexSpace(indexCount, indices)) {
            if (vertexCount) {
                this->resetVertexSource();
            }
            return false;
        }
    }
    return true;
}

bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
                                 int32_t* vertexCount,
                                 int32_t* indexCount) const {
    if (NULL != vertexCount) {
        *vertexCount = -1;
    }
    if (NULL != indexCount) {
        *indexCount = -1;
    }
    return false;
}

void GrDrawTarget::releasePreviousVertexSource() {
    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    switch (geoSrc.fVertexSrc) {
        case kNone_GeometrySrcType:
            break;
        case kArray_GeometrySrcType:
            this->releaseVertexArray();
            break;
        case kReserved_GeometrySrcType:
            this->releaseReservedVertexSpace();
            break;
        case kBuffer_GeometrySrcType:
            geoSrc.fVertexBuffer->unref();
#if GR_DEBUG
            geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
#endif
            break;
        default:
            GrCrash("Unknown Vertex Source Type.");
            break;
    }
}

void GrDrawTarget::releasePreviousIndexSource() {
    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    switch (geoSrc.fIndexSrc) {
        case kNone_GeometrySrcType:   // these two don't require
            break;
        case kArray_GeometrySrcType:
            this->releaseIndexArray();
            break;
        case kReserved_GeometrySrcType:
            this->releaseReservedIndexSpace();
            break;
        case kBuffer_GeometrySrcType:
            geoSrc.fIndexBuffer->unref();
#if GR_DEBUG
            geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
#endif
            break;
        default:
            GrCrash("Unknown Index Source Type.");
            break;
    }
}

void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
                                          const void* vertexArray,
                                          int vertexCount) {
    this->releasePreviousVertexSource();
    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    geoSrc.fVertexSrc = kArray_GeometrySrcType;
    geoSrc.fVertexLayout = vertexLayout;
    geoSrc.fVertexCount = vertexCount;
    this->onSetVertexSourceToArray(vertexArray, vertexCount);
}

void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
                                         int indexCount) {
    this->releasePreviousIndexSource();
    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    geoSrc.fIndexSrc = kArray_GeometrySrcType;
    geoSrc.fIndexCount = indexCount;
    this->onSetIndexSourceToArray(indexArray, indexCount);
}

void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
                                           const GrVertexBuffer* buffer) {
    this->releasePreviousVertexSource();
    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    geoSrc.fVertexSrc    = kBuffer_GeometrySrcType;
    geoSrc.fVertexBuffer = buffer;
    buffer->ref();
    geoSrc.fVertexLayout = vertexLayout;
}

void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
    this->releasePreviousIndexSource();
    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    geoSrc.fIndexSrc     = kBuffer_GeometrySrcType;
    geoSrc.fIndexBuffer  = buffer;
    buffer->ref();
}

void GrDrawTarget::resetVertexSource() {
    this->releasePreviousVertexSource();
    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    geoSrc.fVertexSrc = kNone_GeometrySrcType;
}

void GrDrawTarget::resetIndexSource() {
    this->releasePreviousIndexSource();
    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    geoSrc.fIndexSrc = kNone_GeometrySrcType;
}

void GrDrawTarget::pushGeometrySource() {
    this->geometrySourceWillPush();
    GeometrySrcState& newState = fGeoSrcStateStack.push_back();
    newState.fIndexSrc = kNone_GeometrySrcType;
    newState.fVertexSrc = kNone_GeometrySrcType;
#if GR_DEBUG
    newState.fVertexCount  = ~0;
    newState.fVertexBuffer = (GrVertexBuffer*)~0;
    newState.fIndexCount   = ~0;
    newState.fIndexBuffer = (GrIndexBuffer*)~0;
#endif
}

void GrDrawTarget::popGeometrySource() {
    const GeometrySrcState& geoSrc = this->getGeomSrc();
    // if popping last element then pops are unbalanced with pushes
    GrAssert(fGeoSrcStateStack.count() > 1);
    
    this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
    this->releasePreviousVertexSource();
    this->releasePreviousIndexSource();
    fGeoSrcStateStack.pop_back();
}

////////////////////////////////////////////////////////////////////////////////

bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
                             int startIndex, int vertexCount,
                             int indexCount) const {
#if GR_DEBUG
    const GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    int maxVertex = startVertex + vertexCount;
    int maxValidVertex;
    switch (geoSrc.fVertexSrc) {
        case kNone_GeometrySrcType:
            GrCrash("Attempting to draw without vertex src.");
        case kReserved_GeometrySrcType: // fallthrough
        case kArray_GeometrySrcType:
            maxValidVertex = geoSrc.fVertexCount;
            break;
        case kBuffer_GeometrySrcType:
            maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() /
                             VertexSize(geoSrc.fVertexLayout);
            break;
    }
    if (maxVertex > maxValidVertex) {
        GrCrash("Drawing outside valid vertex range.");
    }
    if (indexCount > 0) {
        int maxIndex = startIndex + indexCount;
        int maxValidIndex;
        switch (geoSrc.fIndexSrc) {
            case kNone_GeometrySrcType:
                GrCrash("Attempting to draw indexed geom without index src.");
            case kReserved_GeometrySrcType: // fallthrough
            case kArray_GeometrySrcType:
                maxValidIndex = geoSrc.fIndexCount;
                break;
            case kBuffer_GeometrySrcType:
                maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t);
                break;
        }
        if (maxIndex > maxValidIndex) {
            GrCrash("Index reads outside valid index range.");
        }
    }

    GrAssert(NULL != this->getDrawState().getRenderTarget());
    for (int i = 0; i < GrDrawState::kNumStages; ++i) {
        if (this->getDrawState().getTexture(i)) {
            GrAssert(this->getDrawState().getTexture(i)->asRenderTarget() != 
                     this->getDrawState().getRenderTarget());
        }
    }
#endif
    const GrDrawState& drawState = this->getDrawState();
    if (NULL == drawState.getRenderTarget()) {
        return false;
    }
    if (GrPixelConfigIsUnpremultiplied(drawState.getRenderTarget()->config())) {
        if (kOne_BlendCoeff != drawState.getSrcBlendCoeff() ||
            kZero_BlendCoeff != drawState.getDstBlendCoeff()) {
            return false;
        }
    }
    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
        // We don't support using unpremultiplied textures with filters (other
        // than nearest). Alpha-premulling is not distributive WRT to filtering.
        // We'd have to filter each texel before filtering. We could do this for
        // our custom filters but we would also have to disable bilerp and do
        // a custom bilerp in the shader. Until Skia itself supports unpremul
        // configs there is no pressure to implement this.
        if (this->isStageEnabled(s) &&
            GrPixelConfigIsUnpremultiplied(drawState.getTexture(s)->config()) &&
            GrSamplerState::kNearest_Filter !=
            drawState.getSampler(s).getFilter()) {
            return false;
        }
    }
    return true;
}

void GrDrawTarget::drawIndexed(GrPrimitiveType type, int startVertex,
                               int startIndex, int vertexCount,
                               int indexCount) {
    if (indexCount > 0 &&
        this->checkDraw(type, startVertex, startIndex,
                        vertexCount, indexCount)) {
        this->onDrawIndexed(type, startVertex, startIndex,
                            vertexCount, indexCount);
    }
}

void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
                                  int startVertex,
                                  int vertexCount) {
    if (vertexCount > 0 &&
        this->checkDraw(type, startVertex, -1, vertexCount, -1)) {
        this->onDrawNonIndexed(type, startVertex, vertexCount);
    }
}

////////////////////////////////////////////////////////////////////////////////

// Some blend modes allow folding a partial coverage value into the color's
// alpha channel, while others will blend incorrectly.
bool GrDrawTarget::canTweakAlphaForCoverage() const {
    /**
     * The fractional coverage is f
     * The src and dst coeffs are Cs and Cd
     * The dst and src colors are S and D
     * We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D
     * By tweaking the source color's alpha we're replacing S with S'=fS. It's
     * obvious that that first term will always be ok. The second term can be
     * rearranged as [1-(1-Cd)f]D. By substituing in the various possbilities
     * for Cd we find that only 1, ISA, and ISC produce the correct depth
     * coeffecient in terms of S' and D.
     */
    GrBlendCoeff dstCoeff = this->getDrawState().getDstBlendCoeff();
    return kOne_BlendCoeff == dstCoeff ||
           kISA_BlendCoeff == dstCoeff ||
           kISC_BlendCoeff == dstCoeff;
}

bool GrDrawTarget::srcAlphaWillBeOne(GrVertexLayout layout) const {
    const GrDrawState& drawState = this->getDrawState();

    // Check if per-vertex or constant color may have partial alpha
    if ((layout & kColor_VertexLayoutBit) ||
        0xff != GrColorUnpackA(drawState.getColor())) {
        return false;
    }
    // Check if color filter could introduce an alpha
    // (TODO: Consider being more aggressive with regards to detecting 0xff
    // final alpha from color filter).
    if (SkXfermode::kDst_Mode != drawState.getColorFilterMode()) {
        return false;
    }
    // Check if a color stage could create a partial alpha
    for (int s = 0; s < drawState.getFirstCoverageStage(); ++s) {
        if (StageWillBeUsed(s, layout, this->getDrawState())) {
            GrAssert(NULL != drawState.getTexture(s));
            GrPixelConfig config = drawState.getTexture(s)->config();
            if (!GrPixelConfigIsOpaque(config)) {
                return false;
            }
        }
    }
    return true;
}

namespace {
GrVertexLayout default_blend_opts_vertex_layout() {
    GrVertexLayout layout = 0;
    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
        layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s);
    }
    return layout;
}
}

GrDrawTarget::BlendOptFlags
GrDrawTarget::getBlendOpts(bool forceCoverage,
                           GrBlendCoeff* srcCoeff,
                           GrBlendCoeff* dstCoeff) const {

    GrVertexLayout layout;
    if (kNone_GeometrySrcType == this->getGeomSrc().fVertexSrc) {
        layout = default_blend_opts_vertex_layout();
    } else {
        layout = this->getVertexLayout();
    }

    const GrDrawState& drawState = this->getDrawState();

    GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
    if (NULL == srcCoeff) {
        srcCoeff = &bogusSrcCoeff;
    }
    *srcCoeff = drawState.getSrcBlendCoeff();

    if (NULL == dstCoeff) {
        dstCoeff = &bogusDstCoeff;
    }
    *dstCoeff = drawState.getDstBlendCoeff();

    // We don't ever expect source coeffecients to reference the source
    GrAssert(kSA_BlendCoeff != *srcCoeff &&
             kISA_BlendCoeff != *srcCoeff &&
             kSC_BlendCoeff != *srcCoeff &&
             kISC_BlendCoeff != *srcCoeff);
    // same for dst
    GrAssert(kDA_BlendCoeff != *dstCoeff &&
             kIDA_BlendCoeff != *dstCoeff &&
             kDC_BlendCoeff != *dstCoeff &&
             kIDC_BlendCoeff != *dstCoeff);

    if (drawState.isColorWriteDisabled()) {
        *srcCoeff = kZero_BlendCoeff;
        *dstCoeff = kOne_BlendCoeff;
    }

    bool srcAIsOne = this->srcAlphaWillBeOne(layout);
    bool dstCoeffIsOne = kOne_BlendCoeff == *dstCoeff ||
                         (kSA_BlendCoeff == *dstCoeff && srcAIsOne);
    bool dstCoeffIsZero = kZero_BlendCoeff == *dstCoeff ||
                         (kISA_BlendCoeff == *dstCoeff && srcAIsOne);


    // When coeffs are (0,1) there is no reason to draw at all, unless
    // stenciling is enabled. Having color writes disabled is effectively
    // (0,1). The same applies when coverage is known to be 0.
    if ((kZero_BlendCoeff == *srcCoeff && dstCoeffIsOne) ||
        (!(layout & kCoverage_VertexLayoutBit) && 
         0 == drawState.getCoverage())) {
        if (drawState.getStencil().doesWrite()) {
            return kDisableBlend_BlendOptFlag |
                   kEmitTransBlack_BlendOptFlag;
        } else {
            return kSkipDraw_BlendOptFlag;
        }
    }

    // check for coverage due to constant coverage, per-vertex coverage,
    // edge aa or coverage texture stage
    bool hasCoverage = forceCoverage ||
                       0xffffffff != drawState.getCoverage() || 
                       drawState.getNumAAEdges() > 0 ||
                       (layout & kCoverage_VertexLayoutBit) ||
                       (layout & kEdge_VertexLayoutBit);
    for (int s = drawState.getFirstCoverageStage();
         !hasCoverage && s < GrDrawState::kNumStages;
         ++s) {
        if (StageWillBeUsed(s, layout, this->getDrawState())) {
            hasCoverage = true;
        }
    }

    // if we don't have coverage we can check whether the dst
    // has to read at all. If not, we'll disable blending.
    if (!hasCoverage) {
        if (dstCoeffIsZero) {
            if (kOne_BlendCoeff == *srcCoeff) {
                // if there is no coverage and coeffs are (1,0) then we
                // won't need to read the dst at all, it gets replaced by src
                return kDisableBlend_BlendOptFlag;
            } else if (kZero_BlendCoeff == *srcCoeff) {
                // if the op is "clear" then we don't need to emit a color
                // or blend, just write transparent black into the dst.
                *srcCoeff = kOne_BlendCoeff;
                *dstCoeff = kZero_BlendCoeff;
                return kDisableBlend_BlendOptFlag |
                       kEmitTransBlack_BlendOptFlag;
            }
        }
    } else {
        // check whether coverage can be safely rolled into alpha
        // of if we can skip color computation and just emit coverage
        if (this->canTweakAlphaForCoverage()) {
            return kCoverageAsAlpha_BlendOptFlag;
        }
        if (dstCoeffIsZero) {
            if (kZero_BlendCoeff == *srcCoeff) {
                // the source color is not included in the blend
                // the dst coeff is effectively zero so blend works out to:
                // (c)(0)D + (1-c)D = (1-c)D.
                *dstCoeff = kISA_BlendCoeff;
                return  kEmitCoverage_BlendOptFlag;
            } else if (srcAIsOne) {
                // the dst coeff is effectively zero so blend works out to:
                // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
                // If Sa is 1 then we can replace Sa with c 
                // and set dst coeff to 1-Sa.
                *dstCoeff = kISA_BlendCoeff;
                return  kCoverageAsAlpha_BlendOptFlag;
            }
        } else if (dstCoeffIsOne) {
            // the dst coeff is effectively one so blend works out to:
            // cS + (c)(1)D + (1-c)D = cS + D.
            *dstCoeff = kOne_BlendCoeff;
            return  kCoverageAsAlpha_BlendOptFlag;
        }
    }
    return kNone_BlendOpt;
}

bool GrDrawTarget::willUseHWAALines() const {
    // there is a conflict between using smooth lines and our use of
    // premultiplied alpha. Smooth lines tweak the incoming alpha value
    // but not in a premul-alpha way. So we only use them when our alpha
    // is 0xff and tweaking the color for partial coverage is OK
    if (!fCaps.fHWAALineSupport ||
        !this->getDrawState().isHWAntialiasState()) {
        return false;
    }
    BlendOptFlags opts = this->getBlendOpts();
    return (kDisableBlend_BlendOptFlag & opts) &&
           (kCoverageAsAlpha_BlendOptFlag & opts);
}

bool GrDrawTarget::canApplyCoverage() const {
    // we can correctly apply coverage if a) we have dual source blending
    // or b) one of our blend optimizations applies.
    return this->getCaps().fDualSourceBlendingSupport ||
           kNone_BlendOpt != this->getBlendOpts(true);
}

////////////////////////////////////////////////////////////////////////////////

void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
                                        int instanceCount,
                                        int verticesPerInstance,
                                        int indicesPerInstance) {
    if (!verticesPerInstance || !indicesPerInstance) {
        return;
    }

    int instancesPerDraw = this->indexCountInCurrentSource() /
                           indicesPerInstance;
    if (!instancesPerDraw) {
        return;
    }

    instancesPerDraw = GrMin(instanceCount, instancesPerDraw);
    int startVertex = 0;
    while (instanceCount) {
        this->drawIndexed(type,
                          startVertex,
                          0,
                          verticesPerInstance * instancesPerDraw,
                          indicesPerInstance * instancesPerDraw);
        startVertex += verticesPerInstance;
        instanceCount -= instancesPerDraw;
    }
}

////////////////////////////////////////////////////////////////////////////////

void GrDrawTarget::drawRect(const GrRect& rect, 
                            const GrMatrix* matrix,
                            StageMask stageMask,
                            const GrRect* srcRects[],
                            const GrMatrix* srcMatrices[]) {
    GrVertexLayout layout = GetRectVertexLayout(stageMask, srcRects);

    AutoReleaseGeometry geo(this, layout, 4, 0);
    if (!geo.succeeded()) {
        GrPrintf("Failed to get space for vertices!\n");
        return;
    }

    SetRectVertices(rect, matrix, srcRects, 
                    srcMatrices, layout, geo.vertices());

    drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
}

GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageMask stageMask, 
                                                 const GrRect* srcRects[]) {
    GrVertexLayout layout = 0;

    for (int i = 0; i < GrDrawState::kNumStages; ++i) {
        int numTC = 0;
        if (stageMask & (1 << i)) {
            if (NULL != srcRects && NULL != srcRects[i]) {
                layout |= StageTexCoordVertexLayoutBit(i, numTC);
                ++numTC;
            } else {
                layout |= StagePosAsTexCoordVertexLayoutBit(i);
            }
        }
    }
    return layout;
}

void GrDrawTarget::clipWillBeSet(const GrClip& clip) {
}

void GrDrawTarget::SetRectVertices(const GrRect& rect,
                                   const GrMatrix* matrix, 
                                   const GrRect* srcRects[], 
                                   const GrMatrix* srcMatrices[],
                                   GrVertexLayout layout, 
                                   void* vertices) {
#if GR_DEBUG
    // check that the layout and srcRects agree
    for (int i = 0; i < GrDrawState::kNumStages; ++i) {
        if (VertexTexCoordsForStage(i, layout) >= 0) {
            GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]);
        } else {
            GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]);
        }
    }
#endif

    int stageOffsets[GrDrawState::kNumStages];
    int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets,
                                            NULL, NULL, NULL);

    GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop,
                                            rect.fRight, rect.fBottom,
                                            vsize);
    if (NULL != matrix) {
        matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4);
    }

    for (int i = 0; i < GrDrawState::kNumStages; ++i) {
        if (stageOffsets[i] > 0) {
            GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) +
                                                stageOffsets[i]);
            coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop,
                               srcRects[i]->fRight, srcRects[i]->fBottom,
                               vsize);
            if (NULL != srcMatrices && NULL != srcMatrices[i]) {
                srcMatrices[i]->mapPointsWithStride(coords, vsize, 4);
            }
        }
    }
}

////////////////////////////////////////////////////////////////////////////////

GrDrawTarget::AutoStateRestore::AutoStateRestore() {
    fDrawTarget = NULL;
}

GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target,
                                                 ASRInit init) {
    fDrawTarget = NULL;
    this->set(target, init);
}

GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
    if (NULL != fDrawTarget) {
        fDrawTarget->setDrawState(fSavedState);
        fSavedState->unref();
    }
}

void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target, ASRInit init) {
    GrAssert(NULL == fDrawTarget);
    fDrawTarget = target;
    fSavedState = target->drawState();
    GrAssert(fSavedState);
    fSavedState->ref();
    if (kReset_ASRInit == init) {
        // calls the default cons
        fTempState.init();
    } else {
        GrAssert(kPreserve_ASRInit == init);
        // calls the copy cons
        fTempState.set(*fSavedState);
    }
    target->setDrawState(fTempState.get());
}

////////////////////////////////////////////////////////////////////////////////

GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(
                                            GrDrawTarget* target,
                                            GrDrawState::StageMask stageMask) {
    GrAssert(NULL != target);
    GrDrawState* drawState = target->drawState();

    fDrawTarget = target;
    fViewMatrix = drawState->getViewMatrix();
    fStageMask = stageMask;
    if (fStageMask) {
        GrMatrix invVM;
        if (fViewMatrix.invert(&invVM)) {
            for (int s = 0; s < GrDrawState::kNumStages; ++s) {
                if (fStageMask & (1 << s)) {
                    fSamplerMatrices[s] = drawState->getSampler(s).getMatrix();
                }
            }
            drawState->preConcatSamplerMatrices(fStageMask, invVM);
        } else {
            // sad trombone sound
            fStageMask = 0;
        }
    }
    drawState->viewMatrix()->reset();
}

GrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() {
    GrDrawState* drawState = fDrawTarget->drawState();
    drawState->setViewMatrix(fViewMatrix);
    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
        if (fStageMask & (1 << s)) {
            *drawState->sampler(s)->matrix() = fSamplerMatrices[s];
        }
    }
}

////////////////////////////////////////////////////////////////////////////////

GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
                                         GrDrawTarget*  target,
                                         GrVertexLayout vertexLayout,
                                         int vertexCount,
                                         int indexCount) {
    fTarget = NULL;
    this->set(target, vertexLayout, vertexCount, indexCount);
}
    
GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
    fTarget = NULL;
}

GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
    this->reset();
}

bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget*  target,
                                            GrVertexLayout vertexLayout,
                                            int vertexCount,
                                            int indexCount) {
    this->reset();
    fTarget = target;
    bool success = true;
    if (NULL != fTarget) {
        fTarget = target;
        success = target->reserveVertexAndIndexSpace(vertexLayout,
                                                     vertexCount,
                                                     indexCount,
                                                     &fVertices,
                                                     &fIndices);
        if (!success) {
            fTarget = NULL;
            this->reset();
        }
    }
    GrAssert(success == (NULL != fTarget));
    return success;
}

void GrDrawTarget::AutoReleaseGeometry::reset() {
    if (NULL != fTarget) {
        if (NULL != fVertices) {
            fTarget->resetVertexSource();
        }
        if (NULL != fIndices) {
            fTarget->resetIndexSource();
        }
        fTarget = NULL;
    }
    fVertices = NULL;
    fIndices = NULL;
}

void GrDrawTarget::Caps::print() const {
    static const char* gNY[] = {"NO", "YES"};
    GrPrintf("8 Bit Palette Support       : %s\n", gNY[f8BitPaletteSupport]);
    GrPrintf("NPOT Texture Tile Support   : %s\n", gNY[fNPOTTextureTileSupport]);
    GrPrintf("Two Sided Stencil Support   : %s\n", gNY[fTwoSidedStencilSupport]);
    GrPrintf("Stencil Wrap Ops  Support   : %s\n", gNY[fStencilWrapOpsSupport]);
    GrPrintf("HW AA Lines Support         : %s\n", gNY[fHWAALineSupport]);
    GrPrintf("Shader Derivative Support   : %s\n", gNY[fShaderDerivativeSupport]);
    GrPrintf("Geometry Shader Support     : %s\n", gNY[fGeometryShaderSupport]);
    GrPrintf("FSAA Support                : %s\n", gNY[fFSAASupport]);
    GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSupport]);
    GrPrintf("Buffer Lock Support         : %s\n", gNY[fBufferLockSupport]);
    GrPrintf("Max Texture Size            : %d\n", fMaxTextureSize);
    GrPrintf("Max Render Target Size      : %d\n", fMaxRenderTargetSize);
}

