| 
					
				 | 
			
			
				@@ -750,6 +750,60 @@ void logClear(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     laNotifyUsers("la.logs"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+laSafeString** la_PerfEnsure(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MAIN.NextPerfCounter++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(MAIN.NextPerfCounter>=32){ MAIN.NextPerfCounter=0; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return &MAIN.PerfLogs[MAIN.NextPerfCounter]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void la_PerfClear(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!MAIN.ShowPerf){ return; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MAIN.NextPerfCounter=0; MAIN.NextPerfGroup++; if(MAIN.NextPerfGroup>=32){ MAIN.NextPerfGroup=0; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    memset(&MAIN.PerfCounter[MAIN.NextPerfGroup],0,32*sizeof(real)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for(int i=0;i<32;i++){ strSafeDestroy(&MAIN.PerfLogs[i]); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void laPerfRecordV(char* format, va_list v){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!format || !format[0]) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laSafeString** ss=la_PerfEnsure(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    strSafePrintV(ss, format, v); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laTimeRecorder tm; laRecordTime(&tm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MAIN.PerfCounter[MAIN.NextPerfGroup][MAIN.NextPerfCounter] = laTimeElapsedSecondsf(&tm, &MAIN.FrameStartTime); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void laPerfRecord(char* format, ...){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!format || !format[0]) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laSafeString** ss=la_PerfEnsure(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    va_list aptr; va_start(aptr, format); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    strSafePrintV(ss, format, aptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    va_end(aptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laTimeRecorder tm; laRecordTime(&tm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    MAIN.PerfCounter[MAIN.NextPerfGroup][MAIN.NextPerfCounter] = laTimeElapsedSecondsf(&tm, &MAIN.FrameStartTime); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void la_PerfDraw(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tnsScale3d(0.75,0.75,0.75); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int sy=0; laBoxedTheme* bt=_LA_THEME_LABEL; real* color=laThemeColor(bt,LA_BT_TEXT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int sl=LA_RH*4; char buf[16]; real totval=0; real vals[32]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for(int i=0;i<32;i++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(MAIN.PerfLogs[i]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            real value = MAIN.PerfCounter[MAIN.NextPerfGroup][i]-(i>0?MAIN.PerfCounter[MAIN.NextPerfGroup][i-1]:0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sprintf(buf,"%0.2lf",value*1000); totval+=value; vals[i]=value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tnsDrawStringAuto(buf,color,0,10000,sy,LA_TEXT_SHADOW); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tnsDrawStringAuto(SSTR(MAIN.PerfLogs[i]),color,sl,10000,sy,LA_TEXT_SHADOW); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sy+=LA_RH; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    real SL=LA_RH*2,SR=LA_RH*3.5; sy=0; tnsColor4dv(color); tnsUseNoTexture(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for(int i=0;i<32;i++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(MAIN.PerfLogs[i]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            real r=vals[i]/totval; real use_r=tnsInterpolate(SL,SR,r); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tnsVertex2d(SL,sy); tnsVertex2d(SL,sy+LA_RH); tnsVertex2d(use_r,sy+LA_RH); tnsVertex2d(use_r,sy); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tnsPackAs(GL_TRIANGLE_FAN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sy+=LA_RH; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tnsFlush(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 laScreen* la_EnsureScreen(char* Name, int mmw, int mmh, int x, int y, int w, int h,int dpi){ if(!Name || !Name[0]) return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     for(laScreen* s=MAIN.Screens.pFirst;s;s=s->Item.pNext){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(strSame(SSTR(s->Name),Name)){ s->x=x;s->y=y;s->w=w;s->h=h; return s; } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2603,7 +2657,7 @@ int la_AnimateUiListRecursive(laUiList *uil); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void la_PanelDefDraw(laWindow *w, laPanel *p, laBoxedTheme *bt){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int DrawState_ = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    laUiListDraw uild = {0}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laUiListDraw uild = {0}; int orig_refresh=p->Refresh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (p->Show){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         la_SetPropMathcerContext(p); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2689,6 +2743,10 @@ void la_PanelDefDraw(laWindow *w, laPanel *p, laBoxedTheme *bt){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }elif (p->AnimationMode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         la_PanelDrawToWindow(p, w); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    laPerfRecord("%s [%s]",(orig_refresh&LA_TAG_RECALC)?"🌑": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           ((orig_refresh&LA_TAG_REDRAW)?"🌓": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           ((orig_refresh&LA_TAG_ANIMATION)?"🌔":"🌕")), SSTR(p->Title)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void la_AttachedPanelDefDraw(laWindow* w, laPanel* p, laBoxedTheme* bt){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(!p->Show && p!=w->MaximizedUiPanel) return; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -3092,6 +3150,10 @@ void la_WindowDefDraw(laWindow *w, laBoxedTheme *bt){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             la_PanelDrawToWindow(p, w); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(MAIN.ShowPerf){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        la_PerfDraw(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int laStartWindow(laWindow *w){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifdef LA_LINUX 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -8080,7 +8142,6 @@ void la_PostFrame(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void laMainLoop(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     laWindow *w = MAIN.Windows.pFirst, *NextW; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    laTimeRecorder FrameStartTime, FrameEndTime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     time_t t1, t2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     real TimeInterval, Pause, TimeAccum = 0, FrameInterval; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     static int a = 0; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -8096,7 +8157,8 @@ void laMainLoop(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while (1){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        laRecordTime(&FrameStartTime); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        laRecordTime(&MAIN.FrameStartTime); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        la_PerfClear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         la_PreFrame(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -8141,8 +8203,8 @@ void laMainLoop(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         la_PostFrame(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         //t2 = clock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        laRecordTime(&FrameEndTime); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        TimeInterval = laTimeElapsedSecondsf(&FrameEndTime, &FrameStartTime); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        laRecordTime(&MAIN.FrameEndTime); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        TimeInterval = laTimeElapsedSecondsf(&MAIN.FrameEndTime, &MAIN.FrameStartTime); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Pause = (1.0 / MAIN.TopFramerate - TimeInterval); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (Pause > 0){ 
			 |