About Monkey 2 › Forums › Monkey 2 Development › Jitter adventure step 2
Tagged: Performance Jitter Smoothness
This topic contains 8 replies, has 3 voices, and was last updated by
DruggedBunny
1 year, 1 month ago.
-
AuthorPosts
-
March 13, 2018 at 4:20 am #13993
Getting closer to hunt down what we begin to call “the jitterbug” in the M2 sourcecode. We’re 7 people now doing it the hard way comparing Monkey1 and Monkey 2 source code line by line.
This short example is a good way to show how it behaves for both window and MacOS (also for both windowed and fullscreen mode). This is how it expresses itself all the time even when things appears smooth, it’s just blown up here.
It induces a good kind of strain, but you need a powerful computer such as a MacBook Air 2015 or 2017 for this particular code. If you got a weaker or more powerful computer you can just increase or decrease the tilesize variable until you get an almost “stable” 60 fps, and then you go backwards to cut the strain in half. This will be a great sweetspot to see what happens.
I show this action in the video.
Overall graphic performance
We noticed that the overall power is about half of Monkey1 but that’s not a problem as there’s plenty enough power to go around still on everything except maybe the weakest computer.But the jitter is there all the time on all systems and machines so far we’ve seen. Even when things seem to be smooth in Windows and MacOS it’s there it’s just tiny, miniscule. It seem to be a timing problem that has to do with events.
Events
If you got one of those convertible tablet/notebooks and you detach the keyboard while a Monkey2 app is running then you can see also that it pauses exactly 4-5 times each and every time you detach it in sequence with it takes about 4-5 seconds to complete.Monkey1 would not give a damn when you do this, It’s perfectly robust, not a glitch.
Monkey2 somehow reacts on a huge amount of events that the OS sends, even “invisible” ones that’s constantly there, this mess up timing of also e.g. graphics in a miniscule (but still important) way. Other things are also affect of course.Note that this is not using only standard commands anymore but also OpengGL/SDL2, the problem is still there.
Sourcecode
https://ufile.io/61ng1Video
EDIT it might be hard to see the video in fullscreen using the thumbnail so here’s the actual url
h t t p s : / / streamable.com/4hj29Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131Namespace Myapp#Import "<std>"#Import "<mojo>"#Import "<mojo3d>"#import "<sdl2>"#Import "assets/"Using std..Using mojo..Using sdl2..Using gles20..Const w:=1440, h:=900 ' Set native resolution here' Class Myapp Extends WindowClass MyWindow Extends GLWindowField canvas:CanvasField icanvas:CanvasField scanvas:CanvasField image:ImageField sourceImage:ImageField targetImage:ImageField size:Int=4 ' try 8 16 32 64Field cx:IntField wx:IntField wy:IntField tilemap:=New Int[512*512]Field s:Int = 4Method New() ' ( title:String,width:Int,height:Int,flags:WindowFlags=WindowFlags.Resizable )'Super.New("Myapp", w, h, WindowFlags.Fullscreen) ' fullscreen with menu and dock when mouse is at edges?'Fullscreen=False'Super.New("Myapp", w, h, WindowFlags.Resizable) '| WindowFlags.Fullscreen WindowFlags.Center windowFlags is type? Null) how mix?Super.New( "GL Window",640,480,WindowFlags.Resizable )ClearEnabled=FalseFor Local y:=0 To 511For Local x:=0 To 511tilemap[x + y * 512] = Int(Rnd(127))NextNextsourceImage=Image.Load( "asset::sheet.png",Null,Null )targetImage=New Image( sourceImage.Width,sourceImage.Height,PixelFormat.RGBA8,TextureFlags.Dynamic )image=New Image( 512,512,PixelFormat.RGBA8,TextureFlags.Dynamic )icanvas=New Canvas(image)scanvas=New Canvas(targetImage)' canvas=New Canvas() NOT NEEDED IN MONKEY2 ' image.Texture.Flags &=~ TextureFlags.FilterMipmapEndProtected' ---------------------------------------------------------------------------------------Method OnRender( canvas:Canvas ) OverrideSuper.OnRender( canvas )' WAS' App.RequestRender()wx=wx+2' canvas.Alpha=1.0scanvas.Clear(Color.Black) ' INSTEAD OF SHADER FOR NOW (copies sourceImage to targetImage)scanvas.DrawImage(sourceImage,0,0)scanvas.Flush()' Init canvas & image'canvas.Viewport(0,0,w,h)'canvas.Scissor(0,0,w,h)'canvas.Projection2d(0,w,0,h)canvas.Clear(Color.None)'icanvas.Viewport(0,0,w,h)'icanvas.Scissor(0,0,w,h)'icanvas.Projection2d(0,w,0,h)icanvas.Clear(Color.None)' Draw to image' Scroll (by drawing onto itself)icanvas.Clear(Color.Black)icanvas.DrawImage(sourceImage,0,0)icanvas.DrawImage(targetImage,256,256)cx=(cx+2) Mod 512For Local temp:=0 To 127icanvas.DrawRect(64+temp,0,1,64,targetImage,0+temp+cx,0,1,64)Next' Plots something in the tiles (shows how to draw something to an image *after* shader have been applied)For Local temp:=1 To 16If Int(Rnd(1)) Then icanvas.Color = Color.Black Else icanvas.Color = Color.WhiteLocal xx:= Int(Rnd(7))Local yy:= Int(Rnd(7))icanvas.DrawRect(xx*4,yy*4,2*4,2*4)Nexticanvas.Flush() ' Finished drawing' Draw to canvas' Cookiecut 32x32 tiles from a 512x512 tilesheet and draw as tiles of any sizeLocal scrx:=wx Mod sizeLocal scry:=wy Mod sizeLocal mapx:=wx / sizeLocal mapy:=wy / sizeLocal cnty:= -scryFor Local y:=mapy To mapy+((h/size)+1)Local cntx:=-scrxFor Local x:=mapx To mapx+((w/size)+1)Local char:= tilemap[x + y * 512]Local tilex:= char & 15Local tiley:= char Shr 4canvas.DrawRect(cntx,cnty,size,size,image,tilex Shl 5,tiley Shl 5,32,32)cntx=cntx+sizeNextcnty=cnty+sizeNextcanvas.Flush() ' Finished drawingIf Keyboard.KeyReleased(Key.Escape) Then App.Terminate()End Method' NEWMethod OnRenderGL() OverrideglClearColor( 0,0,1,1 )glClearDepthf( 0 )glClearStencil( 0 )glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT )glViewport( 0,0,Frame.Width,Frame.Height )App.RequestRender()EndEndFunction Main()Local cfg:=New StringMap<String>cfg["GL_depth_buffer_enabled"]=1cfg["GL_stencil_buffer_enabled"]=1New AppInstance( cfg )New MyWindowApp.Run()' Sleep(1)EndAttachments:
March 13, 2018 at 9:58 am #13997I’m getting a compile error..
Monkey1234567891011121314Mx2cc version 1.1.10***** Making app 'C:/mx2_short/phatPete/untitled2.monkey2' (windows debug x64 msvc) *****Parsing...Semanting...C:/mx2_short/phatPete/untitled2.monkey2 [1] : Error : Namespace 'gles20' not foundC:/mx2_short/phatPete/untitled2.monkey2 [112] : Error : Identifier 'glClearColor' Not foundC:/mx2_short/phatPete/untitled2.monkey2 [113] : Error : Identifier 'glClearDepthf' Not foundC:/mx2_short/phatPete/untitled2.monkey2 [114] : Error : Identifier 'glClearStencil' Not foundC:/mx2_short/phatPete/untitled2.monkey2 [115] : Error : Identifier 'GL_COLOR_BUFFER_BIT' Not foundC:/mx2_short/phatPete/untitled2.monkey2 [116] : Error : Identifier 'glViewport' Not foundC:/mx2_short/phatPete/untitled2.monkey2 [127] : Error : Can't find overload for 'new' with argument types (std.collections.Map<monkey.types.String,monkey.types.String>)March 14, 2018 at 3:33 pm #14020It was meant for the last Monkey2 version that works without updating Macos to HighSierra.
The update that made the error is the transient from naming opengles into a general OpenGL module.
Here it is rewritten for the new one, same result. Don’t forget to set width and height to your native screen before you run it for best effect.Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151Namespace myapp#Import "<std>"#Import "<mojo>"'#Import "<mojo3d>"#Import "assets/"Using std..Using mojo..Using opengl..Const w:=1440, h:=900Class MyWindow Extends GLWindowField canvas:CanvasField icanvas:CanvasField scanvas:CanvasField image:ImageField sourceImage:ImageField targetImage:ImageField size:Int=4 ' try 8 16 32 64Field cx:IntField wx:IntField wy:IntField tilemap:=New Int[512*512]Field s:Int = 4Method OnWindowEvent(event:WindowEvent) OverrideEndMethod OnKeyEvent(event:KeyEvent) OverrideendMethod OnMouseEvent(event:MouseEvent) OverrideendMethod New() ' ( title:String,width:Int,height:Int,flags:WindowFlags=WindowFlags.Resizable )' Super.New("Myapp", w, h, WindowFlags.Fullscreen) ' fullscreen with menu and dock when mouse is at edges?' Fullscreen=False' Super.New("Myapp", w, h, WindowFlags.Resizable) '| WindowFlags.Fullscreen WindowFlags.Center windowFlags is type? Null) how mix?Super.New( "GL Window",640,480,WindowFlags.Resizable )ClearEnabled=FalseClearEnabled=FalseFor Local y:=0 To 511For Local x:=0 To 511tilemap[x + y * 512] = Int(Rnd(127))NextNextsourceImage=Image.Load( "asset::sheet.png",Null,Null )targetImage=New Image( sourceImage.Width,sourceImage.Height,PixelFormat.RGBA8,TextureFlags.Dynamic )image=New Image( 512,512,PixelFormat.RGBA8,TextureFlags.Dynamic )icanvas=New Canvas(image)scanvas=New Canvas(targetImage)' canvas=New Canvas() ONLY NEEDED IN MONKEY1 ' image.Texture.Flags &=~ TextureFlags.FilterMipmapEndProtected' ---------------------------------------------------------------------------------------Method OnRender( canvas:Canvas ) OverrideSuper.OnRender( canvas )' App.RequestRender()wx=wx+10 ' 2' canvas.Alpha=1.0scanvas.Clear(Color.Black)' INSTEAD OF SHADER (copies sourceImage to targetImage)scanvas.DrawImage(sourceImage,0,0)scanvas.Flush()' Init canvas & image'canvas.Viewport(0,0,w,h)'canvas.Scissor(0,0,w,h)'canvas.Projection2d(0,w,0,h)' canvas.Clear(Color.None)'icanvas.Viewport(0,0,w,h)'icanvas.Scissor(0,0,w,h)'icanvas.Projection2d(0,w,0,h)'icanvas.Clear(Color.None)' Draw to image' Scroll (by drawing onto itself)icanvas.Clear(Color.Black)icanvas.DrawImage(sourceImage,0,0)icanvas.DrawImage(targetImage,256,256)cx=(cx+2) Mod 512For Local temp:=0 To 127icanvas.DrawRect(64+temp,0,1,64,targetImage,0+temp+cx,0,1,64)Next' Plots something in tiles (draw something to an image *after* shader have been appliedFor Local temp:=1 To 16If Int(Rnd(1)) Then icanvas.Color = Color.Black Else icanvas.Color = Color.WhiteLocal xx:= Int(Rnd(7))Local yy:= Int(Rnd(7))icanvas.DrawRect(xx*4,yy*4,2*4,2*4)Nexticanvas.Flush()' Draw to canvas' Cookiecut 32x32 tiles from a 512x512 tilesheet and draw them as tiles of any sizeLocal scrx:=wx Mod sizeLocal scry:=wy Mod sizeLocal mapx:=wx / sizeLocal mapy:=wy / sizeLocal cnty:= -scryFor Local y:=mapy To mapy+((h/size)+1)Local cntx:=-scrxFor Local x:=mapx To mapx+((w/size)+1)Local char:= tilemap[x + y * 512]Local tilex:= char & 15Local tiley:= char Shr 4canvas.DrawRect(cntx,cnty,size,size,image,tilex Shl 5,tiley Shl 5,32,32)cntx=cntx+sizeNextcnty=cnty+sizeNextcanvas.Flush() ' Finished drawingIf Keyboard.KeyReleased(Key.Escape) Then App.Terminate()End MethodMethod OnRenderGL() OverrideglClearColor(0,0,1,1)glClearDepth(0)glClearStencil(0)glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)glViewport(0,0,Frame.Width,Frame.Height)'glEnable( GL_SCISSOR_TEST )'glScissor( x-32,Frame.Height-x-32,64,64 )'glClearColor( 1,0,0,1 )'glClear( GL_COLOR_BUFFER_BIT )'glDisable( GL_SCISSOR_TEST )App.RequestRender()EndEnd'Function Main()' New AppInstance' New Myapp' App.Run()'End Function' NEWFunction Main()' Local cfg:=New StringMap<String>' cfg["GL_depth_buffer_enabled"]=1' cfg["GL_stencil_buffer_enabled"]=1' New AppInstance( cfg )New AppInstanceNew MyWindowApp.Run()' Sleep(1)EndMarch 14, 2018 at 3:38 pm #14021The effects are not exactly the same in all installations though, in some you get the event interrupts when you move the mouse in the app window and some gives the results shown in the video but they are both related.
March 14, 2018 at 3:55 pm #14022If running a nice M2 app with a steady 60 fps, then a trained eye could easily compare this to something like the M1 equivalent (I can provide an code if wanted but any code works as long as it’s written in Mojo2) and then compare it with this “smooth” M2 app and you would see and feel the difference of micro stability.
I was personally fooled a long time, so when I noticed glitches I thought it was something wrong with the device like a bad update or driver. Fresh installs on 14 different systems and Windows / Macos machines (haven’t tried Linux or Pi yet because those are lower priority still for us).
Android can never give this experience so it doesn’t matter much if your developing for Android but iOS and Macos and Windows CAN give this ultrastable & smooth experience (but with M1 only so far).
It makes a huge difference on the user overall experience.
March 14, 2018 at 4:05 pm #14023There’s a strange resemblance in Monkey2 & Monkey1-used-together-with-only-Mojo1, but it seems to be nothing but a coincidence, they have nothing to do with each other. There seem to be no inherited code which is a shame I guess because that would have made things so much simpler to fix.
March 14, 2018 at 7:35 pm #14026I have to run it at 500*500 to get 60FPS!
I can see jitter only when the mouse leaves/enter the window (on windows10). I think it’s a sdl2 thing. monkey1/mojo2 is using glfw so it’s managing the events another way.
I must say I cannot help much, it’s too close from metal for me. Is it mojo managing sdl2 events in a way it can be optimised or is sdl2? You could try to do something in native code using pure c++/OpenGL/sdl2 to see if it’s not sdl2 before diving in mx2/mojo code.March 18, 2018 at 10:32 am #14061Ya, the source of lag is that we can’t use the threadsafe SDL_PeepEvents, switching to SDL_PollEvent seem to be the only way to be lagfree.
Actually the way to use SDL_PollEvent is important too.So it seem we need to change while(SDL_PollEvent(&event)) into (SDL_PollEvent(&event))
or to change SDL_PollEvent() into SDL_WaitEvent() SDL2 generates key repeat events automatically so repeated key events needs to be filtered out manually by checking the repeat member of a SDL_KeyboardEvent.March 18, 2018 at 12:19 pm #14063Probably best to raise an ‘issue’ on Github to make sure Mark sees it:
https://github.com/blitz-research/monkey2/issues
-
AuthorPosts
You must be logged in to reply to this topic.
