Skip to content

Commit 4ee5dfb

Browse files
committed
Don't touch the GPU at all if nothing changed
1 parent a5a2d14 commit 4ee5dfb

File tree

3 files changed

+33
-8
lines changed

3 files changed

+33
-8
lines changed

src/Drawable.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ class Drawable {
5959
* An object which can be drawn by the renderer.
6060
* @todo double-buffer all rendering state (position, skin, effects, etc.)
6161
* @param {!int} id - This Drawable's unique ID.
62+
* @param {!RenderWebGL} renderer - The renderer that created this Drawable
6263
* @constructor
6364
*/
64-
constructor (id) {
65+
constructor (id, renderer) {
6566
/** @type {!int} */
6667
this._id = id;
68+
this._renderer = renderer;
6769

6870
/**
6971
* The uniforms to be used by the vertex and pixel shaders.
@@ -222,6 +224,7 @@ class Drawable {
222224
this._position[0] = Math.round(position[0]);
223225
this._position[1] = Math.round(position[1]);
224226
}
227+
this._renderer.dirty = true;
225228
this.setTransformDirty();
226229
}
227230
}
@@ -233,6 +236,7 @@ class Drawable {
233236
updateDirection (direction) {
234237
if (this._direction !== direction) {
235238
this._direction = direction;
239+
this._renderer.dirty = true;
236240
this._rotationTransformDirty = true;
237241
this.setTransformDirty();
238242
}
@@ -247,6 +251,7 @@ class Drawable {
247251
this._scale[1] !== scale[1]) {
248252
this._scale[0] = scale[0];
249253
this._scale[1] = scale[1];
254+
this._renderer.dirty = true;
250255
this._rotationCenterDirty = true;
251256
this._skinScaleDirty = true;
252257
this.setTransformDirty();
@@ -260,6 +265,7 @@ class Drawable {
260265
updateVisible (visible) {
261266
if (this._visible !== visible) {
262267
this._visible = visible;
268+
this._renderer.dirty = true;
263269
this.setConvexHullDirty();
264270
}
265271
}
@@ -270,6 +276,7 @@ class Drawable {
270276
* @param {number} rawValue A new effect value.
271277
*/
272278
updateEffect (effectName, rawValue) {
279+
this._renderer.dirty = true;
273280
const effectInfo = ShaderManager.EFFECT_INFO[effectName];
274281
if (rawValue) {
275282
this.enabledEffects |= effectInfo.mask;
@@ -675,6 +682,7 @@ class Drawable {
675682
* @private
676683
*/
677684
_skinWasAltered () {
685+
this._renderer.dirty = true;
678686
this._rotationCenterDirty = true;
679687
this._skinScaleDirty = true;
680688
this.setConvexHullDirty();

src/RenderWebGL.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ class RenderWebGL extends EventEmitter {
215215
// tw: add high quality render option
216216
this.useHighQualityRender = false;
217217

218+
this.dirty = true;
219+
218220
this._createGeometry();
219221

220222
this.on(RenderConstants.Events.NativeSizeChanged, this.onNativeSizeChanged);
@@ -231,6 +233,7 @@ class RenderWebGL extends EventEmitter {
231233

232234
// tw: implement high quality pen option
233235
setUseHighQualityRender (enabled) {
236+
this.dirty = true;
234237
this.useHighQualityRender = enabled;
235238
this.emit(RenderConstants.Events.UseHighQualityRenderChanged, enabled);
236239
this._updateRenderQuality();
@@ -274,6 +277,7 @@ class RenderWebGL extends EventEmitter {
274277
* @param {int} pixelsTall The desired height in device-independent pixels.
275278
*/
276279
resize (pixelsWide, pixelsTall) {
280+
this.dirty = true;
277281
const {canvas} = this._gl;
278282
const pixelRatio = window.devicePixelRatio || 1;
279283
const newWidth = pixelsWide * pixelRatio;
@@ -517,7 +521,7 @@ class RenderWebGL extends EventEmitter {
517521
return;
518522
}
519523
const drawableID = this._nextDrawableId++;
520-
const drawable = new Drawable(drawableID);
524+
const drawable = new Drawable(drawableID, this);
521525
this._allDrawables[drawableID] = drawable;
522526
this._addToDrawList(drawableID, group);
523527
// tw: implement high quality render
@@ -588,6 +592,7 @@ class RenderWebGL extends EventEmitter {
588592
log.warn('Cannot destroy drawable without known layer group.');
589593
return;
590594
}
595+
this.dirty = true;
591596
const drawable = this._allDrawables[drawableID];
592597
drawable.dispose();
593598
delete this._allDrawables[drawableID];
@@ -643,6 +648,7 @@ class RenderWebGL extends EventEmitter {
643648
return;
644649
}
645650

651+
this.dirty = true;
646652
const currentLayerGroup = this._layerGroups[group];
647653
const startIndex = currentLayerGroup.drawListOffset;
648654
const endIndex = this._endIndexForKnownLayerGroup(currentLayerGroup);
@@ -686,6 +692,11 @@ class RenderWebGL extends EventEmitter {
686692
* Draw all current drawables and present the frame on the canvas.
687693
*/
688694
draw () {
695+
if (!this.dirty) {
696+
return;
697+
}
698+
this.dirty = false;
699+
689700
this._doExitDrawRegion();
690701

691702
const gl = this._gl;
@@ -1708,6 +1719,7 @@ class RenderWebGL extends EventEmitter {
17081719
* @param {int} penSkinID - the unique ID of a Pen Skin.
17091720
*/
17101721
penClear (penSkinID) {
1722+
this.dirty = true;
17111723
const skin = /** @type {PenSkin} */ this._allSkins[penSkinID];
17121724
skin.clear();
17131725
}
@@ -1720,6 +1732,7 @@ class RenderWebGL extends EventEmitter {
17201732
* @param {number} y - the Y coordinate of the point to draw.
17211733
*/
17221734
penPoint (penSkinID, penAttributes, x, y) {
1735+
this.dirty = true;
17231736
const skin = /** @type {PenSkin} */ this._allSkins[penSkinID];
17241737
skin.drawPoint(penAttributes, x, y);
17251738
}
@@ -1734,6 +1747,7 @@ class RenderWebGL extends EventEmitter {
17341747
* @param {number} y1 - the Y coordinate of the end of the line.
17351748
*/
17361749
penLine (penSkinID, penAttributes, x0, y0, x1, y1) {
1750+
this.dirty = true;
17371751
const skin = /** @type {PenSkin} */ this._allSkins[penSkinID];
17381752
skin.drawLine(penAttributes, x0, y0, x1, y1);
17391753
}
@@ -1744,6 +1758,7 @@ class RenderWebGL extends EventEmitter {
17441758
* @param {int} stampID - the unique ID of the Drawable to use as the stamp.
17451759
*/
17461760
penStamp (penSkinID, stampID) {
1761+
this.dirty = true;
17471762
const stampDrawable = this._allDrawables[stampID];
17481763
if (!stampDrawable) {
17491764
return;
@@ -1829,6 +1844,7 @@ class RenderWebGL extends EventEmitter {
18291844
* @private
18301845
*/
18311846
onNativeSizeChanged (event) {
1847+
this.dirty = true;
18321848
const [width, height] = event.newSize;
18331849

18341850
const gl = this._gl;
@@ -2157,6 +2173,7 @@ class RenderWebGL extends EventEmitter {
21572173
* @param {snapshotCallback} callback Function called in the next frame with the snapshot data
21582174
*/
21592175
requestSnapshot (callback) {
2176+
this.dirty = true;
21602177
this._snapshotCallbacks.push(callback);
21612178
}
21622179
}

test/unit/DrawableTests.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const snapToNearest = function (rect, decimals = 3) {
2828

2929
test('translate by position', t => {
3030
const expected = new Rectangle();
31-
const drawable = new Drawable();
31+
const drawable = new Drawable(null, {});
3232
drawable.skin = new MockSkin();
3333
drawable.skin.size = [200, 50];
3434

@@ -44,7 +44,7 @@ test('translate by position', t => {
4444

4545
test('translate by costume center', t => {
4646
const expected = new Rectangle();
47-
const drawable = new Drawable();
47+
const drawable = new Drawable(null, {});
4848
drawable.skin = new MockSkin();
4949
drawable.skin.size = [200, 50];
5050

@@ -61,7 +61,7 @@ test('translate by costume center', t => {
6161

6262
test('translate and rotate', t => {
6363
const expected = new Rectangle();
64-
const drawable = new Drawable();
64+
const drawable = new Drawable(null, {});
6565
drawable.skin = new MockSkin();
6666
drawable.skin.size = [200, 50];
6767

@@ -86,7 +86,7 @@ test('translate and rotate', t => {
8686

8787
test('rotate by non-right-angles', t => {
8888
const expected = new Rectangle();
89-
const drawable = new Drawable();
89+
const drawable = new Drawable(null, {});
9090
drawable.skin = new MockSkin();
9191
drawable.skin.size = [10, 10];
9292
drawable.skin.rotationCenter = [5, 5];
@@ -103,7 +103,7 @@ test('rotate by non-right-angles', t => {
103103

104104
test('scale', t => {
105105
const expected = new Rectangle();
106-
const drawable = new Drawable();
106+
const drawable = new Drawable(null, {});
107107
drawable.skin = new MockSkin();
108108
drawable.skin.size = [200, 50];
109109

@@ -125,7 +125,7 @@ test('scale', t => {
125125

126126
test('rotate and scale', t => {
127127
const expected = new Rectangle();
128-
const drawable = new Drawable();
128+
const drawable = new Drawable(null, {});
129129
drawable.skin = new MockSkin();
130130
drawable.skin.size = [100, 1000];
131131

0 commit comments

Comments
 (0)