Recent

Author Topic: Faster panning and zooming  (Read 4787 times)

big_M

  • Jr. Member
  • **
  • Posts: 91
Faster panning and zooming
« on: October 07, 2020, 12:28:59 am »
So, in my program I need to zoom and pan larger images. Currently I do that this way (using standard components):
When I zoom, I generate a larger version of the image with stretchdraw.
When panning (zoomed in) I then read a part of the larger image with copyRect.

Is this generally a good idea, or is there a better approach?

The problem is that this runs not fast enough. When I zoom in (2x) on a not very large image (1800*1400px), panning gets already sluggish. With larger images it gets unusable. Would the use of BGRABitmap give me any benefits in that regard?

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: Faster panning and zooming
« Reply #1 on: October 07, 2020, 04:47:20 am »
What graphics are you using? BGRABitmap is impressively fast even with large images.
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Faster panning and zooming
« Reply #2 on: October 07, 2020, 05:24:23 am »
TCanvas is it is for maximum compatibility for all hardware, not optimized for performance. So it does not use all the features of your VGA.

Nowadays, almost all even the integrated VGAs have some basic hardware acceleration and support at least OpenGL version 1.5/2.0. If you do graphics processing and performance is important, you should choose a graphics library that supports hardware acceleration:

https://wiki.freepascal.org/Graphics_libraries

Learning a new library is hard you should choose wisely, not all libraries in the link above are hardware accelerated. Graphics32 is not hardware accelerated but you still will get some performance increase because they optimize the code properly. If you want to get the maximum performance you should learn OpenGL, the hardest. Simply drawing a triangle requires you to write plenty of lines. You can use OpenGL in Lazarus via TOpenGLContext. Here are the documentation and a compile-able demo of using TOpenGLContext:

https://wiki.lazarus.freepascal.org/OpenGL_Tutorial
https://forum.lazarus.freepascal.org/index.php/topic,35850.msg238019.html#msg238019

BGRABitmap support OpenGL but it is only enabled in 3D functions not in all drawing functions.

BGRABitmap is impressively fast even with large images.

TBGRABitmap is slow if you do large image stretching/resizing and animation. On small images, it is okay.
 

big_M

  • Jr. Member
  • **
  • Posts: 91
Re: Faster panning and zooming
« Reply #3 on: October 07, 2020, 12:29:01 pm »
Okay, so according to the wiki Graphics32 doesn't work on Linux, is that correct? That would be a shame.

The problem with TOpenGLContext is that, as far as I understand, I have to do everything myself with very basic graphics operations. So I can't easily draw text for example. Tbh, I think this is going to be overkill for my software.

So, you think TBGRABitmap is overall not faster than TCanvas then?

Andorra 2D looked interessting too, but that seems to be dead since 10 years  :(

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: Faster panning and zooming
« Reply #4 on: October 07, 2020, 01:23:31 pm »
BGRABitmap support OpenGL but it is only enabled in 3D functions not in all drawing functions.
No no you can use BGRABitmap for 2D OpenGL.

Quote
TBGRABitmap is slow if you do large image stretching/resizing and animation. On small images, it is okay.
Indeed if you do a fine resample, it is slow. Though if you do a simple stretch, speed is ok. You can as well to a StretchPutImage that will stretch only the visible part.
Conscience is the debugger of the mind

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Faster panning and zooming
« Reply #5 on: October 07, 2020, 01:24:08 pm »
Hi!

BGRAbitmap is definitly faster than TCanvas.

The people are often forgetting with what a high amount of data they are working with images.

An Image with 1280 x 1024 Pixel  has 1.310.720 Pixels

For simple operations you have to touch every of the 4 Channels RGBA.
That are 5.242.880 Operations.

If you write a simple filter and use  only the 8 neighbor pixels then you are at 42 million operations.


Think about it

Winni

If yo

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: Faster panning and zooming
« Reply #6 on: October 07, 2020, 01:26:48 pm »
The problem with TOpenGLContext is that, as far as I understand, I have to do everything myself with very basic graphics operations. So I can't easily draw text for example. Tbh, I think this is going to be overkill for my software.

So, you think TBGRABitmap is overall not faster than TCanvas then?
You can use for example a TBGRAVirtualScreen and in the redraw even a StretchPutImage. This is more or less what LazPaint does.

You can as well use BGRABitmap with OpenGL. In this case, drawing is not too complicated and you can draw text as well. See example:
https://github.com/bgrabitmap/bgrabitmap/tree/master/test/test4lcl_opengl
Conscience is the debugger of the mind

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: Faster panning and zooming
« Reply #7 on: October 07, 2020, 01:29:23 pm »
BGRAbitmap is definitly faster than TCanvas.
Not necessarily. If you have a TBitmap and do a StrecthDraw, it may use hardware acceleration and thus be quicker than BGRABitmap. Though you have less control over what you do. For example, you cannot choose the resample quality with Canvas.
Conscience is the debugger of the mind

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: Faster panning and zooming
« Reply #8 on: October 07, 2020, 01:31:30 pm »
When I zoom, I generate a larger version of the image with stretchdraw.
When panning (zoomed in) I then read a part of the larger image with copyRect.

Is this generally a good idea, or is there a better approach?
I guess whatever library you are using, this is not a good approach because you need a lot of memory to store the scaled image. To avoid that, you can do a StretchDraw directly on the Canvas with the appropriate coordinates (for example with negative X and Y if the top-left of the image is not visible).
Conscience is the debugger of the mind

big_M

  • Jr. Member
  • **
  • Posts: 91
Re: Faster panning and zooming
« Reply #9 on: October 07, 2020, 03:19:09 pm »
I guess whatever library you are using, this is not a good approach because you need a lot of memory to store the scaled image. To avoid that, you can do a StretchDraw directly on the Canvas with the appropriate coordinates (for example with negative X and Y if the top-left of the image is not visible).
Yes, I thought about something similar as an alternative. However then I would have to strechdraw constantly when panning, which I guess would be slower than just reading from an already scaled image. Or I can of course do the strechdraw only after the panning, and live with blank areas during the panning. Not nice, but it would certainly do the job. But I would prefer to avoid that of course

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Faster panning and zooming
« Reply #10 on: October 07, 2020, 03:23:20 pm »
Okay, so according to the wiki Graphics32 doesn't work on Linux, is that correct?
No. Take a look at https://www.pilotlogic.com/sitejoom/index.php/wiki.html?id=198.
pl_Graphics32 was tested on Win/Lin/BSD/Sol/Mac/GTK2/QT4/QT5/x86/x86_64/Arm/Arm64
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: Faster panning and zooming
« Reply #11 on: October 07, 2020, 03:40:05 pm »
Yes, I thought about something similar as an alternative. However then I would have to strechdraw constantly when panning, which I guess would be slower than just reading from an already scaled image. Or I can of course do the strechdraw only after the panning, and live with blank areas during the panning. Not nice, but it would certainly do the job. But I would prefer to avoid that of course
I invite you to try StretchDraw directly, you will see it is not slow.

Alternatively what you could do is divide the image according to a grid and precompute the scaled image for visible tiles and free them as they become invisible.
Conscience is the debugger of the mind

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Faster panning and zooming
« Reply #12 on: October 07, 2020, 04:12:07 pm »
See the image below for a comparison of sample quality: rmSimpleStretch vs rmFineResample. Can you notice any difference? Most people can't tell the difference. But all graphics professionals can tell you the difference.

If you can tolerate that quality then you can use rmSimpleStretch. When writing CATWW I done some tests for the BGRABitmap's performance. The time for painting the whole screen that composed of several scaled and rotated transparent layers using rmFineResample was about 200 ms but rmSimpleStretch was only about 50 ms.

I also found if the image was about 300 x 300 pixels and larger then it started to have noticeable performance issue.

With heavy use of caching, my CATWW finally can run on acceptable performance on old Core2 Duo machines. It 'eats' about 100 MB for the caching the images but I think it's okay because computer memory is now very affordable.

You can download test CATWW 0.2. Unfortunately the sample quality feature is not available on version 0.2. You can manually change it if you search into the code.
https://forum.lazarus.freepascal.org/index.php/topic,50989.0.html

Look at the picture below. Pay attention on the roundness of clock's border. Also, the quality is not good on thin font texts, on large and/or thick font there's almost no noticeable problem.
« Last Edit: October 07, 2020, 04:17:34 pm by Handoko »

big_M

  • Jr. Member
  • **
  • Posts: 91
Re: Faster panning and zooming
« Reply #13 on: October 07, 2020, 06:20:04 pm »
The quality is not that important in this case, but I zoom in with x2-steps anyway, so the result is okay/good enough even with the very simple stretch that StrechDraw does. 

I will try the method that circular has proposed now :) If it's not fast enough I will try it with BGRABitmap.

Thank you so far!

ChrisR

  • Full Member
  • ***
  • Posts: 247
Re: Faster panning and zooming
« Reply #14 on: October 08, 2020, 12:50:19 pm »
Can I suggest you try the OpenGL demo texture.lpr
  https://github.com/neurolabusc/Metal-Demos/tree/master/texture
by default, it loads the small. Coral and ClownFish bitmaps, but you can change these to be very large bitmaps. Dragging the mouse pans the images, and the scroll wheel adjusts the zoom. The nice thing about OpenGL is that the bitmap is stored in the GPU RAM, not the CPU RAM. This means that panning and zooming does not face the memory wall of slow transfer speeds.

The font_gl project demonstrates how to have nice scaleable fonts with OpenGL:
  https://github.com/neurolabusc/Metal-Demos/tree/master/font

 

TinyPortal © 2005-2018