Skip to content

Commit 9905080

Browse files
bruyeretfinetjul
authored andcommitted
feat(shareRw): Add garbage collection to shared graphics resources
The render window owns the graphics resources and frees them when no user is registered
1 parent 87d1180 commit 9905080

File tree

6 files changed

+280
-181
lines changed

6 files changed

+280
-181
lines changed

Examples/Rendering/ManyRenderWindows/index.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,6 @@ function addRenderWindow(actor) {
204204

205205
if (mainRenderWindow.getChildRenderWindowsByReference().length === 0) {
206206
// When there is no child render window anymore, delete the main render window
207-
// We also release the graphics resources, which is not very import as when the context is destroyed, the resources should be freed
208-
// The release of shared graphics resources is not automatic and can be done by hand when the resource is not needed anymore
209-
const imageData = actor.getMapper().getInputData();
210-
const scalars = imageData.getPointData().getScalars();
211-
mainRenderWindowView.releaseGraphicsResourcesForObject(scalars);
212207
mainRenderWindowView.delete();
213208
mainRenderWindow.delete();
214209
}

Sources/Rendering/OpenGL/ImageMapper/index.js

Lines changed: 87 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,19 @@ function vtkOpenGLImageMapper(publicAPI, model) {
5959
// Set our className
6060
model.classHierarchy.push('vtkOpenGLImageMapper');
6161

62+
function unregisterGraphicsResources(renderWindow) {
63+
// The openGLTexture is not shared
64+
model.openGLTexture.releaseGraphicsResources(renderWindow);
65+
// All these other resources are shared
66+
[
67+
model._colorTransferFunc,
68+
model._pwFunc,
69+
model._labelOutlineThicknessArray,
70+
].forEach((coreObject) =>
71+
renderWindow.unregisterGraphicsResourceUser(coreObject, publicAPI)
72+
);
73+
}
74+
6275
publicAPI.buildPass = (prepass) => {
6376
if (prepass) {
6477
model.currentRenderPass = null;
@@ -67,9 +80,17 @@ function vtkOpenGLImageMapper(publicAPI, model) {
6780
);
6881
model._openGLRenderer =
6982
publicAPI.getFirstAncestorOfType('vtkOpenGLRenderer');
83+
const oldOglRenderWindow = model._openGLRenderWindow;
7084
model._openGLRenderWindow = model._openGLRenderer.getLastAncestorOfType(
7185
'vtkOpenGLRenderWindow'
7286
);
87+
if (
88+
oldOglRenderWindow &&
89+
!oldOglRenderWindow.isDeleted() &&
90+
oldOglRenderWindow !== model._openGLRenderWindow
91+
) {
92+
unregisterGraphicsResources(oldOglRenderWindow);
93+
}
7394
model.context = model._openGLRenderWindow.getContext();
7495
model.tris.setOpenGLRenderWindow(model._openGLRenderWindow);
7596
const ren = model._openGLRenderer.getRenderable();
@@ -929,19 +950,15 @@ function vtkOpenGLImageMapper(publicAPI, model) {
929950
model._openGLRenderWindow.getGraphicsResourceForObject(colorTransferFunc);
930951

931952
const reBuildC =
932-
!cTex?.oglObject?.getHandle() ||
933-
cTex?.hash !== cfunToString ||
934-
model.colorTextureString !== cfunToString;
953+
!cTex?.oglObject?.getHandle() || cTex?.hash !== cfunToString;
935954
if (reBuildC) {
955+
model.colorTexture = vtkOpenGLTexture.newInstance({
956+
resizable: true,
957+
});
958+
model.colorTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
936959
const cWidth = 1024;
937960
const cSize = cWidth * textureHeight * 3;
938961
const cTable = new Uint8ClampedArray(cSize);
939-
if (!model.colorTexture) {
940-
model.colorTexture = vtkOpenGLTexture.newInstance({
941-
resizable: true,
942-
});
943-
model.colorTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
944-
}
945962
// set interpolation on the texture based on property setting
946963
if (iType === InterpolationType.NEAREST) {
947964
model.colorTexture.setMinificationFilter(Filter.NEAREST);
@@ -969,7 +986,6 @@ function vtkOpenGLImageMapper(publicAPI, model) {
969986
}
970987
}
971988
}
972-
model.colorTexture.releaseGraphicsResources(model._openGLRenderWindow);
973989
model.colorTexture.resetFormatAndType();
974990
model.colorTexture.create2DFromRaw(
975991
cWidth,
@@ -993,17 +1009,24 @@ function vtkOpenGLImageMapper(publicAPI, model) {
9931009
);
9941010
}
9951011

996-
model.colorTextureString = cfunToString;
9971012
if (colorTransferFunc) {
9981013
model._openGLRenderWindow.setGraphicsResourceForObject(
9991014
colorTransferFunc,
10001015
model.colorTexture,
1001-
model.colorTextureString
1016+
cfunToString
1017+
);
1018+
model._openGLRenderWindow.unregisterGraphicsResourceUser(
1019+
model._colorTransferFunc,
1020+
publicAPI
10021021
);
1022+
model._openGLRenderWindow.registerGraphicsResourceUser(
1023+
colorTransferFunc,
1024+
publicAPI
1025+
);
1026+
model._colorTransferFunc = colorTransferFunc;
10031027
}
10041028
} else {
10051029
model.colorTexture = cTex.oglObject;
1006-
model.colorTextureString = cTex.hash;
10071030
}
10081031

10091032
// Build piecewise function buffer. This buffer is used either
@@ -1015,19 +1038,15 @@ function vtkOpenGLImageMapper(publicAPI, model) {
10151038
model._openGLRenderWindow.getGraphicsResourceForObject(pwFunc);
10161039
// rebuild opacity tfun?
10171040
const reBuildPwf =
1018-
!pwfTex?.oglObject?.getHandle() ||
1019-
pwfTex?.hash !== pwfunToString ||
1020-
model.pwfTextureString !== pwfunToString;
1041+
!pwfTex?.oglObject?.getHandle() || pwfTex?.hash !== pwfunToString;
10211042
if (reBuildPwf) {
10221043
const pwfWidth = 1024;
10231044
const pwfSize = pwfWidth * textureHeight;
10241045
const pwfTable = new Uint8ClampedArray(pwfSize);
1025-
if (!model.pwfTexture) {
1026-
model.pwfTexture = vtkOpenGLTexture.newInstance({
1027-
resizable: true,
1028-
});
1029-
model.pwfTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
1030-
}
1046+
model.pwfTexture = vtkOpenGLTexture.newInstance({
1047+
resizable: true,
1048+
});
1049+
model.pwfTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
10311050
// set interpolation on the texture based on property setting
10321051
if (iType === InterpolationType.NEAREST) {
10331052
model.pwfTexture.setMinificationFilter(Filter.NEAREST);
@@ -1062,7 +1081,6 @@ function vtkOpenGLImageMapper(publicAPI, model) {
10621081
}
10631082
}
10641083
}
1065-
model.pwfTexture.releaseGraphicsResources(model._openGLRenderWindow);
10661084
model.pwfTexture.resetFormatAndType();
10671085
model.pwfTexture.create2DFromRaw(
10681086
pwfWidth,
@@ -1083,17 +1101,24 @@ function vtkOpenGLImageMapper(publicAPI, model) {
10831101
);
10841102
}
10851103

1086-
model.pwfTextureString = pwfunToString;
10871104
if (pwFunc) {
10881105
model._openGLRenderWindow.setGraphicsResourceForObject(
10891106
pwFunc,
10901107
model.pwfTexture,
1091-
model.pwfTextureString
1108+
pwfunToString
1109+
);
1110+
model._openGLRenderWindow.unregisterGraphicsResourceUser(
1111+
model._pwFunc,
1112+
publicAPI
10921113
);
1114+
model._openGLRenderWindow.registerGraphicsResourceUser(
1115+
pwFunc,
1116+
publicAPI
1117+
);
1118+
model._pwFunc = pwFunc;
10931119
}
10941120
} else {
10951121
model.pwfTexture = pwfTex.oglObject;
1096-
model.pwfTextureString = pwfTex.hash;
10971122
}
10981123

10991124
// Build outline thickness buffer
@@ -1139,8 +1164,8 @@ function vtkOpenGLImageMapper(publicAPI, model) {
11391164
model.openGLTexture = vtkOpenGLTexture.newInstance({
11401165
resizable: true,
11411166
});
1142-
model.openGLTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
11431167
}
1168+
model.openGLTexture.setOpenGLRenderWindow(model._openGLRenderWindow);
11441169
// Use norm16 for scalar texture if the extension is available
11451170
model.openGLTexture.setOglNorm16Ext(
11461171
model.context.getExtension('EXT_texture_norm16')
@@ -1272,33 +1297,17 @@ function vtkOpenGLImageMapper(publicAPI, model) {
12721297
vtkErrorMacro('Reformat slicing not yet supported.');
12731298
}
12741299

1275-
const tex =
1276-
model._openGLRenderWindow.getGraphicsResourceForObject(scalars);
1277-
if (!tex?.oglObject?.getHandle()) {
1278-
if (model._scalars !== scalars) {
1279-
model._openGLRenderWindow.releaseGraphicsResourcesForObject(
1280-
model._scalars
1281-
);
1282-
model._scalars = scalars;
1283-
}
1284-
model.openGLTexture.resetFormatAndType();
1285-
model.openGLTexture.create2DFilterableFromRaw(
1286-
dims[0],
1287-
dims[1],
1288-
numComp,
1289-
imgScalars.getDataType(),
1290-
scalars,
1291-
model.renderable.getPreferSizeOverAccuracy?.()
1292-
);
1293-
model._openGLRenderWindow.setGraphicsResourceForObject(
1294-
scalars,
1295-
model.openGLTexture,
1296-
model.VBOBuildString
1297-
);
1298-
} else {
1299-
model.openGLTexture = tex.oglObject;
1300-
model.VBOBuildString = tex.hash;
1301-
}
1300+
// Don't share this resource as `scalars` is created in this function
1301+
// so it is impossible to share
1302+
model.openGLTexture.resetFormatAndType();
1303+
model.openGLTexture.create2DFilterableFromRaw(
1304+
dims[0],
1305+
dims[1],
1306+
numComp,
1307+
imgScalars.getDataType(),
1308+
scalars,
1309+
model.renderable.getPreferSizeOverAccuracy?.()
1310+
);
13021311
model.openGLTexture.activate();
13031312
model.openGLTexture.sendParameters();
13041313
model.openGLTexture.deactivate();
@@ -1339,15 +1348,6 @@ function vtkOpenGLImageMapper(publicAPI, model) {
13391348
};
13401349

13411350
publicAPI.updatelabelOutlineThicknessTexture = (image) => {
1342-
if (!model.labelOutlineThicknessTexture) {
1343-
model.labelOutlineThicknessTexture = vtkOpenGLTexture.newInstance({
1344-
resizable: false,
1345-
});
1346-
model.labelOutlineThicknessTexture.setOpenGLRenderWindow(
1347-
model._openGLRenderWindow
1348-
);
1349-
}
1350-
13511351
const labelOutlineThicknessArray = image
13521352
.getProperty()
13531353
.getLabelOutlineThickness();
@@ -1361,10 +1361,7 @@ function vtkOpenGLImageMapper(publicAPI, model) {
13611361
// or not
13621362
const toString = `${labelOutlineThicknessArray.join('-')}`;
13631363

1364-
const reBuildL =
1365-
!lTex?.oglObject?.getHandle() ||
1366-
lTex?.hash !== toString ||
1367-
model.labelOutlineThicknessTextureString !== toString;
1364+
const reBuildL = !lTex?.oglObject?.getHandle() || lTex?.hash !== toString;
13681365

13691366
if (reBuildL) {
13701367
const lWidth = 1024;
@@ -1382,7 +1379,10 @@ function vtkOpenGLImageMapper(publicAPI, model) {
13821379
: labelOutlineThicknessArray[0];
13831380
lTable[i] = thickness;
13841381
}
1385-
model.labelOutlineThicknessTexture.releaseGraphicsResources(
1382+
model.labelOutlineThicknessTexture = vtkOpenGLTexture.newInstance({
1383+
resizable: false,
1384+
});
1385+
model.labelOutlineThicknessTexture.setOpenGLRenderWindow(
13861386
model._openGLRenderWindow
13871387
);
13881388

@@ -1399,17 +1399,24 @@ function vtkOpenGLImageMapper(publicAPI, model) {
13991399
lTable
14001400
);
14011401

1402-
model.labelOutlineThicknessTextureString = toString;
14031402
if (labelOutlineThicknessArray) {
14041403
model._openGLRenderWindow.setGraphicsResourceForObject(
14051404
labelOutlineThicknessArray,
14061405
model.labelOutlineThicknessTexture,
1407-
model.labelOutlineThicknessTextureString
1406+
toString
14081407
);
1408+
model._openGLRenderWindow.unregisterGraphicsResourceUser(
1409+
model._labelOutlineThicknessArray,
1410+
publicAPI
1411+
);
1412+
model._openGLRenderWindow.registerGraphicsResourceUser(
1413+
labelOutlineThicknessArray,
1414+
publicAPI
1415+
);
1416+
model._labelOutlineThicknessArray = labelOutlineThicknessArray;
14091417
}
14101418
} else {
14111419
model.labelOutlineThicknessTexture = lTex.oglObject;
1412-
model.labelOutlineThicknessTextureString = lTex.hash;
14131420
}
14141421
};
14151422

@@ -1429,6 +1436,12 @@ function vtkOpenGLImageMapper(publicAPI, model) {
14291436

14301437
return [lowerLeftU, lowerLeftV];
14311438
};
1439+
1440+
publicAPI.delete = macro.chain(() => {
1441+
if (model._openGLRenderWindow) {
1442+
unregisterGraphicsResources(model._openGLRenderWindow);
1443+
}
1444+
}, publicAPI.delete);
14321445
}
14331446

14341447
// ----------------------------------------------------------------------------
@@ -1450,6 +1463,9 @@ const DEFAULT_VALUES = {
14501463
haveSeenDepthRequest: false,
14511464
lastTextureComponents: 0,
14521465
_scalars: null,
1466+
_colorTransferFunc: null,
1467+
_pwFunc: null,
1468+
_labelOutlineThicknessArray: null,
14531469
};
14541470

14551471
// ----------------------------------------------------------------------------

0 commit comments

Comments
 (0)