blob: b0faa2cb2c5009a59c4dd5b3e82caeac80efae74 [file] [log] [blame]
bsalomon@google.com27847de2011-02-22 20:59:41 +00001/*
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
bsalomon@google.coma47a48d2011-04-26 20:22:11 +000020struct GrContext::OffscreenRecord {
21 OffscreenRecord() { fEntry = NULL; }
22 ~OffscreenRecord() { GrAssert(NULL == fEntry); }
23
24 GrTextureEntry* fEntry;
25 GrDrawTarget::SavedDrawState fSavedState;
26};
27
bsalomon@google.com27847de2011-02-22 20:59:41 +000028template <typename POS_SRC, typename TEX_SRC,
29 typename COL_SRC, typename IDX_SRC>
30inline void GrContext::drawCustomVertices(const GrPaint& paint,
31 GrPrimitiveType primitiveType,
32 const POS_SRC& posSrc,
33 const TEX_SRC* texCoordSrc,
34 const COL_SRC* colorSrc,
35 const IDX_SRC* idxSrc) {
36
37 GrVertexLayout layout = 0;
38
39 GrDrawTarget::AutoReleaseGeometry geo;
40
41 GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
42
43 if (NULL != paint.getTexture()) {
44 if (NULL != texCoordSrc) {
45 layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
46 } else {
47 layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
48 }
49 }
50
51 if (NULL != colorSrc) {
52 layout |= GrDrawTarget::kColor_VertexLayoutBit;
53 }
54
bsalomon@google.coma47a48d2011-04-26 20:22:11 +000055 bool doOffscreenAA = false;
56 OffscreenRecord record;
57 if (paint.fAntiAlias &&
58 !this->getRenderTarget()->isMultisampled() &&
59 !(GrIsPrimTypeLines(primitiveType) && fGpu->supportsAALines()) &&
60 this->setupOffscreenAAPass1(target, false, &record)) {
61 doOffscreenAA = true;
62 layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(kOffscreenStage);
63 }
64
bsalomon@google.com27847de2011-02-22 20:59:41 +000065 int vertexCount = posSrc.count();
66 int indexCount = (NULL != idxSrc) ? idxSrc->count() : 0;
67
68 if (!geo.set(target, layout, vertexCount, indexCount)) {
69 GrPrintf("Failed to get space for vertices!");
70 return;
71 }
72
73 int texOffsets[GrDrawTarget::kMaxTexCoords];
74 int colorOffset;
75 int vsize = GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
76 texOffsets,
77 &colorOffset);
78 void* curVertex = geo.vertices();
79
80 for (int i = 0; i < vertexCount; ++i) {
81 posSrc.writeValue(i, (GrPoint*)curVertex);
82
83 if (texOffsets[0] > 0) {
84 texCoordSrc->writeValue(i, (GrPoint*)((intptr_t)curVertex + texOffsets[0]));
85 }
86 if (colorOffset > 0) {
87 colorSrc->writeValue(i, (GrColor*)((intptr_t)curVertex + colorOffset));
88 }
89 curVertex = (void*)((intptr_t)curVertex + vsize);
90 }
91
92 uint16_t* indices = (uint16_t*) geo.indices();
93 for (int i = 0; i < indexCount; ++i) {
94 idxSrc->writeValue(i, indices + i);
95 }
96
97 if (NULL == idxSrc) {
98 target->drawNonIndexed(primitiveType, 0, vertexCount);
99 } else {
100 target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
101 }
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000102
103 if (doOffscreenAA) {
104 // draw to the offscreen
105 if (NULL != indices) {
106 target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
107 } else {
108 target->drawNonIndexed(primitiveType, 0, vertexCount);
109 }
110 // When there are custom texture coordinates we can't just draw
111 // a quad to sample the offscreen. Instead we redraw the geometry to
112 // specify the texture coords. This isn't quite right either, primitives
113 // will only be eroded at the edges, not expanded into partial pixels.
114 bool useRect = 0 == (layout & GrDrawTarget::StageTexCoordVertexLayoutBit(0,0));
115 if (useRect) {
116 target->setViewMatrix(GrMatrix::I());
117 }
118 this->setupOffscreenAAPass2(target, paint, &record);
119 if (useRect) {
120 geo.set(NULL, 0, 0, 0);
121 int stages = (NULL != paint.getTexture()) ? 0x1 : 0x0;
122 stages |= (1 << kOffscreenStage);
123 GrRect dstRect(0, 0,
124 target->getRenderTarget()->width(),
125 target->getRenderTarget()->height());
126 target->drawSimpleRect(dstRect, NULL, stages);
127 target->drawSimpleRect(dstRect, NULL, stages);
128 } else {
129 if (NULL != indices) {
130 target->drawIndexed (primitiveType, 0, 0, vertexCount, indexCount);
131 } else {
132 target->drawNonIndexed(primitiveType, 0, vertexCount);
133 }
134 }
135 this->endOffscreenAA(target, &record);
136 } else {
137 if (NULL != indices) {
138 target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
139 } else {
140 target->drawNonIndexed(primitiveType, 0, vertexCount);
141 }
142 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000143}
144
145class GrNullTexCoordSource {
146public:
147 void writeValue(int i, GrPoint* dstCoord) const { GrAssert(false); }
148};
149
150class GrNullColorSource {
151public:
152 void writeValue(int i, GrColor* dstColor) const { GrAssert(false); }
153};
154
155class GrNullIndexSource {
156public:
157 void writeValue(int i, uint16_t* dstIndex) const { GrAssert(false); }
158 int count() const { GrAssert(false); return 0; }
159};
160
161template <typename POS_SRC>
162inline void GrContext::drawCustomVertices(const GrPaint& paint,
163 GrPrimitiveType primitiveType,
164 const POS_SRC& posSrc) {
165 this->drawCustomVertices<POS_SRC,
166 GrNullTexCoordSource,
167 GrNullColorSource,
168 GrNullIndexSource>(paint, primitiveType, posSrc,
169 NULL, NULL, NULL);
170}
171
172template <typename POS_SRC, typename TEX_SRC>
173inline void GrContext::drawCustomVertices(const GrPaint& paint,
174 GrPrimitiveType primitiveType,
175 const POS_SRC& posSrc,
176 const TEX_SRC* texCoordSrc) {
177 this->drawCustomVertices<POS_SRC, TEX_SRC,
178 GrNullColorSource,
179 GrNullIndexSource>(paint, primitiveType, posSrc,
180 texCoordSrc, NULL, NULL);
181}
182
183template <typename POS_SRC, typename TEX_SRC, typename COL_SRC>
184inline void GrContext::drawCustomVertices(const GrPaint& paint,
185 GrPrimitiveType primitiveType,
186 const POS_SRC& posSrc,
187 const TEX_SRC* texCoordSrc,
188 const COL_SRC* colorSrc) {
189 drawCustomVertices<POS_SRC, TEX_SRC, COL_SRC,
190 GrNullIndexSource>(paint, primitiveType, posSrc,
191 texCoordSrc, colorSrc, NULL);
192}
193
194#endif