From 02d5db007c54cd79f2a043a1b4cb39d0432ccbb9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alexis=20Laferri=C3=A8re?= Date: Thu, 22 Jun 2017 22:28:39 -0400 Subject: [PATCH] gamnit: cache sprite GPU index, as index_of is very costly MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexis Laferrière --- lib/gamnit/flat.nit | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/lib/gamnit/flat.nit b/lib/gamnit/flat.nit index b278029..f9710ab 100644 --- a/lib/gamnit/flat.nit +++ b/lib/gamnit/flat.nit @@ -253,6 +253,9 @@ class Sprite # Current context to which `self` was sorted private var context: nullable SpriteContext = null + # Index in `context` + private var context_index: Int = -1 + # Current context to which `self` belongs private var sprite_set: nullable SpriteSet = null end @@ -768,7 +771,7 @@ private class SpriteContext var usage: GLBufferUsage # Sprites drawn by this context - var sprites = new GroupedArray[Sprite] + var sprites = new GroupedSprites # Sprites to update since last `draw` var sprites_to_update = new Set[Sprite] @@ -878,8 +881,11 @@ private class SpriteContext # Update GPU data of `sprite` fun update_sprite(sprite: Sprite) do - var sprite_index = sprites.index_of(sprite) - if sprite_index == -1 then return + var context = sprite.context + if context != self then return + + var sprite_index = sprite.context_index + assert sprite_index != -1 # Vertices data @@ -1169,9 +1175,6 @@ private class GroupedArray[E] # Number of item slots in the array fun capacity: Int do return items.length - # Index of `item` - fun index_of(item: E): Int do return items.index_of(item) - # List of available slots var available = new MinHeap[Int].default @@ -1181,8 +1184,8 @@ private class GroupedArray[E] # Index of the spots after filled chunks var ends = new List[Int] - # Add `item` to the first available slot - fun add(item: E) + # Add `item` to the first available slot and return its index + fun add(item: E): Int do length += 1 @@ -1207,7 +1210,7 @@ private class GroupedArray[E] # at end of first chunk ends.first += 1 end - return + return i end items.add item @@ -1215,13 +1218,20 @@ private class GroupedArray[E] starts.add 0 ends.add 1 else ends.last += 1 + return ends.last - 1 end # Remove the first instance of `item` fun remove(item: E) do - var i = items.index_of(item) - assert i != -1 + var index = items.index_of(item) + remove_at(item, index) + end + + # Remove `item` at `index` + fun remove_at(item: E, index: Int) + do + var i = index length -= 1 items[i] = null @@ -1296,6 +1306,7 @@ private class GroupedArray[E] while max > 0 and (starts.length > 1 or starts.first != 0) do var i = ends.last - 1 var e = items[i] + assert e != null remove e add e moved.add e @@ -1328,6 +1339,20 @@ private class GroupedArray[E] end end +# Optimized `GroupedArray` to use `Sprite::context_index` and avoid using `index_of` +private class GroupedSprites + super GroupedArray[Sprite] + + redef fun add(item) + do + var index = super + item.context_index = index + return index + end + + redef fun remove(item) do remove_at(item, item.context_index) +end + redef class GLfloatArray private fun fill_from_matrix(matrix: Matrix, dst_offset: nullable Int) do -- 1.7.9.5