Wait for proper image load event

There is a specific event for when an image has finished loading,
so trigger on that rather than polling. The polling interval of
requestAnimationFrame() can also be very large.
This commit is contained in:
Pierre Ossman 2016-09-22 10:28:35 +02:00 committed by Samuel Mannehed
parent 1578fa68ac
commit bb6965f2e6
2 changed files with 14 additions and 13 deletions

View File

@ -746,12 +746,18 @@
this._renderQ.push(action); this._renderQ.push(action);
if (this._renderQ.length === 1) { if (this._renderQ.length === 1) {
// If this can be rendered immediately it will be, otherwise // If this can be rendered immediately it will be, otherwise
// the scanner will start polling the queue (every // the scanner will wait for the relevant event
// requestAnimationFrame interval)
this._scan_renderQ(); this._scan_renderQ();
} }
}, },
_resume_renderQ: function() {
// "this" is the object that is ready, not the
// display object
this.removeEventListener('load', this._noVNC_display._resume_renderQ);
this._noVNC_display._scan_renderQ();
},
_scan_renderQ: function () { _scan_renderQ: function () {
var ready = true; var ready = true;
while (ready && this._renderQ.length > 0) { while (ready && this._renderQ.length > 0) {
@ -776,6 +782,8 @@
if (a.img.complete) { if (a.img.complete) {
this.drawImage(a.img, a.x, a.y); this.drawImage(a.img, a.x, a.y);
} else { } else {
a.img._noVNC_display = this;
a.img.addEventListener('load', this._resume_renderQ);
// We need to wait for this image to 'load' // We need to wait for this image to 'load'
// to keep things in-order // to keep things in-order
ready = false; ready = false;
@ -787,10 +795,6 @@
this._renderQ.shift(); this._renderQ.shift();
} }
} }
if (this._renderQ.length > 0) {
requestAnimationFrame(this._scan_renderQ.bind(this));
}
}, },
}; };

View File

@ -384,11 +384,6 @@ describe('Display/Canvas Helper', function () {
display = new Display({ target: document.createElement('canvas'), prefer_js: false }); display = new Display({ target: document.createElement('canvas'), prefer_js: false });
display.resize(4, 4); display.resize(4, 4);
sinon.spy(display, '_scan_renderQ'); sinon.spy(display, '_scan_renderQ');
this.old_requestAnimationFrame = window.requestAnimationFrame;
window.requestAnimationFrame = function (cb) {
this.next_frame_cb = cb;
}.bind(this);
this.next_frame = function () { this.next_frame_cb(); };
}); });
afterEach(function () { afterEach(function () {
@ -407,7 +402,7 @@ describe('Display/Canvas Helper', function () {
}); });
it('should wait until an image is loaded to attempt to draw it and the rest of the queue', function () { it('should wait until an image is loaded to attempt to draw it and the rest of the queue', function () {
var img = { complete: false }; var img = { complete: false, addEventListener: sinon.spy() }
display._renderQ = [{ type: 'img', x: 3, y: 4, img: img }, display._renderQ = [{ type: 'img', x: 3, y: 4, img: img },
{ type: 'fill', x: 1, y: 2, width: 3, height: 4, color: 5 }]; { type: 'fill', x: 1, y: 2, width: 3, height: 4, color: 5 }];
display.drawImage = sinon.spy(); display.drawImage = sinon.spy();
@ -416,11 +411,13 @@ describe('Display/Canvas Helper', function () {
display._scan_renderQ(); display._scan_renderQ();
expect(display.drawImage).to.not.have.been.called; expect(display.drawImage).to.not.have.been.called;
expect(display.fillRect).to.not.have.been.called; expect(display.fillRect).to.not.have.been.called;
expect(img.addEventListener).to.have.been.calledOnce;
display._renderQ[0].img.complete = true; display._renderQ[0].img.complete = true;
this.next_frame(); display._scan_renderQ();
expect(display.drawImage).to.have.been.calledOnce; expect(display.drawImage).to.have.been.calledOnce;
expect(display.fillRect).to.have.been.calledOnce; expect(display.fillRect).to.have.been.calledOnce;
expect(img.addEventListener).to.have.been.calledOnce;
}); });
it('should draw a blit image on type "blit"', function () { it('should draw a blit image on type "blit"', function () {