|
16 | 16 | // CHANGELOG
|
17 | 17 | // (minor and older changes stripped away, please see git history for details)
|
18 | 18 | // 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
| 19 | +// 2022-05-23: OpenGL: Reworking 2021-12-15 "Using buffer orphaning" so it only happens on Intel GPU, seems to cause problems otherwise. (#4468, #4825, #4832, #5127). |
19 | 20 | // 2022-05-13: OpenGL: Fix state corruption on OpenGL ES 2.0 due to not preserving GL_ELEMENT_ARRAY_BUFFER_BINDING and vertex attribute states.
|
20 | 21 | // 2021-12-15: OpenGL: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports with some Intel HD drivers.
|
21 | 22 | // 2021-08-23: OpenGL: Fixed ES 3.0 shader ("#version 300 es") use normal precision floats to avoid wobbly rendering at HD resolutions.
|
|
98 | 99 | #else
|
99 | 100 | #include <stdint.h> // intptr_t
|
100 | 101 | #endif
|
| 102 | +#if defined(__APPLE__) |
| 103 | +#include <TargetConditionals.h> |
| 104 | +#endif |
101 | 105 |
|
102 | 106 | // Clang warnings with -Weverything
|
103 | 107 | #if defined(__clang__)
|
|
123 | 127 | #include <GLES2/gl2ext.h>
|
124 | 128 | #endif
|
125 | 129 | #elif defined(IMGUI_IMPL_OPENGL_ES3)
|
126 |
| -#if defined(__APPLE__) |
127 |
| -#include <TargetConditionals.h> |
128 |
| -#endif |
129 | 130 | #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV))
|
130 | 131 | #include <OpenGLES/ES3/gl.h> // Use GL ES 3
|
131 | 132 | #else
|
@@ -195,6 +196,7 @@ struct ImGui_ImplOpenGL3_Data
|
195 | 196 | GLsizeiptr VertexBufferSize;
|
196 | 197 | GLsizeiptr IndexBufferSize;
|
197 | 198 | bool HasClipOrigin;
|
| 199 | + bool UseBufferSubData; |
198 | 200 |
|
199 | 201 | ImGui_ImplOpenGL3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
200 | 202 | };
|
@@ -267,6 +269,14 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
267 | 269 | sscanf(gl_version, "%d.%d", &major, &minor);
|
268 | 270 | }
|
269 | 271 | bd->GlVersion = (GLuint)(major * 100 + minor * 10);
|
| 272 | + |
| 273 | + // Query vendor to enable glBufferSubData kludge |
| 274 | +#ifdef _WIN32 |
| 275 | + if (const char* vendor = (const char*)glGetString(GL_VENDOR)) |
| 276 | + if (strncmp(vendor, "Intel", 5) == 0) |
| 277 | + bd->UseBufferSubData = true; |
| 278 | +#endif |
| 279 | + //printf("GL_MAJOR_VERSION = %d\nGL_MINOR_VERSION = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", major, minor, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG] |
270 | 280 | #else
|
271 | 281 | bd->GlVersion = 200; // GLES 2
|
272 | 282 | #endif
|
@@ -485,20 +495,31 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
485 | 495 | const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
486 | 496 |
|
487 | 497 | // Upload vertex/index buffers
|
488 |
| - GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert); |
489 |
| - GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx); |
490 |
| - if (bd->VertexBufferSize < vtx_buffer_size) |
| 498 | + // - On Intel windows drivers we got reports that regular glBufferData() led to accumulating leaks when using multi-viewports, so we started using orphaning + glBufferSubData(). (See https://github.com/ocornut/imgui/issues/4468) |
| 499 | + // - On NVIDIA drivers we got reports that using orphaning + glBufferSubData() led to glitches when using multi-viewports. |
| 500 | + // - OpenGL drivers are in a very sorry state in 2022, for now we are switching code path based on vendors. |
| 501 | + const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert); |
| 502 | + const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx); |
| 503 | + if (bd->UseBufferSubData) |
491 | 504 | {
|
492 |
| - bd->VertexBufferSize = vtx_buffer_size; |
493 |
| - glBufferData(GL_ARRAY_BUFFER, bd->VertexBufferSize, NULL, GL_STREAM_DRAW); |
| 505 | + if (bd->VertexBufferSize < vtx_buffer_size) |
| 506 | + { |
| 507 | + bd->VertexBufferSize = vtx_buffer_size; |
| 508 | + glBufferData(GL_ARRAY_BUFFER, bd->VertexBufferSize, NULL, GL_STREAM_DRAW); |
| 509 | + } |
| 510 | + if (bd->IndexBufferSize < idx_buffer_size) |
| 511 | + { |
| 512 | + bd->IndexBufferSize = idx_buffer_size; |
| 513 | + glBufferData(GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize, NULL, GL_STREAM_DRAW); |
| 514 | + } |
| 515 | + glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data); |
| 516 | + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data); |
494 | 517 | }
|
495 |
| - if (bd->IndexBufferSize < idx_buffer_size) |
| 518 | + else |
496 | 519 | {
|
497 |
| - bd->IndexBufferSize = idx_buffer_size; |
498 |
| - glBufferData(GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize, NULL, GL_STREAM_DRAW); |
| 520 | + glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); |
| 521 | + glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); |
499 | 522 | }
|
500 |
| - glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data); |
501 |
| - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data); |
502 | 523 |
|
503 | 524 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
504 | 525 | {
|
|
0 commit comments