void OMXMLWriterSimple::writeAttribute(const wchar_t* ns, const wchar_t* localName, const wchar_t* value) { TRACE("OMXMLWriterSimple::writeAttribute"); PRECONDITION("Valid state", _prevWriteType == ELEMENT_START || _prevWriteType == ATTRIBUTE_START || _prevWriteType == ATTRIBUTE_CONTENT || _prevWriteType == ATTRIBUTE_END); if (_prevWriteType == ATTRIBUTE_START || _prevWriteType == ATTRIBUTE_CONTENT) { writeAttributeEnd(); } write(L" ", 1); if (ns != 0) { const wchar_t* prefix = getNonDefaultNSPrefix(ns); ASSERT("Valid prefix", prefix != 0 && wcslen(prefix) > 0); writeName(prefix, wcslen(prefix)); write(L":", 1); } writeName(localName, wcslen(localName)); write(L"=\"", 2); writeAttributeData(value, wcslen(value)); write(L"\"", 1); _prevWriteType = ATTRIBUTE_END; }
void OMXMLWriterSimple::declareNamespace(const wchar_t* ns, const wchar_t* prefix) { TRACE("OMXMLWriterSimple::declareNamespace"); PRECONDITION("Valid state", _prevWriteType == DELAYED_ELEMENT_START || _prevWriteType == ELEMENT_START || _prevWriteType == ATTRIBUTE_START || _prevWriteType == ATTRIBUTE_CONTENT || _prevWriteType == ATTRIBUTE_END); PRECONDITION("Valid prefix", prefix == 0 || validPrefix(prefix)); PRECONDITION("Valid namespace", validNamespace(ns)); if (_prevWriteType == ATTRIBUTE_START || _prevWriteType == ATTRIBUTE_CONTENT) { writeAttributeEnd(); } ASSERT("Elements count not zero", _elementStack.count() > 0); Element* element = _elementStack.getAt(_elementStack.count() - 1); bool wasAdded; if (prefix == OMXMLWRITER_DEFAULT_NAMESPACE_PREFIX) { wasAdded = element->addNamespaceDecl(ns, g_internalDefaultNamespacePrefix); } else { wasAdded = element->addNamespaceDecl(ns, prefix); } if (wasAdded) { if (_prevWriteType == DELAYED_ELEMENT_START) { ASSERT("Namespace declarations must start with the current element", wcscmp(ns, element->getNamespace()) == 0); writeIndent(_level); write(L"<", 1); if (prefix != OMXMLWRITER_DEFAULT_NAMESPACE_PREFIX) { writeName(prefix, wcslen(prefix)); write(L":", 1); } writeName(element->getLocalName(), wcslen(element->getLocalName())); _level++; _prevWriteType = ELEMENT_START; } write(L" xmlns", 6); if (prefix != OMXMLWRITER_DEFAULT_NAMESPACE_PREFIX) { write(L":",1); writeName(prefix, wcslen(prefix)); } write(L"=\"", 2); writeAttributeData(ns, wcslen(ns)); write(L"\"", 1); } }
void OMXMLWriterSimple::writeAttributeContent(const wchar_t* value) { TRACE("OMXMLWriterSimple::writeAttributeContent"); PRECONDITION("Valid state", _prevWriteType == ATTRIBUTE_START || _prevWriteType == ATTRIBUTE_CONTENT); writeAttributeData(value, wcslen(value)); _prevWriteType = ATTRIBUTE_CONTENT; }
GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances) { if (!mStreamingBuffer) { return GL_OUT_OF_MEMORY; } const VertexAttributeArray &attribs = mContext->getVertexAttributes(); Program *program = mContext->getCurrentProgram(); ProgramBinary *programBinary = program->getProgramBinary(); for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) { translated[attributeIndex].active = (programBinary->getSemanticIndex(attributeIndex) != -1); } // Determine the required storage size per used buffer, and invalidate static buffers that don't contain matching attributes for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { if (translated[i].active && attribs[i].mArrayEnabled) { Buffer *buffer = attribs[i].mBoundBuffer.get(); StaticVertexBuffer *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL; if (staticBuffer) { if (staticBuffer->size() == 0) { int totalCount = elementsInBuffer(attribs[i], buffer->size()); staticBuffer->addRequiredSpace(spaceRequired(attribs[i], totalCount, 0)); } else if (staticBuffer->lookupAttribute(attribs[i]) == -1) { // This static buffer doesn't have matching attributes, so fall back to using the streaming buffer // Add the space of all previous attributes belonging to the invalidated static buffer to the streaming buffer for (int previous = 0; previous < i; previous++) { if (translated[previous].active && attribs[previous].mArrayEnabled) { Buffer *previousBuffer = attribs[previous].mBoundBuffer.get(); StaticVertexBuffer *previousStaticBuffer = previousBuffer ? previousBuffer->getStaticVertexBuffer() : NULL; if (staticBuffer == previousStaticBuffer) { mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[previous], count, instances)); } } } mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count, instances)); buffer->invalidateStaticData(); } } else { mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count, instances)); } } } // Reserve the required space per used buffer for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { if (translated[i].active && attribs[i].mArrayEnabled) { Buffer *buffer = attribs[i].mBoundBuffer.get(); ArrayVertexBuffer *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL; ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : mStreamingBuffer; if (vertexBuffer) { vertexBuffer->reserveRequiredSpace(); } } } // Perform the vertex data translations for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { if (translated[i].active) { if (attribs[i].mArrayEnabled) { Buffer *buffer = attribs[i].mBoundBuffer.get(); if (!buffer && attribs[i].mPointer == NULL) { // This is an application error that would normally result in a crash, but we catch it and return an error ERR("An enabled vertex array has no buffer and no pointer."); return GL_INVALID_OPERATION; } const FormatConverter &converter = formatConverter(attribs[i]); StaticVertexBuffer *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL; ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : static_cast<ArrayVertexBuffer*>(mStreamingBuffer); std::size_t streamOffset = -1; if (staticBuffer) { streamOffset = staticBuffer->lookupAttribute(attribs[i]); if (streamOffset == -1) { // Convert the entire buffer int totalCount = elementsInBuffer(attribs[i], buffer->size()); int startIndex = attribs[i].mOffset / attribs[i].stride(); streamOffset = writeAttributeData(staticBuffer, -startIndex, totalCount, attribs[i], 0); } if (streamOffset != -1) { streamOffset += (attribs[i].mOffset / attribs[i].stride()) * converter.outputElementSize; if (instances == 0 || attribs[i].mDivisor == 0) { streamOffset += start * converter.outputElementSize; } } } else { streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i], instances); } if (streamOffset == -1) { return GL_OUT_OF_MEMORY; } translated[i].vertexBuffer = vertexBuffer->getBuffer(); translated[i].serial = vertexBuffer->getSerial(); translated[i].divisor = attribs[i].mDivisor; translated[i].type = converter.d3dDeclType; translated[i].stride = converter.outputElementSize; translated[i].offset = streamOffset; } else { if (!mCurrentValueBuffer[i]) { mCurrentValueBuffer[i] = new StreamingVertexBuffer(mDevice, CONSTANT_VERTEX_BUFFER_SIZE); } StreamingVertexBuffer *buffer = mCurrentValueBuffer[i]; if (mDirtyCurrentValue[i]) { const int requiredSpace = 4 * sizeof(float); buffer->addRequiredSpace(requiredSpace); buffer->reserveRequiredSpace(); float *data = static_cast<float*>(buffer->map(VertexAttribute(), requiredSpace, &mCurrentValueOffsets[i])); if (data) { data[0] = attribs[i].mCurrentValue[0]; data[1] = attribs[i].mCurrentValue[1]; data[2] = attribs[i].mCurrentValue[2]; data[3] = attribs[i].mCurrentValue[3]; buffer->unmap(); mDirtyCurrentValue[i] = false; } } translated[i].vertexBuffer = mCurrentValueBuffer[i]->getBuffer(); translated[i].serial = mCurrentValueBuffer[i]->getSerial(); translated[i].divisor = 0; translated[i].type = D3DDECLTYPE_FLOAT4; translated[i].stride = 0; translated[i].offset = mCurrentValueOffsets[i]; } } } for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { if (translated[i].active && attribs[i].mArrayEnabled) { Buffer *buffer = attribs[i].mBoundBuffer.get(); if (buffer) { buffer->promoteStaticUsage(count * attribs[i].typeSize()); } } } return GL_NO_ERROR; }