Files
SpeedScope/overlay-rectangle-renderer.ts
Alan Pierce 404aacfa46 Address review comments
* Switch to `bracketSpacing: false`.
* Add prettier-ignore in one case.
2018-04-14 16:19:26 -07:00

127 lines
3.6 KiB
TypeScript

import regl from 'regl'
import {AffineTransform, Rect} from './math'
export interface ViewportRectangleRendererProps {
configSpaceToPhysicalViewSpace: AffineTransform
configSpaceViewportRect: Rect
}
export class ViewportRectangleRenderer {
private command: regl.Command<ViewportRectangleRendererProps>
constructor(regl: regl.Instance) {
this.command = regl<ViewportRectangleRendererProps>({
vert: `
attribute vec2 position;
void main() {
gl_Position = vec4(position, 0, 1);
}
`,
frag: `
precision mediump float;
uniform mat3 configSpaceToPhysicalViewSpace;
uniform vec2 physicalSize;
uniform vec2 physicalOrigin;
uniform vec2 configSpaceViewportOrigin;
uniform vec2 configSpaceViewportSize;
uniform float framebufferHeight;
void main() {
vec2 origin = (configSpaceToPhysicalViewSpace * vec3(configSpaceViewportOrigin, 1.0)).xy;
vec2 size = (configSpaceToPhysicalViewSpace * vec3(configSpaceViewportSize, 0.0)).xy;
vec2 halfSize = physicalSize / 2.0;
float borderWidth = 2.0;
origin = floor(origin * halfSize) / halfSize + borderWidth * vec2(1.0, 1.0);
size = floor(size * halfSize) / halfSize - 2.0 * borderWidth * vec2(1.0, 1.0);
vec2 coord = gl_FragCoord.xy;
coord.x = coord.x - physicalOrigin.x;
coord.y = framebufferHeight - coord.y - physicalOrigin.y;
vec2 clamped = clamp(coord, origin, origin + size);
vec2 gap = clamped - coord;
float maxdist = max(abs(gap.x), abs(gap.y));
// TOOD(jlfwong): Could probably optimize this to use mix somehow.
if (maxdist == 0.0) {
// Inside viewport rectangle
gl_FragColor = vec4(0, 0, 0, 0);
} else if (maxdist < borderWidth) {
// Inside viewport rectangle at border
gl_FragColor = vec4(0.7, 0.7, 0.7, 0.8);
} else {
// Outside viewport rectangle
gl_FragColor = vec4(0.7, 0.7, 0.7, 0.5);
}
}
`,
blend: {
enable: true,
func: {
srcRGB: 'src alpha',
srcAlpha: 'one',
dstRGB: 'one minus src alpha',
dstAlpha: 'one',
},
},
depth: {
enable: false,
},
attributes: {
// Cover full canvas with a rectangle
// with 2 triangles using a triangle
// strip.
//
// 0 +--+ 1
// | /|
// |/ |
// 2 +--+ 3
position: [[-1, 1], [1, 1], [-1, -1], [1, -1]],
},
uniforms: {
configSpaceToPhysicalViewSpace: (context, props) => {
return props.configSpaceToPhysicalViewSpace.flatten()
},
configSpaceViewportOrigin: (context, props) => {
return props.configSpaceViewportRect.origin.flatten()
},
configSpaceViewportSize: (context, props) => {
return props.configSpaceViewportRect.size.flatten()
},
physicalSize: (context, props) => {
return [context.viewportWidth, context.viewportHeight]
},
physicalOrigin: (context, props) => {
return [context.viewportX, context.viewportY]
},
framebufferHeight: (context, props) => {
return context.framebufferHeight
},
},
primitive: 'triangle strip',
count: 4,
})
}
render(props: ViewportRectangleRendererProps) {
this.command(props)
}
resetStats() {
return Object.assign(this.command.stats, {cpuTime: 0, gpuTime: 0, count: 0})
}
stats() {
return this.command.stats
}
}