8000 [DO-NOT-REVIEW] webgl auto-version/feature WIP by nkreeger · Pull Request #1855 · tensorflow/tfjs-core · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Aug 15, 2019. It is now read-only.

[DO-NOT-REVIEW] webgl auto-version/feature WIP #1855

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Move all GL reference to global class.
  • Loading branch information
nkreeger committed Jul 19, 2019
commit f068cfc8ddc0dcca3d112ac7cd1186ec5cb0fd3c
29 changes: 16 additions & 13 deletions src/backends/webgl/backend_webgl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ import * as binaryop_gpu from './binaryop_gpu';
import {BinaryOpProgram} from './binaryop_gpu';
import * as binaryop_packed_gpu from './binaryop_packed_gpu';
import {BinaryOpPackedProgram} from './binaryop_packed_gpu';
import {createCanvas, getWebGLContext} from './canvas_util';
import {ClipProgram} from './clip_gpu';
import {ClipPackedProgram} from './clip_packed_gpu';
import {ComplexAbsProgram} from './complex_abs_gpu';
Expand Down Expand Up @@ -221,7 +220,6 @@ export class MathBackendWebGL implements KernelBackend {
private dataRefCount = new WeakMap<DataId, number>();
private numBytesInGPU = 0;

private canvas: HTMLCanvasElement;
private fromPixels2DContext: CanvasRenderingContext2D|
OffscreenCanvasRenderingContext2D;

Expand All @@ -248,15 +246,15 @@ export class MathBackendWebGL implements KernelBackend {
}

if (gpgpu == null) {
const gl = getWebGLContext(ENV.getNumber('WEBGL_VERSION'));
// TODO(kreeger): Fix this.
this.binaryCache = getBinaryCache(ENV.getNumber('WEBGL_VERSION'));
this.gpgpu = new GPGPUContext(gl);
this.canvas = gl.canvas;
this.gpgpu = new GPGPUContext();
// this.canvas = gl.canvas;
this.gpgpuCreatedLocally = true;
} else {
this.binaryCache = {};
this.gpgpuCreatedLocally = false;
this.canvas = gpgpu.gl.canvas;
// this.canvas = gpgpu.gl.canvas;
}
this.textureManager = new TextureManager(this.gpgpu);
this.numMBBeforeWarning = numMBBeforeWarning();
Expand Down Expand Up @@ -313,8 +311,9 @@ export class MathBackendWebGL implements KernelBackend {
'on the document object');
}
//@ts-ignore
this.fromPixels2DContext =
createCanvas(ENV.getNumber('WEBGL_VERSION')).getContext('2d');
// TODO(kreeger): Fix this.
// this.fromPixels2DContext =
// createCanvas(ENV.getNumber('WEBGL_VERSION')).getContext('2d');
}
this.fromPixels2DContext.canvas.width = pixels.width;
this.fromPixels2DContext.canvas.height = pixels.height;
Expand Down Expand Up @@ -2500,11 +2499,15 @@ export class MathBackendWebGL implements KernelBackend {
return;
}
this.textureManager.dispose();
if (this.canvas != null && this.canvas.remove != null) {
this.canvas.remove();
} else {
this.canvas = null;
}

// TODO(kreeger): This should be cleaned up in the WebGLContextManager
// right?
// if (this.canvas != null && this.canvas.remove != null) {
// this.canvas.remove();
// } else {
// this.canvas = null;
// }

if (this.fromPixels2DContext != null &&
//@ts-ignore
this.fromPixels2DContext.canvas.remove) {
Expand Down
38 changes: 5 additions & 33 deletions src/backends/webgl/canvas_util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
* =============================================================================
*/

const contexts: {[key: string]: WebGLRenderingContext} = {};

const WEBGL_ATTRIBUTES: WebGLContextAttributes = {
alpha: false,
antialias: false,
Expand All @@ -27,35 +25,7 @@ const WEBGL_ATTRIBUTES: WebGLContextAttributes = {
failIfMajorPerformanceCaveat: true
};

export function setWebGLContext(
webGLVersion: number, gl: WebGLRenderingContext) {
contexts[webGLVersion] = gl;
}

export function getWebGLContext(webGLVersion: number): WebGLRenderingContext {
if (!(webGLVersion in contexts)) {
contexts[webGLVersion] = getWebGLRenderingContext(webGLVersion);
}
const gl = contexts[webGLVersion];
if (gl.isContextLost()) {
delete contexts[webGLVersion];
return getWebGLContext(webGLVersion);
}

gl.disable(gl.DEPTH_TEST);
gl.disable(gl.STENCIL_TEST);
gl.disable(gl.BLEND);
gl.disable(gl.DITHER);
gl.disable(gl.POLYGON_OFFSET_FILL);
gl.disable(gl.SAMPLE_COVERAGE);
gl.enable(gl.SCISSOR_TEST);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.BACK);

return contexts[webGLVersion];
}

export function createCanvas(webGLVersion: number) {
function createCanvas(webGLVersion: number) {
if (typeof OffscreenCanvas !== 'undefined' && webGLVersion === 2) {
return new OffscreenCanvas(300, 150);
} else if (typeof document !== 'undefined') {
Expand All @@ -65,15 +35,17 @@ export function createCanvas(webGLVersion: number) {
}
}

function getWebGLRenderingContext(webGLVersion: number): WebGLRenderingContext {
export function createDOMCanvasWebGLRenderingContext(webGLVersion: number):
WebGLRenderingContext {
if (webGLVersion !== 1 && webGLVersion !== 2) {
throw new Error('Cannot get WebGL rendering context, WebGL is disabled.');
}
const canvas = createCanvas(webGLVersion);

canvas.addEventListener('webglcontextlost', (ev: Event) => {
ev.preventDefault();
delete contexts[webGLVersion];
// TODO(kreeger): callback to manager???
// delete contexts[webGLVersion];
}, false);
if (webGLVersion === 1) {
return (canvas.getContext('webgl', WEBGL_ATTRIBUTES) ||
Expand Down
47 changes: 24 additions & 23 deletions src/backends/webgl/canvas_util_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,31 @@
* =============================================================================
*/

import {ENV} from '../../environment';
import {BROWSER_ENVS, describeWithFlags} from '../../jasmine_util';
// import {ENV} from '../../environment';
// import {BROWSER_ENVS, describeWithFlags} from '../../jasmine_util';

import {getWebGLContext} from './canvas_util';
// import {getWebGLContext} from './canvas_util';

describeWithFlags('canvas_util', BROWSER_ENVS, () => {
it('Returns a valid canvas', () => {
const canvas = getWebGLContext(ENV.getNumber('WEBGL_VERSION')).canvas as (
HTMLCanvasElement | OffscreenCanvas);
expect(
(canvas instanceof HTMLCanvasElement) ||
(canvas instanceof OffscreenCanvas))
.toBe(true);
});
// describeWithFlags('canvas_util', BROWSER_ENVS, () => {
// it('Returns a valid canvas', () => {
// const canvas = getWebGLContext(ENV.getNumber('WEBGL_VERSION')).canvas as
// (
// HTMLCanvasElement | OffscreenCanvas);
// expect(
// (canvas instanceof HTMLCanvasElement) ||
// (canvas instanceof OffscreenCanvas))
// .toBe(true);
// });

it('Returns a valid gl context', () => {
const gl = getWebGLContext(ENV.getNumber('WEBGL_VERSION'));
expect(gl.isContextLost()).toBe(false);
});
});
// it('Returns a valid gl context', () => {
// const gl = getWebGLContext(ENV.getNumber('WEBGL_VERSION'));
// expect(gl.isContextLost()).toBe(false);
// });
// });

describeWithFlags('canvas_util webgl2', {flags: {WEBGL_VERSION: 2}}, () => {
it('is ok when the user requests webgl 1 canvas', () => {
const canvas = getWebGLContext(1).canvas;
expect((canvas instanceof HTMLCanvasElement)).toBe(true);
});
});
// describeWithFlags('canvas_util webgl2', {flags: {WEBGL_VERSION: 2}}, () => {
// it('is ok when the user requests webgl 1 canvas', () => {
// const canvas = getWebGLContext(1).canvas;
// expect((canvas instanceof HTMLCanvasElement)).toBe(true);
// });
// });
6 changes: 4 additions & 2 deletions src/backends/webgl/clip_gpu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import {GPGPUContext} from './gpgpu_context';
import {GPGPUProgram} from './gpgpu_math';
import {WebGLContextManager} from './webgl_context_manager';

export class ClipProgram implements GPGPUProgram {
variableNames = ['A'];
Expand Down Expand Up @@ -51,8 +52,9 @@ export class ClipProgram implements GPGPUProgram {
this.minLoc = gpgpu.getUniformLocationNoThrow(webGLProgram, 'min');
this.maxLoc = gpgpu.getUniformLocationNoThrow(webGLProgram, 'max');
}
gpgpu.gl.uniform1f(this.minLoc, min);
gpgpu.gl.uniform1f(this.maxLoc, max);
const gl = WebGLContextManager.getActiveContext();
gl.uniform1f(this.minLoc, min);
gl.uniform1f(this.maxLoc, max);
};
}
}
6 changes: 4 additions & 2 deletions src/backends/webgl/clip_packed_gpu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import {GPGPUContext} from './gpgpu_context';
import {GPGPUProgram} from './gpgpu_math';
import {WebGLContextManager} from './webgl_context_manager';

export class ClipPackedProgram implements GPGPUProgram {
variableNames = ['A'];
Expand Down Expand Up @@ -53,8 +54,9 @@ export class ClipPackedProgram implements GPGPUProgram {
this.minLoc = gpgpu.getUniformLocationNoThrow(webGLProgram, 'min');
this.maxLoc = gpgpu.getUniformLocationNoThrow(webGLProgram, 'max');
}
gpgpu.gl.uniform1f(this.minLoc, min);
gpgpu.gl.uniform1f(this.maxLoc, max);
const gl = WebGLContextManager.getActiveContext();
gl.uniform1f(this.minLoc, min);
gl.uniform1f(this.maxLoc, max);
};
}
}
3 changes: 2 additions & 1 deletion src/backends/webgl/fill_gpu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import {GPGPUContext} from './gpgpu_context';
import {GPGPUProgram} from './gpgpu_math';
import {WebGLContextManager} from './webgl_context_manager';

export class FillProgram implements GPGPUProgram {
variableNames: string[];
Expand All @@ -43,7 +44,7 @@ export class FillProgram implements GPGPUProgram {
if (this.valueLoc == null) {
this.valueLoc = gpgpu.getUniformLocationNoThrow(webGLProgram, 'value');
}
gpgpu.gl.uniform1f(this.valueLoc, value);
WebGLContextManager.getActiveContext().uniform1f(this.valueLoc, value);
};
}
}
50 changes: 25 additions & 25 deletions src/backends/webgl/flags_webgl_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import * as device_util from '../../device_util';
import {ENV} from '../../environment';
import {webgl_util} from '../../webgl';

import * as canvas_util from './canvas_util';

describe('HAS_WEBGL', () => {
beforeEach(() => ENV.reset());
afterAll(() => ENV.reset());
Expand Down Expand Up @@ -197,15 +195,16 @@ describe('WEBGL_MAX_TEXTURE_SIZE', () => {
ENV.reset();
webgl_util.MAX_TEXTURE_SIZE = null;

spyOn(canvas_util, 'getWebGLContext').and.returnValue({
MAX_TEXTURE_SIZE: 101,
getParameter: (param: number) => {
if (param === 101) {
return 50;
}
throw new Error(`Got undefined param ${param}.`);
}
});
// TODO(kreeger): Fix this
// spyOn(canvas_util, 'getWebGLContext').and.returnValue({
// MAX_TEXTURE_SIZE: 101,
// getParameter: (param: number) => {
// if (param === 101) {
// return 50;
// }
// throw new Error(`Got undefined param ${param}.`);
// }
// });
});
afterAll(() => {
ENV.reset();
Expand All @@ -218,35 +217,36 @@ describe('WEBGL_MAX_TEXTURE_SIZE', () => {
});

describe('WEBGL_MAX_TEXTURES_IN_SHADER', () => {
let maxTextures: number;
// let maxTextures: number;
beforeEach(() => {
ENV.reset();
webgl_util.MAX_TEXTURES_IN_SHADER = null;

spyOn(canvas_util, 'getWebGLContext').and.callFake(() => {
return {
MAX_TEXTURE_IMAGE_UNITS: 101,
getParameter: (param: number) => {
if (param === 101) {
return maxTextures;
}
throw new Error(`Got undefined param ${param}.`);
}
};
});
// TODO(kreeger): Fix this.
// spyOn(canvas_util, 'getWebGLContext').and.callFake(() => {
// return {
// MAX_TEXTURE_IMAGE_UNITS: 101,
// getParameter: (param: number) => {
// if (param === 101) {
// return maxTextures;
// }
// throw new Error(`Got undefined param ${param}.`);
// }
// };
// });
});
afterAll(() => {
ENV.reset();
webgl_util.MAX_TEXTURES_IN_SHADER = null;
});

it('is a function of gl.getParameter(MAX_TEXTURE_IMAGE_UNITS)', () => {
maxTextures = 10;
// maxTextures = 10;
expect(ENV.getNumber('WEBGL_MAX_TEXTURES_IN_SHADER')).toBe(10);
});

it('is capped at 16', () => {
maxTextures = 20;
// maxTextures = 20;
expect(ENV.getNumber('WEBGL_MAX_TEXTURES_IN_SHADER')).toBe(16);
});
});
Expand Down
Loading
0