flamegraphView.tsx 4.0 KB

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