Author |
Topic  |
zerob
  
198 Posts |
Posted - Jan 16 2019 : 06:25:51
|
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
  
198 Posts |
Posted - Jan 18 2019 : 10:59:15
|
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 |
 |
|
zerob
  
198 Posts |
Posted - Jan 19 2019 : 11:45:17
|
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?) |
 |
|
zerob
  
198 Posts |
Posted - Jan 21 2019 : 06:45:44
|
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. |
 |
|
nwscomps
  
185 Posts |
|
xequte
    
38924 Posts |
Posted - Jan 23 2019 : 21:11:04
|
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
|
 |
|
zerob
  
198 Posts |
Posted - Jan 25 2019 : 03:41:35
|
>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 |
 |
|
zerob
  
198 Posts |
Posted - Jan 25 2019 : 04:13:22
|
I meant: I only use a ImageLayer with a ImageEnView, no TImageEnLayerMView |
 |
|
xequte
    
38924 Posts |
Posted - Jan 27 2019 : 18:04:04
|
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
|
 |
|
zerob
  
198 Posts |
Posted - Jan 28 2019 : 05:39:02
|
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.
|
 |
|
xequte
    
38924 Posts |
Posted - Jan 28 2019 : 16:27:59
|
Thanks for your research. It looks to be the following call:
GdipCreateFontFromDC()
I'm investigating a solution now.
Nigel Xequte Software www.imageen.com
|
 |
|
xequte
    
38924 Posts |
Posted - Jan 28 2019 : 17:18:51
|
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
|
 |
|
zerob
  
198 Posts |
Posted - Jan 28 2019 : 17:40:43
|
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. |
 |
|
xequte
    
38924 Posts |
Posted - Jan 28 2019 : 20:18:44
|
Yes, this has been implemented for 8.3.0.
Nigel Xequte Software www.imageen.com
|
 |
|
zerob
  
198 Posts |
Posted - Mar 13 2019 : 16:40:10
|
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? |
 |
|
xequte
    
38924 Posts |
Posted - Mar 13 2019 : 18:18:32
|
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
|
 |
|
zerob
  
198 Posts |
Posted - Mar 14 2019 : 02:40:30
|
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. |
 |
|
zerob
  
198 Posts |
Posted - Mar 14 2019 : 16:23:14
|
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. |
 |
|
xequte
    
38924 Posts |
Posted - Mar 14 2019 : 16:45:20
|
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
|
 |
|
xequte
    
38924 Posts |
Posted - Mar 18 2019 : 00:18:17
|
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
|
 |
|
zerob
  
198 Posts |
Posted - Mar 18 2019 : 09:06:53
|
Yes, i have ImageEnView1.EnableInteractionHints turned on. |
 |
|
Topic  |
|