|
@@ -32,6 +32,7 @@
|
|
|
|
|
|
#include "core/os/os.h"
|
|
|
#include "core/project_settings.h"
|
|
|
+#include "drivers/gles_common/rasterizer_asserts.h"
|
|
|
#include "rasterizer_scene_gles2.h"
|
|
|
#include "servers/visual/visual_server_raster.h"
|
|
|
|
|
@@ -447,11 +448,16 @@ void RasterizerCanvasBaseGLES2::_draw_polygon(const int *p_indices, int p_index_
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
|
|
|
|
|
|
uint32_t buffer_ofs = 0;
|
|
|
+ uint32_t buffer_ofs_after = buffer_ofs + (sizeof(Vector2) * p_vertex_count);
|
|
|
+#ifdef DEBUG_ENABLED
|
|
|
+ ERR_FAIL_COND(buffer_ofs_after > data.polygon_buffer_size);
|
|
|
+#endif
|
|
|
+
|
|
|
storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, sizeof(Vector2) * p_vertex_count, p_vertices, GL_ARRAY_BUFFER, _buffer_upload_usage_flag, true);
|
|
|
|
|
|
glEnableVertexAttribArray(VS::ARRAY_VERTEX);
|
|
|
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL);
|
|
|
- buffer_ofs += sizeof(Vector2) * p_vertex_count;
|
|
|
+ buffer_ofs = buffer_ofs_after;
|
|
|
|
|
|
if (p_singlecolor) {
|
|
|
glDisableVertexAttribArray(VS::ARRAY_COLOR);
|
|
@@ -461,31 +467,31 @@ 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);
|
|
|
+ RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors, buffer_ofs_after));
|
|
|
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;
|
|
|
+ buffer_ofs = buffer_ofs_after;
|
|
|
}
|
|
|
|
|
|
if (p_uvs) {
|
|
|
- glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs);
|
|
|
+ RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs, buffer_ofs_after));
|
|
|
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;
|
|
|
+ buffer_ofs = buffer_ofs_after;
|
|
|
} else {
|
|
|
glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
|
|
|
}
|
|
|
|
|
|
if (p_weights && p_bones) {
|
|
|
- glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(float) * 4 * p_vertex_count, p_weights);
|
|
|
+ RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(float) * 4 * p_vertex_count, p_weights, buffer_ofs_after));
|
|
|
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;
|
|
|
+ buffer_ofs = buffer_ofs_after;
|
|
|
|
|
|
- glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(int) * 4 * p_vertex_count, p_bones);
|
|
|
+ RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(int) * 4 * p_vertex_count, p_bones, buffer_ofs_after));
|
|
|
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;
|
|
|
+ buffer_ofs = buffer_ofs_after;
|
|
|
|
|
|
} else {
|
|
|
glDisableVertexAttribArray(VS::ARRAY_WEIGHTS);
|
|
@@ -495,10 +501,16 @@ void RasterizerCanvasBaseGLES2::_draw_polygon(const int *p_indices, int p_index_
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
|
|
|
|
|
|
if (storage->config.support_32_bits_indices) { //should check for
|
|
|
+#ifdef DEBUG_ENABLED
|
|
|
+ ERR_FAIL_COND((sizeof(int) * p_index_count) > data.polygon_index_buffer_size);
|
|
|
+#endif
|
|
|
storage->buffer_orphan_and_upload(data.polygon_index_buffer_size, 0, sizeof(int) * p_index_count, p_indices, GL_ELEMENT_ARRAY_BUFFER, _buffer_upload_usage_flag, true);
|
|
|
glDrawElements(GL_TRIANGLES, p_index_count, GL_UNSIGNED_INT, 0);
|
|
|
storage->info.render._2d_draw_call_count++;
|
|
|
} else {
|
|
|
+#ifdef DEBUG_ENABLED
|
|
|
+ ERR_FAIL_COND((sizeof(uint16_t) * p_index_count) > data.polygon_index_buffer_size);
|
|
|
+#endif
|
|
|
uint16_t *index16 = (uint16_t *)alloca(sizeof(uint16_t) * p_index_count);
|
|
|
for (int i = 0; i < p_index_count; i++) {
|
|
|
index16[i] = uint16_t(p_indices[i]);
|
|
@@ -517,11 +529,15 @@ void RasterizerCanvasBaseGLES2::_draw_generic(GLuint p_primitive, int p_vertex_c
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
|
|
|
|
|
|
uint32_t buffer_ofs = 0;
|
|
|
+ uint32_t buffer_ofs_after = buffer_ofs + (sizeof(Vector2) * p_vertex_count);
|
|
|
+#ifdef DEBUG_ENABLED
|
|
|
+ ERR_FAIL_COND(buffer_ofs_after > data.polygon_buffer_size);
|
|
|
+#endif
|
|
|
storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, sizeof(Vector2) * p_vertex_count, p_vertices, GL_ARRAY_BUFFER, _buffer_upload_usage_flag, true);
|
|
|
|
|
|
glEnableVertexAttribArray(VS::ARRAY_VERTEX);
|
|
|
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL);
|
|
|
- buffer_ofs += sizeof(Vector2) * p_vertex_count;
|
|
|
+ buffer_ofs = buffer_ofs_after;
|
|
|
|
|
|
if (p_singlecolor) {
|
|
|
glDisableVertexAttribArray(VS::ARRAY_COLOR);
|
|
@@ -531,16 +547,17 @@ 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);
|
|
|
+ RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors, buffer_ofs_after));
|
|
|
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;
|
|
|
+ buffer_ofs = buffer_ofs_after;
|
|
|
}
|
|
|
|
|
|
if (p_uvs) {
|
|
|
- glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs);
|
|
|
+ RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs, buffer_ofs_after));
|
|
|
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 = buffer_ofs_after;
|
|
|
} else {
|
|
|
glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
|
|
|
}
|
|
@@ -556,11 +573,15 @@ void RasterizerCanvasBaseGLES2::_draw_generic_indices(GLuint p_primitive, const
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
|
|
|
|
|
|
uint32_t buffer_ofs = 0;
|
|
|
+ uint32_t buffer_ofs_after = buffer_ofs + (sizeof(Vector2) * p_vertex_count);
|
|
|
+#ifdef DEBUG_ENABLED
|
|
|
+ ERR_FAIL_COND(buffer_ofs_after > data.polygon_buffer_size);
|
|
|
+#endif
|
|
|
storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, sizeof(Vector2) * p_vertex_count, p_vertices, GL_ARRAY_BUFFER, _buffer_upload_usage_flag, true);
|
|
|
|
|
|
glEnableVertexAttribArray(VS::ARRAY_VERTEX);
|
|
|
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL);
|
|
|
- buffer_ofs += sizeof(Vector2) * p_vertex_count;
|
|
|
+ buffer_ofs = buffer_ofs_after;
|
|
|
|
|
|
if (p_singlecolor) {
|
|
|
glDisableVertexAttribArray(VS::ARRAY_COLOR);
|
|
@@ -570,28 +591,41 @@ void RasterizerCanvasBaseGLES2::_draw_generic_indices(GLuint p_primitive, const
|
|
|
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);
|
|
|
+ RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors, buffer_ofs_after));
|
|
|
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;
|
|
|
+ buffer_ofs = buffer_ofs_after;
|
|
|
}
|
|
|
|
|
|
if (p_uvs) {
|
|
|
- glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs);
|
|
|
+ RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs, buffer_ofs_after));
|
|
|
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;
|
|
|
+ buffer_ofs = buffer_ofs_after;
|
|
|
} else {
|
|
|
glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
|
|
|
}
|
|
|
|
|
|
+#ifdef RASTERIZER_EXTRA_CHECKS
|
|
|
+ // very slow, do not enable in normal use
|
|
|
+ for (int n = 0; n < p_index_count; n++) {
|
|
|
+ RAST_DEV_DEBUG_ASSERT(p_indices[n] < p_vertex_count);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
|
|
|
|
|
|
if (storage->config.support_32_bits_indices) { //should check for
|
|
|
+#ifdef DEBUG_ENABLED
|
|
|
+ ERR_FAIL_COND((sizeof(int) * p_index_count) > data.polygon_index_buffer_size);
|
|
|
+#endif
|
|
|
storage->buffer_orphan_and_upload(data.polygon_index_buffer_size, 0, sizeof(int) * p_index_count, p_indices, GL_ELEMENT_ARRAY_BUFFER, _buffer_upload_usage_flag, true);
|
|
|
glDrawElements(p_primitive, p_index_count, GL_UNSIGNED_INT, 0);
|
|
|
storage->info.render._2d_draw_call_count++;
|
|
|
} else {
|
|
|
+#ifdef DEBUG_ENABLED
|
|
|
+ ERR_FAIL_COND((sizeof(uint16_t) * p_index_count) > data.polygon_index_buffer_size);
|
|
|
+#endif
|
|
|
uint16_t *index16 = (uint16_t *)alloca(sizeof(uint16_t) * p_index_count);
|
|
|
for (int i = 0; i < p_index_count; i++) {
|
|
|
index16[i] = uint16_t(p_indices[i]);
|
|
@@ -629,6 +663,7 @@ void RasterizerCanvasBaseGLES2::_draw_gui_primitive(int p_points, const Vector2
|
|
|
stride += 1;
|
|
|
}
|
|
|
|
|
|
+ RAST_DEV_DEBUG_ASSERT(p_points <= 4);
|
|
|
float buffer_data[(2 + 2 + 4 + 1) * 4];
|
|
|
|
|
|
for (int i = 0; i < p_points; i++) {
|
|
@@ -939,8 +974,8 @@ void RasterizerCanvasBaseGLES2::initialize() {
|
|
|
{
|
|
|
uint32_t poly_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_buffer_size_kb", 128);
|
|
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/canvas_polygon_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/canvas_polygon_buffer_size_kb", PROPERTY_HINT_RANGE, "0,256,1,or_greater"));
|
|
|
+ poly_size = MAX(poly_size, 2); // minimum 2k, may still see anomalies in editor
|
|
|
poly_size *= 1024;
|
|
|
- poly_size = MAX(poly_size, (2 + 2 + 4) * 4 * sizeof(float));
|
|
|
glGenBuffers(1, &data.polygon_buffer);
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
|
|
|
glBufferData(GL_ARRAY_BUFFER, poly_size, NULL, GL_DYNAMIC_DRAW);
|
|
@@ -951,6 +986,7 @@ void RasterizerCanvasBaseGLES2::initialize() {
|
|
|
|
|
|
uint32_t index_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", 128);
|
|
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", PROPERTY_HINT_RANGE, "0,256,1,or_greater"));
|
|
|
+ index_size = MAX(index_size, 2);
|
|
|
index_size *= 1024; // kb
|
|
|
glGenBuffers(1, &data.polygon_index_buffer);
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
|