Optimize the hot loop
This commit is contained in:
parent
be9b8e993d
commit
2de8c70bb8
@ -8,7 +8,7 @@ from itertools import chain, repeat
|
||||
from queue import Queue, Empty
|
||||
|
||||
from .config import build_ansi_color_tables, to_color, fg_color_table, bg_color_table
|
||||
from .data_types import COL_MASK, COL_SHIFT, ITALIC_MASK, BOLD_MASK, REVERSE_MASK, as_color
|
||||
from .data_types import COL_MASK, COL_SHIFT, REVERSE_MASK, as_color
|
||||
from .fonts import set_font_family
|
||||
from .shaders import Sprites, ShaderProgram
|
||||
from .utils import get_logical_dpi
|
||||
@ -264,6 +264,20 @@ class CharGrid:
|
||||
|
||||
def render(self):
|
||||
' This is the only method in this class called in the UI thread (apart from __init__) '
|
||||
cell_data_changed = self.get_all_render_changes()
|
||||
if cell_data_changed:
|
||||
self.update_sprite_map()
|
||||
data = self.last_render_data
|
||||
|
||||
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
|
||||
if data.screen_geometry is None:
|
||||
return
|
||||
sg = data.screen_geometry
|
||||
self.render_cells(sg, data.sprite_layout)
|
||||
if not data.cursor.hidden:
|
||||
self.render_cursor(sg, data.cursor)
|
||||
|
||||
def get_all_render_changes(self):
|
||||
cell_data_changed = False
|
||||
data = self.last_render_data
|
||||
while True:
|
||||
@ -278,30 +292,27 @@ class CharGrid:
|
||||
if rd.viewport is not None:
|
||||
gl.glViewport(0, 0, self.width, self.height)
|
||||
data.update(rd)
|
||||
if cell_data_changed:
|
||||
spmap, sptext = data.cell_data
|
||||
for i, (text, attrs) in enumerate(sptext):
|
||||
return cell_data_changed
|
||||
|
||||
def update_sprite_map(self):
|
||||
spmap, sptext = self.last_render_data.cell_data
|
||||
psp = self.sprites.primary_sprite_position
|
||||
for i, key in enumerate(sptext):
|
||||
f = i * 9
|
||||
spmap[f:f + 3] = self.sprites.primary_sprite_position(text, attrs & BOLD_MASK, attrs & ITALIC_MASK)
|
||||
spmap[f:f + 3] = psp(key)
|
||||
self.sprites.set_sprite_map(spmap)
|
||||
|
||||
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
|
||||
if data.screen_geometry is None:
|
||||
return
|
||||
sg = data.screen_geometry
|
||||
def render_cells(self, sg, sprite_layout):
|
||||
with self.program:
|
||||
ul = self.program.uniform_location
|
||||
gl.glUniform2ui(ul('dimensions'), sg.xnum, sg.ynum)
|
||||
gl.glUniform4f(ul('steps'), sg.xstart, sg.ystart, sg.dx, sg.dy)
|
||||
gl.glUniform1i(ul('sprites'), self.sprites.sampler_num)
|
||||
gl.glUniform1i(ul('sprite_map'), self.sprites.buffer_sampler_num)
|
||||
gl.glUniform2f(ul('sprite_layout'), *data.sprite_layout)
|
||||
gl.glUniform2f(ul('sprite_layout'), *sprite_layout)
|
||||
with self.sprites:
|
||||
gl.glDrawArraysInstanced(gl.GL_TRIANGLE_FAN, 0, 4, sg.xnum * sg.ynum)
|
||||
|
||||
if not data.cursor.hidden:
|
||||
self.render_cursor(sg, data.cursor)
|
||||
|
||||
def render_cursor(self, sg, cursor):
|
||||
|
||||
def width(w=2, vert=True):
|
||||
|
||||
@ -10,6 +10,7 @@ from OpenGL.GL.ARB.copy_image import glCopyImageSubData # only present in openg
|
||||
from OpenGL.GL.ARB.texture_storage import glTexStorage3D # only present in opengl core >= 4.2
|
||||
|
||||
from .fonts import render_cell, cell_size
|
||||
from .data_types import ITALIC_MASK, BOLD_MASK
|
||||
|
||||
GL_VERSION = (3, 3)
|
||||
VERSION = GL_VERSION[0] * 100 + GL_VERSION[1] * 10
|
||||
@ -121,22 +122,24 @@ class Sprites:
|
||||
gl.glBufferData(tgt, ArrayDatatype.arrayByteCount(data), data, gl.GL_STATIC_DRAW)
|
||||
gl.glBindBuffer(tgt, 0)
|
||||
|
||||
def primary_sprite_position(self, text, bold=False, italic=False):
|
||||
def primary_sprite_position(self, key):
|
||||
' Return a 3-tuple (x, y, z) giving the position of this sprite on the sprite sheet '
|
||||
key = text, bold, italic
|
||||
first = self.first_cell_cache.get(key)
|
||||
if first is None:
|
||||
try:
|
||||
return self.first_cell_cache[key]
|
||||
except KeyError:
|
||||
pass
|
||||
text, attrs = key
|
||||
bold, italic = attrs & BOLD_MASK, attrs & ITALIC_MASK
|
||||
first, second = render_cell(text, bold, italic)
|
||||
self.first_cell_cache[key] = first = self.add_sprite(first)
|
||||
if second is not None:
|
||||
self.second_cell_cache[key] = self.add_sprite(second)
|
||||
return first
|
||||
|
||||
def secondary_sprite_position(self, text, bold=False, italic=False):
|
||||
key = text, bold, italic
|
||||
def secondary_sprite_position(self, key):
|
||||
ans = self.second_cell_cache.get(key)
|
||||
if ans is None:
|
||||
self.primary_sprite_position(text, bold, italic)
|
||||
self.primary_sprite_position(key)
|
||||
ans = self.second_cell_cache.get(key)
|
||||
if ans is None:
|
||||
return 0, 0, 0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user