Make the atlas texture bigger and scissor to improve clearing performance on Intel Mac
This commit is contained in:
parent
132b6e183b
commit
1213eaa3d7
|
@ -34,7 +34,7 @@ const B_QUAD_SIZE: number = 4 * 8;
|
||||||
const B_QUAD_UPPER_INDICES_OFFSET: number = 0;
|
const B_QUAD_UPPER_INDICES_OFFSET: number = 0;
|
||||||
const B_QUAD_LOWER_INDICES_OFFSET: number = 4 * 4;
|
const B_QUAD_LOWER_INDICES_OFFSET: number = 4 * 4;
|
||||||
|
|
||||||
const ATLAS_SIZE: glmatrix.vec2 = glmatrix.vec2.fromValues(2048, 2048);
|
const ATLAS_SIZE: glmatrix.vec2 = glmatrix.vec2.fromValues(4096, 4096);
|
||||||
|
|
||||||
const SHADER_URLS: ShaderMap<ShaderProgramURLs> = {
|
const SHADER_URLS: ShaderMap<ShaderProgramURLs> = {
|
||||||
blit: {
|
blit: {
|
||||||
|
@ -500,8 +500,9 @@ class AppController {
|
||||||
this.rebuildAtlas();
|
this.rebuildAtlas();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTiming(newTime: number) {
|
updateTiming(newTimes: {atlasRendering: number, compositing: number}) {
|
||||||
this.fpsLabel.innerHTML = `${newTime} ms`;
|
this.fpsLabel.innerHTML =
|
||||||
|
`${newTimes.atlasRendering} ms atlas, ${newTimes.compositing} ms compositing`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private rebuildAtlas() {
|
private rebuildAtlas() {
|
||||||
|
@ -615,8 +616,9 @@ class PathfinderView {
|
||||||
this.gl.getExtension('OES_texture_float');
|
this.gl.getExtension('OES_texture_float');
|
||||||
this.gl.getExtension('WEBGL_depth_texture');
|
this.gl.getExtension('WEBGL_depth_texture');
|
||||||
|
|
||||||
// Set up our timer query for profiling.
|
// Set up our timer queries for profiling.
|
||||||
this.timerQuery = this.timerQueryExt.createQueryEXT();
|
this.atlasRenderingTimerQuery = this.timerQueryExt.createQueryEXT();
|
||||||
|
this.compositingTimerQuery = this.timerQueryExt.createQueryEXT();
|
||||||
|
|
||||||
// Upload quad buffers.
|
// Upload quad buffers.
|
||||||
this.quadPositionsBuffer = unwrapNull(this.gl.createBuffer());
|
this.quadPositionsBuffer = unwrapNull(this.gl.createBuffer());
|
||||||
|
@ -801,7 +803,6 @@ class PathfinderView {
|
||||||
window.requestAnimationFrame(() => this.redraw());
|
window.requestAnimationFrame(() => this.redraw());
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(pcwalton): This logic is all wrong.
|
|
||||||
onWheel(event: WheelEvent) {
|
onWheel(event: WheelEvent) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
|
@ -861,9 +862,11 @@ class PathfinderView {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start timing.
|
// Start timing rendering.
|
||||||
if (this.timerQueryPollInterval == null)
|
if (this.timerQueryPollInterval == null) {
|
||||||
this.timerQueryExt.beginQueryEXT(this.timerQueryExt.TIME_ELAPSED_EXT, this.timerQuery);
|
this.timerQueryExt.beginQueryEXT(this.timerQueryExt.TIME_ELAPSED_EXT,
|
||||||
|
this.atlasRenderingTimerQuery);
|
||||||
|
}
|
||||||
|
|
||||||
// Prepare for direct rendering.
|
// Prepare for direct rendering.
|
||||||
this.antialiasingStrategy.prepare(this);
|
this.antialiasingStrategy.prepare(this);
|
||||||
|
@ -875,33 +878,47 @@ class PathfinderView {
|
||||||
// Antialias.
|
// Antialias.
|
||||||
this.antialiasingStrategy.resolve(this);
|
this.antialiasingStrategy.resolve(this);
|
||||||
|
|
||||||
// Finish timing and update the profile.
|
// End the timer, and start a new one.
|
||||||
this.updateTiming();
|
if (this.timerQueryPollInterval == null) {
|
||||||
|
this.timerQueryExt.endQueryEXT(this.timerQueryExt.TIME_ELAPSED_EXT);
|
||||||
|
this.timerQueryExt.beginQueryEXT(this.timerQueryExt.TIME_ELAPSED_EXT,
|
||||||
|
this.compositingTimerQuery);
|
||||||
|
}
|
||||||
|
|
||||||
// Draw the glyphs with the resolved atlas to the default framebuffer.
|
// Draw the glyphs with the resolved atlas to the default framebuffer.
|
||||||
this.composite();
|
this.composite();
|
||||||
|
|
||||||
// Clear dirty bit and finish.
|
// Finish timing, clear dirty bit and finish.
|
||||||
|
this.finishTiming();
|
||||||
this.dirty = false;
|
this.dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTiming() {
|
finishTiming() {
|
||||||
if (this.timerQueryPollInterval != null)
|
if (this.timerQueryPollInterval != null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.timerQueryExt.endQueryEXT(this.timerQueryExt.TIME_ELAPSED_EXT);
|
this.timerQueryExt.endQueryEXT(this.timerQueryExt.TIME_ELAPSED_EXT);
|
||||||
|
|
||||||
this.timerQueryPollInterval = window.setInterval(() => {
|
this.timerQueryPollInterval = window.setInterval(() => {
|
||||||
if (this.timerQueryExt.getQueryObjectEXT(this.timerQuery,
|
for (const queryName of ['atlasRenderingTimerQuery', 'compositingTimerQuery'] as
|
||||||
|
Array<'atlasRenderingTimerQuery' | 'compositingTimerQuery'>) {
|
||||||
|
if (this.timerQueryExt.getQueryObjectEXT(this[queryName],
|
||||||
this.timerQueryExt
|
this.timerQueryExt
|
||||||
.QUERY_RESULT_AVAILABLE_EXT) == 0) {
|
.QUERY_RESULT_AVAILABLE_EXT) == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const elapsedTime =
|
const atlasRenderingTime =
|
||||||
this.timerQueryExt.getQueryObjectEXT(this.timerQuery,
|
this.timerQueryExt.getQueryObjectEXT(this.atlasRenderingTimerQuery,
|
||||||
this.timerQueryExt.QUERY_RESULT_EXT);
|
this.timerQueryExt.QUERY_RESULT_EXT);
|
||||||
this.appController.updateTiming(elapsedTime / 1000000.0);
|
const compositingTime =
|
||||||
|
this.timerQueryExt.getQueryObjectEXT(this.compositingTimerQuery,
|
||||||
|
this.timerQueryExt.QUERY_RESULT_EXT);
|
||||||
|
this.appController.updateTiming({
|
||||||
|
atlasRendering: atlasRenderingTime / 1000000.0,
|
||||||
|
compositing: compositingTime / 1000000.0,
|
||||||
|
});
|
||||||
|
|
||||||
window.clearInterval(this.timerQueryPollInterval!);
|
window.clearInterval(this.timerQueryPollInterval!);
|
||||||
this.timerQueryPollInterval = null;
|
this.timerQueryPollInterval = null;
|
||||||
|
@ -1040,6 +1057,7 @@ class PathfinderView {
|
||||||
this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
|
this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
|
||||||
this.gl.disable(this.gl.DEPTH_TEST);
|
this.gl.disable(this.gl.DEPTH_TEST);
|
||||||
this.gl.disable(this.gl.BLEND);
|
this.gl.disable(this.gl.BLEND);
|
||||||
|
this.gl.disable(this.gl.SCISSOR_TEST);
|
||||||
|
|
||||||
// Clear.
|
// Clear.
|
||||||
this.gl.clearColor(1.0, 1.0, 1.0, 1.0);
|
this.gl.clearColor(1.0, 1.0, 1.0, 1.0);
|
||||||
|
@ -1102,7 +1120,8 @@ class PathfinderView {
|
||||||
meshes: PathfinderMeshBuffers;
|
meshes: PathfinderMeshBuffers;
|
||||||
meshData: PathfinderMeshData;
|
meshData: PathfinderMeshData;
|
||||||
|
|
||||||
timerQuery: WebGLQuery;
|
atlasRenderingTimerQuery: WebGLQuery;
|
||||||
|
compositingTimerQuery: WebGLQuery;
|
||||||
timerQueryPollInterval: number | null;
|
timerQueryPollInterval: number | null;
|
||||||
|
|
||||||
pathColorsBufferTexture: PathfinderBufferTexture;
|
pathColorsBufferTexture: PathfinderBufferTexture;
|
||||||
|
@ -1285,6 +1304,7 @@ class NoAAStrategy implements AntialiasingStrategy {
|
||||||
prepare(view: PathfinderView) {
|
prepare(view: PathfinderView) {
|
||||||
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, view.atlasFramebuffer);
|
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, view.atlasFramebuffer);
|
||||||
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
||||||
|
view.gl.disable(view.gl.SCISSOR_TEST);
|
||||||
|
|
||||||
// Clear.
|
// Clear.
|
||||||
view.gl.clearColor(1.0, 1.0, 1.0, 1.0);
|
view.gl.clearColor(1.0, 1.0, 1.0, 1.0);
|
||||||
|
@ -1315,10 +1335,11 @@ class SSAAStrategy implements AntialiasingStrategy {
|
||||||
|
|
||||||
setFramebufferSize(view: PathfinderView, framebufferSize: Size2D) {
|
setFramebufferSize(view: PathfinderView, framebufferSize: Size2D) {
|
||||||
this.destFramebufferSize = framebufferSize;
|
this.destFramebufferSize = framebufferSize;
|
||||||
this.supersampledFramebufferSize = new Float32Array([
|
|
||||||
framebufferSize[0] * 2,
|
this.supersampledFramebufferSize = glmatrix.vec2.create();
|
||||||
framebufferSize[1] * (this.level == 2 ? 1 : 2),
|
glmatrix.vec2.mul(this.supersampledFramebufferSize,
|
||||||
]) as Size2D;
|
framebufferSize,
|
||||||
|
this.supersampleScale);
|
||||||
|
|
||||||
this.supersampledColorTexture = unwrapNull(view.gl.createTexture());
|
this.supersampledColorTexture = unwrapNull(view.gl.createTexture());
|
||||||
view.gl.activeTexture(view.gl.TEXTURE0);
|
view.gl.activeTexture(view.gl.TEXTURE0);
|
||||||
|
@ -1355,9 +1376,12 @@ class SSAAStrategy implements AntialiasingStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare(view: PathfinderView) {
|
prepare(view: PathfinderView) {
|
||||||
const size = this.supersampledFramebufferSize;
|
const framebufferSize = this.supersampledFramebufferSize;
|
||||||
|
const usedSize = this.usedSupersampledFramebufferSize(view);
|
||||||
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.supersampledFramebuffer);
|
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.supersampledFramebuffer);
|
||||||
view.gl.viewport(0, 0, size[0], size[1]);
|
view.gl.viewport(0, 0, framebufferSize[0], framebufferSize[1]);
|
||||||
|
view.gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
||||||
|
view.gl.enable(view.gl.SCISSOR_TEST);
|
||||||
|
|
||||||
// Clear.
|
// Clear.
|
||||||
view.gl.clearColor(1.0, 1.0, 1.0, 1.0);
|
view.gl.clearColor(1.0, 1.0, 1.0, 1.0);
|
||||||
|
@ -1389,12 +1413,22 @@ class SSAAStrategy implements AntialiasingStrategy {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
level: number;
|
private get supersampleScale(): glmatrix.vec2 {
|
||||||
destFramebufferSize: Size2D;
|
return glmatrix.vec2.fromValues(2, this.level == 2 ? 1 : 2);
|
||||||
supersampledFramebufferSize: Size2D;
|
}
|
||||||
supersampledColorTexture: WebGLTexture;
|
|
||||||
supersampledDepthTexture: WebGLTexture;
|
private usedSupersampledFramebufferSize(view: PathfinderView): glmatrix.vec2 {
|
||||||
supersampledFramebuffer: WebGLFramebuffer;
|
const result = glmatrix.vec2.create();
|
||||||
|
glmatrix.vec2.mul(result, view.appController.atlas.usedSize, this.supersampleScale);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private level: number;
|
||||||
|
private destFramebufferSize: Size2D;
|
||||||
|
private supersampledFramebufferSize: Size2D;
|
||||||
|
private supersampledColorTexture: WebGLTexture;
|
||||||
|
private supersampledDepthTexture: WebGLTexture;
|
||||||
|
private supersampledFramebuffer: WebGLFramebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ECAAStrategy implements AntialiasingStrategy {
|
abstract class ECAAStrategy implements AntialiasingStrategy {
|
||||||
|
@ -1576,7 +1610,7 @@ abstract class ECAAStrategy implements AntialiasingStrategy {
|
||||||
this.curveVAOs = vaos as UpperAndLower<WebGLVertexArrayObject>;
|
this.curveVAOs = vaos as UpperAndLower<WebGLVertexArrayObject>;
|
||||||
}
|
}
|
||||||
|
|
||||||
createResolveVAO(view: PathfinderView) {
|
private createResolveVAO(view: PathfinderView) {
|
||||||
this.resolveVAO = view.vertexArrayObjectExt.createVertexArrayOES();
|
this.resolveVAO = view.vertexArrayObjectExt.createVertexArrayOES();
|
||||||
view.vertexArrayObjectExt.bindVertexArrayOES(this.resolveVAO);
|
view.vertexArrayObjectExt.bindVertexArrayOES(this.resolveVAO);
|
||||||
|
|
||||||
|
@ -1588,8 +1622,11 @@ abstract class ECAAStrategy implements AntialiasingStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare(view: PathfinderView) {
|
prepare(view: PathfinderView) {
|
||||||
|
const usedSize = view.appController.atlas.usedSize;
|
||||||
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.directFramebuffer);
|
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.directFramebuffer);
|
||||||
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
||||||
|
view.gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
||||||
|
view.gl.enable(view.gl.SCISSOR_TEST);
|
||||||
|
|
||||||
// Clear out the color and depth textures.
|
// Clear out the color and depth textures.
|
||||||
view.drawBuffersExt.drawBuffersWEBGL([
|
view.drawBuffersExt.drawBuffersWEBGL([
|
||||||
|
@ -1634,8 +1671,11 @@ abstract class ECAAStrategy implements AntialiasingStrategy {
|
||||||
private cover(view: PathfinderView) {
|
private cover(view: PathfinderView) {
|
||||||
// Set state for conservative coverage.
|
// Set state for conservative coverage.
|
||||||
const coverProgram = view.shaderPrograms.ecaaCover;
|
const coverProgram = view.shaderPrograms.ecaaCover;
|
||||||
|
const usedSize = view.appController.atlas.usedSize;
|
||||||
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.aaFramebuffer);
|
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.aaFramebuffer);
|
||||||
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
||||||
|
view.gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
||||||
|
view.gl.enable(view.gl.SCISSOR_TEST);
|
||||||
|
|
||||||
this.setCoverDepthState(view);
|
this.setCoverDepthState(view);
|
||||||
|
|
||||||
|
@ -1662,8 +1702,11 @@ abstract class ECAAStrategy implements AntialiasingStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
private setAAState(view: PathfinderView) {
|
private setAAState(view: PathfinderView) {
|
||||||
|
const usedSize = view.appController.atlas.usedSize;
|
||||||
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.aaFramebuffer);
|
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, this.aaFramebuffer);
|
||||||
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
||||||
|
view.gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
||||||
|
view.gl.enable(view.gl.SCISSOR_TEST);
|
||||||
|
|
||||||
this.setAADepthState(view);
|
this.setAADepthState(view);
|
||||||
|
|
||||||
|
@ -1731,8 +1774,11 @@ abstract class ECAAStrategy implements AntialiasingStrategy {
|
||||||
|
|
||||||
private resolveAA(view: PathfinderView) {
|
private resolveAA(view: PathfinderView) {
|
||||||
// Set state for ECAA resolve.
|
// Set state for ECAA resolve.
|
||||||
|
const usedSize = view.appController.atlas.usedSize;
|
||||||
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, view.atlasFramebuffer);
|
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, view.atlasFramebuffer);
|
||||||
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
view.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
||||||
|
view.gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
||||||
|
view.gl.enable(view.gl.SCISSOR_TEST);
|
||||||
this.setResolveDepthState(view);
|
this.setResolveDepthState(view);
|
||||||
view.gl.disable(view.gl.BLEND);
|
view.gl.disable(view.gl.BLEND);
|
||||||
view.drawBuffersExt.drawBuffersWEBGL([view.drawBuffersExt.COLOR_ATTACHMENT0_WEBGL]);
|
view.drawBuffersExt.drawBuffersWEBGL([view.drawBuffersExt.COLOR_ATTACHMENT0_WEBGL]);
|
||||||
|
|
Loading…
Reference in New Issue