1 /*
2 Copyright 2011 Google Inc.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 #ifndef GrContext_impl_DEFINED
18 #define GrContext_impl_DEFINED
19
20 struct GrContext::OffscreenRecord {
OffscreenRecordOffscreenRecord21 OffscreenRecord() { fEntry0 = NULL; fEntry1 = NULL; }
~OffscreenRecordOffscreenRecord22 ~OffscreenRecord() { GrAssert(NULL == fEntry0 && NULL == fEntry1); }
23
24 enum Downsample {
25 k4x4TwoPass_Downsample,
26 k4x4SinglePass_Downsample,
27 kFSAA_Downsample
28 } fDownsample;
29 GrTextureEntry* fEntry0;
30 GrTextureEntry* fEntry1;
31 GrDrawTarget::SavedDrawState fSavedState;
32 };
33
34 template <typename POS_SRC, typename TEX_SRC,
35 typename COL_SRC, typename IDX_SRC>
drawCustomVertices(const GrPaint & paint,GrPrimitiveType primitiveType,const POS_SRC & posSrc,const TEX_SRC * texCoordSrc,const COL_SRC * colorSrc,const IDX_SRC * idxSrc)36 inline void GrContext::drawCustomVertices(const GrPaint& paint,
37 GrPrimitiveType primitiveType,
38 const POS_SRC& posSrc,
39 const TEX_SRC* texCoordSrc,
40 const COL_SRC* colorSrc,
41 const IDX_SRC* idxSrc) {
42
43 GrDrawTarget::AutoReleaseGeometry geo;
44
45 GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
46
47 bool hasTexCoords[GrPaint::kTotalStages] = {
48 NULL != texCoordSrc, // texCoordSrc provides explicit stage 0 coords
49 0 // remaining stages use positions
50 };
51 GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords);
52
53 if (NULL != colorSrc) {
54 layout |= GrDrawTarget::kColor_VertexLayoutBit;
55 }
56
57 int vertexCount = posSrc.count();
58 int indexCount = (NULL != idxSrc) ? idxSrc->count() : 0;
59
60 if (!geo.set(target, layout, vertexCount, indexCount)) {
61 GrPrintf("Failed to get space for vertices!");
62 return;
63 }
64
65 int texOffsets[GrDrawTarget::kMaxTexCoords];
66 int colorOffset;
67 int vsize = GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
68 texOffsets,
69 &colorOffset);
70 void* curVertex = geo.vertices();
71
72 for (int i = 0; i < vertexCount; ++i) {
73 posSrc.writeValue(i, (GrPoint*)curVertex);
74
75 if (texOffsets[0] > 0) {
76 texCoordSrc->writeValue(i, (GrPoint*)((intptr_t)curVertex + texOffsets[0]));
77 }
78 if (colorOffset > 0) {
79 colorSrc->writeValue(i, (GrColor*)((intptr_t)curVertex + colorOffset));
80 }
81 curVertex = (void*)((intptr_t)curVertex + vsize);
82 }
83
84 uint16_t* indices = (uint16_t*) geo.indices();
85 for (int i = 0; i < indexCount; ++i) {
86 idxSrc->writeValue(i, indices + i);
87 }
88
89 bool doAA = false;
90 OffscreenRecord record;
91 GrIRect bounds;
92
93 if (-1 == texOffsets[0] && -1 == colorOffset &&
94 this->doOffscreenAA(target, paint, GrIsPrimTypeLines(primitiveType))) {
95 GrRect b;
96 b.setBounds(geo.positions(), vertexCount);
97 target->getViewMatrix().mapRect(&b);
98 b.roundOut(&bounds);
99 if (this->setupOffscreenAAPass1(target, false, bounds, &record)) {
100 doAA = true;
101 }
102 }
103
104 if (NULL == idxSrc) {
105 target->drawNonIndexed(primitiveType, 0, vertexCount);
106 } else {
107 target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
108 }
109
110 if (doAA) {
111 geo.set(NULL, 0, 0, 0); // have to release geom before can draw again
112 this->offscreenAAPass2(target, paint, bounds, &record);
113 }
114 }
115
116 class GrNullTexCoordSource {
117 public:
writeValue(int i,GrPoint * dstCoord)118 void writeValue(int i, GrPoint* dstCoord) const { GrAssert(false); }
119 };
120
121 class GrNullColorSource {
122 public:
writeValue(int i,GrColor * dstColor)123 void writeValue(int i, GrColor* dstColor) const { GrAssert(false); }
124 };
125
126 class GrNullIndexSource {
127 public:
writeValue(int i,uint16_t * dstIndex)128 void writeValue(int i, uint16_t* dstIndex) const { GrAssert(false); }
count()129 int count() const { GrAssert(false); return 0; }
130 };
131
132 template <typename POS_SRC>
drawCustomVertices(const GrPaint & paint,GrPrimitiveType primitiveType,const POS_SRC & posSrc)133 inline void GrContext::drawCustomVertices(const GrPaint& paint,
134 GrPrimitiveType primitiveType,
135 const POS_SRC& posSrc) {
136 this->drawCustomVertices<POS_SRC,
137 GrNullTexCoordSource,
138 GrNullColorSource,
139 GrNullIndexSource>(paint, primitiveType, posSrc,
140 NULL, NULL, NULL);
141 }
142
143 template <typename POS_SRC, typename TEX_SRC>
drawCustomVertices(const GrPaint & paint,GrPrimitiveType primitiveType,const POS_SRC & posSrc,const TEX_SRC * texCoordSrc)144 inline void GrContext::drawCustomVertices(const GrPaint& paint,
145 GrPrimitiveType primitiveType,
146 const POS_SRC& posSrc,
147 const TEX_SRC* texCoordSrc) {
148 this->drawCustomVertices<POS_SRC, TEX_SRC,
149 GrNullColorSource,
150 GrNullIndexSource>(paint, primitiveType, posSrc,
151 texCoordSrc, NULL, NULL);
152 }
153
154 template <typename POS_SRC, typename TEX_SRC, typename COL_SRC>
drawCustomVertices(const GrPaint & paint,GrPrimitiveType primitiveType,const POS_SRC & posSrc,const TEX_SRC * texCoordSrc,const COL_SRC * colorSrc)155 inline void GrContext::drawCustomVertices(const GrPaint& paint,
156 GrPrimitiveType primitiveType,
157 const POS_SRC& posSrc,
158 const TEX_SRC* texCoordSrc,
159 const COL_SRC* colorSrc) {
160 drawCustomVertices<POS_SRC, TEX_SRC, COL_SRC,
161 GrNullIndexSource>(paint, primitiveType, posSrc,
162 texCoordSrc, colorSrc, NULL);
163 }
164
165 #endif
166