-
Notifications
You must be signed in to change notification settings - Fork 189
Using ImageHandleManager for managing multiple Image handles in Image class #2905
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Using ImageHandleManager for managing multiple Image handles in Image class #2905
Conversation
HeikoKlare
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like the idea to wrap the handle-for-zoom mapping into a separate class. That clearly assigns all related management functionality to that class. I would be in favor of extracting the pure refactoring of the management functionality in a dedicated class into a separate PR. That PR will just improve code quality and comprehensibility and not improve thread safety.
You find several questions and proposals in the detailed comments. The probably most essential point is that to my understanding the implementation is not fully thread safe.
In addition, I am not sure if the concept of using a synchronized data structure is fully sufficient for all cases here (e.g., if we also include the rest of the API such as getBounds() and getImageData()). At least the complexity could increase such that ensuring correctness and maintainability becomes complex. Maybe we better see that when we adapt those methods as well, but I could imagine that simply synchronizing write access might be sufficient (as we don't expect multiple consumers to write for different zooms) and provides reduced compexity and error proneness.
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
Outdated
Show resolved
Hide resolved
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
Outdated
Show resolved
Hide resolved
| return imageHandle; | ||
| } | ||
| return zoomLevelToImageHandle.get(targetZoom); | ||
| return imageHandleManager.getImageHandle(targetZoom); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code looks a bit weird (but also did before) because we call a _new_ImageHandle method and then return an existing one. From my understanding, this line of code should never be reached anyway. In case there is a memGC, there should also be an image handle for it, so that newImageHandle will never be called unless the zoom of that handle is not fitting (and then the if block above is executed).
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
Show resolved
Hide resolved
| long newHandle = drawable.internal_new_GC(newData); | ||
| if (newHandle == 0) SWT.error(SWT.ERROR_NO_HANDLES); | ||
| init(drawable, newData, newHandle); | ||
| initWithImageHandle(drawable, newData, newHandle, imageHandle); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this change to GC necessary? Is it a bug in the existing implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this method is created from the earlier implementation of the PlainImageDataProvider as in case it uses GC to scale, it uses this specific method. In the init method of GC, it uses the Image.win32_getHandle, which would want to create a handle and since we already are in the middle of creation of the handle it will fail. Since we also had a specific method in the past for this case, the idea is to use the ImageHandle we just obtained and pass that directly instead of calling win32_getHandle.
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
Outdated
Show resolved
Hide resolved
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
Outdated
Show resolved
Hide resolved
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
Outdated
Show resolved
Hide resolved
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
Outdated
Show resolved
Hide resolved
e9cb651 to
0e6ad0d
Compare
0e6ad0d to
1494ed0
Compare
This commit adds a class ImageHandleManager in Image to manage multiple ImageHandle for different zoom hence encapsulating the usages and operations based on zoomLevelToImageHandle.
This commit makes the ImageHandle creation and ImageData caching process synchronous to avoid any racing condition and inefficient memory usages.
1494ed0 to
22f6ab7
Compare
This PR introduces ImageHandleManager, an inner class to Image responsible for managing the storage, creation and manipulation of ImageHandles. This class provides methods which can be used to dead with ImageHandle instances inside an image for managing it with convenience while hiding the complexity of how the ImageHandle lifecycle is managed inside itself.
All the places where zoomToImageHandle map is accessed for any purposes is replaced by the wrapper methods provided by ImageHandleManager. Each image initializes a final field imageHandleManager with the instance of ImageHandleManager. Every instance of ImageHandle created within the Image object is registered in the manager itself and the manager is responsible for cleaning the dangling resources when are not supposed to be used anymore or when a cleanup is needed. Also the manager creates handles in a thread-safe way, making sure no 2 consumers create the same handle at the same time.
This fixes vi-eclipse/Eclipse-Platform#562