Reduce per OS Window VRAM usage for windows that use layered rendering, such as translucent windows.
The texture used as the intermediate rendering target is now shared between all OS Windows instead of each OS Window having its own. Fixes #9600 Fixes #9599
This commit is contained in:
parent
0170c2c0c6
commit
f7a4bf6be2
3 changed files with 32 additions and 13 deletions
|
|
@ -1400,18 +1400,28 @@ start_os_window_rendering(OSWindow *os_window, Tab *tab) {
|
|||
// note that during live resize rendering is done in layers
|
||||
if (os_window->live_resize.in_progress) blank_os_window(os_window);
|
||||
if (os_window->needs_layers) {
|
||||
if (os_window->indirect_output.width != os_window->viewport_width || os_window->indirect_output.height != os_window->viewport_height) {
|
||||
if (os_window->indirect_output.texture_id) free_texture(&os_window->indirect_output.texture_id);
|
||||
if (os_window->indirect_output.framebuffer_id) free_framebuffer(&os_window->indirect_output.framebuffer_id);
|
||||
// Ensure the global shared texture is large enough for this window
|
||||
if (global_state.layers_render_texture.width < os_window->viewport_width ||
|
||||
global_state.layers_render_texture.height < os_window->viewport_height) {
|
||||
if (global_state.layers_render_texture.texture_id) free_texture(&global_state.layers_render_texture.texture_id);
|
||||
if (global_state.layers_render_texture.framebuffer_id) free_framebuffer(&global_state.layers_render_texture.framebuffer_id);
|
||||
unsigned new_w = (unsigned)MAX(global_state.layers_render_texture.width, os_window->viewport_width);
|
||||
unsigned new_h = (unsigned)MAX(global_state.layers_render_texture.height, os_window->viewport_height);
|
||||
setup_texture_as_render_target(new_w, new_h, &global_state.layers_render_texture.texture_id, &global_state.layers_render_texture.framebuffer_id);
|
||||
global_state.layers_render_texture.width = (int)new_w;
|
||||
global_state.layers_render_texture.height = (int)new_h;
|
||||
global_state.layers_render_texture.texture_generation++;
|
||||
}
|
||||
if (os_window->indirect_output.texture_id == 0) {
|
||||
os_window->indirect_output.width = os_window->viewport_width;
|
||||
os_window->indirect_output.height = os_window->viewport_height;
|
||||
setup_texture_as_render_target((unsigned) os_window->viewport_width, (unsigned)os_window->viewport_height, &os_window->indirect_output.texture_id, &os_window->indirect_output.framebuffer_id);
|
||||
// Create per-window framebuffer if needed and attach the global texture to it
|
||||
if (!os_window->indirect_output.framebuffer_id) glGenFramebuffers(1, &os_window->indirect_output.framebuffer_id);
|
||||
if (os_window->indirect_output.attached_texture_generation != global_state.layers_render_texture.texture_generation) {
|
||||
bind_framebuffer_for_output(os_window->indirect_output.framebuffer_id);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, global_state.layers_render_texture.texture_id, 0);
|
||||
os_window->indirect_output.attached_texture_generation = global_state.layers_render_texture.texture_generation;
|
||||
}
|
||||
set_framebuffer_to_use_for_output(os_window->indirect_output.framebuffer_id);
|
||||
bind_framebuffer_for_output(0);
|
||||
save_viewport_using_bottom_left_origin(0, 0, os_window->indirect_output.width, os_window->indirect_output.height);
|
||||
save_viewport_using_bottom_left_origin(0, 0, os_window->viewport_width, os_window->viewport_height);
|
||||
clear_current_framebuffer();
|
||||
draw_bg_image(os_window, tab);
|
||||
}
|
||||
|
|
@ -1425,8 +1435,10 @@ stop_os_window_rendering(OSWindow *os_window, Tab *tab, Window *active_window) {
|
|||
bind_framebuffer_for_output(0);
|
||||
bind_program(BLIT_PROGRAM);
|
||||
glActiveTexture(GL_TEXTURE0 + GRAPHICS_UNIT);
|
||||
glBindTexture(GL_TEXTURE_2D, os_window->indirect_output.texture_id);
|
||||
glUniform4f(blit_program_layout.uniforms.src_rect, 0, 1, 1, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, global_state.layers_render_texture.texture_id);
|
||||
float sx = global_state.layers_render_texture.width > 0 ? (float)os_window->viewport_width / (float)global_state.layers_render_texture.width : 1.f;
|
||||
float sy = global_state.layers_render_texture.height > 0 ? (float)os_window->viewport_height / (float)global_state.layers_render_texture.height : 1.f;
|
||||
glUniform4f(blit_program_layout.uniforms.src_rect, 0, sy, sx, 0);
|
||||
glUniform4f(blit_program_layout.uniforms.dest_rect, -1, 1, 1, -1);
|
||||
restore_viewport();
|
||||
if (os_window->live_resize.in_progress) save_viewport_using_top_left_origin(
|
||||
|
|
|
|||
|
|
@ -491,7 +491,6 @@ destroy_os_window_item(OSWindow *w) {
|
|||
free(w->tabs); w->tabs = NULL;
|
||||
free_bgimage(&w->bgimage, true);
|
||||
zero_at_ptr(&w->bgimage);
|
||||
if (w->indirect_output.texture_id) free_texture(&w->indirect_output.texture_id);
|
||||
if (w->indirect_output.framebuffer_id) free_framebuffer(&w->indirect_output.framebuffer_id);
|
||||
}
|
||||
|
||||
|
|
@ -507,6 +506,11 @@ remove_os_window(id_type os_window_id) {
|
|||
REMOVER(global_state.os_windows, os_window_id, global_state.num_os_windows, destroy_os_window_item, global_state.capacity);
|
||||
END_WITH_OS_WINDOW_REFS
|
||||
update_os_window_references();
|
||||
if (global_state.num_os_windows == 0) {
|
||||
if (global_state.layers_render_texture.texture_id) free_texture(&global_state.layers_render_texture.texture_id);
|
||||
if (global_state.layers_render_texture.framebuffer_id) free_framebuffer(&global_state.layers_render_texture.framebuffer_id);
|
||||
global_state.layers_render_texture.width = 0; global_state.layers_render_texture.height = 0;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -312,8 +312,7 @@ typedef struct OSWindow {
|
|||
Tab *tabs;
|
||||
BackgroundImage *bgimage;
|
||||
struct {
|
||||
uint32_t texture_id, framebuffer_id;
|
||||
int width, height;
|
||||
uint32_t framebuffer_id, attached_texture_generation;
|
||||
} indirect_output;
|
||||
unsigned int active_tab, num_tabs, capacity, last_active_tab, last_num_tabs, last_active_window_id;
|
||||
bool focused_at_last_render, needs_render, needs_layers;
|
||||
|
|
@ -403,6 +402,10 @@ typedef struct GlobalState {
|
|||
id_type id; bool drag_started;
|
||||
double x, y;
|
||||
} tab_being_dragged;
|
||||
struct {
|
||||
uint32_t texture_id, framebuffer_id, texture_generation;
|
||||
int width, height;
|
||||
} layers_render_texture;
|
||||
} GlobalState;
|
||||
|
||||
extern GlobalState global_state;
|
||||
|
|
|
|||
Loading…
Reference in a new issue