Do not use client-side data pointers in qopenglpaintengine
Buffers can be uploaded - no need to keep these in client memory. Decouple uploading of buffers from the creation of vao. Pick-to: 6.4 6.4.0 Fixes: QTBUG-107539 Change-Id: Idf75bd80033a44c34af6837cd4d65b75c183d886 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
parent
3f8e3c3335
commit
e487b07e18
@ -735,11 +735,11 @@ void QOpenGL2PaintEngineExPrivate::resetGLState()
|
||||
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
funcs.glVertexAttrib4fv(3, color);
|
||||
}
|
||||
if (vao.isCreated()) {
|
||||
if (vao.isCreated())
|
||||
vao.release();
|
||||
funcs.glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
funcs.glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void QOpenGL2PaintEngineEx::endNativePainting()
|
||||
@ -2207,28 +2207,27 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
|
||||
bool created = d->vao.create();
|
||||
|
||||
// If we managed to create it then we have a profile that supports VAOs
|
||||
if (created) {
|
||||
if (created)
|
||||
d->vao.bind();
|
||||
}
|
||||
|
||||
// Generate a new Vertex Buffer Object if we don't have one already
|
||||
if (!d->vertexBuffer.isCreated()) {
|
||||
d->vertexBuffer.create();
|
||||
// Set its usage to StreamDraw, we will use this buffer only a few times before refilling it
|
||||
d->vertexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
||||
}
|
||||
if (!d->texCoordBuffer.isCreated()) {
|
||||
d->texCoordBuffer.create();
|
||||
d->texCoordBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
||||
}
|
||||
if (!d->opacityBuffer.isCreated()) {
|
||||
d->opacityBuffer.create();
|
||||
d->opacityBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
||||
}
|
||||
if (!d->indexBuffer.isCreated()) {
|
||||
d->indexBuffer.create();
|
||||
d->indexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
||||
}
|
||||
}
|
||||
// Generate a new Vertex Buffer Object if we don't have one already
|
||||
if (!d->vertexBuffer.isCreated()) {
|
||||
d->vertexBuffer.create();
|
||||
// Set its usage to StreamDraw, we will use this buffer only a few times before refilling it
|
||||
d->vertexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
||||
}
|
||||
if (!d->texCoordBuffer.isCreated()) {
|
||||
d->texCoordBuffer.create();
|
||||
d->texCoordBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
||||
}
|
||||
if (!d->opacityBuffer.isCreated()) {
|
||||
d->opacityBuffer.create();
|
||||
d->opacityBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
||||
}
|
||||
if (!d->indexBuffer.isCreated()) {
|
||||
d->indexBuffer.create();
|
||||
d->indexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
||||
}
|
||||
|
||||
for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
|
||||
|
@ -307,51 +307,32 @@ void QOpenGL2PaintEngineExPrivate::uploadData(unsigned int arrayIndex, const GLf
|
||||
{
|
||||
Q_ASSERT(arrayIndex < 3);
|
||||
|
||||
// If a vertex array object is created we have a profile that supports them
|
||||
// and we will upload the data via a QOpenGLBuffer. Otherwise we will use
|
||||
// the legacy way of uploading the data via glVertexAttribPointer.
|
||||
if (vao.isCreated()) {
|
||||
if (arrayIndex == QT_VERTEX_COORDS_ATTR) {
|
||||
vertexBuffer.bind();
|
||||
vertexBuffer.allocate(data, count * sizeof(float));
|
||||
}
|
||||
if (arrayIndex == QT_TEXTURE_COORDS_ATTR) {
|
||||
texCoordBuffer.bind();
|
||||
texCoordBuffer.allocate(data, count * sizeof(float));
|
||||
}
|
||||
if (arrayIndex == QT_OPACITY_ATTR) {
|
||||
opacityBuffer.bind();
|
||||
opacityBuffer.allocate(data, count * sizeof(float));
|
||||
}
|
||||
if (arrayIndex == QT_OPACITY_ATTR)
|
||||
funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
else
|
||||
funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
} else {
|
||||
// If we already uploaded the data we don't have to do it again
|
||||
if (data == vertexAttribPointers[arrayIndex])
|
||||
return;
|
||||
if (arrayIndex == QT_VERTEX_COORDS_ATTR) {
|
||||
vertexBuffer.bind();
|
||||
vertexBuffer.allocate(data, count * sizeof(float));
|
||||
}
|
||||
if (arrayIndex == QT_TEXTURE_COORDS_ATTR) {
|
||||
texCoordBuffer.bind();
|
||||
texCoordBuffer.allocate(data, count * sizeof(float));
|
||||
}
|
||||
if (arrayIndex == QT_OPACITY_ATTR) {
|
||||
opacityBuffer.bind();
|
||||
opacityBuffer.allocate(data, count * sizeof(float));
|
||||
|
||||
// Store the data in cache and upload it to the graphics card.
|
||||
vertexAttribPointers[arrayIndex] = data;
|
||||
if (arrayIndex == QT_OPACITY_ATTR)
|
||||
funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, data);
|
||||
else
|
||||
funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, data);
|
||||
funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
} else {
|
||||
funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool QOpenGL2PaintEngineExPrivate::uploadIndexData(const void *data, GLenum indexValueType, GLuint count)
|
||||
{
|
||||
// Follow the uploadData() logic: VBOs are used only when VAO support is available.
|
||||
// Otherwise the legacy client-side pointer path is used.
|
||||
if (vao.isCreated()) {
|
||||
Q_ASSERT(indexValueType == GL_UNSIGNED_SHORT || indexValueType == GL_UNSIGNED_INT);
|
||||
indexBuffer.bind();
|
||||
indexBuffer.allocate(data, count * (indexValueType == GL_UNSIGNED_SHORT ? sizeof(quint16) : sizeof(quint32)));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
Q_ASSERT(indexValueType == GL_UNSIGNED_SHORT || indexValueType == GL_UNSIGNED_INT);
|
||||
indexBuffer.bind();
|
||||
indexBuffer.allocate(
|
||||
data,
|
||||
count * (indexValueType == GL_UNSIGNED_SHORT ? sizeof(quint16) : sizeof(quint32)));
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
Loading…
Reference in New Issue
Block a user