Skip to content

Commit

Permalink
Simple way of triggering GC. Fix canvas clearing.
Browse files Browse the repository at this point in the history
  • Loading branch information
mikekucera committed Nov 5, 2024
1 parent b1c420c commit 23c4daa
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 14 deletions.
14 changes: 10 additions & 4 deletions src/extensions/renderer/canvas/webgl/atlas.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,13 +309,15 @@ export class AtlasCollection {
this.getIdsFor(key).delete(id);
}

checkKey(id, newKey) {
checkKeyIsInvalid(id, newKey) {
if(!this.idToKey.has(id))
return;
return false;
const oldKey = this.idToKey.get(id);
if(oldKey != newKey) {
this.deleteKey(id, oldKey);
return true;
}
return false;
}

_getKeysToCollect() {
Expand Down Expand Up @@ -471,22 +473,26 @@ export class AtlasManager {

/** Marks textues associated with the element for garbage collection. */
invalidate(eles, { testEle, testType, forceRedraw } = {}) {
let gcNeeded = false;
for(const ele of eles) {
if(!testEle || testEle(ele)) {
const id = ele.id();
for(const opts of this.getRenderTypes()) {
if(!testType || testType(opts.type)) {
const styleKey = opts.getKey(ele);
if(forceRedraw) {
if(forceRedraw) {
// when a node's background image finishes loading, the style key doesn't change but still needs to be redrawn
opts.atlasCollection.deleteKey(id, styleKey);
opts.atlasCollection.styleKeyNeedsRedraw.add(styleKey);
gcNeeded = true; // TODO is this too conservative?
} else {
opts.atlasCollection.checkKey(id, styleKey);
gcNeeded |= opts.atlasCollection.checkKeyIsInvalid(id, styleKey);
}
}
}
}
}
return gcNeeded;
}

/** Garbage collect */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class EdgeDrawing {
}

invalidate(eles) {
this.atlasManager.invalidate(eles, { testEle: ele => ele.isEdge() });
return this.atlasManager.invalidate(eles, { testEle: ele => ele.isEdge() });
}

gc() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class NodeDrawing {
const testEle = ele => ele.isNode();
const testType = type ? t => t === type : null;
const forceRedraw = type ? true : false;
this.atlasManager.invalidate(eles, { testEle, testType, forceRedraw });
return this.atlasManager.invalidate(eles, { testEle, testType, forceRedraw });
}

gc() {
Expand Down
37 changes: 29 additions & 8 deletions src/extensions/renderer/canvas/webgl/drawing-redraw-webgl.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { NodeDrawing } from './drawing-nodes-webgl';
import { OverlayUnderlayRenderer } from './drawing-overlay';
import * as util from './webgl-util';
import * as eleTextureCache from '../ele-texture-cache';
import { defaults } from '../../../../util';
import { defaults, debounce } from '../../../../util';
import { color2tuple } from '../../../../util/colors';
import { mat3 } from 'gl-matrix';

Expand Down Expand Up @@ -109,11 +109,20 @@ CRp.initWebgl = function(opts, fns) {
getPadding: ele => our.getPadding('underlay', ele),
});

// TODO not called when deleting elements
// this is a very simplistic way of triggering garbage collection
const setGCFlag = debounce(() => {
console.log('garbage collect flag set');
r.data.gc = true;
}, 10000);

r.onUpdateEleCalcs((willDraw, eles) => {
let gcNeeded = false;
if(eles && eles.length > 0) {
r.nodeDrawing.invalidate(eles);
r.edgeDrawing.invalidate(eles);
gcNeeded |= r.nodeDrawing.invalidate(eles);
gcNeeded |= r.edgeDrawing.invalidate(eles);
}
if(gcNeeded) {
setGCFlag();
}
});

Expand All @@ -127,17 +136,17 @@ CRp.initWebgl = function(opts, fns) {
*/
function overrideCanvasRendererFunctions(r) {
{ // Override the render function to call the webgl render function if the zoom level is appropriate
const baseFunc = r.render;
const renderCanvas = r.render;
r.render = function(options) {
options = options || {};
const cy = r.cy;
if(r.webgl) {
// if the zoom level is greater than the max zoom level, then disable webgl
if(cy.zoom() > eleTextureCache.maxZoom) {
// if the zoom level is greater than the max zoom level, then disable webgl
clearWebgl(r);
baseFunc.call(r, options);
renderCanvas.call(r, options);
} else {
r.clearCanvas();
clearCanvas(r);
renderWebgl(r, options, RENDER_TARGET.SCREEN);
}
}
Expand Down Expand Up @@ -192,6 +201,18 @@ function clearWebgl(r) {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
}

function clearCanvas(r) {
// the CRp.clearCanvas() function doesn't take the transform into account
const clear = context => {
context.save();
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, r.canvasWidth, r.canvasHeight);
context.restore();
};
clear(r.data.contexts[r.NODE]);
clear(r.data.contexts[r.DRAG]);
}


function createPanZoomMatrix(r) {
const width = r.canvasWidth;
Expand Down

0 comments on commit 23c4daa

Please sign in to comment.