void GrGpuGLShaders::resetContextHelper() { fHWGeometryState.fVertexLayout = 0; fHWGeometryState.fVertexOffset = ~0; GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION)); for (int t = 0; t < kMaxTexCoords; ++t) { GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t))); } GR_GL(EnableVertexAttribArray(POS_ATTR_LOCATION)); fHWProgramID = 0; }
int rb_remove_vertex_attrib (struct rb_vertex_array* array, int count, const int* list_of_attrib_indices) { int i = 0; int err = 0; if(!array || count < 0 || (count > 0 && !list_of_attrib_indices)) return -1; OGL(BindVertexArray(array->name)); for(i = 0; i < count; ++i) { const int current_attrib = list_of_attrib_indices[i]; if(current_attrib < 0) { err = -1; } else { OGL(DisableVertexAttribArray(current_attrib)); } } OGL(BindVertexArray(array->ctxt->state_cache.vertex_array_binding)); return err; }
void GrGpuGLShaders::onResetContext() { INHERITED::onResetContext(); fHWGeometryState.fVertexOffset = ~0; // Third party GL code may have left vertex attributes enabled. Some GL // implementations (osmesa) may read vetex attributes that are not required // by the current shader. Therefore, we have to ensure that only the // attributes we require for the current draw are enabled or we may cause an // invalid read. // Disable all vertex layout bits so that next flush will assume all // optional vertex attributes are disabled. fHWGeometryState.fVertexLayout = 0; // We always use the this attribute and assume it is always enabled. int posAttrIdx = GrGLProgram::PositionAttributeIdx(); GL_CALL(EnableVertexAttribArray(posAttrIdx)); // Disable all other vertex attributes. for (int va = 0; va < fMaxVertexAttribs; ++va) { if (va != posAttrIdx) { GL_CALL(DisableVertexAttribArray(va)); } } fHWProgramID = 0; }
void GrGLAttribArrayState::disableUnusedArrays(const GrGpuGL* gpu, uint64_t usedMask) { int count = fAttribArrayStates.count(); for (int i = 0; i < count; ++i) { if (!(usedMask & 0x1)) { if (!fAttribArrayStates[i].fEnableIsValid || fAttribArrayStates[i].fEnabled) { GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i)); fAttribArrayStates[i].fEnableIsValid = true; fAttribArrayStates[i].fEnabled = false; } } else { SkASSERT(fAttribArrayStates[i].fEnableIsValid && fAttribArrayStates[i].fEnabled); } // if the count is greater than 64 then this will become 0 and we will disable arrays 64+. usedMask >>= 1; } }
void GrGpuGL::setupGeometry(const DrawInfo& info, int* startIndexOffset) { int newColorOffset; int newCoverageOffset; int newTexCoordOffsets[GrDrawState::kMaxTexCoords]; int newEdgeOffset; GrVertexLayout currLayout = this->getVertexLayout(); GrGLsizei newStride = GrDrawState::VertexSizeAndOffsetsByIdx(currLayout, newTexCoordOffsets, &newColorOffset, &newCoverageOffset, &newEdgeOffset); int oldColorOffset; int oldCoverageOffset; int oldTexCoordOffsets[GrDrawState::kMaxTexCoords]; int oldEdgeOffset; GrGLsizei oldStride = GrDrawState::VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout, oldTexCoordOffsets, &oldColorOffset, &oldCoverageOffset, &oldEdgeOffset); int extraVertexOffset; this->setBuffers(info.isIndexed(), &extraVertexOffset, startIndexOffset); GrGLenum scalarType; bool texCoordNorm; if (currLayout & GrDrawState::kTextFormat_VertexLayoutBit) { scalarType = TEXT_COORDS_GL_TYPE; texCoordNorm = SkToBool(TEXT_COORDS_ARE_NORMALIZED); } else { scalarType = GR_GL_FLOAT; texCoordNorm = false; } size_t vertexOffset = (info.startVertex() + extraVertexOffset) * newStride; // all the Pointers must be set if any of these are true bool allOffsetsChange = fHWGeometryState.fArrayPtrsDirty || vertexOffset != fHWGeometryState.fVertexOffset || newStride != oldStride; // position and tex coord offsets change if above conditions are true // or the type/normalization changed based on text vs nontext type coords. bool posAndTexChange = allOffsetsChange || (((TEXT_COORDS_GL_TYPE != GR_GL_FLOAT) || TEXT_COORDS_ARE_NORMALIZED) && (GrDrawState::kTextFormat_VertexLayoutBit & (fHWGeometryState.fVertexLayout ^ currLayout))); if (posAndTexChange) { int idx = GrGLProgram::PositionAttributeIdx(); GL_CALL(VertexAttribPointer(idx, 2, scalarType, false, newStride, (GrGLvoid*)vertexOffset)); fHWGeometryState.fVertexOffset = vertexOffset; } for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { if (newTexCoordOffsets[t] > 0) { GrGLvoid* texCoordOffset = (GrGLvoid*)(vertexOffset + newTexCoordOffsets[t]); int idx = GrGLProgram::TexCoordAttributeIdx(t); if (oldTexCoordOffsets[t] <= 0) { GL_CALL(EnableVertexAttribArray(idx)); GL_CALL(VertexAttribPointer(idx, 2, scalarType, texCoordNorm, newStride, texCoordOffset)); } else if (posAndTexChange || newTexCoordOffsets[t] != oldTexCoordOffsets[t]) { GL_CALL(VertexAttribPointer(idx, 2, scalarType, texCoordNorm, newStride, texCoordOffset)); } } else if (oldTexCoordOffsets[t] > 0) { GL_CALL(DisableVertexAttribArray(GrGLProgram::TexCoordAttributeIdx(t))); } } if (newColorOffset > 0) { GrGLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset); int idx = GrGLProgram::ColorAttributeIdx(); if (oldColorOffset <= 0) { GL_CALL(EnableVertexAttribArray(idx)); GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE, true, newStride, colorOffset)); } else if (allOffsetsChange || newColorOffset != oldColorOffset) { GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE, true, newStride, colorOffset)); } } else if (oldColorOffset > 0) { GL_CALL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx())); } if (newCoverageOffset > 0) { GrGLvoid* coverageOffset = (int8_t*)(vertexOffset + newCoverageOffset); int idx = GrGLProgram::CoverageAttributeIdx(); if (oldCoverageOffset <= 0) { GL_CALL(EnableVertexAttribArray(idx)); GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE, true, newStride, coverageOffset)); } else if (allOffsetsChange || newCoverageOffset != oldCoverageOffset) { GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE, true, newStride, coverageOffset)); } } else if (oldCoverageOffset > 0) { GL_CALL(DisableVertexAttribArray(GrGLProgram::CoverageAttributeIdx())); } if (newEdgeOffset > 0) { GrGLvoid* edgeOffset = (int8_t*)(vertexOffset + newEdgeOffset); int idx = GrGLProgram::EdgeAttributeIdx(); if (oldEdgeOffset <= 0) { GL_CALL(EnableVertexAttribArray(idx)); GL_CALL(VertexAttribPointer(idx, 4, scalarType, false, newStride, edgeOffset)); } else if (allOffsetsChange || newEdgeOffset != oldEdgeOffset) { GL_CALL(VertexAttribPointer(idx, 4, scalarType, false, newStride, edgeOffset)); } } else if (oldEdgeOffset > 0) { GL_CALL(DisableVertexAttribArray(GrGLProgram::EdgeAttributeIdx())); } fHWGeometryState.fVertexLayout = currLayout; fHWGeometryState.fArrayPtrsDirty = false; }
void GrGpuGLShaders::setupGeometry(int* startVertex, int* startIndex, int vertexCount, int indexCount) { int newColorOffset; int newTexCoordOffsets[kMaxTexCoords]; GrGLsizei newStride = VertexSizeAndOffsetsByIdx(fGeometrySrc.fVertexLayout, newTexCoordOffsets, &newColorOffset); int oldColorOffset; int oldTexCoordOffsets[kMaxTexCoords]; GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout, oldTexCoordOffsets, &oldColorOffset); bool indexed = NULL != startIndex; int extraVertexOffset; int extraIndexOffset; setBuffers(indexed, &extraVertexOffset, &extraIndexOffset); GrGLenum scalarType; bool texCoordNorm; if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) { scalarType = GrGLTextType; texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED; } else { scalarType = GrGLType; texCoordNorm = false; } size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride; *startVertex = 0; if (indexed) { *startIndex += extraIndexOffset; } // all the Pointers must be set if any of these are true bool allOffsetsChange = fHWGeometryState.fArrayPtrsDirty || vertexOffset != fHWGeometryState.fVertexOffset || newStride != oldStride; // position and tex coord offsets change if above conditions are true // or the type/normalization changed based on text vs nontext type coords. bool posAndTexChange = allOffsetsChange || (((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) && (kTextFormat_VertexLayoutBit & (fHWGeometryState.fVertexLayout ^ fGeometrySrc.fVertexLayout))); if (posAndTexChange) { GR_GL(VertexAttribPointer(POS_ATTR_LOCATION, 2, scalarType, false, newStride, (GrGLvoid*)vertexOffset)); fHWGeometryState.fVertexOffset = vertexOffset; } for (int t = 0; t < kMaxTexCoords; ++t) { if (newTexCoordOffsets[t] > 0) { GrGLvoid* texCoordOffset = (GrGLvoid*)(vertexOffset + newTexCoordOffsets[t]); if (oldTexCoordOffsets[t] <= 0) { GR_GL(EnableVertexAttribArray(TEX_ATTR_LOCATION(t))); GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType, texCoordNorm, newStride, texCoordOffset)); } else if (posAndTexChange || newTexCoordOffsets[t] != oldTexCoordOffsets[t]) { GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType, texCoordNorm, newStride, texCoordOffset)); } } else if (oldTexCoordOffsets[t] > 0) { GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t))); } } if (newColorOffset > 0) { GrGLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset); if (oldColorOffset <= 0) { GR_GL(EnableVertexAttribArray(COL_ATTR_LOCATION)); GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4, GR_GL_UNSIGNED_BYTE, true, newStride, colorOffset)); } else if (allOffsetsChange || newColorOffset != oldColorOffset) { GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4, GR_GL_UNSIGNED_BYTE, true, newStride, colorOffset)); } } else if (oldColorOffset > 0) { GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION)); } fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout; fHWGeometryState.fArrayPtrsDirty = false; }
void cShaderProgram::DisableVertexAttribArray( const std::string& Name ) { DisableVertexAttribArray( AttributeLocation( Name ) ); }
void GrGpuGLShaders::setupGeometry(int* startVertex, int* startIndex, int vertexCount, int indexCount) { int newColorOffset; int newCoverageOffset; int newTexCoordOffsets[GrDrawState::kMaxTexCoords]; int newEdgeOffset; GrGLsizei newStride = VertexSizeAndOffsetsByIdx( this->getGeomSrc().fVertexLayout, newTexCoordOffsets, &newColorOffset, &newCoverageOffset, &newEdgeOffset); int oldColorOffset; int oldCoverageOffset; int oldTexCoordOffsets[GrDrawState::kMaxTexCoords]; int oldEdgeOffset; GrGLsizei oldStride = VertexSizeAndOffsetsByIdx( fHWGeometryState.fVertexLayout, oldTexCoordOffsets, &oldColorOffset, &oldCoverageOffset, &oldEdgeOffset); bool indexed = NULL != startIndex; int extraVertexOffset; int extraIndexOffset; this->setBuffers(indexed, &extraVertexOffset, &extraIndexOffset); GrGLenum scalarType; bool texCoordNorm; if (this->getGeomSrc().fVertexLayout & kTextFormat_VertexLayoutBit) { scalarType = GrGLTextType; texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED; } else { scalarType = GrGLType; texCoordNorm = false; } size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride; *startVertex = 0; if (indexed) { *startIndex += extraIndexOffset; } // all the Pointers must be set if any of these are true bool allOffsetsChange = fHWGeometryState.fArrayPtrsDirty || vertexOffset != fHWGeometryState.fVertexOffset || newStride != oldStride; // position and tex coord offsets change if above conditions are true // or the type/normalization changed based on text vs nontext type coords. bool posAndTexChange = allOffsetsChange || (((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) && (kTextFormat_VertexLayoutBit & (fHWGeometryState.fVertexLayout ^ this->getGeomSrc().fVertexLayout))); if (posAndTexChange) { int idx = GrGLProgram::PositionAttributeIdx(); GL_CALL(VertexAttribPointer(idx, 2, scalarType, false, newStride, (GrGLvoid*)vertexOffset)); fHWGeometryState.fVertexOffset = vertexOffset; } for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) { if (newTexCoordOffsets[t] > 0) { GrGLvoid* texCoordOffset = (GrGLvoid*)(vertexOffset + newTexCoordOffsets[t]); int idx = GrGLProgram::TexCoordAttributeIdx(t); if (oldTexCoordOffsets[t] <= 0) { GL_CALL(EnableVertexAttribArray(idx)); GL_CALL(VertexAttribPointer(idx, 2, scalarType, texCoordNorm, newStride, texCoordOffset)); } else if (posAndTexChange || newTexCoordOffsets[t] != oldTexCoordOffsets[t]) { GL_CALL(VertexAttribPointer(idx, 2, scalarType, texCoordNorm, newStride, texCoordOffset)); } } else if (oldTexCoordOffsets[t] > 0) { GL_CALL(DisableVertexAttribArray(GrGLProgram::TexCoordAttributeIdx(t))); } } if (newColorOffset > 0) { GrGLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset); int idx = GrGLProgram::ColorAttributeIdx(); if (oldColorOffset <= 0) { GL_CALL(EnableVertexAttribArray(idx)); GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE, true, newStride, colorOffset)); } else if (allOffsetsChange || newColorOffset != oldColorOffset) { GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE, true, newStride, colorOffset)); } } else if (oldColorOffset > 0) { GL_CALL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx())); } if (newCoverageOffset > 0) { // bind a single channel, they should all have the same value. GrGLvoid* coverageOffset = (int8_t*)(vertexOffset + newCoverageOffset); int idx = GrGLProgram::CoverageAttributeIdx(); if (oldCoverageOffset <= 0) { GL_CALL(EnableVertexAttribArray(idx)); GL_CALL(VertexAttribPointer(idx, 1, GR_GL_UNSIGNED_BYTE, true, newStride, coverageOffset)); } else if (allOffsetsChange || newCoverageOffset != oldCoverageOffset) { GL_CALL(VertexAttribPointer(idx, 1, GR_GL_UNSIGNED_BYTE, true, newStride, coverageOffset)); } } else if (oldCoverageOffset > 0) { GL_CALL(DisableVertexAttribArray(GrGLProgram::CoverageAttributeIdx())); } if (newEdgeOffset > 0) { GrGLvoid* edgeOffset = (int8_t*)(vertexOffset + newEdgeOffset); int idx = GrGLProgram::EdgeAttributeIdx(); if (oldEdgeOffset <= 0) { GL_CALL(EnableVertexAttribArray(idx)); GL_CALL(VertexAttribPointer(idx, 4, scalarType, false, newStride, edgeOffset)); } else if (allOffsetsChange || newEdgeOffset != oldEdgeOffset) { GL_CALL(VertexAttribPointer(idx, 4, scalarType, false, newStride, edgeOffset)); } } else if (oldEdgeOffset > 0) { GL_CALL(DisableVertexAttribArray(GrGLProgram::EdgeAttributeIdx())); } fHWGeometryState.fVertexLayout = this->getGeomSrc().fVertexLayout; fHWGeometryState.fArrayPtrsDirty = false; }