GrDrawTarget.cpp revision 86afc2ae27fec84c01eb0e81a32766bdaf67dca8
1ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/*
2ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    Copyright 2010 Google Inc.
3ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    Licensed under the Apache License, Version 2.0 (the "License");
5ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    you may not use this file except in compliance with the License.
6ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    You may obtain a copy of the License at
7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com         http://www.apache.org/licenses/LICENSE-2.0
9ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
10ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    Unless required by applicable law or agreed to in writing, software
11ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    distributed under the License is distributed on an "AS IS" BASIS,
12ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    See the License for the specific language governing permissions and
14ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    limitations under the License.
15ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
16ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
17ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
18ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrDrawTarget.h"
19ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrGpuVertex.h"
2086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#include "GrTexture.h"
21ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
228531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com// recursive helper for creating mask with all the tex coord bits set for
238531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com// one stage
248531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comtemplate <int N>
258531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comstatic int stage_mask_recur(int stage) {
265782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    return GrDrawTarget::StageTexCoordVertexLayoutBit(stage, N) |
278531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com           stage_mask_recur<N+1>(stage);
288531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
29d728f6ecfab79c08044a837fbcae2996f7b8619areed@google.comtemplate<> // linux build doesn't like static on specializations
30d728f6ecfab79c08044a837fbcae2996f7b8619areed@google.comint stage_mask_recur<GrDrawTarget::kNumStages>(int) { return 0; }
31ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
328531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com// mask of all tex coord indices for one stage
338531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comstatic int stage_tex_coord_mask(int stage) {
348531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return stage_mask_recur<0>(stage);
358531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
368531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
378531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com// mask of all bits relevant to one stage
388531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comstatic int stage_mask(int stage) {
395782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    return stage_tex_coord_mask(stage) |
408531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com           GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(stage);
418531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
428531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
438531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com// recursive helper for creating mask of with all bits set relevant to one
448531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com// texture coordinate index
458531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comtemplate <int N>
468531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comstatic int tex_coord_mask_recur(int texCoordIdx) {
475782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    return GrDrawTarget::StageTexCoordVertexLayoutBit(N, texCoordIdx) |
488531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com           tex_coord_mask_recur<N+1>(texCoordIdx);
498531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
50d728f6ecfab79c08044a837fbcae2996f7b8619areed@google.comtemplate<> // linux build doesn't like static on specializations
51d728f6ecfab79c08044a837fbcae2996f7b8619areed@google.comint tex_coord_mask_recur<GrDrawTarget::kMaxTexCoords>(int) { return 0; }
528531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
538531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com// mask of all bits relevant to one texture coordinate index
548531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comstatic int tex_coord_idx_mask(int texCoordIdx) {
558531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return tex_coord_mask_recur<0>(texCoordIdx);
568531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
578531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
588531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.combool check_layout(GrVertexLayout layout) {
598531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    // can only have 1 or 0 bits set for each stage.
608531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
618531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        int stageBits = layout & stage_mask(s);
628531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        if (stageBits && !GrIsPow2(stageBits)) {
638531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            return false;
64ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
658531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
668531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return true;
678531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
688531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
698531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comsize_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
708531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
715782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
725782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
738531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                        sizeof(GrGpuTextVertex) :
748531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                        sizeof(GrPoint);
758531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
768531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    size_t size = vecSize; // position
778531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    for (int t = 0; t < kMaxTexCoords; ++t) {
788531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        if (tex_coord_idx_mask(t) & vertexLayout) {
798531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            size += vecSize;
80ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
81ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
828531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    if (vertexLayout & kColor_VertexLayoutBit) {
838531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        size += sizeof(GrColor);
848531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
858531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return size;
86ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
87ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
888531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comint GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) {
898531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
908531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    if (StagePosAsTexCoordVertexLayoutBit(stage) & vertexLayout) {
91ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return 0;
92ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
938531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    int tcIdx = VertexTexCoordsForStage(stage, vertexLayout);
948531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    if (tcIdx >= 0) {
955782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
965782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
978531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                    sizeof(GrGpuTextVertex) :
988531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                    sizeof(GrPoint);
998531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        int offset = vecSize; // position
1008531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        // figure out how many tex coordinates are present and precede this one.
1018531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        for (int t = 0; t < tcIdx; ++t) {
1028531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            if (tex_coord_idx_mask(t) & vertexLayout) {
1038531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                offset += vecSize;
1048531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            }
1058531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        }
1068531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        return offset;
1078531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
1088531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
109ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return -1;
110ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
111ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
112ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comint  GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) {
1138531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
1145782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
115ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (vertexLayout & kColor_VertexLayoutBit) {
1165782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com        int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
1178531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                    sizeof(GrGpuTextVertex) :
1188531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                    sizeof(GrPoint);
1198531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        int offset = vecSize; // position
1208531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        // figure out how many tex coordinates are present and precede this one.
1218531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        for (int t = 0; t < kMaxTexCoords; ++t) {
1228531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            if (tex_coord_idx_mask(t) & vertexLayout) {
1238531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                offset += vecSize;
1248531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            }
125ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
1268531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        return offset;
127ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
128ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return -1;
129ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
130ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
1318531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comint GrDrawTarget::VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
1328531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                             int texCoordOffsetsByIdx[kMaxTexCoords],
1338531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                             int* colorOffset) {
1348531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
1355782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
1368531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(NULL != texCoordOffsetsByIdx);
137ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(NULL != colorOffset);
138ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
1395782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
1408531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                                    sizeof(GrGpuTextVertex) :
1418531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                                    sizeof(GrPoint);
1428531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    int size = vecSize; // position
1435782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
1448531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    for (int t = 0; t < kMaxTexCoords; ++t) {
1458531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        if (tex_coord_idx_mask(t) & vertexLayout) {
1468531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            texCoordOffsetsByIdx[t] = size;
1478531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            size += vecSize;
148ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        } else {
1498531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            texCoordOffsetsByIdx[t] = -1;
150ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
1518531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
1528531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    if (kColor_VertexLayoutBit & vertexLayout) {
1538531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        *colorOffset = size;
1548531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        size += sizeof(GrColor);
1558531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    } else {
1568531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        *colorOffset = -1;
1578531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
1588531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return size;
1598531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
1608531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
1618531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comint GrDrawTarget::VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
1628531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                              int texCoordOffsetsByStage[kNumStages],
1638531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                              int* colorOffset) {
1648531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
1658531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
1668531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(NULL != texCoordOffsetsByStage);
1678531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(NULL != colorOffset);
1685782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
1698531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    int texCoordOffsetsByIdx[kMaxTexCoords];
1705782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    int size = VertexSizeAndOffsetsByIdx(vertexLayout,
1715782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com                                         texCoordOffsetsByIdx,
1728531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                         colorOffset);
1738531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    for (int s = 0; s < kNumStages; ++s) {
1748531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        int tcIdx;
1758531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        if (StagePosAsTexCoordVertexLayoutBit(s) & vertexLayout) {
1768531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            texCoordOffsetsByStage[s] = 0;
1778531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        } else if ((tcIdx = VertexTexCoordsForStage(s, vertexLayout)) >= 0) {
1788531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            texCoordOffsetsByStage[s] = texCoordOffsetsByIdx[tcIdx];
179ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        } else {
1808531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            texCoordOffsetsByStage[s] = -1;
181ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
182ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
1835782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    return size;
1848531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
1858531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
1868531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.combool GrDrawTarget::VertexUsesStage(int stage, GrVertexLayout vertexLayout) {
1878531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(stage < kNumStages);
1888531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
1898531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return !!(stage_mask(stage) & vertexLayout);
1908531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
1918531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
1925782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.combool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex,
1938531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                                         GrVertexLayout vertexLayout) {
1945782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    GrAssert(coordIndex < kMaxTexCoords);
1958531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
1968531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return !!(tex_coord_idx_mask(coordIndex) & vertexLayout);
1978531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
1988531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
1998531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comint GrDrawTarget::VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout) {
2008531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(stage < kNumStages);
2018531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(check_layout(vertexLayout));
2028531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    int bit = vertexLayout & stage_tex_coord_mask(stage);
2038531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    if (bit) {
2048531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        // figure out which set of texture coordates is used
2058531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ...
2068531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        // and start at bit 0.
2078531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t));
2088531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        return (32 - Gr_clz(bit) - 1) / kNumStages;
2098531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
2108531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return -1;
211ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
212ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2138531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comvoid GrDrawTarget::VertexLayoutUnitTest() {
2148531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    // not necessarily exhaustive
2158531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    static bool run;
2168531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    if (!run) {
2178531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        run = true;
2188531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        for (int s = 0; s < kNumStages; ++s) {
2198531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
2208531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(!VertexUsesStage(s, 0));
2218531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(-1 == VertexStageCoordOffset(s, 0));
2228531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrVertexLayout stageMask = 0;
2238531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            for (int t = 0; t < kMaxTexCoords; ++t) {
2248531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                stageMask |= StageTexCoordVertexLayoutBit(s,t);
2258531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            }
2265782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com            GrAssert(1 == kMaxTexCoords || !check_layout(stageMask));
2278531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(stage_tex_coord_mask(s) == stageMask);
2288531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            stageMask |= StagePosAsTexCoordVertexLayoutBit(s);
2298531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(stage_mask(s) == stageMask);
2308531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(!check_layout(stageMask));
2318531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        }
2328531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        for (int t = 0; t < kMaxTexCoords; ++t) {
2338531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrVertexLayout tcMask = 0;
2348531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(!VertexUsesTexCoordIdx(t, 0));
2358531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            for (int s = 0; s < kNumStages; ++s) {
2368531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                tcMask |= StageTexCoordVertexLayoutBit(s,t);
2378531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(VertexUsesStage(s, tcMask));
2388531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
2398531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(VertexUsesTexCoordIdx(t, tcMask));
2408531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
2418531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(t == VertexTexCoordsForStage(s, tcMask));
2428531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                for (int s2 = s + 1; s2 < kNumStages; ++s2) {
2438531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrAssert(-1 == VertexStageCoordOffset(s2, tcMask));
2448531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrAssert(!VertexUsesStage(s2, tcMask));
2458531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));
2465782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
2471962832771a435426a0ed6a1cf5069c45918b141bsalomon@google.com                #if GR_DEBUG
2488531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2);
2491962832771a435426a0ed6a1cf5069c45918b141bsalomon@google.com                #endif
2508531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
2518531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrAssert(VertexUsesStage(s2, posAsTex));
2528531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
2538531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                    GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex));
2548531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                }
2551962832771a435426a0ed6a1cf5069c45918b141bsalomon@google.com            #if GR_DEBUG
2568531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
2571962832771a435426a0ed6a1cf5069c45918b141bsalomon@google.com            #endif
2588531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
2598531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
2608531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            }
2618531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(tex_coord_idx_mask(t) == tcMask);
2628531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(check_layout(tcMask));
2635782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
2648531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            int stageOffsets[kNumStages];
2658531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            int colorOffset;
2668531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            int size;
2678531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            size = VertexSizeAndOffsetsByStage(tcMask, stageOffsets, &colorOffset);
2688531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(2*sizeof(GrPoint) == size);
2698531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            GrAssert(-1 == colorOffset);
2708531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            for (int s = 0; s < kNumStages; ++s) {
2718531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(VertexUsesStage(s, tcMask));
2728531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(sizeof(GrPoint) == stageOffsets[s]);
2738531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com                GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
2748531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com            }
2758531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        }
2768531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    }
277ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
278ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
279ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com////////////////////////////////////////////////////////////////////////////////
280ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
281ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrDrawTarget::GrDrawTarget() {
2828531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com#if GR_DEBUG
2838531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    VertexLayoutUnitTest();
2848531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com#endif
285ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fReservedGeometry.fLocked = false;
286ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#if GR_DEBUG
287ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fReservedGeometry.fVertexCount  = ~0;
288ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fReservedGeometry.fIndexCount   = ~0;
289ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
290ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType;
291ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fGeometrySrc.fIndexSrc  = kReserved_GeometrySrcType;
292ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
293ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
294ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setClip(const GrClip& clip) {
29586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    clipWillBeSet(clip);
296ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fClip = clip;
297ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
298ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
299ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comconst GrClip& GrDrawTarget::getClip() const {
300ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return fClip;
301ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
302ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3038531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comvoid GrDrawTarget::setTexture(int stage, GrTexture* tex) {
3048531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(stage >= 0 && stage < kNumStages);
3058531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    fCurrDrawState.fTextures[stage] = tex;
306ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
307ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3085782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.comconst GrTexture* GrDrawTarget::getTexture(int stage) const {
3095782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    GrAssert(stage >= 0 && stage < kNumStages);
3105782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    return fCurrDrawState.fTextures[stage];
3115782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com}
3125782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
3135782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.comGrTexture* GrDrawTarget::getTexture(int stage) {
3148531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(stage >= 0 && stage < kNumStages);
3158531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    return fCurrDrawState.fTextures[stage];
316ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
317ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
318ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setRenderTarget(GrRenderTarget* target) {
319ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState.fRenderTarget = target;
320ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
321ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3225782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.comconst GrRenderTarget* GrDrawTarget::getRenderTarget() const {
3235782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    return fCurrDrawState.fRenderTarget;
3245782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com}
3255782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
3265782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.comGrRenderTarget* GrDrawTarget::getRenderTarget() {
327ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return fCurrDrawState.fRenderTarget;
328ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
329ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3308531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comvoid GrDrawTarget::setViewMatrix(const GrMatrix& m) {
3318531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    fCurrDrawState.fViewMatrix = m;
3328531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
3338531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
334ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::concatViewMatrix(const GrMatrix& matrix) {
3358531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    fCurrDrawState.fViewMatrix.preConcat(matrix);
336ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
337ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3385782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.comconst GrMatrix& GrDrawTarget::getViewMatrix() const {
3395782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    return fCurrDrawState.fViewMatrix;
340ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
341ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
342ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.combool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
3435782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    // Mike:  Can we cache this somewhere?
3448531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    // Brian: Sure, do we use it often?
345ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
346ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrMatrix inverse;
3478531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    if (fCurrDrawState.fViewMatrix.invert(&inverse)) {
348ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        if (matrix) {
349ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            *matrix = inverse;
350ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
351ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return true;
352ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
353ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return false;
354ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
355ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3568531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comvoid GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) {
3578531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(stage >= 0 && stage < kNumStages);
3588531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    fCurrDrawState.fSamplerStates[stage] = state;
3598531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com}
3608531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com
3618531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.comvoid GrDrawTarget::setTextureMatrix(int stage, const GrMatrix& m) {
3628531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    GrAssert(stage >= 0 && stage < kNumStages);
3638531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com    fCurrDrawState.fTextureMatrices[stage] = m;
364ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
365ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3666f7fbc9fbb584b9b9fa6ed3a677d71ecd49aafcebsalomon@google.comvoid GrDrawTarget::concatTextureMatrix(int stage, const GrMatrix& m) {
3676f7fbc9fbb584b9b9fa6ed3a677d71ecd49aafcebsalomon@google.com    GrAssert(stage >= 0 && stage < kNumStages);
3686f7fbc9fbb584b9b9fa6ed3a677d71ecd49aafcebsalomon@google.com    fCurrDrawState.fTextureMatrices[stage].preConcat(m);
3696f7fbc9fbb584b9b9fa6ed3a677d71ecd49aafcebsalomon@google.com}
3706f7fbc9fbb584b9b9fa6ed3a677d71ecd49aafcebsalomon@google.com
3716f7fbc9fbb584b9b9fa6ed3a677d71ecd49aafcebsalomon@google.comconst GrMatrix& GrDrawTarget::getTextureMatrix(int stage) const {
3726f7fbc9fbb584b9b9fa6ed3a677d71ecd49aafcebsalomon@google.com    GrAssert(stage >= 0 && stage < kNumStages);
3736f7fbc9fbb584b9b9fa6ed3a677d71ecd49aafcebsalomon@google.com    return fCurrDrawState.fTextureMatrices[stage];
3746f7fbc9fbb584b9b9fa6ed3a677d71ecd49aafcebsalomon@google.com}
3756f7fbc9fbb584b9b9fa6ed3a677d71ecd49aafcebsalomon@google.com
376ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setStencilPass(StencilPass pass) {
377ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState.fStencilPass = pass;
378ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
379ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
380ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setReverseFill(bool reverse) {
381ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState.fReverseFill = reverse;
382ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
383ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
384ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::enableState(uint32_t bits) {
385ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState.fFlagBits |= bits;
386ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
387ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
388ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::disableState(uint32_t bits) {
389ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState.fFlagBits &= ~(bits);
390ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
391ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
392ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setBlendFunc(BlendCoeff srcCoef,
393ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                BlendCoeff dstCoef) {
394ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState.fSrcBlend = srcCoef;
395ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState.fDstBlend = dstCoef;
396ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
397ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
398ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setColor(GrColor c) {
399ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState.fColor = c;
400ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
401ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
402ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setAlpha(uint8_t a) {
403ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    this->setColor((a << 24) | (a << 16) | (a << 8) | a);
404ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
405ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
406ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const {
407ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    state->fState = fCurrDrawState;
408ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
409ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
410ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::restoreDrawState(const SavedDrawState& state) {
411ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState = state.fState;
412ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
413ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
414ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) {
415ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCurrDrawState = srcTarget.fCurrDrawState;
416ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
417ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
418ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
419ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.combool GrDrawTarget::reserveAndLockGeometry(GrVertexLayout    vertexLayout,
420ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                          uint32_t          vertexCount,
421ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                          uint32_t          indexCount,
422ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                          void**            vertices,
423ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                          void**            indices) {
424ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(!fReservedGeometry.fLocked);
425ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fReservedGeometry.fVertexCount  = vertexCount;
426ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fReservedGeometry.fIndexCount   = indexCount;
427ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
428ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fReservedGeometry.fLocked = acquireGeometryHelper(vertexLayout,
429ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                                      vertices,
430ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                                      indices);
431ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (fReservedGeometry.fLocked) {
432ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        if (vertexCount) {
433ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType;
434ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            fGeometrySrc.fVertexLayout = vertexLayout;
435ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
436ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        if (indexCount) {
437ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            fGeometrySrc.fIndexSrc = kReserved_GeometrySrcType;
438ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
439ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
440ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return fReservedGeometry.fLocked;
441ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
442ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
443ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.combool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
444ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                 int32_t* vertexCount,
445ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                 int32_t* indexCount) const {
446ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(!fReservedGeometry.fLocked);
447ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL != vertexCount) {
448ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        *vertexCount = -1;
449ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
450ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL != indexCount) {
451ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        *indexCount = -1;
452ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
453ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return false;
454ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
455ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
456ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::releaseReservedGeometry() {
457ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(fReservedGeometry.fLocked);
458ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    releaseGeometryHelper();
459ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fReservedGeometry.fLocked = false;
460ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
461ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4621c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.comvoid GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
4631c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                          const void* vertexArray,
4641c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                          int vertexCount) {
4651c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fGeometrySrc.fVertexSrc = kArray_GeometrySrcType;
466ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fGeometrySrc.fVertexLayout = vertexLayout;
4671c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    setVertexSourceToArrayHelper(vertexArray, vertexCount);
468ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
469ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4701c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.comvoid GrDrawTarget::setIndexSourceToArray(const void* indexArray,
4711c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                         int indexCount) {
4721c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fGeometrySrc.fIndexSrc = kArray_GeometrySrcType;
4731c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    setIndexSourceToArrayHelper(indexArray, indexCount);
474ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
475ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4761c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.comvoid GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
4771c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                           const GrVertexBuffer* buffer) {
478ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fGeometrySrc.fVertexSrc    = kBuffer_GeometrySrcType;
479ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fGeometrySrc.fVertexBuffer = buffer;
480ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fGeometrySrc.fVertexLayout = vertexLayout;
481ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
482ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
483ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
484ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fGeometrySrc.fIndexSrc     = kBuffer_GeometrySrcType;
485ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fGeometrySrc.fIndexBuffer  = buffer;
486ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
487ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
48886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
48986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
49086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.combool GrDrawTarget::canDisableBlend() const {
49186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    if ((kOne_BlendCoeff == fCurrDrawState.fSrcBlend) &&
49286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        (kZero_BlendCoeff == fCurrDrawState.fDstBlend)) {
49386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            return true;
49486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
49586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
49686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    // If we have vertex color without alpha then we can't force blend off
49786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    if ((fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) ||
49886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com         0xff != GrColorUnpackA(fCurrDrawState.fColor)) {
49986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        return false;
50086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
50186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
50286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    // If the src coef will always be 1...
50386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    if (kSA_BlendCoeff != fCurrDrawState.fSrcBlend &&
50486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        kOne_BlendCoeff != fCurrDrawState.fSrcBlend) {
50586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        return false;
50686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
50786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
50886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    // ...and the dst coef is always 0...
50986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    if (kISA_BlendCoeff != fCurrDrawState.fDstBlend &&
51086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        kZero_BlendCoeff != fCurrDrawState.fDstBlend) {
51186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        return false;
51286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
51386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
51486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    // ...and there isn't a texture with an alpha channel...
51586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    for (int s = 0; s < kNumStages; ++s) {
51686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (VertexUsesStage(s, fGeometrySrc.fVertexLayout)) {
51786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrAssert(NULL != fCurrDrawState.fTextures[s]);
51886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrTexture::PixelConfig config = fCurrDrawState.fTextures[s]->config();
51986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
52086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            if (GrTexture::kRGB_565_PixelConfig != config &&
52186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                GrTexture::kRGBX_8888_PixelConfig != config) {
52286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                return false;
52386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
52486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
52586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
52686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
52786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    // ...then we disable blend.
52886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    return true;
52986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
53086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
53186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.comvoid GrDrawTarget::drawRect(const GrRect& rect,
53286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                            const GrMatrix* matrix,
53386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                            int stageEnableMask,
53486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                            const GrRect* srcRects[],
53586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                            const GrMatrix* srcMatrices[]) {
53686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GR_STATIC_ASSERT(8*sizeof(int) >= kNumStages);
53786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
53886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrVertexLayout layout = GetRectVertexLayout(stageEnableMask, srcRects);
53986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
54086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    AutoReleaseGeometry geo(this, layout, 4, 0);
54186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
54286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    SetRectVertices(rect, matrix, srcRects,
54386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                    srcMatrices, layout, geo.vertices());
54486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
54586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
54686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
54786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
54886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.comGrVertexLayout GrDrawTarget::GetRectVertexLayout(int stageEnableMask,
54986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                                 const GrRect* srcRects[]) {
55086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrVertexLayout layout = 0;
55186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
55286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    for (int i = 0; i < kNumStages; ++i) {
55386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        int numTC = 0;
55486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (stageEnableMask & (1 << i)) {
55586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            if (NULL != srcRects && NULL != srcRects[i]) {
55686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                layout |= StageTexCoordVertexLayoutBit(i, numTC);
55786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                ++numTC;
55886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            } else {
55986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                layout |= StagePosAsTexCoordVertexLayoutBit(i);
56086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
56186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
56286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
56386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    return layout;
56486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
56586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.comvoid GrDrawTarget::SetRectVertices(const GrRect& rect,
56686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   const GrMatrix* matrix,
56786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   const GrRect* srcRects[],
56886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   const GrMatrix* srcMatrices[],
56986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   GrVertexLayout layout,
57086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   void* vertices) {
57186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#if GR_DEBUG
57286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    // check that the layout and srcRects agree
57386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    for (int i = 0; i < kNumStages; ++i) {
57486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (VertexTexCoordsForStage(i, layout) >= 0) {
57586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]);
57686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        } else {
57786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]);
57886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
57986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
58086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#endif
58186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
58286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    int stageOffsets[kNumStages];
58386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    int colorOffset;
58486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets, &colorOffset);
58586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrAssert(-1 == colorOffset);
58686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
58786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop,
58886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                            rect.fRight, rect.fBottom,
58986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                            vsize);
59086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    if (NULL != matrix) {
59186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4);
59286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
59386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
59486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    for (int i = 0; i < kNumStages; ++i) {
59586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (stageOffsets[i] > 0) {
59686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) +
59786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                                stageOffsets[i]);
59886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop,
59986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                               srcRects[i]->fRight, srcRects[i]->fBottom,
60086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                               vsize);
60186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            if (NULL != srcMatrices && NULL != srcMatrices[i]) {
60286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                srcMatrices[i]->mapPointsWithStride(coords, vsize, 4);
60386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
60486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
60586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
60686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
60786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
60886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
609ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
610ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target) {
611ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fDrawTarget = target;
6127d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com    if (NULL != fDrawTarget) {
6137d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com        fDrawTarget->saveCurrentDrawState(&fDrawState);
6147d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com    }
615ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
616ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
617ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrDrawTarget::AutoStateRestore::~AutoStateRestore() {
6187d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com    if (NULL != fDrawTarget) {
6197d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com        fDrawTarget->restoreDrawState(fDrawState);
6207d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com    }
621ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
6227d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com
623