ref: a961748acce8e85042c85fc36e074aaa71cd3b01
parent: c928eb5927903cb3e390aa5ff391ea91113517e1
author: rodri <rgl@antares-labs.eu>
date: Mon Feb 16 12:41:46 EST 2026
premultiply alpha when writing to color rasters with this we can avoid duplicating the raster on every framebufctl_(mem)draw() call. we already apply gamma correction to the colors before storage, so with this change the rasters are effectively just Memimages.
--- a/color.c
+++ b/color.c
@@ -10,13 +10,13 @@
ulong
col2ul(Color c)
{- uchar cbuf[4];
+ ulong l;
- cbuf[0] = fclamp(c.a, 0, 1)*0xFF;
- cbuf[1] = fclamp(c.b, 0, 1)*0xFF;
- cbuf[2] = fclamp(c.g, 0, 1)*0xFF;
- cbuf[3] = fclamp(c.r, 0, 1)*0xFF;
- return cbuf[3]<<24 | cbuf[2]<<16 | cbuf[1]<<8 | cbuf[0];
+ l = (int)(fclamp(c.a, 0, 1)*0xFF);
+ l |= (int)(fclamp(c.b, 0, 1)*0xFF) << 8;
+ l |= (int)(fclamp(c.g, 0, 1)*0xFF) << 16;
+ l |= (int)(fclamp(c.r, 0, 1)*0xFF) << 24;
+ return l;
}
Color
@@ -126,7 +126,7 @@
* Equations 5.32 and 5.30 from “Display Encoding”, Real-Time Rendering 4th ed. § 5.6
*/
//static double
-//_srgb2linear(double c)
+//srgb2linear1(double c)
//{// if(c > 0.04045)
// return pow((c + 0.055)/1.055, 2.4);
@@ -134,7 +134,7 @@
//}
//
//static double
-//_linear2srgb(double c)
+//linear2srgb1(double c)
//{// if(c > 0.0031308)
// return 1.055*pow(c, 1.0/2.4) - 0.055;
@@ -142,7 +142,7 @@
//}
static double
-_srgb2linear(double c)
+srgb2linear1(double c)
{c = fclamp(c, 0, 1);
return srgb2lineartab[(int)(c*255)]/255.0;
@@ -149,7 +149,7 @@
}
static double
-_linear2srgb(double c)
+linear2srgb1(double c)
{c = fclamp(c, 0, 1);
return linear2srgbtab[(int)(c*255)]/255.0;
@@ -158,9 +158,9 @@
Color
srgb2linear(Color c)
{- c.r = _srgb2linear(c.r);
- c.g = _srgb2linear(c.g);
- c.b = _srgb2linear(c.b);
+ c.r = srgb2linear1(c.r);
+ c.g = srgb2linear1(c.g);
+ c.b = srgb2linear1(c.b);
return c;
}
@@ -167,9 +167,9 @@
Color
linear2srgb(Color c)
{- c.r = _linear2srgb(c.r);
- c.g = _linear2srgb(c.g);
- c.b = _linear2srgb(c.b);
+ c.r = linear2srgb1(c.r);
+ c.g = linear2srgb1(c.g);
+ c.b = linear2srgb1(c.b);
return c;
}
@@ -181,7 +181,7 @@
* https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
*/
static double
-_aces(double value)
+aces1(double value)
{double a = 2.51;
double b = 0.03;
@@ -195,9 +195,9 @@
Color
aces(Color c)
{- c.r = _aces(c.r);
- c.g = _aces(c.g);
- c.b = _aces(c.b);
+ c.r = aces1(c.r);
+ c.g = aces1(c.g);
+ c.b = aces1(c.b);
return c;
}
--- a/fb.c
+++ b/fb.c
@@ -129,23 +129,6 @@
}
static void
-premulalpha(Raster *r)
-{- Color c;
- ulong *p, len;
-
- len = Dx(r->r)*Dy(r->r);
- p = r->data;
- while(len--){- c = ul2col(*p);
- c.r *= c.a;
- c.g *= c.a;
- c.b *= c.a;
- *p++ = col2ul(c);
- }
-}
-
-static void
upscaledraw(Raster *fb, Image *dst, Point off, Point scale, uint filter)
{void (*filterfn)(ulong*, Raster*, Point, Point, ulong);
@@ -212,14 +195,6 @@
r = r2;
}
- /* this means the raster is a color one, so duplicate it */
- if(r2 == nil){- r2 = _allocraster(nil, r->r, COLOR32);
- memmove(r2->data, r->data, Dx(r->r)*Dy(r->r)*4);
- r = r2;
- }
- premulalpha(r);
-
if(scale.x > 1 || scale.y > 1){upscaledraw(r, dst, off, scale, ctl->upfilter);
qunlock(ctl);
@@ -311,14 +286,6 @@
rasterconvF2C(r2, r);
r = r2;
}
-
- /* this means the raster is a color one, so duplicate it */
- if(r2 == nil){- r2 = _allocraster(nil, r->r, COLOR32);
- memmove(r2->data, r->data, Dx(r->r)*Dy(r->r)*4);
- r = r2;
- }
- premulalpha(r);
if(scale.x > 1 || scale.y > 1){upscalememdraw(r, dst, off, scale, ctl->upfilter);
--- a/render.c
+++ b/render.c
@@ -31,6 +31,23 @@
_addvattr(sp->v, id, type, val);
}
+#define mulalpha1(a, v, tmp) (tmp=(a)*(v)+128, (tmp+(tmp>>8))>>8)
+
+static ulong
+mulalpha(ulong c)
+{+ ushort r, g, b, a, t;
+
+ a = c & 0xff;
+ b = c>>8 & 0xff;
+ g = c>>16 & 0xff;
+ r = c>>24 & 0xff;
+ r = mulalpha1(a, r, t);
+ g = mulalpha1(a, g, t);
+ b = mulalpha1(a, b, t);
+ return (r<<24)|(g<<16)|(b<<8)|a;
+}
+
static void
sparams_toraster(Shaderparams *sp, char *rname, void *v)
{@@ -49,7 +66,7 @@
switch(r->chan){case COLOR32:
- c = col2ul(*(Color*)v);
+ c = mulalpha(col2ul(*(Color*)v));
_rasterput(r, sp->p, &c);
break;
case FLOAT32:
@@ -70,7 +87,7 @@
// c = subpt3(Vec3(1,1,1), subpt3(dc, c));
// c = subpt3(addpt3(dc, c), Vec3(1,1,1));
}
- putpixel(fb, p, col2ul(linear2srgb(c)));
+ putpixel(fb, p, mulalpha(col2ul(linear2srgb(c))));
}
static int
--
⑨