diff --git a/drivers/gles2/rasterizer_canvas_base_gles2.cpp b/drivers/gles2/rasterizer_canvas_base_gles2.cpp index d7c85646a0b..ab78ec3b855 100644 --- a/drivers/gles2/rasterizer_canvas_base_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_base_gles2.cpp @@ -446,8 +446,21 @@ void RasterizerCanvasBaseGLES2::_draw_polygon(const int *p_indices, int p_index_ glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); + // precalculate the buffer size ahead of time instead of making multiple glBufferSubData calls + uint32_t total_buffer_size = sizeof(Vector2) * p_vertex_count; + if (!p_singlecolor && p_colors) { + total_buffer_size += sizeof(Color) * p_vertex_count; + } + if (p_uvs) { + total_buffer_size += sizeof(Vector2) * p_vertex_count; + } + if (p_weights && p_bones) { + total_buffer_size += sizeof(float) * 4 * p_vertex_count; // weights + total_buffer_size += sizeof(int) * 4 * p_vertex_count; // bones + } + uint32_t buffer_ofs = 0; - storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, sizeof(Vector2) * p_vertex_count, p_vertices); + storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, total_buffer_size, p_vertices); glEnableVertexAttribArray(VS::ARRAY_VERTEX); glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL); @@ -461,14 +474,12 @@ void RasterizerCanvasBaseGLES2::_draw_polygon(const int *p_indices, int p_index_ glDisableVertexAttribArray(VS::ARRAY_COLOR); glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); } else { - glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors); glEnableVertexAttribArray(VS::ARRAY_COLOR); glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(Color) * p_vertex_count; } if (p_uvs) { - glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs); glEnableVertexAttribArray(VS::ARRAY_TEX_UV); glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(Vector2) * p_vertex_count; @@ -477,12 +488,10 @@ void RasterizerCanvasBaseGLES2::_draw_polygon(const int *p_indices, int p_index_ } if (p_weights && p_bones) { - glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(float) * 4 * p_vertex_count, p_weights); glEnableVertexAttribArray(VS::ARRAY_WEIGHTS); glVertexAttribPointer(VS::ARRAY_WEIGHTS, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(float) * 4 * p_vertex_count; - glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(int) * 4 * p_vertex_count, p_bones); glEnableVertexAttribArray(VS::ARRAY_BONES); glVertexAttribPointer(VS::ARRAY_BONES, 4, GL_UNSIGNED_INT, GL_FALSE, sizeof(int) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(int) * 4 * p_vertex_count; @@ -516,8 +525,17 @@ void RasterizerCanvasBaseGLES2::_draw_generic(GLuint p_primitive, int p_vertex_c glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); + // precalculate the buffer size ahead of time instead of making multiple glBufferSubData calls + uint32_t total_buffer_size = sizeof(Vector2) * p_vertex_count; + if (!p_singlecolor && p_colors) { + total_buffer_size += sizeof(Color) * p_vertex_count; + } + if (p_uvs) { + total_buffer_size += sizeof(Vector2) * p_vertex_count; + } + uint32_t buffer_ofs = 0; - storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, sizeof(Vector2) * p_vertex_count, p_vertices); + storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, total_buffer_size, p_vertices); glEnableVertexAttribArray(VS::ARRAY_VERTEX); glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL); @@ -531,14 +549,12 @@ void RasterizerCanvasBaseGLES2::_draw_generic(GLuint p_primitive, int p_vertex_c glDisableVertexAttribArray(VS::ARRAY_COLOR); glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); } else { - glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors); glEnableVertexAttribArray(VS::ARRAY_COLOR); glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(Color) * p_vertex_count; } if (p_uvs) { - glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs); glEnableVertexAttribArray(VS::ARRAY_TEX_UV); glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); } else { diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index 55ae2d3f373..80b5b5a1c31 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -3788,14 +3788,17 @@ void RasterizerStorageGLES2::_update_skeleton_transform_buffer(const PoolVector< glBindBuffer(GL_ARRAY_BUFFER, resources.skeleton_transform_buffer); + uint32_t buffer_size = p_size * sizeof(float); + if (p_size > resources.skeleton_transform_buffer_size) { // new requested buffer is bigger, so resizing the GPU buffer resources.skeleton_transform_buffer_size = p_size; - glBufferData(GL_ARRAY_BUFFER, p_size * sizeof(float), p_data.read().ptr(), GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, buffer_size, p_data.read().ptr(), GL_DYNAMIC_DRAW); } else { - glBufferSubData(GL_ARRAY_BUFFER, 0, p_size * sizeof(float), p_data.read().ptr()); + // this may not be best, it could be better to use glBufferData in both cases. + buffer_orphan_and_upload(resources.skeleton_transform_buffer_size, 0, buffer_size, p_data.read().ptr()); } glBindBuffer(GL_ARRAY_BUFFER, 0); diff --git a/drivers/gles3/rasterizer_canvas_base_gles3.cpp b/drivers/gles3/rasterizer_canvas_base_gles3.cpp index e60e06be40f..eebe9e75405 100644 --- a/drivers/gles3/rasterizer_canvas_base_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_base_gles3.cpp @@ -348,8 +348,21 @@ void RasterizerCanvasBaseGLES3::_draw_polygon(const int *p_indices, int p_index_ glBindVertexArray(data.polygon_buffer_pointer_array); glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); + // precalculate the buffer size ahead of time instead of making multiple glBufferSubData calls + uint32_t total_buffer_size = sizeof(Vector2) * p_vertex_count; + if (!p_singlecolor && p_colors) { + total_buffer_size += sizeof(Color) * p_vertex_count; + } + if (p_uvs) { + total_buffer_size += sizeof(Vector2) * p_vertex_count; + } + if (p_weights && p_bones) { + total_buffer_size += sizeof(int) * 4 * p_vertex_count; // bones + total_buffer_size += sizeof(float) * 4 * p_vertex_count; // weights + } + uint32_t buffer_ofs = 0; - storage->buffer_orphan_and_upload(data.polygon_buffer_size, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_vertices); + storage->buffer_orphan_and_upload(data.polygon_buffer_size, buffer_ofs, total_buffer_size, p_vertices); glEnableVertexAttribArray(VS::ARRAY_VERTEX); glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); @@ -368,7 +381,6 @@ void RasterizerCanvasBaseGLES3::_draw_polygon(const int *p_indices, int p_index_ glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); } else { - glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors); glEnableVertexAttribArray(VS::ARRAY_COLOR); glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(Color) * p_vertex_count; @@ -380,7 +392,6 @@ void RasterizerCanvasBaseGLES3::_draw_polygon(const int *p_indices, int p_index_ if (p_uvs) { - glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs); glEnableVertexAttribArray(VS::ARRAY_TEX_UV); glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(Vector2) * p_vertex_count; @@ -395,13 +406,11 @@ void RasterizerCanvasBaseGLES3::_draw_polygon(const int *p_indices, int p_index_ if (p_bones && p_weights) { - glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(int) * 4 * p_vertex_count, p_bones); glEnableVertexAttribArray(VS::ARRAY_BONES); //glVertexAttribPointer(VS::ARRAY_BONES, 4, GL_UNSIGNED_INT, false, sizeof(int) * 4, ((uint8_t *)0) + buffer_ofs); glVertexAttribIPointer(VS::ARRAY_BONES, 4, GL_UNSIGNED_INT, sizeof(int) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(int) * 4 * p_vertex_count; - glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(float) * 4 * p_vertex_count, p_weights); glEnableVertexAttribArray(VS::ARRAY_WEIGHTS); glVertexAttribPointer(VS::ARRAY_WEIGHTS, 4, GL_FLOAT, false, sizeof(float) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(float) * 4 * p_vertex_count; @@ -439,9 +448,18 @@ void RasterizerCanvasBaseGLES3::_draw_generic(GLuint p_primitive, int p_vertex_c glBindVertexArray(data.polygon_buffer_pointer_array); glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer); + // precalculate the buffer size ahead of time instead of making multiple glBufferSubData calls + uint32_t total_buffer_size = sizeof(Vector2) * p_vertex_count; + if (!p_singlecolor && p_colors) { + total_buffer_size += sizeof(Color) * p_vertex_count; + } + if (p_uvs) { + total_buffer_size += sizeof(Vector2) * p_vertex_count; + } + //vertex uint32_t buffer_ofs = 0; - storage->buffer_orphan_and_upload(data.polygon_buffer_size, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_vertices); + storage->buffer_orphan_and_upload(data.polygon_buffer_size, buffer_ofs, total_buffer_size, p_vertices); glEnableVertexAttribArray(VS::ARRAY_VERTEX); glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); @@ -457,7 +475,6 @@ void RasterizerCanvasBaseGLES3::_draw_generic(GLuint p_primitive, int p_vertex_c glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); } else { - glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors); glEnableVertexAttribArray(VS::ARRAY_COLOR); glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(Color) * p_vertex_count; @@ -465,7 +482,6 @@ void RasterizerCanvasBaseGLES3::_draw_generic(GLuint p_primitive, int p_vertex_c if (p_uvs) { - glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs); glEnableVertexAttribArray(VS::ARRAY_TEX_UV); glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs)); buffer_ofs += sizeof(Vector2) * p_vertex_count; diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 71ee1c17b5b..77021631c6e 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -5085,7 +5085,8 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() { if (multimesh->size && multimesh->dirty_data) { glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer); - glBufferSubData(GL_ARRAY_BUFFER, 0, multimesh->data.size() * sizeof(float), multimesh->data.ptr()); + uint32_t buffer_size = multimesh->data.size() * sizeof(float); + glBufferData(GL_ARRAY_BUFFER, buffer_size, multimesh->data.ptr(), GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); }