Fix rendering when multiple windows are visible

This commit is contained in:
Kovid Goyal
2016-12-05 08:28:26 +05:30
parent 594ca34868
commit 319f06931a
3 changed files with 34 additions and 10 deletions

View File

@@ -213,6 +213,7 @@ class CharGrid:
def __init__(self, screen, opts):
self.buffer_lock = Lock()
self.buffer_id = None
self.current_selection = Selection()
self.last_rendered_selection = self.current_selection.limits(0, screen.lines, screen.columns)
self.render_buf_is_dirty = True
@@ -409,6 +410,8 @@ class CharGrid:
sg = self.render_data
if sg is None:
return
if self.buffer_id is None:
self.buffer_id = sprites.add_sprite_map()
buf = self.render_buf
start, end = sel = self.current_selection.limits(self.scrolled_by, self.screen.lines, self.screen.columns)
if start != end:
@@ -417,12 +420,13 @@ class CharGrid:
memmove(buf, self.render_buf, sizeof(type(buf)))
self.screen.apply_selection(addressof(buf), start[0], start[1], end[0], end[1], self.selection_foreground, self.selection_background)
if self.render_buf_is_dirty or self.last_rendered_selection != sel:
sprites.set_sprite_map(buf)
sprites.set_sprite_map(self.buffer_id, buf)
self.render_buf_is_dirty = False
self.last_rendered_selection = sel
return sg
def render_cells(self, sg, cell_program, sprites):
sprites.bind_sprite_map(self.buffer_id)
ul = cell_program.uniform_location
glUniform2ui(ul('dimensions'), sg.xnum, sg.ynum)
glUniform4f(ul('steps'), sg.xstart, sg.ystart, sg.dx, sg.dy)

View File

@@ -46,7 +46,7 @@ class Sprites:
self.first_cell_cache = {}
self.second_cell_cache = {}
self.x = self.y = self.z = 0
self.texture_id = self.buffer_id = self.buffer_texture_id = None
self.texture_id = self.buffer_texture_id = None
self.last_num_of_layers = 1
self.last_ynum = -1
self.texture_unit = GL_TEXTURE0
@@ -135,18 +135,25 @@ class Sprites:
self.texture_id = None
if self.buffer_texture_id is not None:
glDeleteTexture(self.buffer_texture_id)
if self.buffer_id is not None:
glDeleteBuffer(self.buffer_id)
def ensure_state(self):
if self.texture_id is None:
self.realloc_texture()
self.buffer_id = glGenBuffers(1)
self.buffer_texture_id = glGenTextures(1)
self.buffer_texture_unit = GL_TEXTURE1
def set_sprite_map(self, data, usage=GL_STREAM_DRAW):
glNamedBufferData(self.buffer_id, sizeof(data), addressof(data), usage)
def add_sprite_map(self):
return glGenBuffers(1)
def set_sprite_map(self, buf_id, data, usage=GL_STREAM_DRAW):
glNamedBufferData(buf_id, sizeof(data), addressof(data), usage)
def bind_sprite_map(self, buf_id):
glBindBuffer(GL_TEXTURE_BUFFER, buf_id)
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32UI, buf_id)
def destroy_sprite_map(self, buf_id):
glDeleteBuffer(buf_id)
def __enter__(self):
self.ensure_state()
@@ -155,8 +162,6 @@ class Sprites:
glActiveTexture(self.buffer_texture_unit)
glBindTexture(GL_TEXTURE_BUFFER, self.buffer_texture_id)
glBindBuffer(GL_TEXTURE_BUFFER, self.buffer_id)
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32UI, self.buffer_id)
def __exit__(self, *a):
glBindTexture(GL_TEXTURE_2D_ARRAY, 0)

View File

@@ -266,7 +266,7 @@ class TabManager(Thread):
glfw_post_empty_event()
def close_window(self, window=None):
' Can be called in either thread, will first kill the child (with SIGHUP), then remove the window from the gui '
' Can be called in either thread, will first kill the child, then remove the window from the gui '
if window is None:
window = self.active_window
if current_thread() is main_thread:
@@ -276,6 +276,18 @@ class TabManager(Thread):
window.destroy()
self.queue_ui_action(self.gui_close_window, window)
def close_tab(self, tab=None):
' Can be called in either thread, will first kill all children, then remove the tab from the gui '
if tab is None:
tab = self.active_tab
if current_thread() is main_thread:
self.queue_action(self.close_tab, tab)
else:
for window in tab:
self.remove_child_fd(window.child_fd)
window.destroy()
self.queue_ui_action(self.gui_close_window, window)
def run(self):
if self.args.profile:
import cProfile
@@ -478,6 +490,9 @@ class TabManager(Thread):
active.char_grid.render_cursor(rd, self.cursor_program)
def gui_close_window(self, window):
if window.char_grid.buffer_id is not None:
self.sprites.destroy_sprite_map(window.char_grid.buffer_id)
window.char_grid.buffer_id = None
for tab in self.tabs:
if window in tab:
break