Skip to content

Commit

Permalink
Worldview: Paint again if onDirty was called during paint (copy of #614
Browse files Browse the repository at this point in the history
…) (#616)

* Worldview: Paint again if onDirty was called during paint

In some cases, since components can register arbitrary functions to be called during paint(), painting may trigger a React state update, which causes us to call onDirty again. But since a paint is currently in progress, we just ignore the onDirty call, which means that the new state never gets drawn until another paint is triggered in the future.

Fix this by keeping track of whether onDirty is called during paint, and if so just queue up another frame.

* Bump regl-worldview to 0.16.1

* Fix build error

Co-authored-by: Jacob Bandes-Storch <[email protected]>
  • Loading branch information
vidaaudrey and jtbandes authored Apr 7, 2021
1 parent 67fce1d commit 05c5ab9
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 157 deletions.
2 changes: 1 addition & 1 deletion packages/regl-worldview/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "regl-worldview",
"version": "0.16.0",
"version": "0.16.1",
"description": "A reusable component for rendering 2D and 3D views using regl",
"license": "Apache-2.0",
"repository": "cruise-automation/webviz/tree/master/packages/regl-worldview",
Expand Down
12 changes: 11 additions & 1 deletion packages/regl-worldview/src/WorldviewContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export class WorldviewContext {
_compiled: Map<Function, CompiledReglCommand<any>> = new Map();
_drawCalls: Map<React.Component<any>, DrawInput> = new Map();
_frame: ?AnimationFrameID;
_needsPaint = false;
_paintCalls: Map<PaintFn, PaintFn> = new Map();
_hitmapObjectIdManager: HitmapObjectIdManager = new HitmapObjectIdManager();
_cachedReadHitmapCall: ?{
Expand Down Expand Up @@ -233,6 +234,7 @@ export class WorldviewContext {
}

_paint() {
this._needsPaint = false;
const start = Date.now();
this.reglCommandObjects.forEach((cmd) => (cmd.stats.count = 0));
if (!this.initializedData) {
Expand All @@ -251,12 +253,20 @@ export class WorldviewContext {
paintCall();
});
this.counters.render = Date.now() - start;
this._frame = undefined;
// More React state updates may have happened while we were painting, since paint happens
// outside the normal React render flow. If this is the case, we need to paint again.
if (this._needsPaint) {
this._frame = requestAnimationFrame(() => this.paint());
} else {
this._frame = undefined;
}
}

onDirty = () => {
if (undefined === this._frame) {
this._frame = requestAnimationFrame(() => this.paint());
} else {
this._needsPaint = true;
}
};

Expand Down
166 changes: 11 additions & 155 deletions packages/webviz-core/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/webviz-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
"devDependencies": {
"@babel/register": "7.11.5",
"@testing-library/react-hooks": "1.1.0",
"@welldone-software/why-did-you-render": "6.1.1",
"eslint-plugin-react-hooks": "^1.5.0",
"fake-indexeddb": "2.0.4",
"fetch-mock": "7.2.5",
Expand Down

0 comments on commit 05c5ab9

Please sign in to comment.