AndyObtiva / glimmer-dsl-libui

Glimmer DSL for LibUI - Prerequisite-Free Ruby Desktop Development Cross-Platform Native GUI Library - The Quickest Way From Zero To GUI - If You Liked Shoes, You'll Love Glimmer! - No need to pre-install any prerequisites. Just install the gem and have platform-independent GUI that just works on Mac, Windows, and Linux.
MIT License
497 stars 15 forks source link

basic image - works fine. Is there a way to make the rendering faster somehow? It's not a huge issue though, so this is mostly just feedback #6

Open rubyFeedback opened 2 years ago

rubyFeedback commented 2 years ago

Hey there Andy,

I just tested the display of an image, based on the plenty examples you offer.

I managed to get this to work on the first run \o/

Image screenshot:

https://i.imgur.com/xyVUCFQ.png

(Yes, this is unfinished; I just copy/pasted form.rb and modified it ... I just wanted to see whether I can get it to work and I can, which is good! I am a noob tester; if I can get it to work others can as well. :D)

Anyway I'll continue with this, but there is one thing I noticed that is ... hmm, not a problem, but perhaps not perfect either.

You mentioned that in the comments, that this is slow. And indeed, on a re-draw, it takes a few seconds before it is re-rendered.

The testing code I used was something along those lines:

this_image = '/home/x/programming/ruby/src/backup_paradise/lib/backup_paradise/images/BACKUP_IMAGE.png'
area {
  on_draw { |area_draw_params|
    image(this_image, 96, 96)
  }
}

So, not sure if it can be made faster. But if you have some idea, perhaps you could either add an example or show how to fast-render an image if that is possible. It works for my use cases already (I only need a simple image to give a visual cue to the elderly person on windows ... I have not tested it on windows yet but will do so later, or tomorrow. First I have to finish the rest) - but of course nobody minds more speed.

I had a look at basic_image5.rb too

https://github.com/AndyObtiva/glimmer-dsl-libui/blob/master/examples/basic_image5.rb

and it uses ChunkyPNG which I suppose I could use as well. But right now I don't know whether this approach my be faster. If it is then perhaps I would use it, but as I don't know right now I just stick to area {} and image().

Perhaps at a later time I may look at basic_table_image.rb and use a table-layout instead anyway. But right now I just keep it simple: a single image.

If there are faster alternatives then this would be great of course, but for my use case it suffices as-is. I can designate the initial window size as-is via window() so that's not a problem; resizing doesn't need to be done. I can just add a link from the desktop on Win10 to the ruby application; I know that this works because I tested it before on my win10 laptop. \o/

Pretty cool that libui works well on windows - that is actually even simpler than web-apps too, because I'd have to set up a webserver or add a lot of javascript which I don't want to do on other people's win10 computers.

AndyObtiva commented 2 years ago

Actually, I could perhaps use your Computer Science computational geometry algorithm knowledge to help me with this.

The main issue is that C libui does not natively support images/pixels yet, so in order to draw an image on an area, you need to specify the colors of "each pixel", meaning thousands of pixels, and for bigger images, millions of pixels. Now, to do that with libui, you would have to construct a rectangle per pixel since it does not have a pixel construct alternative. That means, it has to process millions of rectangles (and in Ruby, rectangle objects) for bigger images.

One optimization I implemented to significantly decrease the number of rectangle objects rendered through libui was by looking into each scanline in an image and seeing if there were neighboring pixels that shared the same exact color value, and then grouping them together into one rectangle. That ended up cutting down the number of pixels from 9,216 for a specific 96x96 image to about 923 shapes to render (a huge 10x speed improvement, but depends on the image having similar neighboring pixels) as reported by examples/basic_image5.rb (which is doing the work of the image control manually). That optimization is already inside the library.

Now, I worked very hard on trying to do a similar optimization vertically, by attempting to group multiple scanlines or even similarly-colored pixels vertically. Unfortunately, the logic needed to calculate such similarity on the fly turned out to be such a processor intensive task that it negated the vertical optimization. As such, I only kept the horizontal grouping-of-pixels-into-lines optimization for now.

If you can come up with a better algorithm, I would be happy to add to Glimmer DSL for LibUI. The logic for the image control shapes is at the bottom of this file (#calculate_shapes method): https://github.com/AndyObtiva/glimmer-dsl-libui/blob/master/lib/glimmer/libui/control_proxy/image_proxy.rb

Otherwise, here are a few tips for your situation that should work for the time being:

I hope that was helpful. Let me know what works for you.