Use faster pixel check method with caching
This commit is contained in:
@@ -4,9 +4,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
import test from '@playwright/test';
|
import test, { LocatorScreenshotOptions } from '@playwright/test';
|
||||||
import { ITheme } from 'xterm';
|
import { ITheme } from 'xterm';
|
||||||
import { ITestContext, createTestContext, openTerminal, pollFor } from '../../../out-test/playwright/TestUtils';
|
import { ITestContext, MaybeAsync, createTestContext, openTerminal, pollFor } from '../../../out-test/playwright/TestUtils';
|
||||||
|
import { IImage32, decodePng } from '@lunapaint/png-codec';
|
||||||
|
|
||||||
let ctx: ITestContext;
|
let ctx: ITestContext;
|
||||||
test.beforeAll(async ({ browser }) => {
|
test.beforeAll(async ({ browser }) => {
|
||||||
@@ -28,7 +29,7 @@ test.describe.only('WebGL Renderer Integration Tests', async () => {
|
|||||||
`);
|
`);
|
||||||
// TODO: Introduce frame caching
|
// TODO: Introduce frame caching
|
||||||
// Clear the cached screenshot before each test
|
// Clear the cached screenshot before each test
|
||||||
// frameDetails = undefined;
|
frameDetails = undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose removes renderer canvases', async function(): Promise<void> {
|
test('dispose removes renderer canvases', async function(): Promise<void> {
|
||||||
@@ -792,6 +793,7 @@ test.describe.only('WebGL Renderer Integration Tests', async () => {
|
|||||||
// exact to the contrast ratio, if the increase luminance algorithm
|
// exact to the contrast ratio, if the increase luminance algorithm
|
||||||
// changes then these will probably fail
|
// changes then these will probably fail
|
||||||
await ctx.page.evaluate(`window.term.options.minimumContrastRatio = 10;`);
|
await ctx.page.evaluate(`window.term.options.minimumContrastRatio = 10;`);
|
||||||
|
frameDetails = undefined;
|
||||||
await pollFor(ctx.page, () => getCellColor(1, 1), [176, 180, 180, 255]);
|
await pollFor(ctx.page, () => getCellColor(1, 1), [176, 180, 180, 255]);
|
||||||
await pollFor(ctx.page, () => getCellColor(2, 1), [238, 158, 158, 255]);
|
await pollFor(ctx.page, () => getCellColor(2, 1), [238, 158, 158, 255]);
|
||||||
await pollFor(ctx.page, () => getCellColor(3, 1), [152, 198, 110, 255]);
|
await pollFor(ctx.page, () => getCellColor(3, 1), [152, 198, 110, 255]);
|
||||||
@@ -861,6 +863,7 @@ test.describe.only('WebGL Renderer Integration Tests', async () => {
|
|||||||
// exact to the contrast ratio, if the increase luminance algorithm
|
// exact to the contrast ratio, if the increase luminance algorithm
|
||||||
// changes then these will probably fail
|
// changes then these will probably fail
|
||||||
await ctx.page.evaluate(`window.term.options.minimumContrastRatio = 10;`);
|
await ctx.page.evaluate(`window.term.options.minimumContrastRatio = 10;`);
|
||||||
|
frameDetails = undefined;
|
||||||
await pollFor(ctx.page, () => getCellColor(1, 1), [46, 52, 54, 255]);
|
await pollFor(ctx.page, () => getCellColor(1, 1), [46, 52, 54, 255]);
|
||||||
await pollFor(ctx.page, () => getCellColor(2, 1), [132, 0, 0, 255]);
|
await pollFor(ctx.page, () => getCellColor(2, 1), [132, 0, 0, 255]);
|
||||||
await pollFor(ctx.page, () => getCellColor(3, 1), [36, 72, 0, 255]);
|
await pollFor(ctx.page, () => getCellColor(3, 1), [36, 72, 0, 255]);
|
||||||
@@ -935,6 +938,7 @@ test.describe.only('WebGL Renderer Integration Tests', async () => {
|
|||||||
// exact to the contrast ratio, if the increase luminance algorithm
|
// exact to the contrast ratio, if the increase luminance algorithm
|
||||||
// changes then these will probably fail
|
// changes then these will probably fail
|
||||||
await ctx.page.evaluate(`window.term.options.minimumContrastRatio = 10;`);
|
await ctx.page.evaluate(`window.term.options.minimumContrastRatio = 10;`);
|
||||||
|
frameDetails = undefined;
|
||||||
await pollFor(ctx.page, () => getCellColor(1, 1), [150, 153, 154, 255]);
|
await pollFor(ctx.page, () => getCellColor(1, 1), [150, 153, 154, 255]);
|
||||||
await pollFor(ctx.page, () => getCellColor(2, 1), [229, 127, 127, 255]);
|
await pollFor(ctx.page, () => getCellColor(2, 1), [229, 127, 127, 255]);
|
||||||
await pollFor(ctx.page, () => getCellColor(3, 1), [63, 124, 4, 255]);
|
await pollFor(ctx.page, () => getCellColor(3, 1), [63, 124, 4, 255]);
|
||||||
@@ -967,6 +971,7 @@ test.describe.only('WebGL Renderer Integration Tests', async () => {
|
|||||||
await pollFor(ctx.page, () => getCellColor(2, 1), [255, 0, 0, 255]);
|
await pollFor(ctx.page, () => getCellColor(2, 1), [255, 0, 0, 255]);
|
||||||
await pollFor(ctx.page, () => getCellColor(3, 1), [0, 255, 0, 255]);
|
await pollFor(ctx.page, () => getCellColor(3, 1), [0, 255, 0, 255]);
|
||||||
await ctx.page.evaluate(`window.term.selectAll()`);
|
await ctx.page.evaluate(`window.term.selectAll()`);
|
||||||
|
frameDetails = undefined;
|
||||||
// Selection only cell needs to be first to ensure renderer has kicked in
|
// Selection only cell needs to be first to ensure renderer has kicked in
|
||||||
await pollFor(ctx.page, () => getCellColor(1, 1), [0, 0, 255, 255]);
|
await pollFor(ctx.page, () => getCellColor(1, 1), [0, 0, 255, 255]);
|
||||||
await pollFor(ctx.page, () => getCellColor(2, 1), [255, 0, 0, 255]);
|
await pollFor(ctx.page, () => getCellColor(2, 1), [255, 0, 0, 255]);
|
||||||
@@ -1086,33 +1091,40 @@ test.describe.only('WebGL Renderer Integration Tests', async () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
async function getCellColor(col: number, row: number): Promise<number[]> {
|
/**
|
||||||
await ctx.page.evaluate(`
|
* Gets the color of the pixel in the center of a cell.
|
||||||
window.gl = window.term._core._renderService._renderer.value._gl;
|
* @param col The 1-based column index to get the color for.
|
||||||
window.result = new Uint8Array(4);
|
* @param row The 1-based row index to get the color for.
|
||||||
window.d = window.term._core._renderService.dimensions;
|
*/
|
||||||
window.gl.readPixels(
|
function getCellColor(col: number, row: number): MaybeAsync<[red: number, green: number, blue: number, alpha: number]> {
|
||||||
Math.floor((${col - 0.5}) * window.d.device.cell.width),
|
if (!frameDetails) {
|
||||||
Math.floor(window.gl.drawingBufferHeight - 1 - (${row - 0.5}) * window.d.device.cell.height),
|
return getFrameDetails().then(frameDetails => getCellColorInner(frameDetails, col, row));
|
||||||
1, 1, window.gl.RGBA, window.gl.UNSIGNED_BYTE, window.result
|
}
|
||||||
);
|
return getCellColorInner(frameDetails, col, row);
|
||||||
`);
|
|
||||||
return await ctx.page.evaluate(`Array.from(window.result)`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// async function getCellPixels(col: number, row: number): Promise<number[]> {
|
let frameDetails: { cols: number, rows: number, decoded: IImage32 } | undefined = undefined;
|
||||||
// await ctx.page.evaluate(`
|
async function getFrameDetails(): Promise<{ cols: number, rows: number, decoded: IImage32 }> {
|
||||||
// window.gl = window.term._core._renderService._renderer.value._gl;
|
const screenshotOptions: LocatorScreenshotOptions | undefined = process.env.DEBUG ? { path: 'out-test/playwright/screenshot.png' } : undefined;
|
||||||
// window.result = new Uint8Array(window.d.device.cell.width * window.d.device.cell.height * 4);
|
const buffer = await ctx.page.locator('#terminal-container .xterm-screen').screenshot(screenshotOptions);
|
||||||
// window.d = window.term._core._renderService.dimensions;
|
frameDetails = {
|
||||||
// window.gl.readPixels(
|
cols: await ctx.proxy.cols,
|
||||||
// Math.floor(${col - 1} * window.d.device.cell.width),
|
rows: await ctx.proxy.rows,
|
||||||
// Math.floor(window.gl.drawingBufferHeight - ${row} * window.d.device.cell.height),
|
decoded: (await decodePng(buffer, { force32: true })).image
|
||||||
// window.d.device.cell.width, window.d.device.cell.height, window.gl.RGBA, window.gl.UNSIGNED_BYTE, window.result
|
};
|
||||||
// );
|
return frameDetails;
|
||||||
// `);
|
}
|
||||||
// return await ctx.page.evaluate(`Array.from(window.result)`);
|
|
||||||
// }
|
function getCellColorInner(frameDetails: { cols: number, rows: number, decoded: IImage32 }, col: number, row: number): [red: number, green: number, blue: number, alpha: number] {
|
||||||
|
const cellSize = {
|
||||||
|
width: frameDetails.decoded.width / frameDetails.cols,
|
||||||
|
height: frameDetails.decoded.height / frameDetails.rows
|
||||||
|
};
|
||||||
|
const x = Math.floor((col - 1/* 1- to 0-based index */ + 0.5/* middle of cell */) * cellSize.width);
|
||||||
|
const y = Math.floor((row - 1/* 1- to 0-based index */ + 0.5/* middle of cell */) * cellSize.height);
|
||||||
|
const i = (y * frameDetails.decoded.width + x) * 4/* 4 channels per pixel */;
|
||||||
|
return Array.from(frameDetails.decoded.data.slice(i, i + 4)) as [number, number, number, number];
|
||||||
|
}
|
||||||
|
|
||||||
const COLORS_16_TO_255 = [
|
const COLORS_16_TO_255 = [
|
||||||
'#000000', '#00005f', '#000087', '#0000af', '#0000d7', '#0000ff', '#005f00', '#005f5f', '#005f87', '#005faf', '#005fd7', '#005fff', '#008700', '#00875f', '#008787', '#0087af',
|
'#000000', '#00005f', '#000087', '#0000af', '#0000d7', '#0000ff', '#005f00', '#005f5f', '#005f87', '#005faf', '#005fd7', '#005fff', '#008700', '#00875f', '#008787', '#0087af',
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
"strict": true,
|
"strict": true,
|
||||||
"types": [
|
"types": [
|
||||||
"../../../node_modules/@types/node",
|
"../../../node_modules/@types/node",
|
||||||
|
"../../../node_modules/@lunapaint/png-codec",
|
||||||
"../../../out-test/playwright/TestUtils"
|
"../../../out-test/playwright/TestUtils"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const cp = require('child_process');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const configs = [
|
const configs = [
|
||||||
{ name: 'core', path: 'out-test/playwright/playwright.config.js' },
|
// { name: 'core', path: 'out-test/playwright/playwright.config.js' },
|
||||||
{ name: 'xterm-addon-webgl', path: 'addons/xterm-addon-webgl/out-test/playwright.config.js' }
|
{ name: 'xterm-addon-webgl', path: 'addons/xterm-addon-webgl/out-test/playwright.config.js' }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user