ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
Forum membership is Free!  Click Join to sign-up
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 First Layermovement has a lag.
 New Topic  Reply to Topic
Next Page
Author Previous Topic Topic Next Topic
Page: of 2

zerob

111 Posts

Posted - Jan 16 2019 :  06:25:51  Show Profile  Reply
If i add a ImageLayer to a TImageEnView and try to move it with the mouse, the first movement freezes the app for a short duration and after that all movements are nice and without that effect.

It seems that ImageEn does some heavy work on the first Layermovement (With mouse).

Can you do that on creation of the ImageEnView or expose a function to manually do it at the best time?

zerob

111 Posts

Posted - Jan 18 2019 :  10:59:15  Show Profile  Reply
Here is a zip file with a Video showing the first stutter/lag on first movement, and also a compiled exe and the sources of a small demo containing only "ImageEnView1.LayersAdd('demo.jpg',1,1);" to load a demo.jpg and some settings set in the editor for ImageEnView.

If you grab the ImageLayer and try to move it the first time, it gets stuck for a short duration and then moves like normal. All other movements after that first stutter are smooth... even when i create more than 1 ImageLayer.

attach/zerob/201911810561_bug.zip
4148.78 KB
Go to Top of Page

zerob

111 Posts

Posted - Jan 19 2019 :  11:45:17  Show Profile  Reply
Tried it on a slow AMD CPU and a slow small Intel Atom and there was no lag.
But on my fast Intel machine there is the lag.

I also tested it on VirtualBox with Windows XP and Windows 7 on the same machine and with emulation,
there is no lag.

My Machine has these specs:
Intel Core i7-3930K 3.20GHz 16 Threads
32 GB RAM
2 TB Samsung SSD Pro (Windows and all apps)
6 TB Normal disk (data)
Windows 10 Pro
Nvidia Geforce GTX 680
Liquid Cooled.
My CPU and Disk and GPU has 0% usage.


What seems interresting is the ram and cpu usage of the app...
1 picture loaded without moving = 7.6MB
1 picture moved the first time = 12.3 MB
Loading an additional image after the first got moved = 13.4 MB


Loading 2 images without moving = 8.8 MB
2 images and moving one the first time = 13.4 MB
Loading a 3rd image after the first got moved = 14.3 MB

So it seems that on first moving / resizing, ImageEn allocates a big junk of memory and does some heavy work.
The CPU also shows a big spike that dissapears after the first movement... all further movements don't spike the CPU at all.

I also have no problems with anything on my pc and all ImageEn functions run smoothly... even calculations and Langzos run perfect. but the first movement lags.
I also set cpu and IO priority of the app to realtime and my cpu min speed to 100% for a test and it still lags.
Maybe ImageEn does something that my CPU doesn't like in the current design (bottleneck?)
Go to Top of Page

zerob

111 Posts

Posted - Jan 21 2019 :  06:45:44  Show Profile  Reply
I've seen that creating a first TextLayer also causes the lag. It seems to trigger the same thing like moving a ImageLayer.
After creating a first TextLayer there is no more ImageLayer first movement or TextLayer creation lag.
Go to Top of Page

nwscomps

185 Posts

Posted - Jan 21 2019 :  06:58:42  Show Profile  Reply
just to add that I have seen this lag too.

Francesco Savastano
Add-ons for the ImageEn Library
web: http://www.fssoft.it/delphicomps.html
Go to Top of Page

xequte

38176 Posts

Posted - Jan 23 2019 :  21:11:04  Show Profile  Reply
Hi

Do any of the following affect it:

- Disabling connection to TImageEnLayerMView (if any)
- Enabling/disabling TImageEnView.LayersCaching
- Changing TImageEnView.ZoomFilter/DelayZoomFilter
- Disabling TImageEnView.Proc.AutoUndo



Nigel
Xequte Software
www.imageen.com
Go to Top of Page

zerob

111 Posts

Posted - Jan 25 2019 :  03:41:35  Show Profile  Reply
>Do any of the following affect it:
>- Disabling connection to TImageEnLayerMView (if any)
I only use a TImageEnLayer with a ImageLayer, no TImageEnLayerMView

>- Enabling/disabling TImageEnView.LayersCaching
It happens with -1 0 or any number. so this setting doesn't affect it.

>- Changing TImageEnView.ZoomFilter/DelayZoomFilter
It happens even with TResampleFilter.rfNone and DelayZoomFilter True/False

>- Disabling TImageEnView.Proc.AutoUndo
Happens with ImageEnView1.Proc.AutoUndo := False; or True.

OnLayerMoveSize gets triggered before the lag.
OnLayerNotify triggers with ielSelected (sometimes it doesn't show that event) and then ielMoving before it lags.

It happens like this:
ielMouseOver
ielMoving
Lag
ielMoving
ielLeftClicked
ielMoved
ielMouseOver
Go to Top of Page

zerob

111 Posts

Posted - Jan 25 2019 :  04:13:22  Show Profile  Reply
I meant: I only use a ImageLayer with a ImageEnView, no TImageEnLayerMView
Go to Top of Page

xequte

38176 Posts

Posted - Jan 27 2019 :  18:04:04  Show Profile  Reply
Sorry, I am unable to reproduce that (loading a large JPEG into the All Layers demo).

Do your layers have a mask? (IsMask=True)

If you step through the imageenview.pas code in the MouseMove event, do you detect the slowness (perhaps in the Update event)?



Nigel
Xequte Software
www.imageen.com
Go to Top of Page

zerob

111 Posts

Posted - Jan 28 2019 :  05:39:02  Show Profile  Reply
I've found the reason for the slow movement of ImageLayers. It is the interactionhint...
EnableInteractionHints
SetInteractionHint('X:' + IntToStr( Layer.PosX ) + ' Y:' + IntToStr( Layer.PosY ), X, Y, 'X:000 Y:000');

If i comment this function out or do a Exit in the function or disable "EnableInteractionHints", then the first layer movement is buttery smooth.
It seems that you create that hint on the first movement or you do something heavy with it on the first movement?

With that disabled, all runs nice. (The interaction hints aren't that nice right now anyways, as they flicker so hard, that you need to stop or slow down the movement to read the values).

A funny thing is, if i create a TextLayer, this seems to trigger the same laggy function as the Interactionhints does, as after creating a first TextLayer (which also lags), a ImageLayer movement doesn't lag anymore (even with InteractionHints enabled).

This EnableInteractionHints setting did "fix" the first layer movement lag but not the first TextLayer creation lag.
The first TextLayer needs longer to be created than all following TextLayers.
I didn't test all LayerTypes to see if they also have this lag.
Creating the first TextLayer with only 100x26 Pixel and the text "test" needs longer to show up than creating a large Imagelayer and loading a JPEG into it. All TextLayers created after the first, show up fast.
In a test, creating the layer and setting the text is done instantly, but time passes till the layer is visible.
For testing i added logging and also a ImageEnLayersView to see if the Layers show up there (which they don't until the lag is over).

A thing to mention is, that i have 2500 fonts installed, maybe you enum them or interact with them on the first creation?
But having it also lag when telling the function to use Arial seems to contradict this... ImageEnView1.LayersAdd('test',8,clRed,'Arial',[],1,1).
Creating and moving a layer (with EnableInteractionH... and the lag) and then creating a TextLayer removes the TextLayer creation lag.
Go to Top of Page

xequte

38176 Posts

Posted - Jan 28 2019 :  16:27:59  Show Profile  Reply
Thanks for your research. It looks to be the following call:

GdipCreateFontFromDC()

I'm investigating a solution now.

Nigel
Xequte Software
www.imageen.com
Go to Top of Page

xequte

38176 Posts

Posted - Jan 28 2019 :  17:18:51  Show Profile  Reply
There doesn't seem to be an easy fix for this. Whatever method used to create the font, the first call is very slow.

  GdipCreateFontFamilyFromName(PWCHAR(fCanvas.Font.Name), nil, fontFamily );
  GdipCreateFont(fontFamily, fCanvas.Font.Size, FontStyleRegular, UnitPoint, font);



In terms of workaround, you need only call the following once:

ImageEnView1.IEBitmap.IECanvas.MeasureText(' ');

Nigel
Xequte Software
www.imageen.com
Go to Top of Page

zerob

111 Posts

Posted - Jan 28 2019 :  17:40:43  Show Profile  Reply
I tested the "ImageEnView1.IEBitmap.IECanvas.MeasureText(' ');" and it works very well.

Maybe you can expose a nicer shorter function for manual initialization or try to initialize it in a thread at creation to not slow down the whole app with packing it into ImageEnView.create?

Anyway, i will use your workaround from now on.
Go to Top of Page

xequte

38176 Posts

Posted - Jan 28 2019 :  20:18:44  Show Profile  Reply
Yes, this has been implemented for 8.3.0.



Nigel
Xequte Software
www.imageen.com
Go to Top of Page

zerob

111 Posts

Posted - Mar 13 2019 :  16:40:10  Show Profile  Reply
I still see the lag in the most recent version.
Seems i still have to use "ImageEnView1.IEBitmap.IECanvas.MeasureText(' ');"
How is the new, shorter and cleaner looking function named, that i need to call?
Go to Top of Page

xequte

38176 Posts

Posted - Mar 13 2019 :  18:18:32  Show Profile  Reply
Hi

We avoid calling the initialization unless we think it is needed.

Are you able to reproduce the issue in our demos? If so, what are the steps?

The method to pre-initialize is:

procedure InitGDIPFont(Canvas: TCanvas);

It is defined in iegdip, and you can call as follows:

InitGDIPFont( ImageEnView1.Canvas );

Nigel
Xequte Software
www.imageen.com
Go to Top of Page

zerob

111 Posts

Posted - Mar 14 2019 :  02:40:30  Show Profile  Reply
Ah thanks for the function name. Was looking for anything with "Init" in the ImageEnView class or the helpfile index but didn't find anything.

Can you add that function to the help file index and maybe write about it in some other parts so people know about it?

Yes, you need to be careful with placing that function in automode in multiple places (for example in the create function of components) if you put that function on the wrong places, it will lag when people create multiple ImageEnView's or do the stuff that triggers it, which makes the problem worse.

Calling that function myself at places i know the user won't notice it is the best solution for me (as i imagine it can't be executed in a separate thread).

You ask what i do to still get it? I just created a ImageLayer and moved it with the mouse.
Go to Top of Page

zerob

111 Posts

Posted - Mar 14 2019 :  16:23:14  Show Profile  Reply
It still has the same bug until i move the layer the first time.
Doing a InitGDIPFont fixes the bug, it is found in the unit "ieGDIPlus".
InitGDIPFont( ImageEnView1.IEBitmap.Canvas );

I call the function in a timer, so it isn't blocking the GUI, which works nice.
So this solution is perfect.
Go to Top of Page

xequte

38176 Posts

Posted - Mar 14 2019 :  16:45:20  Show Profile  Reply
Hi

I don't want to expose the method, because the developer should not need to use it, it should occur in the background.

So I need to determine why that is failing in your application.

Do you have ImageEnView1.EnableInteractionHints turned on?



Nigel
Xequte Software
www.imageen.com
Go to Top of Page

xequte

38176 Posts

Posted - Mar 18 2019 :  00:18:17  Show Profile  Reply
Also, in the next release, you can set IEGlobalSettings().HintStyle.Transparency to 255 to prevent it using GDI+ for hover hints.

Nigel
Xequte Software
www.imageen.com
Go to Top of Page

zerob

111 Posts

Posted - Mar 18 2019 :  09:06:53  Show Profile  Reply
Yes, i have ImageEnView1.EnableInteractionHints turned on.
Go to Top of Page
Page: of 2 Previous Topic Topic Next Topic  
Next Page
 New Topic  Reply to Topic
Jump To: