123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- import {mat3, vec2} from 'gl-matrix';
- import {FlamegraphCanvas} from 'sentry/utils/profiling/flamegraphCanvas';
- import {
- computeClampedConfigView,
- Rect,
- transformMatrixBetweenRect,
- } from 'sentry/utils/profiling/gl/utils';
- export class CanvasView<T extends {configSpace: Rect}> {
- configView: Rect = Rect.Empty();
- configSpace: Readonly<Rect> = Rect.Empty();
- configSpaceTransform: mat3 = mat3.create();
- inverted: boolean;
- minWidth: number;
- depthOffset: number;
- barHeight: number;
- model: T;
- constructor({
- canvas,
- options,
- model,
- }: {
- canvas: FlamegraphCanvas;
- model: T;
- options: {
- barHeight: number;
- configSpaceTransform?: Rect;
- depthOffset?: number;
- inverted?: boolean;
- minWidth?: number;
- };
- }) {
- this.inverted = !!options.inverted;
- this.minWidth = options.minWidth ?? 0;
- this.model = model;
- this.depthOffset = options.depthOffset ?? 0;
- this.barHeight = options.barHeight ? options.barHeight * window.devicePixelRatio : 0;
- // This is a transformation matrix that is applied to the configView, it allows us to
- // transform an entire view and render it without having to recompute the models.
- // This is useful for example when we want to offset a profile by some duration.
- this.configSpaceTransform = options.configSpaceTransform
- ? mat3.fromValues(
- options.configSpaceTransform.width || 1,
- 0,
- 0,
- 0,
- options.configSpaceTransform.height || 1,
- 0,
- options.configSpaceTransform.x || 0,
- options.configSpaceTransform.y || 0,
- 1
- )
- : mat3.create();
- this.initConfigSpace(canvas);
- }
- private _initConfigSpace(canvas: FlamegraphCanvas): void {
- this.configSpace = new Rect(
- 0,
- 0,
- this.model.configSpace.width,
- Math.max(
- this.model.configSpace.height + this.depthOffset,
- canvas.physicalSpace.height / this.barHeight
- )
- );
- }
- private _initConfigView(canvas: FlamegraphCanvas, space: Rect): void {
- this.configView = Rect.From(space).withHeight(
- canvas.physicalSpace.height / this.barHeight
- );
- }
- initConfigSpace(canvas: FlamegraphCanvas): void {
- this._initConfigSpace(canvas);
- this._initConfigView(canvas, this.configSpace);
- }
- resizeConfigSpace(canvas: FlamegraphCanvas): void {
- this._initConfigSpace(canvas);
- this._initConfigView(canvas, this.configView);
- }
- resetConfigView(canvas: FlamegraphCanvas): void {
- this._initConfigView(canvas, this.configSpace);
- }
- setConfigView(configView: Rect) {
- this.configView = computeClampedConfigView(configView, {
- width: {
- min: this.minWidth,
- max: this.configSpace.width,
- },
- height: {
- min: 0,
- max: this.configSpace.height,
- },
- });
- }
- transformConfigView(transformation: mat3) {
- this.setConfigView(this.configView.transformRect(transformation));
- }
- toConfigSpace(space: Rect): mat3 {
- const toConfigSpace = transformMatrixBetweenRect(space, this.configSpace);
- if (this.inverted) {
- mat3.multiply(toConfigSpace, this.configSpace.invertYTransform(), toConfigSpace);
- }
- return toConfigSpace;
- }
- toConfigView(space: Rect): mat3 {
- const toConfigView = transformMatrixBetweenRect(space, this.configView);
- if (this.inverted) {
- mat3.multiply(toConfigView, this.configView.invertYTransform(), toConfigView);
- }
- return toConfigView;
- }
- fromConfigSpace(space: Rect): mat3 {
- const fromConfigSpace = transformMatrixBetweenRect(this.configSpace, space);
- if (this.inverted) {
- mat3.multiply(fromConfigSpace, space.invertYTransform(), fromConfigSpace);
- }
- return fromConfigSpace;
- }
- fromConfigView(space: Rect): mat3 {
- const fromConfigView = transformMatrixBetweenRect(this.configView, space);
- if (this.inverted) {
- mat3.multiply(fromConfigView, space.invertYTransform(), fromConfigView);
- }
- return fromConfigView;
- }
- fromTransformedConfigView(space: Rect): mat3 {
- const fromConfigView = mat3.multiply(
- mat3.create(),
- transformMatrixBetweenRect(this.configView, space),
- this.configSpaceTransform
- );
- if (this.inverted) {
- mat3.multiply(fromConfigView, space.invertYTransform(), fromConfigView);
- }
- return fromConfigView;
- }
- fromTransformedConfigSpace(space: Rect): mat3 {
- const fromConfigView = mat3.multiply(
- mat3.create(),
- transformMatrixBetweenRect(this.configSpace, space),
- this.configSpaceTransform
- );
- if (this.inverted) {
- mat3.multiply(fromConfigView, space.invertYTransform(), fromConfigView);
- }
- return fromConfigView;
- }
- getConfigSpaceCursor(logicalSpaceCursor: vec2, canvas: FlamegraphCanvas): vec2 {
- const physicalSpaceCursor = vec2.transformMat3(
- vec2.create(),
- logicalSpaceCursor,
- canvas.logicalToPhysicalSpace
- );
- return vec2.transformMat3(
- vec2.create(),
- physicalSpaceCursor,
- this.toConfigSpace(canvas.physicalSpace)
- );
- }
- getTransformedConfigSpaceCursor(
- logicalSpaceCursor: vec2,
- canvas: FlamegraphCanvas
- ): vec2 {
- const physicalSpaceCursor = vec2.transformMat3(
- vec2.create(),
- logicalSpaceCursor,
- canvas.logicalToPhysicalSpace
- );
- const finalMatrix = mat3.multiply(
- mat3.create(),
- mat3.invert(mat3.create(), this.configSpaceTransform),
- this.toConfigSpace(canvas.physicalSpace)
- );
- const configViewCursor = vec2.transformMat3(
- vec2.create(),
- physicalSpaceCursor,
- finalMatrix
- );
- return configViewCursor;
- }
- getConfigViewCursor(logicalSpaceCursor: vec2, canvas: FlamegraphCanvas): vec2 {
- const physicalSpaceCursor = vec2.transformMat3(
- vec2.create(),
- logicalSpaceCursor,
- canvas.logicalToPhysicalSpace
- );
- return vec2.transformMat3(
- vec2.create(),
- physicalSpaceCursor,
- this.toConfigView(canvas.physicalSpace)
- );
- }
- getTransformedConfigViewCursor(
- logicalSpaceCursor: vec2,
- canvas: FlamegraphCanvas
- ): vec2 {
- const physicalSpaceCursor = vec2.transformMat3(
- vec2.create(),
- logicalSpaceCursor,
- canvas.logicalToPhysicalSpace
- );
- const finalMatrix = mat3.multiply(
- mat3.create(),
- mat3.invert(mat3.create(), this.configSpaceTransform),
- this.toConfigView(canvas.physicalSpace)
- );
- const configViewCursor = vec2.transformMat3(
- vec2.create(),
- physicalSpaceCursor,
- finalMatrix
- );
- return configViewCursor;
- }
- /**
- * Applies the inverse of the config space transform to the given config space rect
- * @returns Rect
- */
- toOriginConfigView(space: Rect): Rect {
- return space.transformRect(mat3.invert(mat3.create(), this.configSpaceTransform));
- }
- }
|