Skip to content
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

Destroy unused handles #1477

Merged
merged 1 commit into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*******************************************************************************/
package org.eclipse.swt.graphics;

import java.util.*;
import java.util.function.*;

import org.eclipse.swt.*;
Expand Down Expand Up @@ -123,6 +124,17 @@ public Resource() {
void destroy() {
}

/**
* Destroy all handles of the resource which are not necessary for the given
* zoom levels. This method is supposed to be overridden by sub-classes that
* retain handles for different zoom levels.
*
* @param zoomLevels The zoom levels for which the handles are supposed to be
* retained.
*/
void destroyHandlesExcept(Set<Integer> zoomLevels) {
fedejeanne marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Disposes of the operating system resources associated with
* this resource. Applications must dispose of all resources
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@
package org.eclipse.swt.graphics;


import java.util.*;
import java.util.concurrent.*;

import org.eclipse.swt.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gdip.*;
import org.eclipse.swt.internal.win32.*;
import org.eclipse.swt.widgets.*;

/**
* This class is the abstract superclass of all device objects,
Expand Down Expand Up @@ -55,6 +59,7 @@ public abstract class Device implements Drawable {
String[] loadedFonts;

volatile boolean disposed;
private Set<Resource> resourcesWithZoomSupport = ConcurrentHashMap.newKeySet();

/*
* TEMPORARY CODE. When a graphics object is
Expand Down Expand Up @@ -914,6 +919,8 @@ protected void release () {
Gdip.GdiplusShutdown (gdipToken[0]);
}
SWTFontProvider.disposeFontRegistry(this);
resourcesWithZoomSupport.clear();
resourcesWithZoomSupport = null;
gdipToken = null;
scripts = null;
logFonts = null;
Expand Down Expand Up @@ -947,4 +954,24 @@ public void setWarnings (boolean warnings) {
protected int getDeviceZoom () {
return DPIUtil.mapDPIToZoom ( _getDPIx ());
}

void registerResourceWithZoomSupport(Resource resource) {
resourcesWithZoomSupport.add(resource);
}

/**
* Destroys the handles of all the resources in the resource tracker by
* identifying the zoom levels which is not valid for any monitor
*
* @noreference This method is not intended to be referenced by clients.
*/
public static void win32_destroyUnusedHandles(Display display) {
Set<Integer> availableZoomLevels = new HashSet<>();
for (Monitor monitor : display.getMonitors()) {
availableZoomLevels.add(DPIUtil.getZoomForAutoscaleProperty(monitor.getZoom()));
}
for (Resource resource: ((Device) display).resourcesWithZoomSupport) {
resource.destroyHandlesExcept(availableZoomLevels);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ public final class Image extends Resource implements Drawable {
Image (Device device) {
super(device);
initialNativeZoom = DPIUtil.getNativeDeviceZoom();
this.device.registerResourceWithZoomSupport(this);
}

/**
Expand Down Expand Up @@ -209,6 +210,7 @@ public Image(Device device, int width, int height) {
height = DPIUtil.scaleUp (height, zoom);
init(width, height);
init();
this.device.registerResourceWithZoomSupport(this);
}

/**
Expand Down Expand Up @@ -311,6 +313,7 @@ public Image(Device device, Image srcImage, int flag) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
init();
this.device.registerResourceWithZoomSupport(this);
}

/**
Expand Down Expand Up @@ -355,6 +358,7 @@ public Image(Device device, Rectangle bounds) {
bounds = DPIUtil.scaleUp (bounds, getZoom());
init(bounds.width, bounds.height);
init();
this.device.registerResourceWithZoomSupport(this);
fedejeanne marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down Expand Up @@ -388,6 +392,7 @@ public Image(Device device, ImageData data) {
data = DPIUtil.autoScaleUp(device, this.dataAtBaseZoom);
init(data, getZoom());
init();
this.device.registerResourceWithZoomSupport(this);
}

/**
Expand Down Expand Up @@ -434,6 +439,7 @@ public Image(Device device, ImageData source, ImageData mask) {
mask = ImageData.convertMask(mask);
init(this.device, this, source, mask, getZoom());
init();
this.device.registerResourceWithZoomSupport(this);
}

/**
Expand Down Expand Up @@ -496,6 +502,7 @@ public Image (Device device, InputStream stream) {
ImageData data = DPIUtil.autoScaleUp(device, this.dataAtBaseZoom);
init(data, getZoom());
init();
this.device.registerResourceWithZoomSupport(this);
}

/**
Expand Down Expand Up @@ -538,6 +545,7 @@ public Image (Device device, String filename) {
ImageData data = DPIUtil.autoScaleUp(device, this.dataAtBaseZoom);
init(data, getZoom());
init();
this.device.registerResourceWithZoomSupport(this);
}

/**
Expand Down Expand Up @@ -586,6 +594,7 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
init(resizedData, getZoom());
}
init();
this.device.registerResourceWithZoomSupport(this);
}

/**
Expand Down Expand Up @@ -625,6 +634,7 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
ImageData resizedData = DPIUtil.scaleImageData(device, data.element(), getZoom(), data.zoom());
init (resizedData, getZoom());
init();
this.device.registerResourceWithZoomSupport(this);
}

private ImageData adaptImageDataIfDisabledOrGray(ImageData data) {
Expand Down Expand Up @@ -1186,16 +1196,32 @@ void destroy () {

private void destroyHandle () {
for (Long handle : zoomLevelToHandle.values()) {
if (type == SWT.ICON) {
OS.DestroyIcon (handle);
} else {
OS.DeleteObject (handle);
}
destroyHandle(handle);
}
zoomLevelToHandle.clear();
handle = 0;
}

@Override
void destroyHandlesExcept(Set<Integer> zoomLevels) {
zoomLevelToHandle.entrySet().removeIf(entry -> {
final Integer zoom = entry.getKey();
if (!zoomLevels.contains(zoom) && zoom != DPIUtil.getZoomForAutoscaleProperty(initialNativeZoom)) {
destroyHandle(entry.getValue());
return true;
}
return false;
});
}

private void destroyHandle(long handle) {
if (type == SWT.ICON) {
OS.DestroyIcon (handle);
} else {
OS.DeleteObject (handle);
}
}

/**
* Compares the argument to the receiver, and returns true
* if they represent the <em>same</em> object using a class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ private Path(Device device, int zoom) {
if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
zoomLevelToHandle.put(initialZoom, handle);
init();
this.device.registerResourceWithZoomSupport(this);
}

/**
Expand Down Expand Up @@ -133,6 +134,7 @@ public Path (Device device, Path path, float flatness) {
initialZoom = path.initialZoom;
zoomLevelToHandle.put(initialZoom, handle);
init();
this.device.registerResourceWithZoomSupport(this);
}

/**
Expand Down Expand Up @@ -172,6 +174,7 @@ private Path(Device device, PathData data, int zoom) {
this(device, zoom);
if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
init(data);
this.device.registerResourceWithZoomSupport(this);
}

/**
Expand Down Expand Up @@ -438,6 +441,18 @@ void destroy() {
zoomLevelToHandle.clear();
}

@Override
void destroyHandlesExcept(Set<Integer> zoomLevels) {
zoomLevelToHandle.entrySet().removeIf(entry -> {
final Integer zoom = entry.getKey();
if (!zoomLevels.contains(zoom) && zoom != initialZoom) {
Gdip.GraphicsPath_delete(entry.getValue());
return true;
}
return false;
});
}

/**
* Replaces the first four elements in the parameter with values that
* describe the smallest rectangle that will completely contain the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public Pattern(Device device, Image image) {
initialZoom = DPIUtil.getDeviceZoom();
setImageHandle(image, initialZoom);
init();
this.device.registerResourceWithZoomSupport(this);
}

/**
Expand Down Expand Up @@ -183,6 +184,7 @@ public Pattern(Device device, float x1, float y1, float x2, float y2, Color colo
this.image = null;
initialZoom = DPIUtil.getDeviceZoom();
initializeSize(initialZoom);
this.device.registerResourceWithZoomSupport(this);
}

long getHandle(int zoom) {
Expand Down Expand Up @@ -260,21 +262,7 @@ void setImageHandle(Image image, int zoom) {
@Override
void destroy() {
for (long handle: zoomLevelToHandle.values()) {
int type = Gdip.Brush_GetType(handle);
switch (type) {
case Gdip.BrushTypeSolidColor:
Gdip.SolidBrush_delete(handle);
break;
case Gdip.BrushTypeHatchFill:
Gdip.HatchBrush_delete(handle);
break;
case Gdip.BrushTypeLinearGradient:
Gdip.LinearGradientBrush_delete(handle);
break;
case Gdip.BrushTypeTextureFill:
Gdip.TextureBrush_delete(handle);
break;
}
destroyHandle(handle);
}
zoomLevelToHandle.clear();
if (bitmapDestructor != null) {
Expand All @@ -283,6 +271,36 @@ void destroy() {
}
}

@Override
void destroyHandlesExcept(Set<Integer> zoomLevels) {
zoomLevelToHandle.entrySet().removeIf(entry -> {
final Integer zoom = entry.getKey();
if (!zoomLevels.contains(zoom) && zoom != initialZoom) {
destroyHandle(entry.getValue());
return true;
}
return false;
});
}

private void destroyHandle(long handle) {
int type = Gdip.Brush_GetType(handle);
switch (type) {
case Gdip.BrushTypeSolidColor:
Gdip.SolidBrush_delete(handle);
break;
case Gdip.BrushTypeHatchFill:
Gdip.HatchBrush_delete(handle);
break;
case Gdip.BrushTypeLinearGradient:
Gdip.LinearGradientBrush_delete(handle);
break;
case Gdip.BrushTypeTextureFill:
Gdip.TextureBrush_delete(handle);
break;
}
}

/**
* Returns <code>true</code> if the Pattern has been disposed,
* and <code>false</code> otherwise.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public Region (Device device) {
zoomToHandle.put(initialZoom, handle);
if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
init();
this.device.registerResourceWithZoomSupport(this);
}

/**
Expand Down Expand Up @@ -227,6 +228,18 @@ void destroy () {
operations.clear();
}

@Override
void destroyHandlesExcept(Set<Integer> zoomLevels) {
zoomToHandle.entrySet().removeIf(entry -> {
final Integer zoom = entry.getKey();
if (!zoomLevels.contains(zoom) && zoom != initialZoom) {
OS.DeleteObject(entry.getValue());
return true;
}
return false;
});
}

/**
* Compares the argument to the receiver, and returns true
* if they represent the <em>same</em> object using a class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ public Transform (Device device, float m11, float m12, float m21, float m22, flo
if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
zoomLevelToHandle.put(initialZoom, handle);
init();
this.device.registerResourceWithZoomSupport(this);
}

static float[] checkTransform(float[] elements) {
Expand All @@ -159,6 +160,18 @@ void destroy() {
zoomLevelToHandle.clear();
}

@Override
void destroyHandlesExcept(Set<Integer> zoomLevels) {
zoomLevelToHandle.entrySet().removeIf(entry -> {
final Integer zoom = entry.getKey();
if (!zoomLevels.contains(zoom) && zoom != initialZoom) {
Gdip.Matrix_delete(entry.getValue());
return true;
}
return false;
});
}

/**
* Fills the parameter with the values of the transformation matrix
* that the receiver represents, in the order {m11, m12, m21, m22, dx, dy}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4899,6 +4899,7 @@ LRESULT WM_DPICHANGED (long wParam, long lParam) {
// Map DPI to Zoom and compare
int newNativeZoom = DPIUtil.mapDPIToZoom (OS.HIWORD (wParam));
if (getDisplay().isRescalingAtRuntime()) {
Device.win32_destroyUnusedHandles(getDisplay());
int oldNativeZoom = nativeZoom;
if (newNativeZoom != oldNativeZoom) {
DPIUtil.setDeviceZoom (newNativeZoom);
Expand Down
Loading