Texture based approach WIP
This commit is contained in:
@@ -176,32 +176,6 @@ export class GLCanvas extends ReloadableComponent<GLCanvasProps, void> {
|
||||
}
|
||||
}
|
||||
|
||||
function rectangleBatchForFlamechart(canvasContext: CanvasContext, flamechart: Flamechart) {
|
||||
console.time('rectangle batch generation')
|
||||
|
||||
const batch = canvasContext.createRectangleBatch()
|
||||
|
||||
const layers = flamechart.getLayers()
|
||||
for (let i = 0; i < layers.length; i++) {
|
||||
const layer = layers[i]
|
||||
for (let flamechartFrame of layer) {
|
||||
const configSpaceBounds = new Rect(
|
||||
new Vec2(flamechartFrame.start, i + 1),
|
||||
new Vec2(flamechartFrame.end - flamechartFrame.start, 1)
|
||||
)
|
||||
const color = flamechart.getColorForFrame(flamechartFrame.node.frame)
|
||||
batch.addRect(configSpaceBounds, color)
|
||||
}
|
||||
}
|
||||
|
||||
// GPU upload
|
||||
batch.uploadToGPU()
|
||||
|
||||
console.timeEnd('rectangle batch generation')
|
||||
|
||||
return batch
|
||||
}
|
||||
|
||||
export class Application extends ReloadableComponent<{}, ApplicationState> {
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
+12
-2
@@ -1,7 +1,7 @@
|
||||
import * as regl from 'regl'
|
||||
import { RectangleBatchRenderer, RectangleBatch, RectangleBatchRendererProps } from './rectangle-batch-renderer';
|
||||
import { ViewportRectangleRenderer, ViewportRectangleRendererProps } from './overlay-rectangle-renderer';
|
||||
import { TextureCachedRenderer, TextureRenderer } from './texture-catched-renderer'
|
||||
import { TextureCachedRenderer, TextureRenderer, TextureRendererProps } from './texture-catched-renderer'
|
||||
|
||||
import { Vec2, Rect } from './math';
|
||||
|
||||
@@ -12,7 +12,7 @@ interface SetViewportScopeProps {
|
||||
}
|
||||
|
||||
export class CanvasContext {
|
||||
private gl: regl.Instance
|
||||
public gl: regl.Instance
|
||||
private rectangleBatchRenderer: RectangleBatchRenderer
|
||||
private viewportRectangleRenderer: ViewportRectangleRenderer
|
||||
private textureRenderer: TextureRenderer
|
||||
@@ -120,6 +120,12 @@ export class CanvasContext {
|
||||
this.rectangleBatchRenderer.render(props)
|
||||
}
|
||||
|
||||
drawTexture(props: TextureRendererProps) {
|
||||
this.gl({})((context: regl.Context) => {
|
||||
this.textureRenderer.render(context, props)
|
||||
})
|
||||
}
|
||||
|
||||
createRectangleBatch(): RectangleBatch {
|
||||
return new RectangleBatch(this.gl)
|
||||
}
|
||||
@@ -146,4 +152,8 @@ export class CanvasContext {
|
||||
)
|
||||
this.setViewportScope({ physicalBounds }, cb)
|
||||
}
|
||||
|
||||
getMaxTextureSize() {
|
||||
return this.gl.limits.maxTextureSize
|
||||
}
|
||||
}
|
||||
+52
-2
@@ -1,3 +1,4 @@
|
||||
import * as regl from 'regl'
|
||||
import { Flamechart } from './flamechart'
|
||||
import { RectangleBatch } from './rectangle-batch-renderer'
|
||||
import { CanvasContext } from './canvas-context';
|
||||
@@ -129,16 +130,65 @@ class BoundedLayer {
|
||||
|
||||
export class FlamechartRenderer {
|
||||
private layers: BoundedLayer[] = []
|
||||
private texture: regl.Texture | null = null
|
||||
|
||||
constructor(canvasContext: CanvasContext, flamechart: Flamechart) {
|
||||
for (let i = 0; i < flamechart.getLayers().length; i++) {
|
||||
constructor(private canvasContext: CanvasContext, flamechart: Flamechart) {
|
||||
const nLayers = flamechart.getLayers().length
|
||||
const maxTextureSize = canvasContext.getMaxTextureSize()
|
||||
|
||||
if (nLayers > maxTextureSize) {
|
||||
throw new Error(`This profile has more than ${maxTextureSize} layers!`)
|
||||
}
|
||||
|
||||
this.texture = canvasContext.gl.texture({
|
||||
width: canvasContext.getMaxTextureSize(),
|
||||
height: nLayers,
|
||||
})
|
||||
const fbo = canvasContext.gl.framebuffer({ color: [this.texture] })
|
||||
|
||||
for (let i = 0; i < nLayers; i++) {
|
||||
this.layers.push(new BoundedLayer(canvasContext, flamechart, i))
|
||||
}
|
||||
|
||||
const configSpaceToNDC = AffineTransform.withScale(new Vec2(1, -1)).times(
|
||||
AffineTransform.betweenRects(
|
||||
new Rect(new Vec2(0, 0), new Vec2(flamechart.getTotalWeight(), nLayers)),
|
||||
new Rect(new Vec2(-1, -1), new Vec2(2, 2))
|
||||
)
|
||||
)
|
||||
|
||||
canvasContext.gl({
|
||||
viewport: (context, props) => {
|
||||
return {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: canvasContext.getMaxTextureSize(),
|
||||
height: nLayers
|
||||
}
|
||||
},
|
||||
framebuffer: fbo
|
||||
})((context: regl.Context) => {
|
||||
const physicalSize = new Vec2(context.drawingBufferWidth, context.drawingBufferHeight)
|
||||
for (let layer of this.layers) {
|
||||
layer.render({ physicalSize, configSpaceToNDC })
|
||||
}
|
||||
})
|
||||
|
||||
fbo.destroy()
|
||||
}
|
||||
|
||||
render(props: FlamechartRendererProps) {
|
||||
if (!this.texture) return
|
||||
this.canvasContext.drawTexture({
|
||||
texture: this.texture,
|
||||
ndcRect: new Rect(new Vec2(-1, -1), new Vec2(2, 2)),
|
||||
uvRect: new Rect(new Vec2(0, 0), new Vec2(1, 1))
|
||||
})
|
||||
|
||||
/*
|
||||
for (let layer of this.layers) {
|
||||
layer.render(props)
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
+33
-13
@@ -1,7 +1,10 @@
|
||||
import * as regl from 'regl'
|
||||
import { Vec2, Rect } from './math'
|
||||
|
||||
export class TextureRendererProps {
|
||||
texture: regl.Texture
|
||||
ndcRect: Rect
|
||||
uvRect: Rect
|
||||
}
|
||||
|
||||
export class TextureRenderer {
|
||||
@@ -28,6 +31,11 @@ export class TextureRenderer {
|
||||
gl_FragColor = texture2D(texture, vUv);
|
||||
}
|
||||
`,
|
||||
|
||||
depth: {
|
||||
enable: false
|
||||
},
|
||||
|
||||
attributes: {
|
||||
// Cover full canvas with a rectangle
|
||||
// with 2 triangles using a triangle
|
||||
@@ -37,18 +45,26 @@ export class TextureRenderer {
|
||||
// | /|
|
||||
// |/ |
|
||||
// 2 +--+ 3
|
||||
position: [
|
||||
[-1, 1],
|
||||
[1, 1],
|
||||
[-1, -1],
|
||||
[1, -1]
|
||||
],
|
||||
uv: [
|
||||
[0, 1],
|
||||
[1, 1],
|
||||
[0, 0],
|
||||
[1, 0]
|
||||
]
|
||||
position: (context, props) => {
|
||||
const rect = props.ndcRect
|
||||
|
||||
return [
|
||||
rect.topLeft().flatten(),
|
||||
rect.topRight().flatten(),
|
||||
rect.bottomLeft().flatten(),
|
||||
rect.bottomRight().flatten()
|
||||
]
|
||||
},
|
||||
uv: (context, props) => {
|
||||
const rect = props.uvRect
|
||||
|
||||
return [
|
||||
rect.topLeft().flatten(),
|
||||
rect.topRight().flatten(),
|
||||
rect.bottomLeft().flatten(),
|
||||
rect.bottomRight().flatten()
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
uniforms: {
|
||||
@@ -132,7 +148,11 @@ export class TextureCachedRenderer<T> {
|
||||
}
|
||||
|
||||
// Render from texture
|
||||
this.textureRenderer.render(context, {texture: this.texture})
|
||||
this.textureRenderer.render(context, {
|
||||
texture: this.texture,
|
||||
ndcRect: new Rect(new Vec2(-1, -1), new Vec2(2, 2)),
|
||||
uvRect: new Rect(new Vec2(0, 0), new Vec2(1, 1))
|
||||
})
|
||||
this.lastRenderProps = props
|
||||
this.dirty = false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user