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. Fixes: QTBUG-107539 Change-Id: Idf75bd80033a44c34af6837cd4d65b75c183d886 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> (cherry picked from commit e487b07e18f1cb7ff126744be57b2ae1b9839c6c) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
c0b54bf6fa
commit
81252ea92a
@ -726,11 +726,11 @@ void QOpenGL2PaintEngineExPrivate::resetGLState()
|
|||||||
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
funcs.glVertexAttrib4fv(3, color);
|
funcs.glVertexAttrib4fv(3, color);
|
||||||
}
|
}
|
||||||
if (vao.isCreated()) {
|
if (vao.isCreated())
|
||||||
vao.release();
|
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()
|
void QOpenGL2PaintEngineEx::endNativePainting()
|
||||||
@ -2198,28 +2198,27 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
|
|||||||
bool created = d->vao.create();
|
bool created = d->vao.create();
|
||||||
|
|
||||||
// If we managed to create it then we have a profile that supports VAOs
|
// If we managed to create it then we have a profile that supports VAOs
|
||||||
if (created) {
|
if (created)
|
||||||
d->vao.bind();
|
d->vao.bind();
|
||||||
|
}
|
||||||
|
|
||||||
// Generate a new Vertex Buffer Object if we don't have one already
|
// Generate a new Vertex Buffer Object if we don't have one already
|
||||||
if (!d->vertexBuffer.isCreated()) {
|
if (!d->vertexBuffer.isCreated()) {
|
||||||
d->vertexBuffer.create();
|
d->vertexBuffer.create();
|
||||||
// Set its usage to StreamDraw, we will use this buffer only a few times before refilling it
|
// Set its usage to StreamDraw, we will use this buffer only a few times before refilling it
|
||||||
d->vertexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
d->vertexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
||||||
}
|
}
|
||||||
if (!d->texCoordBuffer.isCreated()) {
|
if (!d->texCoordBuffer.isCreated()) {
|
||||||
d->texCoordBuffer.create();
|
d->texCoordBuffer.create();
|
||||||
d->texCoordBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
d->texCoordBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
||||||
}
|
}
|
||||||
if (!d->opacityBuffer.isCreated()) {
|
if (!d->opacityBuffer.isCreated()) {
|
||||||
d->opacityBuffer.create();
|
d->opacityBuffer.create();
|
||||||
d->opacityBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
d->opacityBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
||||||
}
|
}
|
||||||
if (!d->indexBuffer.isCreated()) {
|
if (!d->indexBuffer.isCreated()) {
|
||||||
d->indexBuffer.create();
|
d->indexBuffer.create();
|
||||||
d->indexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
d->indexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
|
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);
|
Q_ASSERT(arrayIndex < 3);
|
||||||
|
|
||||||
// If a vertex array object is created we have a profile that supports them
|
if (arrayIndex == QT_VERTEX_COORDS_ATTR) {
|
||||||
// and we will upload the data via a QOpenGLBuffer. Otherwise we will use
|
vertexBuffer.bind();
|
||||||
// the legacy way of uploading the data via glVertexAttribPointer.
|
vertexBuffer.allocate(data, count * sizeof(float));
|
||||||
if (vao.isCreated()) {
|
}
|
||||||
if (arrayIndex == QT_VERTEX_COORDS_ATTR) {
|
if (arrayIndex == QT_TEXTURE_COORDS_ATTR) {
|
||||||
vertexBuffer.bind();
|
texCoordBuffer.bind();
|
||||||
vertexBuffer.allocate(data, count * sizeof(float));
|
texCoordBuffer.allocate(data, count * sizeof(float));
|
||||||
}
|
}
|
||||||
if (arrayIndex == QT_TEXTURE_COORDS_ATTR) {
|
if (arrayIndex == QT_OPACITY_ATTR) {
|
||||||
texCoordBuffer.bind();
|
opacityBuffer.bind();
|
||||||
texCoordBuffer.allocate(data, count * sizeof(float));
|
opacityBuffer.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;
|
|
||||||
|
|
||||||
// Store the data in cache and upload it to the graphics card.
|
funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||||
vertexAttribPointers[arrayIndex] = data;
|
} else {
|
||||||
if (arrayIndex == QT_OPACITY_ATTR)
|
funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||||
funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, data);
|
|
||||||
else
|
|
||||||
funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QOpenGL2PaintEngineExPrivate::uploadIndexData(const void *data, GLenum indexValueType, GLuint count)
|
bool QOpenGL2PaintEngineExPrivate::uploadIndexData(const void *data, GLenum indexValueType, GLuint count)
|
||||||
{
|
{
|
||||||
// Follow the uploadData() logic: VBOs are used only when VAO support is available.
|
Q_ASSERT(indexValueType == GL_UNSIGNED_SHORT || indexValueType == GL_UNSIGNED_INT);
|
||||||
// Otherwise the legacy client-side pointer path is used.
|
indexBuffer.bind();
|
||||||
if (vao.isCreated()) {
|
indexBuffer.allocate(
|
||||||
Q_ASSERT(indexValueType == GL_UNSIGNED_SHORT || indexValueType == GL_UNSIGNED_INT);
|
data,
|
||||||
indexBuffer.bind();
|
count * (indexValueType == GL_UNSIGNED_SHORT ? sizeof(quint16) : sizeof(quint32)));
|
||||||
indexBuffer.allocate(data, count * (indexValueType == GL_UNSIGNED_SHORT ? sizeof(quint16) : sizeof(quint32)));
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user