Saturday, June 10, 2017

sdlvnc redux

This time I was really planning to make something useful out of the fgui code and prove to myself that it was good enough for whatever.  But... once again something else came up that captured my attention and I lost focus.  Someday I swear I'll finish.  Just not today.

So what happened was this.  I was minding my own business, lurking on the zipit IRC channel, when someone mentioned how he wanted X11 on the zipit to serve as the remote display for some other gizmo.  And that got me thinking...  Sounds familiar?  Yeah I know, it's the same story every time.  Oh well.  I just roll with it and see where it takes me.  This time it took me back to sdlvnc -- another project I never quite finished.  But maybe things would be different this time.

Anyhow since a modern X server is a bit heavy for the poor little zipit I figured let the remote gizmo do the rendering to a local headless X11vnc server.  Then you can run the less resource hungry sdlvnc client on the zipit if you want to see it and interact with it.  After all, if that other gizmo has the horsepower to run X clients, the it can probably run an instance of the X11vnc server too.   That's a much better use of the available resources.  Of course I've visited this particular problem before, but I never quite finished, and left some serious quick-N-dirty hackery in the sdlvnc zoom code.  Also I never made it  into a real openwrt package.  It was finally time to get serious about it.

First I got the old sdlvnc code working again by compiling it right on the bleeding edge openwrt zipit. In the process I fixed a few bugs with the connection setup code that I'd known about previously, but never bothered to fix.  It felt real good to finally get those out of the way.  Next I created an openwrt project for it and got a real sdlvnc openwrt package built.  That was also quite rewarding. In the process I also fixed the ebindkeys mouse emulation code to make the zipit mouse tracking less jumpy, so there's a new package for that as well. And, since everything was moving right along, I thought I'd step it up and tackle the zoom code.

The problem here was that I'd done a quick paste of the sdl_gfx zoomSurface function into the sdlvnc code the first time around.  That function is really intended for rescaling small sprites and images, and not so much for working with the entire screen.  It worked, but the performance was awful.  That's  mostly because the linear interpolation code is only written for 32 bits per pixel surfaces, so the 16 bpp vnc screen surface had to be converted, zoomed, and then converted back for every refresh.  All of those surface copies were created and destroyed on the fly by zoomSurface, for every screen refresh.  Yikes!  That's a lot of memory, and a lot of copying. It was wasting a third of a second per refresh for a 640x480 screen on the vnc server, and was even more excruciating for bigger screens, when it didn't crash for lack of memory.  So, I decided to add a 16 bpp path through the sdl_gfx zoomSurface function to eliminate all those wasteful copies.

I scribbled lots of notes and pieced it together a tiny bit at a time in the evenings, starting from a copy of the 32 bpp zoomSurfaceRGBA subfunction in sdl_gfx. Surprisingly, two or three weeks later when I tried it on a whim, it actually worked.   That never happens.  So for the next few days I cleaned it up and ran some timing tests.  The 16bit path was running in about one third the time of the 32 bit path -- a tenth of a second or so to zoom the 640x480 screen.  Much better, but I was hoping for more.  What to do next?  I was pretty sure small constant array offsets were essentially free in modern instruction sets, whereas maintaining an extra set of nearly identical pointers was not.  So I worked up some inner loop optimizations and squeezed another 12% speed gain out of it.  I also discovered that the code runs much faster the more you zoom out because it skips over more of the inner loops.  That's a nice bonus.  So converting 640x480 to 320x240 only takes about 0.03 seconds.  I can live with that, so I think I'll call this one finished.  Here's what it looks like.

I love the way the mouse pointer also gets scaled in zoom mode.

It's almost useful at that scale.  But now you can zoom in and out pretty much at will, so that's not such a problem.

Now I just need to find some new project that'd be great to have on the zipit, if only the display fit in the 320x240 pixel zipit screen.  I'm sure I passed up a few of those over the years...

Saturday, April 1, 2017

April Fooling

It's April 1st, and the weather gods have once again played a nasty little joke, dumping a chilly mix of snow and ice onto the lawn.  So I decided to make the best of it, staying inside and tinkering with some zipit software that's just barely past the idea phase.

One such idea that I keep revisiting is how to make the gmenu2x GUI more versatile.  So this time I thought, perhaps I can do it from outside the box.  Maybe I can make some scripted modal dialogs that could launch from gmenu2x, but run outside of gmenu2x and simply display over it temporarily.  Or maybe we could find a use for popup notifications that post themselves over gmenu2x temporarily.


So I grabbed a few small example programs that open /dev/fb0 and write directly to the screen.  And that's where I am right now.  I can save the gmenu2x screen, write over part of it, and then restore it when I'm done.  Not too exciting, but lotsa potential, especially if I pull in the fgui code for some nice looking widgets.  Fgui makes for a nice fit because it's only requirements are a pair of get and put_pixel functions, so it's easy to graft onto any sort of graphical backend.

With any luck, I'll have an actual dialog screenshot before the snow melts.

Update April 2

And there it is...
Check out that shiny new icon for the ziptuner.  Pretty sweet eh?

Ok, it's not an actual dialog, but it is a small chunk of the fgui demo program -- reworked with /dev/fb0 as the backend instead of the original sdl backend.   The new backend  lets me pop it up over the gmenu2x display and tinker with the controls.  There may still be a few patches of snow left in the shadows beneath the trees, so I think I'll call this a success.

It'd be even better if it used the /dev/fb1 overlay screen so I could display the popup with no worries about contention with gmenu2x screen updates.  Unfortunately there appears to be some bugs in the PXA video driver that make the overlay less than optimal for my purposes.    Perhaps I can do a workaround someday for the overlay, but first I want to try and make what I've got do something useful.

Tuesday, March 14, 2017

Back in the Groove

Um... yeah, it's been a while since I wrote much of anything around here. For now I'll simply blame writers block.  I've got lots to say but just haven't found the motivation to say it.  Spending more time doing than talking about it, I suppose.  So, in order to keep this particular train rolling, I selected an encouraging title in the hope that I could somehow get "Back on Track".  Unfortunately I already used that title -- this must be a recurring problem -- so I tweaked it a little.  I hope it works.

To get things started I'm just gonna post a picture or two of my current pet project, the ziptuner -- a tiny internet radio browser program for the zipit.  For just about forever I've wanted something to make it easier to acquire, try, and save internet radio station urls for my playlists on the zipit.  This is what I eventually came up with.  It's uses the nice clean http://www.radio-browser.info json API.

Here's the main screen.

Actually there's a few more choices now, but I'm too lazy to update the picture.

And here's the results of a Tag search for "disco".

Only 43 disco stations on the internet?  I find that hard to believe.


I'm truly impressed that someone -- more than one someone, actually -- found the need to devote a full 320Kbps to stream disco to the teeming masses on the internet.

Anyhow, that's it for now because it's still more fun to work on a project than to write about it.  So I'll try to revisit this page again when I run out of ideas.

Meanwhile openwrt packages are available in the usual place.

And here's an iz2s build:  ziptuner-iz2s.zip 

And a  ziptuner quick demo video