Skip to content

Commit c61d1a8

Browse files
committed
Track and dispose resources created by operations in GC
Each Operation subclass now maintains its own list of disposable SWT resources. These are added to a `disposables` list within the Operation and are disposed when the GC is disposed. This ensures cleanup of resources.
1 parent ac52a23 commit c61d1a8

File tree

1 file changed

+73
-22
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

1 file changed

+73
-22
lines changed

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java

Lines changed: 73 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,8 @@ private class CopyAreaToImageOperation extends Operation {
497497
private final int y;
498498

499499
CopyAreaToImageOperation(Image image, int x, int y) {
500-
this.image = image;
500+
this.image = new Image(image.getDevice(), image, SWT.IMAGE_COPY);
501+
track(this.image);
501502
this.x = x;
502503
this.y = y;
503504
}
@@ -1018,7 +1019,8 @@ private class DrawImageOperation extends Operation {
10181019
private final Point location;
10191020

10201021
DrawImageOperation(Image image, Point location) {
1021-
this.image = image;
1022+
this.image = new Image(image.getDevice(), image, SWT.IMAGE_COPY);
1023+
track(this.image);
10221024
this.location = location;
10231025
}
10241026

@@ -1087,7 +1089,8 @@ private class DrawScalingImageToImageOperation extends Operation {
10871089
private final Rectangle destination;
10881090

10891091
DrawScalingImageToImageOperation(Image image, Rectangle source, Rectangle destination) {
1090-
this.image = image;
1092+
this.image = new Image(image.getDevice(), image, SWT.IMAGE_COPY);
1093+
track(this.image);
10911094
this.source = source;
10921095
this.destination = destination;
10931096
}
@@ -1161,7 +1164,8 @@ private class DrawImageToImageOperation extends Operation {
11611164
private final boolean simple;
11621165

11631166
DrawImageToImageOperation(Image image, Rectangle source, Rectangle destination, boolean simple) {
1164-
this.image = image;
1167+
this.image = new Image(image.getDevice(), image, SWT.IMAGE_COPY);
1168+
track(this.image);
11651169
this.source = source;
11661170
this.destination = destination;
11671171
this.simple = simple;
@@ -1958,14 +1962,20 @@ private class DrawPathOperation extends Operation {
19581962
@Override
19591963
void apply() {
19601964
Path path = new Path(device, pathData);
1961-
long pathHandle = path.getHandle(getZoom());
1962-
if (pathHandle == 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
1963-
initGdip();
1964-
checkGC(DRAW);
1965-
long gdipGraphics = data.gdipGraphics;
1966-
Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend);
1967-
Gdip.Graphics_DrawPath(gdipGraphics, data.gdipPen, pathHandle);
1968-
Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend);
1965+
try {
1966+
long pathHandle = path.getHandle(getZoom());
1967+
if (pathHandle == 0)
1968+
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
1969+
initGdip();
1970+
checkGC(DRAW);
1971+
long gdipGraphics = data.gdipGraphics;
1972+
Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend);
1973+
Gdip.Graphics_DrawPath(gdipGraphics, data.gdipPen, pathHandle);
1974+
Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset,
1975+
Gdip.MatrixOrderPrepend);
1976+
} finally {
1977+
path.dispose();
1978+
}
19691979
}
19701980
}
19711981

@@ -3272,13 +3282,18 @@ private class FillPathOperation extends Operation {
32723282
@Override
32733283
void apply() {
32743284
Path path = new Path(device, pathData);
3275-
long pathHandle = path.getHandle(getZoom());
3276-
if (pathHandle == 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
3277-
initGdip();
3278-
checkGC(FILL);
3279-
int mode = OS.GetPolyFillMode(handle) == OS.WINDING ? Gdip.FillModeWinding : Gdip.FillModeAlternate;
3280-
Gdip.GraphicsPath_SetFillMode(pathHandle, mode);
3281-
Gdip.Graphics_FillPath(data.gdipGraphics, data.gdipBrush, pathHandle);
3285+
try {
3286+
long pathHandle = path.getHandle(getZoom());
3287+
if (pathHandle == 0)
3288+
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
3289+
initGdip();
3290+
checkGC(FILL);
3291+
int mode = OS.GetPolyFillMode(handle) == OS.WINDING ? Gdip.FillModeWinding : Gdip.FillModeAlternate;
3292+
Gdip.GraphicsPath_SetFillMode(pathHandle, mode);
3293+
Gdip.Graphics_FillPath(data.gdipGraphics, data.gdipBrush, pathHandle);
3294+
} finally {
3295+
path.dispose();
3296+
}
32823297
}
32833298
}
32843299

@@ -4629,7 +4644,9 @@ private class SetBackgroundOperation extends Operation {
46294644
private final Color color;
46304645

46314646
SetBackgroundOperation(Color color) {
4632-
this.color = color;
4647+
RGB rgb = color.getRGB();
4648+
this.color = new Color(color.getDevice(), rgb);
4649+
track(this.color);
46334650
}
46344651

46354652
@Override
@@ -4676,6 +4693,7 @@ private class SetBackgroundPatternOperation extends Operation {
46764693

46774694
SetBackgroundPatternOperation(Pattern pattern) {
46784695
this.pattern = pattern == null ? null : pattern.copy();
4696+
track(this.pattern);
46794697
}
46804698

46814699
@Override
@@ -4938,7 +4956,8 @@ private class SetFontOperation extends Operation {
49384956
private final Font font;
49394957

49404958
SetFontOperation(Font font) {
4941-
this.font = font;
4959+
this.font = new Font(font.getDevice(), font.getFontData());
4960+
track(this.font);
49424961
}
49434962

49444963
@Override
@@ -4973,7 +4992,9 @@ private class SetForegroundOperation extends Operation {
49734992
private final Color color;
49744993

49754994
SetForegroundOperation(Color color) {
4976-
this.color = color;
4995+
RGB rgb = color.getRGB();
4996+
this.color = new Color(color.getDevice(), rgb);
4997+
track(this.color);
49774998
}
49784999

49795000
@Override
@@ -5019,6 +5040,7 @@ private class SetForegroundPatternOperation extends Operation {
50195040

50205041
SetForegroundPatternOperation(Pattern pattern) {
50215042
this.pattern = pattern == null ? null : pattern.copy();
5043+
track(this.pattern);
50225044
}
50235045

50245046
@Override
@@ -5604,6 +5626,7 @@ private class SetTransformOperation extends Operation {
56045626
float[] elements = new float[6];
56055627
transform.getElements(elements);
56065628
this.transform = new Transform(device, elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]);
5629+
track(this.transform);
56075630
} else {
56085631
this.transform = null;
56095632
}
@@ -5876,8 +5899,36 @@ private void createGcHandle(Drawable drawable, GCData newData, int nativeZoom) {
58765899
}
58775900
}
58785901

5902+
5903+
@Override
5904+
public void dispose() {
5905+
super.dispose();
5906+
disposeOperations();
5907+
}
5908+
5909+
private void disposeOperations() {
5910+
for (Operation op : operations) {
5911+
op.disposeAll();
5912+
}
5913+
operations.clear();
5914+
}
5915+
58795916
private abstract class Operation {
5917+
private final List<Resource> disposables = new ArrayList<>();
58805918
abstract void apply();
5919+
5920+
protected void track(Resource resource) {
5921+
if (resource != null) {
5922+
disposables.add(resource);
5923+
}
5924+
}
5925+
5926+
void disposeAll() {
5927+
for (Resource r : disposables) {
5928+
r.dispose();
5929+
}
5930+
disposables.clear();
5931+
}
58815932
}
58825933
}
58835934

0 commit comments

Comments
 (0)