Skip to content
31 changes: 21 additions & 10 deletions src/color/p5.Color.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ class Color {
// where if we `import { Color }` directly, it will be a separate copy of the
// Color class from the one imported in the main p5.js bundle.
isColor = true;
#srgbCoords = null;

#invalidateSrgbCache() {
this.#srgbCoords = null;
}

// Used to add additional color modes to p5.js
// Uses underlying library's definition
Expand Down Expand Up @@ -241,6 +246,7 @@ class Color {
this._initialize();
this._initialize = undefined;
}
this.#invalidateSrgbCache();
this._cachedColor = newColor;
}

Expand Down Expand Up @@ -559,6 +565,7 @@ class Color {

if(this.mode === RGB || this.mode === RGBP3){
this._color.coords[0] = newval;
this.#invalidateSrgbCache();
}else{
// Will do an imprecise conversion to 'srgb', not recommended
const space = this._color.space.id;
Expand Down Expand Up @@ -611,6 +618,7 @@ class Color {

if(this.mode === RGB || this.mode === RGBP3){
this._color.coords[1] = newval;
this.#invalidateSrgbCache();
}else{
// Will do an imprecise conversion to 'srgb', not recommended
const space = this._color.space.id;
Expand Down Expand Up @@ -663,6 +671,7 @@ class Color {

if(this.mode === RGB || this.mode === RGBP3){
this._color.coords[2] = newval;
this.#invalidateSrgbCache();
}else{
// Will do an imprecise conversion to 'srgb', not recommended
const space = this._color.space.id;
Expand Down Expand Up @@ -715,33 +724,35 @@ class Color {
const newval = map(new_alpha, max[0], max[1], colorjsMax[0], colorjsMax[1]);

this._color.alpha = newval;
this.#invalidateSrgbCache();
}

_getRGBA(maxes=[1, 1, 1, 1]) {
// Get colorjs maxes
const colorjsMaxes = Color.#colorjsMaxes[RGB];

// Normalize everything to 0,1 or the provided range (map)
let coords = structuredClone(to(this._color, 'srgb').coords);
coords.push(this._color.alpha);
// Cache the srgb conversion (the expensive step)
if (!this.#srgbCoords) {
if (this.mode === RGB || this._color.space.id === 'srgb') {
this.#srgbCoords = [...this._color.coords, this._color.alpha];
} else {
this.#srgbCoords = [...to(this._color, 'srgb').coords, this._color.alpha];
}
}

const rangeMaxes = maxes.map((v) => {
const colorjsMaxes = Color.#colorjsMaxes[RGB];
const rangeMaxes = maxes.map(v => {
if(!Array.isArray(v)){
return [0, v];
}else{
return v;
}
});

coords = coords.map((coord, i) => {
return this.#srgbCoords.map((coord, i) => {
return map(
coord,
colorjsMaxes[i][0], colorjsMaxes[i][1],
rangeMaxes[i][0], rangeMaxes[i][1]
);
});

return coords;
}

_getMode() {
Expand Down
71 changes: 71 additions & 0 deletions test/bench/set_benchmark.html

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file shouldn't be committed as it does not match the required format of the benchmark harness.

Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>p5.Graphics.set() benchmark</title>
<script src="../../lib/p5.js"></script>
<style>
body { font-family: monospace; padding: 20px; background: #1a1a1a; color: #eee; }
#output { white-space: pre-wrap; line-height: 1.6; }
.highlight { color: #7fdbca; }
.warn { color: #ffcc66; }
</style>
</head>
<body>
<h2>p5.Graphics.set() benchmark</h2>
<div id="output">Starting benchmark...</div>

<script>
const output = document.getElementById('output');
const W = 100, H = 100;
const ITERATIONS = 50; // frames to average
const FPS_OVERHEAD_MS = 1; // rough p5 overhead per frame

let myp5;
let results = [];

function log(msg, cls = '') {
output.innerHTML += (cls ? `<span class="${cls}">${msg}</span>` : msg) + '\n';
}

function run() {
myp5 = new p5(function (p) {
p.setup = function () {
p.noCanvas();
const buf = p.createGraphics(W, H);
const col = p.color(255, 0, 0);

log(`Buffer: ${W}x${H}, iterations: ${ITERATIONS}`);
log('Running set() benchmark...\n');

for (let i = 0; i < ITERATIONS; i++) {
const t0 = performance.now();
for (let y = 0; y < H; y++) {
for (let x = 0; x < W; x++) {
buf.set(x, y, col);
}
}
const t1 = performance.now();
results.push(t1 - t0);
}

const avg = results.reduce((a, b) => a + b, 0) / results.length;
const min = Math.min(...results);
const max = Math.max(...results);

log(`Results (${ITERATIONS} iterations):`);
log(` Average: ${avg.toFixed(2)} ms`);
log(` Min: ${min.toFixed(2)} ms`);
log(` Max: ${max.toFixed(2)} ms`);
log(`\np5.js version: ${p5.version || 'unknown'}`);

myp5.remove();
};
});
}

// small delay so p5 loads
setTimeout(run, 100);
</script>
</body>
</html>
Loading