GrDrawTarget.cpp revision d46e2423a71d38b8a057cec2356741e35b03334d
1ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2010 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
9ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
10ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
11ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrDrawTarget.h"
12ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrGpuVertex.h"
1386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#include "GrTexture.h"
1425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#include "GrVertexBuffer.h"
1525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#include "GrIndexBuffer.h"
16ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
176acc9b3d2b26d11d3da5eb81775d67a0410d1ae7junov@google.comnamespace {
186acc9b3d2b26d11d3da5eb81775d67a0410d1ae7junov@google.com
198531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com// recursive helper for creating mask with all the tex coord bits set for
208531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com// one stage
218531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comtemplate <int N>
2234cec2416c70a2fd8e60a9f0831eaddbde7d72b5reed@google.comint stage_mask_recur(int stage) {
235782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    return GrDrawTarget::StageTexCoordVertexLayoutBit(stage, N) |
248531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com           stage_mask_recur<N+1>(stage);
258531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
266acc9b3d2b26d11d3da5eb81775d67a0410d1ae7junov@google.comtemplate<>
27d728f6ecfab79c08044a837fbcae2996f7b8619areed@google.comint stage_mask_recur<GrDrawTarget::kNumStages>(int) { return 0; }
28ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
298531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com// mask of all tex coord indices for one stage
306acc9b3d2b26d11d3da5eb81775d67a0410d1ae7junov@google.comint stage_tex_coord_mask(int stage) {
318531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return stage_mask_recur<0>(stage);
328531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
338531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
348531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com// mask of all bits relevant to one stage
356acc9b3d2b26d11d3da5eb81775d67a0410d1ae7junov@google.comint stage_mask(int stage) {
365782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    return stage_tex_coord_mask(stage) |
378531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com           GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(stage);
388531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
398531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
408531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com// recursive helper for creating mask of with all bits set relevant to one
418531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com// texture coordinate index
428531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comtemplate <int N>
4334cec2416c70a2fd8e60a9f0831eaddbde7d72b5reed@google.comint tex_coord_mask_recur(int texCoordIdx) {
445782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    return GrDrawTarget::StageTexCoordVertexLayoutBit(N, texCoordIdx) |
458531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com           tex_coord_mask_recur<N+1>(texCoordIdx);
468531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
476acc9b3d2b26d11d3da5eb81775d67a0410d1ae7junov@google.comtemplate<>
48d728f6ecfab79c08044a837fbcae2996f7b8619areed@google.comint tex_coord_mask_recur<GrDrawTarget::kMaxTexCoords>(int) { return 0; }
498531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
508531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com// mask of all bits relevant to one texture coordinate index
516acc9b3d2b26d11d3da5eb81775d67a0410d1ae7junov@google.comint tex_coord_idx_mask(int texCoordIdx) {
528531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return tex_coord_mask_recur<0>(texCoordIdx);
538531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
548531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
558531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.combool check_layout(GrVertexLayout layout) {
568531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    // can only have 1 or 0 bits set for each stage.
578531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
588531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        int stageBits = layout & stage_mask(s);
598531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        if (stageBits && !GrIsPow2(stageBits)) {
608531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            return false;
61ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
628531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
638531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return true;
648531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
658531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
66aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.comint num_tex_coords(GrVertexLayout layout) {
67aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    int cnt = 0;
68aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    // figure out how many tex coordinates are present
69aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    for (int t = 0; t < GrDrawTarget::kMaxTexCoords; ++t) {
70aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com        if (tex_coord_idx_mask(t) & layout) {
71aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com            ++cnt;
72aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com        }
73aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    }
74aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    return cnt;
75aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com}
76aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com
776acc9b3d2b26d11d3da5eb81775d67a0410d1ae7junov@google.com} //unnamed namespace
786acc9b3d2b26d11d3da5eb81775d67a0410d1ae7junov@google.com
798531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comsize_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
808531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
815782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
825782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
838531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                        sizeof(GrGpuTextVertex) :
848531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                        sizeof(GrPoint);
858531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
868531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    size_t size = vecSize; // position
87aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    size += num_tex_coords(vertexLayout) * vecSize;
888531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    if (vertexLayout & kColor_VertexLayoutBit) {
898531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        size += sizeof(GrColor);
908531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
91aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    if (vertexLayout & kEdge_VertexLayoutBit) {
92aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com        size += 4 * sizeof(GrScalar);
93aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    }
948531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return size;
95ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
96ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
978531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comint GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) {
988531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
998531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    if (StagePosAsTexCoordVertexLayoutBit(stage) & vertexLayout) {
100ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return 0;
101ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
1028531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    int tcIdx = VertexTexCoordsForStage(stage, vertexLayout);
1038531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    if (tcIdx >= 0) {
1045782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
1055782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
1068531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                    sizeof(GrGpuTextVertex) :
1078531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                    sizeof(GrPoint);
1088531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        int offset = vecSize; // position
1098531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        // figure out how many tex coordinates are present and precede this one.
1108531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        for (int t = 0; t < tcIdx; ++t) {
1118531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            if (tex_coord_idx_mask(t) & vertexLayout) {
1128531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                offset += vecSize;
1138531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            }
1148531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        }
1158531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        return offset;
1168531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
1178531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
118ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return -1;
119ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
120ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
121ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comint  GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) {
1228531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
1235782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
124aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    // color is after the pos and tex coords
125ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (vertexLayout & kColor_VertexLayoutBit) {
1265782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
1278531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                    sizeof(GrGpuTextVertex) :
1288531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                    sizeof(GrPoint);
129aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com        return vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos
130aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    }
131aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    return -1;
132aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com}
133aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com
134aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.comint  GrDrawTarget::VertexEdgeOffset(GrVertexLayout vertexLayout) {
135aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    GrAssert(check_layout(vertexLayout));
136aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com
137aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    // edge pts are after the pos, tex coords, and color
138aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    if (vertexLayout & kEdge_VertexLayoutBit) {
139aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
140aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                                    sizeof(GrGpuTextVertex) :
141aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                                    sizeof(GrPoint);
142aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com        int offset = vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos
143aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com        if (vertexLayout & kColor_VertexLayoutBit) {
144aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com            offset += sizeof(GrColor);
145ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
1468531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        return offset;
147ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
148ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return -1;
149ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
150ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
1518531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comint GrDrawTarget::VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
1528531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                             int texCoordOffsetsByIdx[kMaxTexCoords],
153aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                                             int* colorOffset,
154aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                                             int* edgeOffset) {
1558531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
1565782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
1578531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(NULL != texCoordOffsetsByIdx);
158ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(NULL != colorOffset);
159aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    GrAssert(NULL != edgeOffset);
160ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
1615782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
1628531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                                    sizeof(GrGpuTextVertex) :
1638531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                                    sizeof(GrPoint);
1648531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    int size = vecSize; // position
1655782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
1668531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    for (int t = 0; t < kMaxTexCoords; ++t) {
1678531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        if (tex_coord_idx_mask(t) & vertexLayout) {
1688531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            texCoordOffsetsByIdx[t] = size;
1698531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            size += vecSize;
170ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        } else {
1718531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            texCoordOffsetsByIdx[t] = -1;
172ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
1738531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
1748531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    if (kColor_VertexLayoutBit & vertexLayout) {
1758531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        *colorOffset = size;
1768531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        size += sizeof(GrColor);
1778531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    } else {
1788531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        *colorOffset = -1;
1798531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
180aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    if (kEdge_VertexLayoutBit & vertexLayout) {
181aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com        *edgeOffset = size;
182aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com        size += 4 * sizeof(GrScalar);
183aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    } else {
184aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com        *edgeOffset = -1;
185aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    }
1868531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return size;
1878531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
1888531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
1898531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comint GrDrawTarget::VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
1908531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                              int texCoordOffsetsByStage[kNumStages],
191aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                                              int* colorOffset,
192aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                                              int* edgeOffset) {
1938531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
1948531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
1958531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(NULL != texCoordOffsetsByStage);
1968531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(NULL != colorOffset);
197aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    GrAssert(NULL != edgeOffset);
1985782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
1998531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    int texCoordOffsetsByIdx[kMaxTexCoords];
2005782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    int size = VertexSizeAndOffsetsByIdx(vertexLayout,
2015782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com                                         texCoordOffsetsByIdx,
202aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                                         colorOffset,
203aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                                         edgeOffset);
2048531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    for (int s = 0; s < kNumStages; ++s) {
2058531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        int tcIdx;
2068531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        if (StagePosAsTexCoordVertexLayoutBit(s) & vertexLayout) {
2078531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            texCoordOffsetsByStage[s] = 0;
2088531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        } else if ((tcIdx = VertexTexCoordsForStage(s, vertexLayout)) >= 0) {
2098531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            texCoordOffsetsByStage[s] = texCoordOffsetsByIdx[tcIdx];
210ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        } else {
2118531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            texCoordOffsetsByStage[s] = -1;
212ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
213ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
2145782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    return size;
2158531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
2168531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
2178531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.combool GrDrawTarget::VertexUsesStage(int stage, GrVertexLayout vertexLayout) {
2188531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(stage < kNumStages);
2198531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
2208531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return !!(stage_mask(stage) & vertexLayout);
2218531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
2228531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
2235782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.combool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex,
2248531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                         GrVertexLayout vertexLayout) {
2255782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    GrAssert(coordIndex < kMaxTexCoords);
2268531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
2278531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return !!(tex_coord_idx_mask(coordIndex) & vertexLayout);
2288531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
2298531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
2308531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comint GrDrawTarget::VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout) {
2318531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(stage < kNumStages);
2328531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
2338531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    int bit = vertexLayout & stage_tex_coord_mask(stage);
2348531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    if (bit) {
2358531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        // figure out which set of texture coordates is used
2368531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ...
2378531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        // and start at bit 0.
2388531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t));
2398531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        return (32 - Gr_clz(bit) - 1) / kNumStages;
2408531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
2418531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return -1;
242ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
243ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2448531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comvoid GrDrawTarget::VertexLayoutUnitTest() {
2458531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    // not necessarily exhaustive
2468531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    static bool run;
2478531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    if (!run) {
2488531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        run = true;
2498531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        for (int s = 0; s < kNumStages; ++s) {
2508531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
2518531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(!VertexUsesStage(s, 0));
2528531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(-1 == VertexStageCoordOffset(s, 0));
2538531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrVertexLayout stageMask = 0;
2548531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            for (int t = 0; t < kMaxTexCoords; ++t) {
2558531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                stageMask |= StageTexCoordVertexLayoutBit(s,t);
2568531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            }
2575782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com            GrAssert(1 == kMaxTexCoords || !check_layout(stageMask));
2588531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(stage_tex_coord_mask(s) == stageMask);
2598531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            stageMask |= StagePosAsTexCoordVertexLayoutBit(s);
2608531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(stage_mask(s) == stageMask);
2618531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(!check_layout(stageMask));
2628531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        }
2638531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        for (int t = 0; t < kMaxTexCoords; ++t) {
2648531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrVertexLayout tcMask = 0;
2658531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(!VertexUsesTexCoordIdx(t, 0));
2668531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            for (int s = 0; s < kNumStages; ++s) {
2678531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                tcMask |= StageTexCoordVertexLayoutBit(s,t);
2688531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(VertexUsesStage(s, tcMask));
2698531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
2708531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(VertexUsesTexCoordIdx(t, tcMask));
2718531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
2728531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(t == VertexTexCoordsForStage(s, tcMask));
2738531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                for (int s2 = s + 1; s2 < kNumStages; ++s2) {
2748531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrAssert(-1 == VertexStageCoordOffset(s2, tcMask));
2758531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrAssert(!VertexUsesStage(s2, tcMask));
2768531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));
2775782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
2781962832771a435426a0ed6a1cf5069c45918b141bsalomon@google.com                #if GR_DEBUG
2798531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2);
2801962832771a435426a0ed6a1cf5069c45918b141bsalomon@google.com                #endif
2818531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
2828531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrAssert(VertexUsesStage(s2, posAsTex));
2838531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
2848531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex));
285aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                    GrAssert(-1 == VertexEdgeOffset(posAsTex));
2868531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                }
287aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                GrAssert(-1 == VertexEdgeOffset(tcMask));
288aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                GrAssert(-1 == VertexColorOffset(tcMask));
2891962832771a435426a0ed6a1cf5069c45918b141bsalomon@google.com            #if GR_DEBUG
2908531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
2911962832771a435426a0ed6a1cf5069c45918b141bsalomon@google.com            #endif
2928531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
2938531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
294aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com            #if GR_DEBUG
295aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit;
296aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com            #endif
297aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                GrAssert(-1 == VertexColorOffset(withEdge));
298aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge));
299aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge));
300aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com            #if GR_DEBUG
301aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit;
302aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com            #endif
303aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge));
304aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge));
305aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge));
3068531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            }
3078531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(tex_coord_idx_mask(t) == tcMask);
3088531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(check_layout(tcMask));
3095782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
3108531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            int stageOffsets[kNumStages];
3118531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            int colorOffset;
312aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com            int edgeOffset;
3138531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            int size;
314aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com            size = VertexSizeAndOffsetsByStage(tcMask, stageOffsets, &colorOffset, &edgeOffset);
3158531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(2*sizeof(GrPoint) == size);
3168531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(-1 == colorOffset);
317aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com            GrAssert(-1 == edgeOffset);
3188531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            for (int s = 0; s < kNumStages; ++s) {
3198531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(VertexUsesStage(s, tcMask));
3208531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(sizeof(GrPoint) == stageOffsets[s]);
3218531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
3228531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            }
3238531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        }
3248531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
325ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
326ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
327ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com////////////////////////////////////////////////////////////////////////////////
328ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
32925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#define DEBUG_INVAL_BUFFER 0xdeadcafe
33025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#define DEBUG_INVAL_START_IDX -1
33125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
33225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comGrDrawTarget::GrDrawTarget()
33325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com: fGeoSrcStateStack(&fGeoSrcStateStackStorage) {
3348531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com#if GR_DEBUG
3358531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    VertexLayoutUnitTest();
3368531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com#endif
33725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
338ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#if GR_DEBUG
33925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
34025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
34125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
34225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
343ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
34425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexSrc = kNone_GeometrySrcType;
34525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexSrc  = kNone_GeometrySrcType;
34625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
34725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
34825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comGrDrawTarget::~GrDrawTarget() {
34925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    int popCnt = fGeoSrcStateStack.count() - 1;
35025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    while (popCnt) {
35125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        this->popGeometrySource();
35225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        --popCnt;
35325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
35425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousVertexSource();
35525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousIndexSource();
356ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
357ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
358ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setClip(const GrClip& clip) {
35986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    clipWillBeSet(clip);
360ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fClip = clip;
361ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
362ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
363ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comconst GrClip& GrDrawTarget::getClip() const {
364ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return fClip;
365ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
366ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3678531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comvoid GrDrawTarget::setTexture(int stage, GrTexture* tex) {
3688531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(stage >= 0 && stage < kNumStages);
3698531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    fCurrDrawState.fTextures[stage] = tex;
370ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
371ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3725782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.comconst GrTexture* GrDrawTarget::getTexture(int stage) const {
3735782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    GrAssert(stage >= 0 && stage < kNumStages);
3745782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    return fCurrDrawState.fTextures[stage];
3755782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com}
3765782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
3775782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.comGrTexture* GrDrawTarget::getTexture(int stage) {
3788531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(stage >= 0 && stage < kNumStages);
3798531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return fCurrDrawState.fTextures[stage];
380ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
381ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
382ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setRenderTarget(GrRenderTarget* target) {
383ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState.fRenderTarget = target;
384ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
385ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3865782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.comconst GrRenderTarget* GrDrawTarget::getRenderTarget() const {
3875782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    return fCurrDrawState.fRenderTarget;
3885782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com}
3895782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
3905782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.comGrRenderTarget* GrDrawTarget::getRenderTarget() {
391ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return fCurrDrawState.fRenderTarget;
392ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
393ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3948531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comvoid GrDrawTarget::setViewMatrix(const GrMatrix& m) {
3958531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    fCurrDrawState.fViewMatrix = m;
3968531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
3978531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
398c6cf72381b212eb21e61d5c5e14247b483a77753bsalomon@google.comvoid GrDrawTarget::preConcatViewMatrix(const GrMatrix& matrix) {
3998531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    fCurrDrawState.fViewMatrix.preConcat(matrix);
400ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
401ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
40206afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.comvoid GrDrawTarget::postConcatViewMatrix(const GrMatrix& matrix) {
40306afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com    fCurrDrawState.fViewMatrix.postConcat(matrix);
40406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com}
40506afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
4065782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.comconst GrMatrix& GrDrawTarget::getViewMatrix() const {
4075782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    return fCurrDrawState.fViewMatrix;
408ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
409ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
410ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.combool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
4115782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    // Mike:  Can we cache this somewhere?
4128531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    // Brian: Sure, do we use it often?
413ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
414ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrMatrix inverse;
4158531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    if (fCurrDrawState.fViewMatrix.invert(&inverse)) {
416ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        if (matrix) {
417ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            *matrix = inverse;
418ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
419ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return true;
420ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
421ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return false;
422ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
423ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4248531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comvoid GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) {
4258531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(stage >= 0 && stage < kNumStages);
4268531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    fCurrDrawState.fSamplerStates[stage] = state;
4278531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
4288531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
429ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::enableState(uint32_t bits) {
430ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState.fFlagBits |= bits;
431ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
432ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
433ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::disableState(uint32_t bits) {
434ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState.fFlagBits &= ~(bits);
435ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
436ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
437271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.comvoid GrDrawTarget::setBlendFunc(GrBlendCoeff srcCoeff,
438271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com                                GrBlendCoeff dstCoeff) {
439271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    fCurrDrawState.fSrcBlend = srcCoeff;
440271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    fCurrDrawState.fDstBlend = dstCoeff;
441271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com#if GR_DEBUG
442271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    switch (dstCoeff) {
443271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    case kDC_BlendCoeff:
444271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    case kIDC_BlendCoeff:
445271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    case kDA_BlendCoeff:
446271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    case kIDA_BlendCoeff:
447271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
448271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com                 "coverage stages.\n");
449271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        break;
450271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    default:
451271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        break;
452271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    }
453271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    switch (srcCoeff) {
454271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    case kSC_BlendCoeff:
455271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    case kISC_BlendCoeff:
456271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    case kSA_BlendCoeff:
457271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    case kISA_BlendCoeff:
458271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        GrPrintf("Unexpected src blend coeff. Won't work correctly with"
459271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com                 "coverage stages.\n");
460271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        break;
461271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    default:
462271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        break;
463271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    }
464271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com#endif
465ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
466ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
467ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setColor(GrColor c) {
468ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState.fColor = c;
469ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
470ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
47197c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggovoid GrDrawTarget::setColorFilter(GrColor c, SkXfermode::Mode mode) {
47297c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo    fCurrDrawState.fColorFilterColor = c;
47397c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo    fCurrDrawState.fColorFilterXfermode = mode;
47497c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo}
47597c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo
476ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setAlpha(uint8_t a) {
477ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    this->setColor((a << 24) | (a << 16) | (a << 8) | a);
478ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
479ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
480ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const {
481ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    state->fState = fCurrDrawState;
482ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
483ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
484ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::restoreDrawState(const SavedDrawState& state) {
485ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState = state.fState;
486ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
487ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
488ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) {
489ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState = srcTarget.fCurrDrawState;
490ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
491ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
49225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout,
49325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      int vertexCount,
49425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      void** vertices) {
49525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
49625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    bool acquired = false;
49725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (vertexCount > 0) {
49825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        GrAssert(NULL != vertices);
49925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        this->releasePreviousVertexSource();
50025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fVertexSrc = kNone_GeometrySrcType;
501ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
50225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        acquired = this->onReserveVertexSpace(vertexLayout,
50325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                              vertexCount,
50425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                              vertices);
50525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
50625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (acquired) {
50725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fVertexSrc = kReserved_GeometrySrcType;
50825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fVertexCount = vertexCount;
50925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fVertexLayout = vertexLayout;
51025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    } else if (NULL != vertices) {
51125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        *vertices = NULL;
51225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
51325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return acquired;
51425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
51525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
51625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrDrawTarget::reserveIndexSpace(int indexCount,
51725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                     void** indices) {
51825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
51925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    bool acquired = false;
52025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (indexCount > 0) {
52125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        GrAssert(NULL != indices);
52225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        this->releasePreviousIndexSource();
52325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fIndexSrc = kNone_GeometrySrcType;
52425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
52525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        acquired = this->onReserveIndexSpace(indexCount, indices);
526ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
52725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (acquired) {
52825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fIndexSrc = kReserved_GeometrySrcType;
52925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fIndexCount = indexCount;
53025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    } else if (NULL != indices) {
53125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        *indices = NULL;
53225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
53325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return acquired;
53425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
535ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
536ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
537ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.combool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
538ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                 int32_t* vertexCount,
539ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                 int32_t* indexCount) const {
540ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL != vertexCount) {
541ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        *vertexCount = -1;
542ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
543ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL != indexCount) {
544ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        *indexCount = -1;
545ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
546ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return false;
547ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
548ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
54925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::releasePreviousVertexSource() {
55025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
55125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (geoSrc.fVertexSrc) {
55225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kNone_GeometrySrcType:
55325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
55425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kArray_GeometrySrcType:
55525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            this->releaseVertexArray();
55625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
55725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kReserved_GeometrySrcType:
55825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            this->releaseReservedVertexSpace();
55925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
56025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kBuffer_GeometrySrcType:
56125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            geoSrc.fVertexBuffer->unref();
56225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
56325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
56425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
56525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
56625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        default:
56725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            GrCrash("Unknown Vertex Source Type.");
56825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
56925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
57025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
57125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
57225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::releasePreviousIndexSource() {
57325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
57425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (geoSrc.fIndexSrc) {
57525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kNone_GeometrySrcType:   // these two don't require
57625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
57725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kArray_GeometrySrcType:
57825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            this->releaseIndexArray();
57925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
58025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kReserved_GeometrySrcType:
58125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            this->releaseReservedIndexSpace();
58225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
58325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kBuffer_GeometrySrcType:
58425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            geoSrc.fIndexBuffer->unref();
58525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
58625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
58725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
58825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
58925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        default:
59025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            GrCrash("Unknown Index Source Type.");
59125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
59225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
593ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
594ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
5951c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.comvoid GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
5961c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                          const void* vertexArray,
5971c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                          int vertexCount) {
59825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousVertexSource();
59925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
60025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexSrc = kArray_GeometrySrcType;
60125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexLayout = vertexLayout;
60225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexCount = vertexCount;
603bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com    this->onSetVertexSourceToArray(vertexArray, vertexCount);
604ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
605ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
6061c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.comvoid GrDrawTarget::setIndexSourceToArray(const void* indexArray,
6071c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                         int indexCount) {
60825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousIndexSource();
60925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
61025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexSrc = kArray_GeometrySrcType;
61125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexCount = indexCount;
612bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com    this->onSetIndexSourceToArray(indexArray, indexCount);
613ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
614ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
6151c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.comvoid GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
6161c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                           const GrVertexBuffer* buffer) {
61725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousVertexSource();
61825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
61925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexSrc    = kBuffer_GeometrySrcType;
62025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexBuffer = buffer;
62125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    buffer->ref();
62225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexLayout = vertexLayout;
623ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
624ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
625ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
62625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousIndexSource();
62725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
62825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexSrc     = kBuffer_GeometrySrcType;
62925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexBuffer  = buffer;
63025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    buffer->ref();
631ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
632ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
63325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::resetVertexSource() {
63425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousVertexSource();
63525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
63625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexSrc = kNone_GeometrySrcType;
63725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
63825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
63925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::resetIndexSource() {
64025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousIndexSource();
64125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
64225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexSrc = kNone_GeometrySrcType;
64325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
64425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
64525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::pushGeometrySource() {
64625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->geometrySourceWillPush();
64725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& newState = fGeoSrcStateStack.push_back();
64825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fIndexSrc = kNone_GeometrySrcType;
64925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fVertexSrc = kNone_GeometrySrcType;
65025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
65125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fVertexCount  = ~0;
65225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fVertexBuffer = (GrVertexBuffer*)~0;
65325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fIndexCount   = ~0;
65425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fIndexBuffer = (GrIndexBuffer*)~0;
65525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
65625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
65725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
65825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::popGeometrySource() {
65925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
66025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // if popping last element then pops are unbalanced with pushes
66125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(fGeoSrcStateStack.count() > 1);
66225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
66325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
66425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousVertexSource();
66525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousIndexSource();
66625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fGeoSrcStateStack.pop_back();
66725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
66825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
66925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
67025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
67125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::drawIndexed(GrPrimitiveType type, int startVertex,
67225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                               int startIndex, int vertexCount,
67325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                               int indexCount) {
67425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
67525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
67625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    int maxVertex = startVertex + vertexCount;
67725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    int maxValidVertex;
67825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (geoSrc.fVertexSrc) {
67925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kNone_GeometrySrcType:
68025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            GrCrash("Attempting to draw indexed geom without vertex src.");
68125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kReserved_GeometrySrcType: // fallthrough
68225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kArray_GeometrySrcType:
68325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            maxValidVertex = geoSrc.fVertexCount;
68425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
68525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kBuffer_GeometrySrcType:
686cee661af926cc977addc6e039b7022975a448acebsalomon@google.com            maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() /
68725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                             VertexSize(geoSrc.fVertexLayout);
68825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
68925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
69025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (maxVertex > maxValidVertex) {
69125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        GrCrash("Indexed drawing outside valid vertex range.");
69225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
69325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    int maxIndex = startIndex + indexCount;
69425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    int maxValidIndex;
69525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (geoSrc.fIndexSrc) {
69625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kNone_GeometrySrcType:
69725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            GrCrash("Attempting to draw indexed geom without index src.");
69825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kReserved_GeometrySrcType: // fallthrough
69925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kArray_GeometrySrcType:
70025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            maxValidIndex = geoSrc.fIndexCount;
70125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
70225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kBuffer_GeometrySrcType:
703cee661af926cc977addc6e039b7022975a448acebsalomon@google.com            maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t);
70425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
70525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
70625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (maxIndex > maxValidIndex) {
70725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        GrCrash("Indexed drawing outside valid index range.");
70825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
70925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
7108214587a79c0a4398664289c4d1ce2c0bf542b42bsalomon@google.com    if (indexCount > 0) {
7118214587a79c0a4398664289c4d1ce2c0bf542b42bsalomon@google.com        this->onDrawIndexed(type, startVertex, startIndex,
7128214587a79c0a4398664289c4d1ce2c0bf542b42bsalomon@google.com                            vertexCount, indexCount);
7138214587a79c0a4398664289c4d1ce2c0bf542b42bsalomon@google.com    }
71425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
71525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
71625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
71725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
71825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                  int startVertex,
71925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                  int vertexCount) {
72025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
72125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
72225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    int maxVertex = startVertex + vertexCount;
72325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    int maxValidVertex;
72425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (geoSrc.fVertexSrc) {
72525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kNone_GeometrySrcType:
72625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            GrCrash("Attempting to draw non-indexed geom without vertex src.");
72725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kReserved_GeometrySrcType: // fallthrough
72825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kArray_GeometrySrcType:
72925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            maxValidVertex = geoSrc.fVertexCount;
73025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
73125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kBuffer_GeometrySrcType:
732cee661af926cc977addc6e039b7022975a448acebsalomon@google.com            maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() /
73325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            VertexSize(geoSrc.fVertexLayout);
73425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
73525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
73625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (maxVertex > maxValidVertex) {
73725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        GrCrash("Non-indexed drawing outside valid vertex range.");
73825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
73925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
7408214587a79c0a4398664289c4d1ce2c0bf542b42bsalomon@google.com    if (vertexCount > 0) {
7418214587a79c0a4398664289c4d1ce2c0bf542b42bsalomon@google.com        this->onDrawNonIndexed(type, startVertex, vertexCount);
7428214587a79c0a4398664289c4d1ce2c0bf542b42bsalomon@google.com    }
74325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
74425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
74525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
74686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
747d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com// Some blend modes allow folding a partial coverage value into the color's
748d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com// alpha channel, while others will blend incorrectly.
749d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.combool GrDrawTarget::CanTweakAlphaForCoverage(GrBlendCoeff dstCoeff) {
750d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    /**
751d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com     * The fractional coverage is f
752d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com     * The src and dst coeffs are Cs and Cd
753d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com     * The dst and src colors are S and D
754d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com     * We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D
755d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com     * By tweaking the source color's alpha we're replacing S with S'=fS. It's
756d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com     * obvious that that first term will always be ok. The second term can be
757d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com     * rearranged as [1-(1-Cd)f]D. By substituing in the various possbilities
758d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com     * for Cd we find that only 1, ISA, and ISC produce the correct depth
759d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com     * coeffecient in terms of S' and D.
760d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com     */
761d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    return kOne_BlendCoeff == dstCoeff ||
762d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com           kISA_BlendCoeff == dstCoeff ||
763d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com           kISC_BlendCoeff == dstCoeff;
764d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com}
765d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com
766471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.combool GrDrawTarget::CanDisableBlend(GrVertexLayout layout, const DrState& state) {
767271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    // If we compute a coverage value (using edge AA or a coverage stage) then
768271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    // we can't force blending off.
769aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    if (state.fEdgeAANumEdges > 0 ||
770aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com        layout & kEdge_VertexLayoutBit) {
77192e0f222fb311a296acd081c1216d6b9652347ebsenorblanco@chromium.org        return false;
77292e0f222fb311a296acd081c1216d6b9652347ebsenorblanco@chromium.org    }
773471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    for (int s = state.fFirstCoverageStage; s < kNumStages; ++s) {
774471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com        if (StageWillBeUsed(s, layout, state)) {
775271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com            return false;
776271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        }
777271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    }
77892e0f222fb311a296acd081c1216d6b9652347ebsenorblanco@chromium.org
779471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    if ((kOne_BlendCoeff == state.fSrcBlend) &&
780471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com        (kZero_BlendCoeff == state.fDstBlend)) {
78186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            return true;
78286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
78386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
78486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    // If we have vertex color without alpha then we can't force blend off
785471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    if ((layout & kColor_VertexLayoutBit) ||
786471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com         0xff != GrColorUnpackA(state.fColor)) {
78786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        return false;
78886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
78986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
79086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    // If the src coef will always be 1...
791471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    if (kSA_BlendCoeff != state.fSrcBlend &&
792471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com        kOne_BlendCoeff != state.fSrcBlend) {
79386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        return false;
79486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
79586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
79686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    // ...and the dst coef is always 0...
797471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    if (kISA_BlendCoeff != state.fDstBlend &&
798471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com        kZero_BlendCoeff != state.fDstBlend) {
79986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        return false;
80086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
80186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
802271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    // ...and there isn't a texture stage with an alpha channel...
803471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    for (int s = 0; s < state.fFirstCoverageStage; ++s) {
804471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com        if (StageWillBeUsed(s, layout, state)) {
805471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com            GrAssert(NULL != state.fTextures[s]);
806a47a48dca5045d71cbc5de343404045209a13e15bsalomon@google.com
807471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com            GrPixelConfig config = state.fTextures[s]->config();
80886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
809a47a48dca5045d71cbc5de343404045209a13e15bsalomon@google.com            if (!GrPixelConfigIsOpaque(config)) {
81086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                return false;
81186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
81286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
81386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
81486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
8150bad67303d57c1cc2532eb6fff673cc0101ecd81Scroggo    // ...and there isn't an interesting color filter...
8160bad67303d57c1cc2532eb6fff673cc0101ecd81Scroggo    // TODO: Consider being more aggressive with regards to disabling
8170bad67303d57c1cc2532eb6fff673cc0101ecd81Scroggo    // blending when a color filter is used.
818471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    if (SkXfermode::kDst_Mode != state.fColorFilterXfermode) {
8190bad67303d57c1cc2532eb6fff673cc0101ecd81Scroggo        return false;
8200bad67303d57c1cc2532eb6fff673cc0101ecd81Scroggo    }
8210bad67303d57c1cc2532eb6fff673cc0101ecd81Scroggo
82286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    // ...then we disable blend.
82386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    return true;
82486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
82592e0f222fb311a296acd081c1216d6b9652347ebsenorblanco@chromium.org
826471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.combool GrDrawTarget::CanUseHWAALines(GrVertexLayout layout, const DrState& state) {
827471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    // there is a conflict between using smooth lines and our use of
828471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    // premultiplied alpha. Smooth lines tweak the incoming alpha value
829471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    // but not in a premul-alpha way. So we only use them when our alpha
830d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    // is 0xff and tweaking the color for partial coverage is OK
831471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    return (kAntialias_StateBit & state.fFlagBits) &&
832d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com           CanDisableBlend(layout, state) &&
833d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com           CanTweakAlphaForCoverage(state.fDstBlend);
834d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com}
835d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com
836d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.combool GrDrawTarget::canApplyCoverage() const {
837d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    return this->getCaps().fDualSourceBlendingSupport ||
838d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com           CanTweakAlphaForCoverage(fCurrDrawState.fDstBlend);
839471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com}
840471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com
841471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.combool GrDrawTarget::canDisableBlend() const {
842471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    return CanDisableBlend(this->getGeomSrc().fVertexLayout, fCurrDrawState);
843471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com}
844471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com
84592e0f222fb311a296acd081c1216d6b9652347ebsenorblanco@chromium.org///////////////////////////////////////////////////////////////////////////////
846471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com
847ef3913bcbff265ff86116ae4f3dd2768dc42cccasenorblanco@chromium.orgvoid GrDrawTarget::setEdgeAAData(const Edge* edges, int numEdges) {
848ef3913bcbff265ff86116ae4f3dd2768dc42cccasenorblanco@chromium.org    GrAssert(numEdges <= kMaxEdges);
849ef3913bcbff265ff86116ae4f3dd2768dc42cccasenorblanco@chromium.org    memcpy(fCurrDrawState.fEdgeAAEdges, edges, numEdges * sizeof(Edge));
850ef3913bcbff265ff86116ae4f3dd2768dc42cccasenorblanco@chromium.org    fCurrDrawState.fEdgeAANumEdges = numEdges;
85192e0f222fb311a296acd081c1216d6b9652347ebsenorblanco@chromium.org}
85292e0f222fb311a296acd081c1216d6b9652347ebsenorblanco@chromium.org
85392e0f222fb311a296acd081c1216d6b9652347ebsenorblanco@chromium.org
85425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
85525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
85686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.comvoid GrDrawTarget::drawRect(const GrRect& rect,
85786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                            const GrMatrix* matrix,
858ffca400ef6f96a280c3e2c09210f950af64a1f24bsalomon@google.com                            StageBitfield stageEnableBitfield,
85986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                            const GrRect* srcRects[],
86086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                            const GrMatrix* srcMatrices[]) {
861ffca400ef6f96a280c3e2c09210f950af64a1f24bsalomon@google.com    GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects);
86286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
86386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    AutoReleaseGeometry geo(this, layout, 4, 0);
8646513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com    if (!geo.succeeded()) {
8656513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com        GrPrintf("Failed to get space for vertices!\n");
8666513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com        return;
8676513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com    }
86886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
86986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    SetRectVertices(rect, matrix, srcRects,
87086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                    srcMatrices, layout, geo.vertices());
87186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
87286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
87386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
87486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
875ffca400ef6f96a280c3e2c09210f950af64a1f24bsalomon@google.comGrVertexLayout GrDrawTarget::GetRectVertexLayout(StageBitfield stageEnableBitfield,
87686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                                 const GrRect* srcRects[]) {
87786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrVertexLayout layout = 0;
87886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
87986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    for (int i = 0; i < kNumStages; ++i) {
88086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        int numTC = 0;
881ffca400ef6f96a280c3e2c09210f950af64a1f24bsalomon@google.com        if (stageEnableBitfield & (1 << i)) {
88286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            if (NULL != srcRects && NULL != srcRects[i]) {
88386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                layout |= StageTexCoordVertexLayoutBit(i, numTC);
88486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                ++numTC;
88586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            } else {
88686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                layout |= StagePosAsTexCoordVertexLayoutBit(i);
88786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
88886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
88986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
89086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    return layout;
89186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
892dea2f8d86378b791a2de94384a18e29f13f65a3ebsalomon@google.com
893dea2f8d86378b791a2de94384a18e29f13f65a3ebsalomon@google.comvoid GrDrawTarget::clipWillBeSet(const GrClip& clip) {
894dea2f8d86378b791a2de94384a18e29f13f65a3ebsalomon@google.com}
895dea2f8d86378b791a2de94384a18e29f13f65a3ebsalomon@google.com
89686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.comvoid GrDrawTarget::SetRectVertices(const GrRect& rect,
89786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   const GrMatrix* matrix,
89886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   const GrRect* srcRects[],
89986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   const GrMatrix* srcMatrices[],
90086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   GrVertexLayout layout,
90186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   void* vertices) {
90286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#if GR_DEBUG
90386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    // check that the layout and srcRects agree
90486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    for (int i = 0; i < kNumStages; ++i) {
90586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (VertexTexCoordsForStage(i, layout) >= 0) {
90686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]);
90786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        } else {
90886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]);
90986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
91086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
91186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#endif
91286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
91386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    int stageOffsets[kNumStages];
91486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    int colorOffset;
915aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    int edgeOffset;
916aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets,
917aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                                            &colorOffset, &edgeOffset);
91886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrAssert(-1 == colorOffset);
919aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com    GrAssert(-1 == edgeOffset);
92086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
92186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop,
92286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                            rect.fRight, rect.fBottom,
92386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                            vsize);
92486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    if (NULL != matrix) {
92586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4);
92686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
92786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
92886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    for (int i = 0; i < kNumStages; ++i) {
92986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (stageOffsets[i] > 0) {
93086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) +
93186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                                stageOffsets[i]);
93286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop,
93386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                               srcRects[i]->fRight, srcRects[i]->fBottom,
93486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                               vsize);
93586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            if (NULL != srcMatrices && NULL != srcMatrices[i]) {
93686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                srcMatrices[i]->mapPointsWithStride(coords, vsize, 4);
93786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
93886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
93986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
94086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
94186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
94225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
9437ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com
94406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.comGrDrawTarget::AutoStateRestore::AutoStateRestore() {
94506afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com    fDrawTarget = NULL;
94606afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com}
947ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
948ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target) {
949ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fDrawTarget = target;
9507d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com    if (NULL != fDrawTarget) {
9517d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com        fDrawTarget->saveCurrentDrawState(&fDrawState);
9527d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com    }
953ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
954ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
955ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrDrawTarget::AutoStateRestore::~AutoStateRestore() {
9567d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com    if (NULL != fDrawTarget) {
9577d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com        fDrawTarget->restoreDrawState(fDrawState);
9587d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com    }
959ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
9607d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com
96106afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.comvoid GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target) {
96206afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com    if (target != fDrawTarget) {
96306afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com        if (NULL != fDrawTarget) {
96406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com            fDrawTarget->restoreDrawState(fDrawState);
96506afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com        }
96606afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com        if (NULL != target) {
967d19aa27e03f0fcd540af6b243a657bcd7be98305bsalomon@google.com            target->saveCurrentDrawState(&fDrawState);
96806afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com        }
96906afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com        fDrawTarget = target;
97006afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com    }
97106afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com}
9727ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com
97325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
9747ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com
9757ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.comGrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(GrDrawTarget* target,
9767ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                                                       int stageMask) {
9777ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com    GrAssert(NULL != target);
9787ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com
9797ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com    fDrawTarget = target;
9807ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com    fViewMatrix = target->getViewMatrix();
9817ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com    fStageMask = stageMask;
9827ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com    if (fStageMask) {
9837ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com        GrMatrix invVM;
9847ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com        if (fViewMatrix.invert(&invVM)) {
9857ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com            for (int s = 0; s < kNumStages; ++s) {
9867ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                if (fStageMask & (1 << s)) {
9877ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                    fSamplerMatrices[s] = target->getSamplerMatrix(s);
9887ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                }
9897ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com            }
9907ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com            target->preConcatSamplerMatrices(fStageMask, invVM);
9917ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com        } else {
9927ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com            // sad trombone sound
9937ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com            fStageMask = 0;
9947ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com        }
9957ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com    }
9967ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com    target->setViewMatrix(GrMatrix::I());
9977ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com}
9987ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com
9997ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.comGrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() {
10007ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com    fDrawTarget->setViewMatrix(fViewMatrix);
10017ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com    for (int s = 0; s < kNumStages; ++s) {
10027ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com        if (fStageMask & (1 << s)) {
10037ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com            fDrawTarget->setSamplerMatrix(s, fSamplerMatrices[s]);
10047ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com        }
10057ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com    }
10067ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com}
10077ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com
100825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
100925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
101025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comGrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
101125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         GrDrawTarget*  target,
101225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         GrVertexLayout vertexLayout,
101325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         int vertexCount,
101425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         int indexCount) {
101525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fTarget = NULL;
101625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->set(target, vertexLayout, vertexCount, indexCount);
101725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
101825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
101925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comGrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
102025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fTarget = NULL;
102125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
102225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
102325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comGrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
102425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->reset();
102525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
102625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
102725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget*  target,
102825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                            GrVertexLayout vertexLayout,
102925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                            int vertexCount,
103025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                            int indexCount) {
103125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->reset();
103225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fTarget = target;
103325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    bool success = true;
103425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (NULL != fTarget) {
103525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        fTarget = target;
103625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        if (vertexCount > 0) {
103725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            success = target->reserveVertexSpace(vertexLayout,
103825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                                 vertexCount,
103925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                                 &fVertices);
104025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            if (!success) {
104125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                this->reset();
104225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            }
104325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        }
104425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        if (success && indexCount > 0) {
104525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            success = target->reserveIndexSpace(indexCount, &fIndices);
104625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            if (!success) {
104725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                this->reset();
104825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            }
104925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        }
105025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
105125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(success == (NULL != fTarget));
105225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return success;
105325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
105425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
105525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::AutoReleaseGeometry::reset() {
105625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (NULL != fTarget) {
105725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        if (NULL != fVertices) {
105825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            fTarget->resetVertexSource();
105925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        }
106025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        if (NULL != fIndices) {
106125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            fTarget->resetIndexSource();
106225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        }
106325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        fTarget = NULL;
106425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
1065cb0c5ab54d69f813f4faf4c7ac2092358bc663aabsalomon@google.com    fVertices = NULL;
1066cb0c5ab54d69f813f4faf4c7ac2092358bc663aabsalomon@google.com    fIndices = NULL;
106725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
106825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
106918c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.comvoid GrDrawTarget::Caps::print() const {
107018c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    static const char* gNY[] = {"NO", "YES"};
107118c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("8 Bit Palette Support       : %s\n", gNY[f8BitPaletteSupport]);
107218c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("NPOT Texture Support        : %s\n", gNY[fNPOTTextureSupport]);
107318c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("NPOT Texture Tile Support   : %s\n", gNY[fNPOTTextureTileSupport]);
107418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("NPOT Render Target Support  : %s\n", gNY[fNPOTRenderTargetSupport]);
107518c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("Two Sided Stencil Support   : %s\n", gNY[fTwoSidedStencilSupport]);
107618c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("Stencil Wrap Ops  Support   : %s\n", gNY[fStencilWrapOpsSupport]);
107718c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("HW AA Lines Support         : %s\n", gNY[fHWAALineSupport]);
107818c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("Shader Support              : %s\n", gNY[fShaderSupport]);
107918c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("Shader Derivative Support   : %s\n", gNY[fShaderDerivativeSupport]);
108018c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("FSAA Support                : %s\n", gNY[fFSAASupport]);
108118c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSupport]);
108218c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("Buffer Lock Support         : %s\n", gNY[fBufferLockSupport]);
108318c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("Min Render Target Width     : %d\n", fMinRenderTargetWidth);
108418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("Min Render Target Height    : %d\n", fMinRenderTargetHeight);
108518c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("Max Texture Size            : %d\n", fMaxTextureSize);
108618c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrPrintf("Max Render Target Size      : %d\n", fMaxRenderTargetSize);
108718c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com}
108818c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com
1089