Browse Source

Added WIP experimental Window.SwapAsync flag + Window.ResizeWindow.

Mark Sibly 7 years ago
parent
commit
86e41bfabd

+ 22 - 12
modules/mojo/app/app.monkey2

@@ -456,7 +456,7 @@ Class AppInstance
 	#end
 	#end
 	Property Renderable:Bool()
 	Property Renderable:Bool()
 		
 		
-		Return _activeWindow And Not _activeWindow.Minimized And Not _renderingSuspended
+		Return _activeWindow And Not _activeWindow.Minimized And _activeWindow.CanRender And Not _renderingSuspended
 	End
 	End
 
 
 	#rem monkeydoc @hidden
 	#rem monkeydoc @hidden
@@ -466,7 +466,6 @@ Class AppInstance
 		If Not _requestRender Or Not Renderable
 		If Not _requestRender Or Not Renderable
 
 
 			SDL_WaitEvent( Null )
 			SDL_WaitEvent( Null )
-
 		Endif
 		Endif
 		
 		
 		UpdateEvents()
 		UpdateEvents()
@@ -507,7 +506,7 @@ Class AppInstance
 		
 		
 		For Local window:=Eachin Window.VisibleWindows()
 		For Local window:=Eachin Window.VisibleWindows()
 			window.UpdateWindow( render )
 			window.UpdateWindow( render )
-		End
+		Next
 		
 		
 		If _mouseView And Not IsActive( _mouseView )
 		If _mouseView And Not IsActive( _mouseView )
 			SendMouseEvent( EventType.MouseUp,_mouseView )
 			SendMouseEvent( EventType.MouseUp,_mouseView )
@@ -618,20 +617,18 @@ Class AppInstance
 		While SDL_PollEvent( Varptr event )
 		While SDL_PollEvent( Varptr event )
 			
 			
 			Window.CreateNewWindows()
 			Window.CreateNewWindows()
-		
-			DispatchEvent( Varptr event )
 			
 			
+			DispatchEvent( Varptr event )
 		Wend
 		Wend
-		
 	End
 	End
 	
 	
 	Method UpdateEvents()
 	Method UpdateEvents()
 	
 	
-		Keyboard.Update()
+'		Keyboard.Update()
 		
 		
-		Mouse.Update()
+'		Mouse.Update()
 		
 		
-		Touch.Update()
+'		Touch.Update()
 		
 		
 		DispatchEvents()
 		DispatchEvents()
 		
 		
@@ -1063,9 +1060,16 @@ Class AppInstance
 		
 		
 			Local uevent:=Cast<SDL_UserEvent Ptr>( event )
 			Local uevent:=Cast<SDL_UserEvent Ptr>( event )
 			
 			
-			Local event:=Cast<AsyncEvent Ptr>( uevent->data1 )
-			
-			event->Dispatch()
+			Select uevent->code
+			Case 0
+				Local event:=Cast<AsyncEvent Ptr>( uevent->data1 )
+				event->Dispatch()
+			Case 1
+				_window=Window.WindowForID( uevent->windowID )
+				If Not _window Return
+				
+				SendWindowEvent( EventType.WindowSwapped )
+			End
 
 
 		Case SDL_DROPFILE
 		Case SDL_DROPFILE
 		
 		
@@ -1159,6 +1163,12 @@ Class AppInstance
 			
 			
 				Return 0
 				Return 0
 					
 					
+			Case SDL_WINDOWEVENT_SIZE_CHANGED
+				
+'				Print "SDL_WINDOWEVENT_SIZE_CHANGED"
+
+				Return 0
+				
 			Case SDL_WINDOWEVENT_RESIZED
 			Case SDL_WINDOWEVENT_RESIZED
 				
 				
 '				Print "SDL_WINDOWEVENT_RESIZED"
 '				Print "SDL_WINDOWEVENT_RESIZED"

+ 2 - 1
modules/mojo/app/event.monkey2

@@ -53,7 +53,8 @@ Enum EventType
 	WindowLostFocus,
 	WindowLostFocus,
 	WindowMaximized,
 	WindowMaximized,
 	WindowMinimized,
 	WindowMinimized,
-	WindowRestored
+	WindowRestored,
+	WindowSwapped
 	
 	
 	Eaten=$40000000
 	Eaten=$40000000
 End
 End

+ 39 - 0
modules/mojo/app/native/app.cpp

@@ -5,8 +5,13 @@
 
 
 #include <SDL.h>
 #include <SDL.h>
 
 
+#include <thread>
+
 namespace bbApp{
 namespace bbApp{
 
 
+	bool swapThread;
+	bbAsync::Semaphore swapSema;
+
 	void postEventFilter( bbAsync::Event *event ){
 	void postEventFilter( bbAsync::Event *event ){
 
 
 		SDL_UserEvent uevent;
 		SDL_UserEvent uevent;
@@ -24,4 +29,38 @@ namespace bbApp{
 
 
 		bbAsync::setPostEventFilter( postEventFilter );
 		bbAsync::setPostEventFilter( postEventFilter );
 	}
 	}
+	
+	void swapBuffers( void *window,void *context ){
+	
+		if( !swapThread ){
+			
+			swapThread=true;
+	
+			SDL_Window *sdlwindow=(SDL_Window*)window;
+			SDL_GLContext sdlcontext=(SDL_GLContext)context;
+			
+			std::thread( [=](){
+			
+				SDL_GL_MakeCurrent( sdlwindow,sdlcontext );
+				
+				SDL_UserEvent uevent;
+				uevent.type=SDL_USEREVENT;
+				uevent.windowID=SDL_GetWindowID( sdlwindow );
+				uevent.code=1;
+		
+				for(;;){
+				
+					swapSema.wait();
+			
+					SDL_GL_SwapWindow( sdlwindow );
+		
+					if( SDL_PeepEvents( (SDL_Event*)&uevent,1,SDL_ADDEVENT,SDL_FIRSTEVENT,SDL_LASTEVENT )!=1 ){
+						printf( "SDL_PeepEvents error: %s\n",SDL_GetError() );fflush( stdout );
+					}
+				}
+	
+			} ).detach();
+		}
+		swapSema.signal();
+	}
 }
 }

+ 1 - 0
modules/mojo/app/native/app.h

@@ -5,6 +5,7 @@
 namespace bbApp{
 namespace bbApp{
 
 
 	void init();
 	void init();
+	void swapBuffers( void *window,void *context );
 }
 }
 
 
 #endif
 #endif

+ 58 - 2
modules/mojo/app/window.monkey2

@@ -1,6 +1,14 @@
 	
 	
+#Import "native/app.h"
+
 Namespace mojo.app
 Namespace mojo.app
 
 
+Extern Private
+
+Function swapBuffers( window:Void Ptr,context:Void Ptr )="bbApp::swapBuffers"
+	
+Public
+
 #rem monkeydoc Window creation flags.
 #rem monkeydoc Window creation flags.
 
 
 | WindowFlags	| Description
 | WindowFlags	| Description
@@ -86,6 +94,20 @@ Class Window Extends View
 		_swapInterval=swapInterval
 		_swapInterval=swapInterval
 	End
 	End
 	
 	
+	Property SwapAsync:Bool()
+		
+		Return _swapAsync
+	
+	Setter( swapAsync:Bool )
+		
+		_swapAsync=swapAsync
+	End
+	
+	Property CanRender:Bool()
+		
+		Return _canRender
+	End
+	
 	#rem monkeydoc Window fullscreen state.
 	#rem monkeydoc Window fullscreen state.
 	
 	
 	Note: The setter for this property deprecated! Please use BeginFullscreen/EndFullscreen instead.
 	Note: The setter for this property deprecated! Please use BeginFullscreen/EndFullscreen instead.
@@ -133,7 +155,32 @@ Class Window Extends View
 		If _contentView AddChildView( _contentView )
 		If _contentView AddChildView( _contentView )
 		
 		
 	End
 	End
-
+	
+	Method ResizeWindow( rect:Recti )
+		
+		Local x:Int=rect.Left/_mouseScale.x
+		Local y:Int=rect.Top/_mouseScale.y
+		Local w:Int=rect.Right/_mouseScale.x-x
+		Local h:Int=rect.Bottom/_mouseScale.y-y
+			
+		SDL_SetWindowPosition( _sdlWindow,x,y )
+		SDL_SetWindowSize( _sdlWindow,w,h )
+			
+		Frame=GetFrame()
+		_frame=Frame
+		_weirdHack=True
+	End
+	
+	Method ResizeWindow( x:Int,y:Int,width:Int,height:Int )
+		
+		ResizeWindow( New Recti( x,y,x+width,y+height ) )
+	End
+	
+	Method ResizeWindow( width:Int,height:Int )
+		
+		ResizeWindow( New Recti( 0,0,width,height ).Centered( New Recti( 0,0,App.DesktopSize ) ) )
+	End
+	
 	#rem monkeydoc Switches to 'desktop' fullscreen mode.
 	#rem monkeydoc Switches to 'desktop' fullscreen mode.
 	
 	
 	Switches to 'desktop' fullscreen mode. 
 	Switches to 'desktop' fullscreen mode. 
@@ -261,6 +308,8 @@ Class Window Extends View
 		Case EventType.WindowMaximized
 		Case EventType.WindowMaximized
 		Case EventType.WindowMinimized
 		Case EventType.WindowMinimized
 		Case EventType.WindowRestored
 		Case EventType.WindowRestored
+		Case EventType.WindowSwapped
+			_canRender=True
 		Case EventType.WindowMoved,EventType.WindowResized
 		Case EventType.WindowMoved,EventType.WindowResized
 			Frame=GetFrame()
 			Frame=GetFrame()
 			_frame=Frame
 			_frame=Frame
@@ -373,6 +422,8 @@ Class Window Extends View
 	Field _maxfudge:Int
 	Field _maxfudge:Int
 	Field _rswapInterval:=1
 	Field _rswapInterval:=1
 	Field _swapInterval:=1
 	Field _swapInterval:=1
+	Field _swapAsync:=False
+	Field _canRender:=True
 	
 	
 	Field _canvas:Canvas
 	Field _canvas:Canvas
 
 
@@ -539,7 +590,12 @@ Class Window Extends View
 		
 		
 		_canvas.EndRender()
 		_canvas.EndRender()
 		
 		
-		SDL_GL_SwapWindow( _sdlWindow )
+		If _swapAsync
+			_canRender=False
+			swapBuffers( _sdlWindow,_sdlGLContext )
+		Else
+			SDL_GL_SwapWindow( _sdlWindow )
+		Endif
 	End
 	End
 	
 	
 	Method Init( title:String,rect:Recti,flags:WindowFlags )
 	Method Init( title:String,rect:Recti,flags:WindowFlags )

+ 7 - 1
modules/std/async/native/async.h

@@ -11,10 +11,16 @@ namespace bbAsync{
 
 
 	struct Semaphore{
 	struct Semaphore{
 	
 	
-		int count=0;
+		int count;
 		std::mutex mutex;
 		std::mutex mutex;
 		std::condition_variable cond_var;
 		std::condition_variable cond_var;
 		
 		
+		Semaphore():count( 0 ){
+		}
+		
+		Semaphore( int count ):count( count ){
+		}
+		
 		void wait(){
 		void wait(){
 			std::unique_lock<std::mutex> lock( mutex );
 			std::unique_lock<std::mutex> lock( mutex );
 			while( !count ) cond_var.wait( lock );
 			while( !count ) cond_var.wait( lock );