flamegraphView.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import {mat3, vec2} from 'gl-matrix';
  2. import {Flamegraph} from 'sentry/utils/profiling/flamegraph';
  3. import {FlamegraphTheme} from 'sentry/utils/profiling/flamegraph/flamegraphTheme';
  4. import {FlamegraphCanvas} from 'sentry/utils/profiling/flamegraphCanvas';
  5. import {computeClampedConfigView, Rect, Transform} from 'sentry/utils/profiling/gl/utils';
  6. export class FlamegraphView {
  7. flamegraph: Flamegraph;
  8. theme: FlamegraphTheme;
  9. configView: Rect = Rect.Empty();
  10. configSpace: Rect = Rect.Empty();
  11. constructor({
  12. canvas,
  13. flamegraph,
  14. theme,
  15. }: {
  16. canvas: FlamegraphCanvas;
  17. flamegraph: Flamegraph;
  18. theme: FlamegraphTheme;
  19. }) {
  20. this.flamegraph = flamegraph;
  21. this.theme = theme;
  22. this.initConfigSpace(canvas);
  23. }
  24. private _initConfigSpace(canvas: FlamegraphCanvas): void {
  25. const BAR_HEIGHT = this.theme.SIZES.BAR_HEIGHT * window.devicePixelRatio;
  26. this.configSpace = new Rect(
  27. 0,
  28. 0,
  29. this.flamegraph.configSpace.width,
  30. Math.max(
  31. this.flamegraph.depth + this.theme.SIZES.FLAMEGRAPH_DEPTH_OFFSET + 1,
  32. canvas.physicalSpace.height / BAR_HEIGHT
  33. )
  34. );
  35. }
  36. private _initConfigView(canvas: FlamegraphCanvas, space: Rect): void {
  37. const BAR_HEIGHT = this.theme.SIZES.BAR_HEIGHT * window.devicePixelRatio;
  38. this.configView = Rect.From(space).withHeight(
  39. canvas.physicalSpace.height / BAR_HEIGHT
  40. );
  41. }
  42. initConfigSpace(canvas: FlamegraphCanvas): void {
  43. this._initConfigSpace(canvas);
  44. this._initConfigView(canvas, this.configSpace);
  45. }
  46. resizeConfigSpace(canvas: FlamegraphCanvas): void {
  47. this._initConfigSpace(canvas);
  48. this._initConfigView(canvas, this.configView);
  49. }
  50. resetConfigView(canvas: FlamegraphCanvas): void {
  51. this._initConfigView(canvas, this.configSpace);
  52. }
  53. setConfigView(configView: Rect) {
  54. this.configView = computeClampedConfigView(configView, {
  55. width: {
  56. min: this.flamegraph.profile.minFrameDuration,
  57. max: this.configSpace.width,
  58. },
  59. height: {
  60. min: 0,
  61. max: this.configSpace.height,
  62. },
  63. });
  64. }
  65. transformConfigView(transformation: mat3) {
  66. this.setConfigView(this.configView.transformRect(transformation));
  67. }
  68. toConfigSpace(space: Rect): mat3 {
  69. const toConfigSpace = Transform.transformMatrixBetweenRect(space, this.configSpace);
  70. if (this.flamegraph.inverted) {
  71. mat3.multiply(toConfigSpace, this.configSpace.invertYTransform(), toConfigSpace);
  72. }
  73. return toConfigSpace;
  74. }
  75. toConfigView(space: Rect): mat3 {
  76. const toConfigView = Transform.transformMatrixBetweenRect(space, this.configView);
  77. if (this.flamegraph.inverted) {
  78. mat3.multiply(toConfigView, this.configView.invertYTransform(), toConfigView);
  79. }
  80. return toConfigView;
  81. }
  82. fromConfigSpace(space: Rect): mat3 {
  83. const fromConfigSpace = Transform.transformMatrixBetweenRect(this.configSpace, space);
  84. if (this.flamegraph.inverted) {
  85. mat3.multiply(fromConfigSpace, space.invertYTransform(), fromConfigSpace);
  86. }
  87. return fromConfigSpace;
  88. }
  89. fromConfigView(space: Rect): mat3 {
  90. const fromConfigView = Transform.transformMatrixBetweenRect(this.configView, space);
  91. if (this.flamegraph.inverted) {
  92. mat3.multiply(fromConfigView, space.invertYTransform(), fromConfigView);
  93. }
  94. return fromConfigView;
  95. }
  96. getConfigSpaceCursor(logicalSpaceCursor: vec2, canvas: FlamegraphCanvas): vec2 {
  97. const physicalSpaceCursor = vec2.transformMat3(
  98. vec2.create(),
  99. logicalSpaceCursor,
  100. canvas.logicalToPhysicalSpace
  101. );
  102. return vec2.transformMat3(
  103. vec2.create(),
  104. physicalSpaceCursor,
  105. this.toConfigSpace(canvas.physicalSpace)
  106. );
  107. }
  108. getConfigViewCursor(logicalSpaceCursor: vec2, canvas: FlamegraphCanvas): vec2 {
  109. const physicalSpaceCursor = vec2.transformMat3(
  110. vec2.create(),
  111. logicalSpaceCursor,
  112. canvas.logicalToPhysicalSpace
  113. );
  114. return vec2.transformMat3(
  115. vec2.create(),
  116. physicalSpaceCursor,
  117. this.toConfigView(canvas.physicalSpace)
  118. );
  119. }
  120. }