blob: feff02e94d71a92dce43b8ef9c402b6abbffc9c8 [file] [log] [blame]
junov@google.comf93e7172011-03-31 21:26:24 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
junov@google.comf93e7172011-03-31 21:26:24 +00006 */
7
bsalomon@google.com5739d2c2012-05-31 15:07:19 +00008#include "GrGpuGL.h"
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
bsalomon@google.coma469c282012-10-24 18:28:34 +000010#include "GrEffect.h"
bsalomon@google.comd698f772012-10-25 13:22:00 +000011#include "GrGLEffect.h"
junov@google.comf93e7172011-03-31 21:26:24 +000012
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000013typedef GrGLUniformManager::UniformHandle UniformHandle;
14static const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidUniformHandle;
15
junov@google.comf93e7172011-03-31 21:26:24 +000016#define SKIP_CACHE_CHECK true
17#define GR_UINT32_MAX static_cast<uint32_t>(-1)
18
bsalomon@google.comc1d2a582012-06-01 15:08:19 +000019GrGpuGL::ProgramCache::ProgramCache(const GrGLContextInfo& gl)
20 : fCount(0)
21 , fCurrLRUStamp(0)
22 , fGL(gl) {
23}
junov@google.comf93e7172011-03-31 21:26:24 +000024
bsalomon@google.comc1d2a582012-06-01 15:08:19 +000025void GrGpuGL::ProgramCache::abandon() {
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000026 for (int i = 0; i < fCount; ++i) {
27 GrAssert(NULL != fEntries[i].fProgram.get());
28 fEntries[i].fProgram->abandon();
29 fEntries[i].fProgram.reset(NULL);
30 }
bsalomon@google.comc1d2a582012-06-01 15:08:19 +000031 fCount = 0;
32}
33
bsalomon@google.com91207482013-02-12 21:45:24 +000034GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgram::Desc& desc,
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +000035 const GrEffectStage* stages[]) {
bsalomon@google.comc1d2a582012-06-01 15:08:19 +000036 Entry newEntry;
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000037 newEntry.fKey.setKeyData(desc.asKey());
38
bsalomon@google.comc1d2a582012-06-01 15:08:19 +000039 Entry* entry = fHashCache.find(newEntry.fKey);
40 if (NULL == entry) {
bsalomon@google.comecb60aa2012-07-18 13:20:29 +000041 newEntry.fProgram.reset(GrGLProgram::Create(fGL, desc, stages));
42 if (NULL == newEntry.fProgram.get()) {
bsalomon@google.comc1d2a582012-06-01 15:08:19 +000043 return NULL;
44 }
45 if (fCount < kMaxEntries) {
46 entry = fEntries + fCount;
47 ++fCount;
48 } else {
49 GrAssert(kMaxEntries == fCount);
50 entry = fEntries;
51 for (int i = 1; i < kMaxEntries; ++i) {
52 if (fEntries[i].fLRUStamp < entry->fLRUStamp) {
53 entry = fEntries + i;
junov@google.comf93e7172011-03-31 21:26:24 +000054 }
junov@google.comf93e7172011-03-31 21:26:24 +000055 }
bsalomon@google.comc1d2a582012-06-01 15:08:19 +000056 fHashCache.remove(entry->fKey, entry);
junov@google.comf93e7172011-03-31 21:26:24 +000057 }
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000058 *entry = newEntry;
bsalomon@google.comc1d2a582012-06-01 15:08:19 +000059 fHashCache.insert(entry->fKey, entry);
junov@google.comf93e7172011-03-31 21:26:24 +000060 }
bsalomon@google.comc1d2a582012-06-01 15:08:19 +000061
62 entry->fLRUStamp = fCurrLRUStamp;
63 if (GR_UINT32_MAX == fCurrLRUStamp) {
64 // wrap around! just trash our LRU, one time hit.
65 for (int i = 0; i < fCount; ++i) {
66 fEntries[i].fLRUStamp = 0;
67 }
68 }
69 ++fCurrLRUStamp;
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +000070 return entry->fProgram;
bsalomon@google.comc1d2a582012-06-01 15:08:19 +000071}
junov@google.comf93e7172011-03-31 21:26:24 +000072
bsalomon@google.com1e257a52011-07-06 19:52:16 +000073////////////////////////////////////////////////////////////////////////////////
74
bsalomon@google.com5739d2c2012-05-31 15:07:19 +000075void GrGpuGL::abandonResources(){
76 INHERITED::abandonResources();
77 fProgramCache->abandon();
78 fHWProgramID = 0;
79}
80
81////////////////////////////////////////////////////////////////////////////////
82
bsalomon@google.com0b77d682011-08-19 13:28:54 +000083#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
84
bsalomon@google.comded4f4b2012-06-28 18:48:06 +000085void GrGpuGL::flushViewMatrix(DrawType type) {
bsalomon@google.com4c883782012-06-04 19:05:11 +000086 const GrGLRenderTarget* rt = static_cast<const GrGLRenderTarget*>(this->getDrawState().getRenderTarget());
87 SkISize viewportSize;
88 const GrGLIRect& viewport = rt->getViewport();
89 viewportSize.set(viewport.fWidth, viewport.fHeight);
junov@google.comf93e7172011-03-31 21:26:24 +000090
bsalomon@google.comb9086a02012-11-01 18:02:54 +000091 const SkMatrix& vm = this->getDrawState().getViewMatrix();
bsalomon@google.com4c883782012-06-04 19:05:11 +000092
bsalomon@google.comded4f4b2012-06-28 18:48:06 +000093 if (kStencilPath_DrawType == type) {
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +000094 if (fHWPathMatrixState.fLastOrigin != rt->origin() ||
95 fHWPathMatrixState.fViewMatrix != vm ||
bsalomon@google.com05a718c2012-06-29 14:01:53 +000096 fHWPathMatrixState.fRTSize != viewportSize) {
97 // rescale the coords from skia's "device" coords to GL's normalized coords,
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +000098 // and perform a y-flip if required.
bsalomon@google.comb9086a02012-11-01 18:02:54 +000099 SkMatrix m;
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000100 if (kBottomLeft_GrSurfaceOrigin == rt->origin()) {
101 m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(-2) / rt->height());
102 m.postTranslate(-SK_Scalar1, SK_Scalar1);
103 } else {
104 m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(2) / rt->height());
105 m.postTranslate(-SK_Scalar1, -SK_Scalar1);
106 }
bsalomon@google.com05a718c2012-06-29 14:01:53 +0000107 m.preConcat(vm);
108
109 // GL wants a column-major 4x4.
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000110 GrGLfloat mv[] = {
111 // col 0
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000112 SkScalarToFloat(m[SkMatrix::kMScaleX]),
113 SkScalarToFloat(m[SkMatrix::kMSkewY]),
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000114 0,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000115 SkScalarToFloat(m[SkMatrix::kMPersp0]),
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000116
117 // col 1
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000118 SkScalarToFloat(m[SkMatrix::kMSkewX]),
119 SkScalarToFloat(m[SkMatrix::kMScaleY]),
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000120 0,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000121 SkScalarToFloat(m[SkMatrix::kMPersp1]),
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000122
123 // col 2
124 0, 0, 0, 0,
125
126 // col3
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000127 SkScalarToFloat(m[SkMatrix::kMTransX]),
128 SkScalarToFloat(m[SkMatrix::kMTransY]),
bsalomon@google.com05a718c2012-06-29 14:01:53 +0000129 0.0f,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000130 SkScalarToFloat(m[SkMatrix::kMPersp2])
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000131 };
132 GL_CALL(MatrixMode(GR_GL_PROJECTION));
bsalomon@google.com05a718c2012-06-29 14:01:53 +0000133 GL_CALL(LoadMatrixf(mv));
134 fHWPathMatrixState.fViewMatrix = vm;
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000135 fHWPathMatrixState.fRTSize = viewportSize;
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000136 fHWPathMatrixState.fLastOrigin = rt->origin();
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000137 }
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000138 } else if (fCurrentProgram->fOrigin != rt->origin() ||
139 !fCurrentProgram->fViewMatrix.cheapEqualTo(vm) ||
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +0000140 fCurrentProgram->fViewportSize != viewportSize) {
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000141 SkMatrix m;
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000142 if (kBottomLeft_GrSurfaceOrigin == rt->origin()) {
143 m.setAll(
144 SkIntToScalar(2) / viewportSize.fWidth, 0, -SK_Scalar1,
145 0,-SkIntToScalar(2) / viewportSize.fHeight, SK_Scalar1,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000146 0, 0, SkMatrix::I()[8]);
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000147 } else {
148 m.setAll(
149 SkIntToScalar(2) / viewportSize.fWidth, 0, -SK_Scalar1,
150 0, SkIntToScalar(2) / viewportSize.fHeight,-SK_Scalar1,
151 0, 0, SkMatrix::I()[8]);
152 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000153 m.setConcat(m, vm);
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000154
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000155 // ES doesn't allow you to pass true to the transpose param,
156 // so do our own transpose
157 GrGLfloat mt[] = {
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000158 SkScalarToFloat(m[SkMatrix::kMScaleX]),
159 SkScalarToFloat(m[SkMatrix::kMSkewY]),
160 SkScalarToFloat(m[SkMatrix::kMPersp0]),
161 SkScalarToFloat(m[SkMatrix::kMSkewX]),
162 SkScalarToFloat(m[SkMatrix::kMScaleY]),
163 SkScalarToFloat(m[SkMatrix::kMPersp1]),
164 SkScalarToFloat(m[SkMatrix::kMTransX]),
165 SkScalarToFloat(m[SkMatrix::kMTransY]),
166 SkScalarToFloat(m[SkMatrix::kMPersp2])
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000167 };
bsalomon@google.com34cccde2013-01-04 18:34:30 +0000168 fCurrentProgram->fUniformManager.setMatrix3f(
169 fCurrentProgram->fUniformHandles.fViewMatrixUni,
170 mt);
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +0000171 fCurrentProgram->fViewMatrix = vm;
172 fCurrentProgram->fViewportSize = viewportSize;
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000173 fCurrentProgram->fOrigin = rt->origin();
bsalomon@google.com91961302011-05-09 18:39:58 +0000174 }
junov@google.comf93e7172011-03-31 21:26:24 +0000175}
176
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000177bool GrGpuGL::flushGraphicsState(DrawType type) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000178 const GrDrawState& drawState = this->getDrawState();
179
bsalomon@google.comc96cb3a2012-06-04 19:31:00 +0000180 // GrGpu::setupClipAndFlushState should have already checked this
181 // and bailed if not true.
182 GrAssert(NULL != drawState.getRenderTarget());
183
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000184 if (kStencilPath_DrawType != type) {
185 this->flushMiscFixedFunctionState();
bsalomon@google.comc96cb3a2012-06-04 19:31:00 +0000186
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000187 GrBlendCoeff srcCoeff;
188 GrBlendCoeff dstCoeff;
bsalomon@google.com2b446732013-02-12 16:47:41 +0000189 GrDrawState::BlendOptFlags blendOpts = drawState.getBlendOpts(false, &srcCoeff, &dstCoeff);
190 if (GrDrawState::kSkipDraw_BlendOptFlag & blendOpts) {
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000191 return false;
192 }
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000193
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +0000194 const GrEffectStage* stages[GrDrawState::kNumStages];
195 for (int i = 0; i < GrDrawState::kNumStages; ++i) {
196 stages[i] = drawState.isStageEnabled(i) ? &drawState.getStage(i) : NULL;
197 }
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +0000198 GrGLProgram::Desc desc;
bsalomon@google.com91207482013-02-12 21:45:24 +0000199 GrGLProgram::BuildDesc(this->getDrawState(),
200 kDrawPoints_DrawType == type,
201 blendOpts,
202 srcCoeff,
203 dstCoeff,
204 this,
205 &desc);
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +0000206
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +0000207 fCurrentProgram.reset(fProgramCache->getProgram(desc, stages));
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +0000208 if (NULL == fCurrentProgram.get()) {
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000209 GrAssert(!"Failed to create program!");
210 return false;
211 }
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +0000212 fCurrentProgram.get()->ref();
junov@google.comf93e7172011-03-31 21:26:24 +0000213
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +0000214 if (fHWProgramID != fCurrentProgram->fProgramID) {
215 GL_CALL(UseProgram(fCurrentProgram->fProgramID));
216 fHWProgramID = fCurrentProgram->fProgramID;
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000217 }
bsalomon@google.com9ba4fa62012-07-16 17:36:28 +0000218 fCurrentProgram->overrideBlend(&srcCoeff, &dstCoeff);
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000219 this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff);
junov@google.comf93e7172011-03-31 21:26:24 +0000220
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000221 GrColor color;
222 GrColor coverage;
bsalomon@google.com2b446732013-02-12 16:47:41 +0000223 if (blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag) {
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000224 color = 0;
225 coverage = 0;
bsalomon@google.com2b446732013-02-12 16:47:41 +0000226 } else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) {
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000227 color = 0xffffffff;
228 coverage = drawState.getCoverage();
229 } else {
230 color = drawState.getColor();
231 coverage = drawState.getCoverage();
232 }
bsalomon@google.com91207482013-02-12 21:45:24 +0000233 fCurrentProgram->setData(this, color, coverage, &fSharedGLProgramState);
junov@google.comf93e7172011-03-31 21:26:24 +0000234 }
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000235 this->flushStencil(type);
236 this->flushViewMatrix(type);
bsalomon@google.coma3201942012-06-21 19:58:20 +0000237 this->flushScissor();
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000238 this->flushAAState(type);
bsalomon@google.com4c883782012-06-04 19:05:11 +0000239
robertphillips@google.com7b112892012-07-31 15:18:21 +0000240 GrIRect* devRect = NULL;
241 GrIRect devClipBounds;
robertphillips@google.com3e11c0b2012-07-11 18:20:35 +0000242 if (drawState.isClipState()) {
bsalomon@google.com02ddc8b2013-01-28 15:35:28 +0000243 this->getClip()->getConservativeBounds(drawState.getRenderTarget(), &devClipBounds);
robertphillips@google.com7b112892012-07-31 15:18:21 +0000244 devRect = &devClipBounds;
bsalomon@google.com4c883782012-06-04 19:05:11 +0000245 }
246 // This must come after textures are flushed because a texture may need
247 // to be msaa-resolved (which will modify bound FBO state).
robertphillips@google.com7b112892012-07-31 15:18:21 +0000248 this->flushRenderTarget(devRect);
bsalomon@google.com4c883782012-06-04 19:05:11 +0000249
junov@google.comf93e7172011-03-31 21:26:24 +0000250 return true;
251}
252
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000253void GrGpuGL::setupGeometry(const DrawInfo& info, int* startIndexOffset) {
junov@google.comf93e7172011-03-31 21:26:24 +0000254
255 int newColorOffset;
bsalomon@google.coma3108262011-10-10 14:08:47 +0000256 int newCoverageOffset;
tomhudson@google.com93813632011-10-27 20:21:16 +0000257 int newTexCoordOffsets[GrDrawState::kMaxTexCoords];
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000258 int newEdgeOffset;
junov@google.comf93e7172011-03-31 21:26:24 +0000259
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000260 GrVertexLayout currLayout = this->getDrawState().getVertexLayout();
bsalomon@google.come79c8152012-03-29 19:07:12 +0000261
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000262 GrGLsizei newStride = GrDrawState::VertexSizeAndOffsetsByIdx(currLayout,
263 newTexCoordOffsets,
264 &newColorOffset,
265 &newCoverageOffset,
266 &newEdgeOffset);
junov@google.comf93e7172011-03-31 21:26:24 +0000267 int oldColorOffset;
bsalomon@google.coma3108262011-10-10 14:08:47 +0000268 int oldCoverageOffset;
tomhudson@google.com93813632011-10-27 20:21:16 +0000269 int oldTexCoordOffsets[GrDrawState::kMaxTexCoords];
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000270 int oldEdgeOffset;
271
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000272 GrGLsizei oldStride = GrDrawState::VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout,
273 oldTexCoordOffsets,
274 &oldColorOffset,
275 &oldCoverageOffset,
276 &oldEdgeOffset);
junov@google.comf93e7172011-03-31 21:26:24 +0000277
278 int extraVertexOffset;
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000279 this->setBuffers(info.isIndexed(), &extraVertexOffset, startIndexOffset);
junov@google.comf93e7172011-03-31 21:26:24 +0000280
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000281 size_t vertexOffset = (info.startVertex() + extraVertexOffset) * newStride;
junov@google.comf93e7172011-03-31 21:26:24 +0000282
283 // all the Pointers must be set if any of these are true
284 bool allOffsetsChange = fHWGeometryState.fArrayPtrsDirty ||
285 vertexOffset != fHWGeometryState.fVertexOffset ||
286 newStride != oldStride;
287
bsalomon@google.com85983282013-02-07 22:00:29 +0000288 if (allOffsetsChange) {
bsalomon@google.com91961302011-05-09 18:39:58 +0000289 int idx = GrGLProgram::PositionAttributeIdx();
bsalomon@google.com85983282013-02-07 22:00:29 +0000290 GL_CALL(VertexAttribPointer(idx, 2, GR_GL_FLOAT, false, newStride, (GrGLvoid*)vertexOffset));
junov@google.comf93e7172011-03-31 21:26:24 +0000291 fHWGeometryState.fVertexOffset = vertexOffset;
292 }
293
tomhudson@google.com93813632011-10-27 20:21:16 +0000294 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
junov@google.comf93e7172011-03-31 21:26:24 +0000295 if (newTexCoordOffsets[t] > 0) {
296 GrGLvoid* texCoordOffset = (GrGLvoid*)(vertexOffset + newTexCoordOffsets[t]);
bsalomon@google.com91961302011-05-09 18:39:58 +0000297 int idx = GrGLProgram::TexCoordAttributeIdx(t);
junov@google.comf93e7172011-03-31 21:26:24 +0000298 if (oldTexCoordOffsets[t] <= 0) {
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000299 GL_CALL(EnableVertexAttribArray(idx));
bsalomon@google.com85983282013-02-07 22:00:29 +0000300 GL_CALL(VertexAttribPointer(idx, 2, GR_GL_FLOAT, false, newStride, texCoordOffset));
301 } else if (allOffsetsChange || newTexCoordOffsets[t] != oldTexCoordOffsets[t]) {
302 GL_CALL(VertexAttribPointer(idx, 2, GR_GL_FLOAT, false, newStride, texCoordOffset));
junov@google.comf93e7172011-03-31 21:26:24 +0000303 }
304 } else if (oldTexCoordOffsets[t] > 0) {
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000305 GL_CALL(DisableVertexAttribArray(GrGLProgram::TexCoordAttributeIdx(t)));
junov@google.comf93e7172011-03-31 21:26:24 +0000306 }
307 }
308
309 if (newColorOffset > 0) {
bsalomon@google.com91207482013-02-12 21:45:24 +0000310 fSharedGLProgramState.fConstAttribColor = GrColor_ILLEGAL;
junov@google.comf93e7172011-03-31 21:26:24 +0000311 GrGLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset);
bsalomon@google.com91961302011-05-09 18:39:58 +0000312 int idx = GrGLProgram::ColorAttributeIdx();
junov@google.comf93e7172011-03-31 21:26:24 +0000313 if (oldColorOffset <= 0) {
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000314 GL_CALL(EnableVertexAttribArray(idx));
bsalomon@google.com85983282013-02-07 22:00:29 +0000315 GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE, true, newStride, colorOffset));
junov@google.comf93e7172011-03-31 21:26:24 +0000316 } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
bsalomon@google.com85983282013-02-07 22:00:29 +0000317 GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE, true, newStride, colorOffset));
junov@google.comf93e7172011-03-31 21:26:24 +0000318 }
319 } else if (oldColorOffset > 0) {
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000320 GL_CALL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx()));
junov@google.comf93e7172011-03-31 21:26:24 +0000321 }
322
bsalomon@google.coma3108262011-10-10 14:08:47 +0000323 if (newCoverageOffset > 0) {
bsalomon@google.com91207482013-02-12 21:45:24 +0000324 fSharedGLProgramState.fConstAttribColor = GrColor_ILLEGAL;
bsalomon@google.come10f6fd2011-10-11 20:15:26 +0000325 GrGLvoid* coverageOffset = (int8_t*)(vertexOffset + newCoverageOffset);
bsalomon@google.coma3108262011-10-10 14:08:47 +0000326 int idx = GrGLProgram::CoverageAttributeIdx();
327 if (oldCoverageOffset <= 0) {
328 GL_CALL(EnableVertexAttribArray(idx));
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000329 GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
bsalomon@google.coma3108262011-10-10 14:08:47 +0000330 true, newStride, coverageOffset));
331 } else if (allOffsetsChange || newCoverageOffset != oldCoverageOffset) {
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000332 GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
bsalomon@google.coma3108262011-10-10 14:08:47 +0000333 true, newStride, coverageOffset));
334 }
335 } else if (oldCoverageOffset > 0) {
336 GL_CALL(DisableVertexAttribArray(GrGLProgram::CoverageAttributeIdx()));
337 }
338
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000339 if (newEdgeOffset > 0) {
340 GrGLvoid* edgeOffset = (int8_t*)(vertexOffset + newEdgeOffset);
341 int idx = GrGLProgram::EdgeAttributeIdx();
342 if (oldEdgeOffset <= 0) {
343 GL_CALL(EnableVertexAttribArray(idx));
bsalomon@google.com85983282013-02-07 22:00:29 +0000344 GL_CALL(VertexAttribPointer(idx, 4, GR_GL_FLOAT, false, newStride, edgeOffset));
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000345 } else if (allOffsetsChange || newEdgeOffset != oldEdgeOffset) {
bsalomon@google.com85983282013-02-07 22:00:29 +0000346 GL_CALL(VertexAttribPointer(idx, 4, GR_GL_FLOAT, false, newStride, edgeOffset));
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000347 }
348 } else if (oldEdgeOffset > 0) {
349 GL_CALL(DisableVertexAttribArray(GrGLProgram::EdgeAttributeIdx()));
350 }
351
bsalomon@google.come79c8152012-03-29 19:07:12 +0000352 fHWGeometryState.fVertexLayout = currLayout;
junov@google.comf93e7172011-03-31 21:26:24 +0000353 fHWGeometryState.fArrayPtrsDirty = false;
354}