Skip to content

Commit ab93105

Browse files
paulirishDevtools-frontend LUCI CQ
authored andcommitted
RPP: Use readWillFrequently on more canvases
Additionally, cache our canvasPatterns to avoid repeated calls of createPattern. Thx https://crrev.com/c/6425762 for the FYI. Change-Id: I68a1d2fa6fa439f257a24e1aa15e2f622f708fbd Bug: none Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6431355 Auto-Submit: Paul Irish <[email protected]> Reviewed-by: Connor Clark <[email protected]> Commit-Queue: Connor Clark <[email protected]>
1 parent 3a5823d commit ab93105

File tree

4 files changed

+47
-53
lines changed

4 files changed

+47
-53
lines changed

front_end/panels/screencast/ScreencastView.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ export class ScreencastView extends UI.Widget.VBox implements SDK.OverlayModel.H
660660
const size = 32;
661661
pattern.width = size * 2;
662662
pattern.height = size * 2;
663-
const pctx = pattern.getContext('2d') as CanvasRenderingContext2D;
663+
const pctx = pattern.getContext('2d', {willReadFrequently: true}) as CanvasRenderingContext2D;
664664

665665
pctx.fillStyle = 'var(--sys-color-neutral-outline)';
666666
pctx.fillRect(0, 0, size * 2, size * 2);

front_end/panels/timeline/TimelineFlameChartDataProvider.ts

Lines changed: 37 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2828
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2929
*/
30+
/* eslint-disable rulesdir/no-imperative-dom-api */
3031

3132
import * as Common from '../../core/common/common.js';
3233
import * as i18n from '../../core/i18n/i18n.js';
@@ -106,8 +107,8 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
106107

107108
export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectWrapper<EventTypes> implements
108109
PerfUI.FlameChart.FlameChartDataProvider {
109-
private droppedFramePatternCanvas: HTMLCanvasElement;
110-
private partialFramePatternCanvas: HTMLCanvasElement;
110+
private droppedFramePattern: CanvasPattern|null;
111+
private partialFramePattern: CanvasPattern|null;
111112
private timelineDataInternal: PerfUI.FlameChart.FlameChartTimelineData|null = null;
112113
private currentLevel = 0;
113114

@@ -150,9 +151,7 @@ export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectW
150151
super();
151152
this.reset();
152153

153-
this.droppedFramePatternCanvas = document.createElement('canvas');
154-
this.partialFramePatternCanvas = document.createElement('canvas');
155-
this.preparePatternCanvas();
154+
[this.droppedFramePattern, this.partialFramePattern] = this.preparePatternCanvas();
156155

157156
this.framesGroupStyle = this.buildGroupStyle({useFirstLineForOverview: true});
158157
this.screenshotsGroupStyle =
@@ -900,40 +899,38 @@ export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectW
900899
return '';
901900
}
902901

903-
private preparePatternCanvas(): void {
902+
private preparePatternCanvas(): Array<CanvasPattern|null> {
904903
// Set the candy stripe pattern to 17px so it repeats well.
905904
const size = 17;
906-
this.droppedFramePatternCanvas.width = size;
907-
this.droppedFramePatternCanvas.height = size;
908-
909-
this.partialFramePatternCanvas.width = size;
910-
this.partialFramePatternCanvas.height = size;
911-
912-
const ctx = this.droppedFramePatternCanvas.getContext('2d');
913-
if (ctx) {
914-
// Make a dense solid-line pattern.
915-
ctx.translate(size * 0.5, size * 0.5);
916-
ctx.rotate(Math.PI * 0.25);
917-
ctx.translate(-size * 0.5, -size * 0.5);
918-
919-
ctx.fillStyle = 'rgb(255, 255, 255)';
920-
for (let x = -size; x < size * 2; x += 3) {
921-
ctx.fillRect(x, -size, 1, size * 3);
922-
}
923-
}
924-
925-
const ctx2 = this.partialFramePatternCanvas.getContext('2d');
926-
if (ctx2) {
927-
// Make a sparse dashed-line pattern.
928-
ctx2.strokeStyle = 'rgb(255, 255, 255)';
929-
ctx2.lineWidth = 2;
930-
ctx2.beginPath();
931-
ctx2.moveTo(17, 0);
932-
ctx2.lineTo(10, 7);
933-
ctx2.moveTo(8, 9);
934-
ctx2.lineTo(2, 15);
935-
ctx2.stroke();
936-
}
905+
const droppedFrameCanvas = document.createElement('canvas');
906+
const partialFrameCanvas = document.createElement('canvas');
907+
droppedFrameCanvas.width = droppedFrameCanvas.height = size;
908+
partialFrameCanvas.width = partialFrameCanvas.height = size;
909+
910+
const ctx = droppedFrameCanvas.getContext('2d', {willReadFrequently: true}) as CanvasRenderingContext2D;
911+
// Make a dense solid-line pattern.
912+
ctx.translate(size * 0.5, size * 0.5);
913+
ctx.rotate(Math.PI * 0.25);
914+
ctx.translate(-size * 0.5, -size * 0.5);
915+
916+
ctx.fillStyle = 'rgb(255, 255, 255)';
917+
for (let x = -size; x < size * 2; x += 3) {
918+
ctx.fillRect(x, -size, 1, size * 3);
919+
}
920+
const droppedFramePattern = ctx.createPattern(droppedFrameCanvas, 'repeat');
921+
922+
const ctx2 = partialFrameCanvas.getContext('2d', {willReadFrequently: true}) as CanvasRenderingContext2D;
923+
// Make a sparse dashed-line pattern.
924+
ctx2.strokeStyle = 'rgb(255, 255, 255)';
925+
ctx2.lineWidth = 2;
926+
ctx2.beginPath();
927+
ctx2.moveTo(17, 0);
928+
ctx2.lineTo(10, 7);
929+
ctx2.moveTo(8, 9);
930+
ctx2.lineTo(2, 15);
931+
ctx2.stroke();
932+
const partialFramePattern = ctx.createPattern(partialFrameCanvas, 'repeat');
933+
return [droppedFramePattern, partialFramePattern];
937934
}
938935

939936
private drawFrame(
@@ -946,20 +943,15 @@ export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectW
946943
context.fillStyle = transformColor(this.entryColor(entryIndex));
947944

948945
if (frame.dropped) {
946+
context.fillRect(barX, barY, barWidth, barHeight);
949947
if (frame.isPartial) {
950948
// For partially presented frame boxes, paint a yellow background with
951949
// a sparse white dashed-line pattern overlay.
952-
context.fillRect(barX, barY, barWidth, barHeight);
953-
954-
const overlay = context.createPattern(this.partialFramePatternCanvas, 'repeat');
955-
context.fillStyle = overlay || context.fillStyle;
950+
context.fillStyle = this.partialFramePattern || context.fillStyle;
956951
} else {
957952
// For dropped frame boxes, paint a red background with a dense white
958953
// solid-line pattern overlay.
959-
context.fillRect(barX, barY, barWidth, barHeight);
960-
961-
const overlay = context.createPattern(this.droppedFramePatternCanvas, 'repeat');
962-
context.fillStyle = overlay || context.fillStyle;
954+
context.fillStyle = this.droppedFramePattern || context.fillStyle;
963955
}
964956
}
965957
context.fillRect(barX, barY, barWidth, barHeight);

front_end/ui/legacy/components/perf_ui/FlameChart.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
269269
private contextMenu?: UI.ContextMenu.ContextMenu;
270270
private viewportElement: HTMLElement;
271271
private canvas: HTMLCanvasElement;
272+
private context: CanvasRenderingContext2D;
272273
private popoverElement: HTMLElement;
273274
private readonly markerHighlighElement: HTMLElement;
274275
readonly highlightElement: HTMLElement;
@@ -367,6 +368,7 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
367368

368369
this.viewportElement = this.chartViewport.viewportElement;
369370
this.canvas = this.viewportElement.createChild('canvas', 'fill');
371+
this.context = this.canvas.getContext('2d') as CanvasRenderingContext2D;
370372
this.candyStripePattern = this.candyStripePatternGray = null;
371373

372374
this.canvas.tabIndex = 0;
@@ -619,7 +621,7 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
619621
const candyStripeCanvas = document.createElement('canvas');
620622
candyStripeCanvas.width = size;
621623
candyStripeCanvas.height = size;
622-
const ctx = candyStripeCanvas.getContext('2d') as CanvasRenderingContext2D;
624+
const ctx = candyStripeCanvas.getContext('2d', {willReadFrequently: true}) as CanvasRenderingContext2D;
623625

624626
// Rotate the stripe by 45deg to the right.
625627
ctx.translate(size * 0.5, size * 0.5);
@@ -2071,7 +2073,7 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
20712073
if (y >= this.groupOffsets[groupIndex] && y < this.groupOffsets[nextIndex]) {
20722074
// This section is used to calculate the position of current group's header
20732075
// If we are in edit mode, the track label is pushed right to make room for the icons.
2074-
const context = (this.canvas.getContext('2d') as CanvasRenderingContext2D);
2076+
const context = this.context;
20752077
context.save();
20762078
context.font = this.#font;
20772079
const headerRight = HEADER_LEFT_PADDING + (this.#inTrackConfigEditMode ? EDIT_MODE_TOTAL_ICON_WIDTH : 0) +
@@ -2191,7 +2193,7 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
21912193
});
21922194
const canvasWidth = this.offsetWidth;
21932195
const canvasHeight = this.offsetHeight;
2194-
const context = (this.canvas.getContext('2d') as CanvasRenderingContext2D);
2196+
const context = this.context;
21952197

21962198
context.save();
21972199
const ratio = window.devicePixelRatio;
@@ -2657,7 +2659,7 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
26572659
* there is no group being hovered.
26582660
*/
26592661
private drawGroupHeaders(width: number, height: number): void {
2660-
const context = (this.canvas.getContext('2d') as CanvasRenderingContext2D);
2662+
const context = this.context;
26612663
const top = this.chartViewport.scrollOffset();
26622664
const ratio = window.devicePixelRatio;
26632665
if (!this.rawTimelineData) {
@@ -3091,7 +3093,7 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
30913093
const range = new Common.SegmentedRange.SegmentedRange<string>(mergeCallback);
30923094
const timeWindowLeft = this.chartViewport.windowLeftTime();
30933095
const timeWindowRight = this.chartViewport.windowRightTime();
3094-
const context = (this.canvas.getContext('2d') as CanvasRenderingContext2D);
3096+
const context = this.context;
30953097
const groupBarHeight = group.style.height;
30963098
if (!this.rawTimelineData) {
30973099
return;
@@ -3326,7 +3328,7 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
33263328
const rightBoundary = this.maximumBoundary();
33273329
const timeToPixel = this.chartViewport.timeToPixel();
33283330

3329-
const context = (this.canvas.getContext('2d') as CanvasRenderingContext2D);
3331+
const context = this.context;
33303332
context.save();
33313333
const ratio = window.devicePixelRatio;
33323334
context.scale(ratio, ratio);

inspector_overlay/highlight_common.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ export function hatchFillPath(
206206
offscreenCanvas.width = delta;
207207
offscreenCanvas.height = HATCH_LINE_LENGTH + HATCH_LINE_GAP;
208208

209-
const offscreenCtx = offscreenCanvas.getContext('2d') as CanvasRenderingContext2D;
209+
const offscreenCtx = offscreenCanvas.getContext('2d', {willReadFrequently: true}) as CanvasRenderingContext2D;
210210
offscreenCtx.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
211211
offscreenCtx.rect(0, 0, 1, HATCH_LINE_LENGTH);
212212
offscreenCtx.fillStyle = color;

0 commit comments

Comments
 (0)