Skip to content

Commit

Permalink
Prevent creation of unused depth renderbuffer attachments (#9377)
Browse files Browse the repository at this point in the history
* Remove unused depth renderbuffer

Should save width * height * 2 bytes of uncompressed buffer memory

* Prevent creation of unused depth renderbuffers

Add option to allow not creating extra renderbuffers
Refer https://www.khronos.org/registry/webgl/specs/latest/1.0/\#6.8 for supported attachment variants
Should save the hillshade offscreen buffer width * height * 2 bytes of uncompressed gpu memory

* Fix lint

* Update src/gl/framebuffer.js

Co-Authored-By: Vladimir Agafonkin <agafonkin@gmail.com>

Co-authored-by: Vladimir Agafonkin <agafonkin@gmail.com>
  • Loading branch information
karimnaaji and mourner authored Mar 5, 2020
1 parent 320755a commit 00d7026
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 28 deletions.
4 changes: 2 additions & 2 deletions src/gl/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ class Context {
return rbo;
}

createFramebuffer(width: number, height: number) {
return new Framebuffer(this, width, height);
createFramebuffer(width: number, height: number, hasDepth: boolean) {
return new Framebuffer(this, width, height, hasDepth);
}

clear({color, depth}: ClearArgs) {
Expand Down
14 changes: 10 additions & 4 deletions src/gl/framebuffer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @flow
import {ColorAttachment, DepthAttachment} from './value';
import assert from 'assert';

import type Context from './context';

Expand All @@ -11,15 +12,18 @@ class Framebuffer {
colorAttachment: ColorAttachment;
depthAttachment: DepthAttachment;

constructor(context: Context, width: number, height: number) {
constructor(context: Context, width: number, height: number, hasDepth: boolean) {
this.context = context;
this.width = width;
this.height = height;
const gl = context.gl;
const fbo = this.framebuffer = gl.createFramebuffer();

this.colorAttachment = new ColorAttachment(context, fbo);
this.depthAttachment = new DepthAttachment(context, fbo);
if (hasDepth) {
this.depthAttachment = new DepthAttachment(context, fbo);
}
assert(gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE);
}

destroy() {
Expand All @@ -28,8 +32,10 @@ class Framebuffer {
const texture = this.colorAttachment.get();
if (texture) gl.deleteTexture(texture);

const renderbuffer = this.depthAttachment.get();
if (renderbuffer) gl.deleteRenderbuffer(renderbuffer);
if (this.depthAttachment) {
const renderbuffer = this.depthAttachment.get();
if (renderbuffer) gl.deleteRenderbuffer(renderbuffer);
}

gl.deleteFramebuffer(this.framebuffer);
}
Expand Down
2 changes: 1 addition & 1 deletion src/render/draw_heatmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ function bindFramebuffer(context, painter, layer) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);

fbo = layer.heatmapFbo = context.createFramebuffer(painter.width / 4, painter.height / 4);
fbo = layer.heatmapFbo = context.createFramebuffer(painter.width / 4, painter.height / 4, false);

bindTextureToFramebuffer(context, painter, texture, fbo);

Expand Down
2 changes: 1 addition & 1 deletion src/render/draw_hillshade.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ function prepareHillshade(painter, tile, layer, sourceMaxZoom, depthMode, stenci
const renderTexture = new Texture(context, {width: tileSize, height: tileSize, data: null}, gl.RGBA);
renderTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE);

fbo = tile.fbo = context.createFramebuffer(tileSize, tileSize);
fbo = tile.fbo = context.createFramebuffer(tileSize, tileSize, true);
fbo.colorAttachment.set(renderTexture.texture);
}

Expand Down
20 changes: 0 additions & 20 deletions src/render/painter.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ class Painter {
emptyProgramConfiguration: ProgramConfiguration;
width: number;
height: number;
depthRbo: WebGLRenderbuffer;
depthRboNeedsClear: boolean;
tileExtentBuffer: VertexBuffer;
tileExtentSegments: SegmentVector;
debugBuffer: VertexBuffer;
Expand Down Expand Up @@ -136,8 +134,6 @@ class Painter {
this.numSublayers = SourceCache.maxUnderzooming + SourceCache.maxOverzooming + 1;
this.depthEpsilon = 1 / Math.pow(2, 16);

this.depthRboNeedsClear = true;

this.crossTileSymbolIndex = new CrossTileSymbolIndex();

this.gpuTimers = {};
Expand All @@ -148,8 +144,6 @@ class Painter {
* for a new width and height value.
*/
resize(width: number, height: number) {
const gl = this.context.gl;

this.width = width * browser.devicePixelRatio;
this.height = height * browser.devicePixelRatio;
this.context.viewport.set([0, 0, this.width, this.height]);
Expand All @@ -159,11 +153,6 @@ class Painter {
this.style._layers[layerId].resize();
}
}

if (this.depthRbo) {
gl.deleteRenderbuffer(this.depthRbo);
this.depthRbo = null;
}
}

setup() {
Expand Down Expand Up @@ -402,7 +391,6 @@ class Painter {
// framebuffer, and then save those for rendering back to the map
// later: in doing this we avoid doing expensive framebuffer restores.
this.renderPass = 'offscreen';
this.depthRboNeedsClear = true;

for (const layerId of layerIds) {
const layer = this.style._layers[layerId];
Expand Down Expand Up @@ -483,14 +471,6 @@ class Painter {
this.context.setDefault();
}

setupOffscreenDepthRenderbuffer(): void {
const context = this.context;
// All of the 3D textures will use the same depth renderbuffer.
if (!this.depthRbo) {
this.depthRbo = context.createRenderbuffer(context.gl.DEPTH_COMPONENT16, this.width, this.height);
}
}

renderLayer(painter: Painter, sourceCache: SourceCache, layer: StyleLayer, coords: Array<OverscaledTileID>) {
if (layer.isHidden(this.transform.zoom)) return;
if (layer.type !== 'background' && layer.type !== 'custom' && !coords.length) return;
Expand Down

0 comments on commit 00d7026

Please sign in to comment.