Commit b0a27025 authored by Alexei Filippov's avatar Alexei Filippov Committed by Commit Bot

DevTools: Cache parsed colors to speedup flamechart GL geometry setup.

Color.parse is quite expensive, resulted in 7 seconds wait for a million entries.
We can just cache parsed colors provided there are just few dozens of them.

Also move gl.get* operations out of the main draw routine as they known to be expensive.

BUG=874116

Change-Id: I6b02210a1dd1d2b9e8ef9d9931ee3eebd0087872
Reviewed-on: https://chromium-review.googlesource.com/1178579Reviewed-by: default avatarAleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#583797}
parent d1671644
...@@ -940,6 +940,8 @@ PerfUI.FlameChart = class extends UI.VBox { ...@@ -940,6 +940,8 @@ PerfUI.FlameChart = class extends UI.VBox {
// 2 triangles x 3 points x 4 color values (RGBA) = 24. // 2 triangles x 3 points x 4 color values (RGBA) = 24.
const colorArray = new Uint8Array(entryTotalTimes.length * 24); const colorArray = new Uint8Array(entryTotalTimes.length * 24);
let vertex = 0; let vertex = 0;
/** @type {!Map<string, !Array<number>>} */
const parsedColorCache = new Map();
for (let i = 0; i < entryTotalTimes.length; ++i) { for (let i = 0; i < entryTotalTimes.length; ++i) {
const level = entryLevels[i]; const level = entryLevels[i];
if (!this._visibleLevels[level]) if (!this._visibleLevels[level])
...@@ -947,11 +949,19 @@ PerfUI.FlameChart = class extends UI.VBox { ...@@ -947,11 +949,19 @@ PerfUI.FlameChart = class extends UI.VBox {
const color = this._dataProvider.entryColor(i); const color = this._dataProvider.entryColor(i);
if (!color) if (!color)
continue; continue;
const rgba = Common.Color.parse(color).canonicalRGBA(); let rgba = parsedColorCache.get(color);
rgba[3] = Math.round(rgba[3] * 255); if (!rgba) {
rgba = Common.Color.parse(color).canonicalRGBA();
rgba[3] = Math.round(rgba[3] * 255);
parsedColorCache.set(color, rgba);
}
const cpos = vertex * 4; const cpos = vertex * 4;
for (let j = 0; j < 6; ++j) // All of the bar vertices have the same color. for (let j = 0; j < 6; ++j) { // All of the bar vertices have the same color.
colorArray.set(rgba, cpos + j * 4); colorArray[cpos + j * 4 + 0] = rgba[0];
colorArray[cpos + j * 4 + 1] = rgba[1];
colorArray[cpos + j * 4 + 2] = rgba[2];
colorArray[cpos + j * 4 + 3] = rgba[3];
}
const vpos = vertex * 2; const vpos = vertex * 2;
const x0 = entryStartTimes[i] - this._minimumBoundary; const x0 = entryStartTimes[i] - this._minimumBoundary;
...@@ -989,40 +999,35 @@ PerfUI.FlameChart = class extends UI.VBox { ...@@ -989,40 +999,35 @@ PerfUI.FlameChart = class extends UI.VBox {
const aVertexColor = gl.getAttribLocation(this._shaderProgram, 'aVertexColor'); const aVertexColor = gl.getAttribLocation(this._shaderProgram, 'aVertexColor');
gl.enableVertexAttribArray(aVertexColor); gl.enableVertexAttribArray(aVertexColor);
gl.vertexAttribPointer(aVertexColor, /* colorComponents*/ 4, gl.UNSIGNED_BYTE, true, 0, 0); gl.vertexAttribPointer(aVertexColor, /* colorComponents*/ 4, gl.UNSIGNED_BYTE, true, 0, 0);
this._uScalingFactor = gl.getUniformLocation(this._shaderProgram, 'uScalingFactor');
this._uShiftVector = gl.getUniformLocation(this._shaderProgram, 'uShiftVector');
} }
_drawGL() { _drawGL() {
const gl = /** @type {?WebGLRenderingContext} */ (this._canvasGL.getContext('webgl')); const gl = /** @type {?WebGLRenderingContext} */ (this._canvasGL.getContext('webgl'));
if (!gl) if (!gl)
return; return;
const timelineData = this._timelineData(); const timelineData = this._timelineData();
if (!timelineData) if (!timelineData)
return; return;
const width = this._canvasGL.width;
const height = this._canvasGL.height;
if (!this._prevTimelineData || timelineData.entryTotalTimes !== this._prevTimelineData.entryTotalTimes) { if (!this._prevTimelineData || timelineData.entryTotalTimes !== this._prevTimelineData.entryTotalTimes) {
this._prevTimelineData = timelineData; this._prevTimelineData = timelineData;
this._setupGLGeometry(); this._setupGLGeometry();
} }
const viewportScale = [2.0 / this.boundarySpan(), -2.0 * window.devicePixelRatio / height]; gl.viewport(0, 0, this._canvasGL.width, this._canvasGL.height);
const viewportShift = [this.minimumBoundary() - this.zeroTime(), this._chartViewport.scrollOffset()];
gl.viewport(0, 0, width, height);
gl.clearColor(1.0, 1.0, 1.0, 1.0); gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT); gl.clear(gl.COLOR_BUFFER_BIT);
if (!this._vertexCount) if (!this._vertexCount)
return; return;
const uScalingFactor = gl.getUniformLocation(this._shaderProgram, 'uScalingFactor'); const viewportScale = [2.0 / this.boundarySpan(), -2.0 * window.devicePixelRatio / this._canvasGL.height];
const uShiftVector = gl.getUniformLocation(this._shaderProgram, 'uShiftVector'); const viewportShift = [this.minimumBoundary() - this.zeroTime(), this._chartViewport.scrollOffset()];
gl.uniform2fv(this._uScalingFactor, viewportScale);
gl.uniform2fv(uScalingFactor, viewportScale); gl.uniform2fv(this._uShiftVector, viewportShift);
gl.uniform2fv(uShiftVector, viewportShift);
gl.drawArrays(gl.TRIANGLES, 0, this._vertexCount); gl.drawArrays(gl.TRIANGLES, 0, this._vertexCount);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment