gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint start, GLsizei count, std::vector<TranslatedAttribute> *translatedAttribs, GLsizei instances) { ASSERT(mStreamingBuffer); const gl::VertexArray *vertexArray = state.getVertexArray(); const auto &vertexAttributes = vertexArray->getVertexAttributes(); mDynamicAttribsMaskCache.reset(); const gl::Program *program = state.getProgram(); translatedAttribs->clear(); for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex) { // Skip attrib locations the program doesn't use. if (!program->isAttribLocationActive(attribIndex)) continue; const auto &attrib = vertexAttributes[attribIndex]; // Resize automatically puts in empty attribs translatedAttribs->resize(attribIndex + 1); TranslatedAttribute *translated = &(*translatedAttribs)[attribIndex]; auto currentValueData = state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex)); // Record the attribute now translated->active = true; translated->attribute = &attrib; translated->currentValueType = currentValueData.Type; translated->divisor = attrib.divisor; switch (ClassifyAttributeStorage(attrib)) { case VertexStorageType::STATIC: { // Store static attribute. gl::Error error = StoreStaticAttrib(translated, start, count, instances); if (error.isError()) { return error; } break; } case VertexStorageType::DYNAMIC: // Dynamic attributes must be handled together. mDynamicAttribsMaskCache.set(attribIndex); break; case VertexStorageType::DIRECT: // Update translated data for direct attributes. StoreDirectAttrib(translated, start); break; case VertexStorageType::CURRENT_VALUE: { gl::Error error = storeCurrentValue(currentValueData, translated, attribIndex); if (error.isError()) { return error; } break; } default: UNREACHABLE(); break; } } if (mDynamicAttribsMaskCache.none()) { gl::Error(GL_NO_ERROR); } return storeDynamicAttribs(translatedAttribs, mDynamicAttribsMaskCache, start, count, instances); }
angle::Result VertexDataManager::prepareVertexData( const gl::Context *context, GLint start, GLsizei count, std::vector<TranslatedAttribute> *translatedAttribs, GLsizei instances) { const gl::State &state = context->getGLState(); const gl::VertexArray *vertexArray = state.getVertexArray(); const auto &vertexAttributes = vertexArray->getVertexAttributes(); const auto &vertexBindings = vertexArray->getVertexBindings(); mDynamicAttribsMaskCache.reset(); const gl::Program *program = state.getProgram(); translatedAttribs->clear(); for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex) { // Skip attrib locations the program doesn't use. if (!program->isAttribLocationActive(attribIndex)) continue; const auto &attrib = vertexAttributes[attribIndex]; const auto &binding = vertexBindings[attrib.bindingIndex]; // Resize automatically puts in empty attribs translatedAttribs->resize(attribIndex + 1); TranslatedAttribute *translated = &(*translatedAttribs)[attribIndex]; auto currentValueData = state.getVertexAttribCurrentValue(attribIndex); // Record the attribute now translated->active = true; translated->attribute = &attrib; translated->binding = &binding; translated->currentValueType = currentValueData.Type; translated->divisor = binding.getDivisor(); switch (ClassifyAttributeStorage(context, attrib, binding)) { case VertexStorageType::STATIC: { // Store static attribute. ANGLE_TRY(StoreStaticAttrib(context, translated)); break; } case VertexStorageType::DYNAMIC: // Dynamic attributes must be handled together. mDynamicAttribsMaskCache.set(attribIndex); break; case VertexStorageType::DIRECT: // Update translated data for direct attributes. StoreDirectAttrib(context, translated); break; case VertexStorageType::CURRENT_VALUE: { ANGLE_TRY(storeCurrentValue(context, currentValueData, translated, attribIndex)); break; } default: UNREACHABLE(); break; } } if (mDynamicAttribsMaskCache.none()) { return angle::Result::Continue(); } ANGLE_TRY(storeDynamicAttribs(context, translatedAttribs, mDynamicAttribsMaskCache, start, count, instances)); PromoteDynamicAttribs(context, *translatedAttribs, mDynamicAttribsMaskCache, count); return angle::Result::Continue(); }