Webgl / improve reading of render targets data

Now two methods are available: `readAll` and `readPixel`,
and the data from the render target is not re-read every time unless
`clearCachedData` is called.
This commit is contained in:
Olivier Guyot
2019-06-06 10:21:00 +02:00
parent 917950a32b
commit e852294938
2 changed files with 107 additions and 20 deletions

View File

@@ -11,10 +11,10 @@ describe('ol.webgl.RenderTarget', function() {
const canvas = document.createElement('canvas');
testImage_4x4 = canvas.getContext('2d').createImageData(4, 4);
for (let i = 0; i < testImage_4x4.data.length; i += 4) {
testImage_4x4.data[i] = 100;
testImage_4x4.data[i + 1] = 150;
testImage_4x4.data[i + 2] = 200;
testImage_4x4.data[i + 3] = 250;
testImage_4x4.data[i] = 100 + i / 4;
testImage_4x4.data[i + 1] = 100 + i / 4;
testImage_4x4.data[i + 2] = 200 + i / 4;
testImage_4x4.data[i + 3] = 200 + i / 4;
}
});
@@ -52,29 +52,77 @@ describe('ol.webgl.RenderTarget', function() {
});
describe('#readData', function() {
describe('#readAll', function() {
it('returns 1-pixel data with the default options', function() {
const rt = new WebGLRenderTarget(helper);
expect(rt.read().length).to.eql(4);
expect(rt.readAll().length).to.eql(4);
});
it('returns the content of the texture', function() {
const rt = new WebGLRenderTarget(helper, [4, 4]);
helper.createTexture([4, 4], testImage_4x4, rt.getTexture());
const data = rt.read();
const data = rt.readAll();
expect(data[0]).to.eql(100);
expect(data[1]).to.eql(150);
expect(data[1]).to.eql(100);
expect(data[2]).to.eql(200);
expect(data[3]).to.eql(250);
expect(data[4]).to.eql(100);
expect(data[5]).to.eql(150);
expect(data[6]).to.eql(200);
expect(data[7]).to.eql(250);
expect(data[3]).to.eql(200);
expect(data[4]).to.eql(101);
expect(data[5]).to.eql(101);
expect(data[6]).to.eql(201);
expect(data[7]).to.eql(201);
expect(data.length).to.eql(4 * 4 * 4);
});
it('does not call gl.readPixels again when #clearCachedData is not called', function() {
const rt = new WebGLRenderTarget(helper, [4, 4]);
helper.createTexture([4, 4], testImage_4x4, rt.getTexture());
const spy = sinon.spy(rt.helper_.getGL(), 'readPixels');
rt.readAll();
expect(spy.callCount).to.eql(1);
rt.readAll();
expect(spy.callCount).to.eql(1);
rt.clearCachedData();
rt.readAll();
expect(spy.callCount).to.eql(2);
});
});
describe('#readPixel', function() {
it('returns the content of one pixel', function() {
const rt = new WebGLRenderTarget(helper, [4, 4]);
helper.createTexture([4, 4], testImage_4x4, rt.getTexture());
let data = rt.readPixel(0, 0);
expect(data[0]).to.eql(112);
expect(data[1]).to.eql(112);
expect(data[2]).to.eql(212);
expect(data[3]).to.eql(212);
data = rt.readPixel(3, 3);
expect(data[0]).to.eql(103);
expect(data[1]).to.eql(103);
expect(data[2]).to.eql(203);
expect(data[3]).to.eql(203);
expect(data.length).to.eql(4);
});
it('does not call gl.readPixels again when #clearCachedData is not called', function() {
const rt = new WebGLRenderTarget(helper, [4, 4]);
helper.createTexture([4, 4], testImage_4x4, rt.getTexture());
const spy = sinon.spy(rt.helper_.getGL(), 'readPixels');
rt.readPixel(0, 0);
expect(spy.callCount).to.eql(1);
rt.readPixel(1, 1);
expect(spy.callCount).to.eql(1);
rt.clearCachedData();
rt.readPixel(2, 2);
expect(spy.callCount).to.eql(2);
});
});
});