Use RGB5_A1 on macOS to work around driver stalls with RGBA

This commit is contained in:
Patrick Walton 2017-12-11 12:18:48 -08:00
parent 00433d418a
commit 1102965f6d
4 changed files with 44 additions and 41 deletions

View File

@ -82,19 +82,20 @@ export class Atlas {
if (this._texture != null)
return this._texture;
const texture = unwrapNull(renderContext.gl.createTexture());
const gl = renderContext.gl;
const texture = unwrapNull(gl.createTexture());
this._texture = texture;
renderContext.gl.bindTexture(renderContext.gl.TEXTURE_2D, texture);
renderContext.gl.texImage2D(renderContext.gl.TEXTURE_2D,
0,
renderContext.colorAlphaFormat,
ATLAS_SIZE[0],
ATLAS_SIZE[1],
0,
renderContext.colorAlphaFormat,
renderContext.gl.UNSIGNED_BYTE,
null);
setTextureParameters(renderContext.gl, renderContext.gl.NEAREST);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D,
0,
gl.RGBA,
ATLAS_SIZE[0],
ATLAS_SIZE[1],
0,
gl.RGBA,
gl.UNSIGNED_BYTE,
null);
setTextureParameters(gl, gl.NEAREST);
return texture;
}

View File

@ -9,9 +9,10 @@
// except according to those terms.
import * as glmatrix from 'gl-matrix';
import * as _ from 'lodash';
import {assert, UINT32_SIZE, unwrapNull} from './utils';
import {DemoView} from './view';
import {ColorAlphaFormat, DemoView} from './view';
export type WebGLVertexArrayObject = any;
@ -47,25 +48,30 @@ export const QUAD_ELEMENTS: Uint8Array = new Uint8Array([2, 0, 1, 1, 3, 2]);
export function createFramebufferColorTexture(gl: WebGLRenderingContext,
size: glmatrix.vec2,
colorAlphaFormat: GLenum):
colorAlphaFormat: ColorAlphaFormat,
filter?: number):
WebGLTexture {
// Firefox seems to have a bug whereby textures don't get marked as initialized when cleared
// if they're anything other than the first attachment of an FBO. To work around this, supply
// zero data explicitly when initializing the texture.
const zeroes = new Uint8Array(size[0] * size[1] * UINT32_SIZE);
let format, type, internalFormat, bitDepth, zeroes;
if (colorAlphaFormat === 'RGBA8') {
format = internalFormat = gl.RGBA;
type = gl.UNSIGNED_BYTE;
bitDepth = 32;
zeroes = new Uint8Array(size[0] * size[1] * 4);
} else {
format = internalFormat = gl.RGBA;
type = gl.UNSIGNED_SHORT_5_5_5_1;
bitDepth = 16;
zeroes = new Uint16Array(size[0] * size[1] * 4);
}
const texture = unwrapNull(gl.createTexture());
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D,
0,
colorAlphaFormat,
size[0],
size[1],
0,
colorAlphaFormat,
gl.UNSIGNED_BYTE,
zeroes);
setTextureParameters(gl, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, size[0], size[1], 0, format, type, zeroes);
setTextureParameters(gl, _.defaultTo(filter, gl.NEAREST));
return texture;
}

View File

@ -56,19 +56,11 @@ export default class SSAAStrategy extends AntialiasingStrategy {
this.destFramebufferSize,
this.supersampleScale);
this.supersampledColorTexture = unwrapNull(gl.createTexture());
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this.supersampledColorTexture);
gl.texImage2D(gl.TEXTURE_2D,
0,
renderContext.colorAlphaFormat,
this.supersampledFramebufferSize[0],
this.supersampledFramebufferSize[1],
0,
renderContext.colorAlphaFormat,
gl.UNSIGNED_BYTE,
null);
setTextureParameters(gl, gl.LINEAR);
this.supersampledColorTexture =
createFramebufferColorTexture(gl,
this.supersampledFramebufferSize,
renderContext.colorAlphaFormat,
gl.LINEAR);
this.supersampledDepthTexture =
createFramebufferDepthTexture(gl, this.supersampledFramebufferSize);

View File

@ -46,6 +46,8 @@ export interface Timings {
rendering: number;
}
export type ColorAlphaFormat = 'RGBA8' | 'RGB5_A1';
declare class WebGLQuery {}
export abstract class PathfinderView {
@ -157,8 +159,10 @@ export abstract class DemoView extends PathfinderView implements RenderContext {
meshes: PathfinderMeshBuffers[];
meshData: PathfinderMeshData[];
get colorAlphaFormat(): GLenum {
return this.gl.RGBA;
get colorAlphaFormat(): ColorAlphaFormat {
// On macOS, RGBA framebuffers seem to cause driver stalls when switching between rendering
// and texturing. Work around this by using RGB5A1 instead.
return navigator.platform === 'MacIntel' ? 'RGB5_A1' : 'RGBA8';
}
get renderContext(): RenderContext {
@ -360,7 +364,7 @@ export interface RenderContext {
readonly timerQueryExt: EXTDisjointTimerQuery;
readonly vertexArrayObjectExt: OESVertexArrayObject;
readonly colorAlphaFormat: GLenum;
readonly colorAlphaFormat: ColorAlphaFormat;
readonly shaderPrograms: ShaderMap<PathfinderShaderProgram>;
readonly gammaLUT: HTMLImageElement;