Przeglądaj źródła

Reworked dead tex handling. Fixes #71.

woollybah 7 lat temu
rodzic
commit
6c8fa4f6ba
1 zmienionych plików z 65 dodań i 19 usunięć
  1. 65 19
      glmax2d.mod/glmax2d.bmx

+ 65 - 19
glmax2d.mod/glmax2d.bmx

@@ -82,7 +82,7 @@ Function Pow2Size( n )
 	Return t
 End Function
 
-Global dead_texs[],n_dead_texs,dead_tex_seq,n_live_texs
+Global dead_texs:TDynamicArray = New TDynamicArray(32),dead_tex_seq
 
 Extern
 	Function bbAtomicAdd:Int( target:Int Ptr,value:Int )="int bbAtomicAdd( int *,int )!"
@@ -91,18 +91,8 @@ End Extern
 'Enqueues a texture for deletion, to prevent release textures on wrong thread.
 Function DeleteTex( name,seq )
 	If seq<>dead_tex_seq Return
-	
-	Local n:Int = bbAtomicAdd(Varptr n_dead_texs, 1)
-	bbAtomicAdd(Varptr n_live_texs, -1)
-
-	dead_texs[n] = name
-End Function
 
-Function _ManageDeadTexArray()
-	If dead_texs.length <= n_live_texs
-		' expand array so it's large enough to hold all the current live textures.
-		dead_texs=dead_texs[..n_live_texs+20]
-	EndIf
+	dead_texs.AddLast(name)
 End Function
 
 Function CreateTex( width,height,flags )
@@ -110,16 +100,15 @@ Function CreateTex( width,height,flags )
 	Local name
 	glGenTextures 1,Varptr name
 	
-	n_live_texs :+ 1
-	_ManageDeadTexArray()
-	
 	'flush dead texs
 	If dead_tex_seq=GraphicsSeq
-		For Local i=0 Until n_dead_texs
-			glDeleteTextures 1,Varptr dead_texs[i]
-		Next
+		Local n:Int = dead_texs.RemoveLast()
+		While n <> $FFFFFFFF
+			glDeleteTextures 1, Varptr n
+			n = dead_texs.RemoveLast()
+		Wend
 	EndIf
-	n_dead_texs=0
+
 	dead_tex_seq=GraphicsSeq
 
 	'bind new tex
@@ -194,6 +183,63 @@ Function AdjustTexSize( width Var,height Var )
 	Forever
 End Function
 
+Type TDynamicArray
+
+	Private
+	
+	Field data:Int Ptr
+	Field size:Size_T
+	Field capacity:Size_T
+	
+	Field guard:TMutex
+	
+	Public
+	
+	Method New(initialCapacity:Int = 8)
+		capacity = initialCapacity
+		data = malloc_(Size_T(initialCapacity * 4))
+		guard = CreateMutex()
+	End Method
+
+	Method AddLast(value:Int)
+		guard.Lock()
+		If size = capacity Then
+			capacity :* 2
+			Local d:Byte Ptr = realloc_(data, capacity * 4)
+			If Not d Then
+				Throw "Failed to allocate more memory"
+			End If
+			data = d
+		End If
+		
+		data[size] = value
+		size :+ 1
+		guard.Unlock()
+	End Method
+	
+	Method RemoveLast:Int()
+		guard.Lock()
+		Local v:Int
+		
+		If size > 0 Then
+			size :- 1
+			v = data[size]
+		Else
+			v = $FFFFFFFF
+		End If
+		
+		guard.Unlock()
+		
+		Return v
+	End Method
+
+	Method Delete()
+		free_(data)
+		CloseMutex(guard)
+	End Method
+	
+End Type
+
 Public
 
 Type TGLImageFrame Extends TImageFrame