ref: 8070f221ed04c1e5adf9e0c2475c8ddf80ef772e
parent: 79050578c7fb0a2efc4c4d9c04ba63738fb5f660
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Oct 15 14:42:53 EDT 2024
color matrix: optimize general case for identity (== 1) and just scaling up (> 1)
--- a/cmprocess.c
+++ b/cmprocess.c
@@ -1,15 +1,45 @@
#include "quakedef.h"
#include "colormatrix.h"
+extern int cmflags;
+
void
cmprocess(s16int cm[4*4], void *in_, void *out_, int n)
{
pixel_t *in, *out;
- int i;
+ if(cmkind == CmIdent)
+ return;
+
in = in_;
out = out_;
- for(i = 0; i < n; i++, in++){
+
+ if(cmkind == CmBright){
+ for(; n > 0; in++, n--){
+ s32int x[4] = {
+ (*in>>0)&0xff,
+ (*in>>8)&0xff,
+ (*in>>16)&0xff,
+ 0xff,
+ };
+ s32int y[4] = {
+ x[0]*cm[4*0+0]/CM(1),
+ x[1]*cm[4*1+1]/CM(1),
+ x[2]*cm[4*2+2]/CM(1),
+ 0xff,
+ };
+ u8int z[4] = {
+ min(y[0], 255),
+ min(y[1], 255),
+ min(y[2], 255),
+ 0xff,
+ };
+ *out++ = z[0]<<0 | z[1]<<8 | z[2]<<16 | (pixel_t)0xff<<24;
+ }
+ return;
+ }
+
+ for(; n > 0; in++, n--){
s32int x[4] = {
(*in>>0)&0xff,
(*in>>8)&0xff,
@@ -17,17 +47,17 @@
0xff,
};
s32int y[4] = {
- (x[0]*cm[4*0+0] + x[1]*cm[4*0+1] + x[2]*cm[4*0+2] + x[3]*cm[4*0+3])/CM(1),
- (x[0]*cm[4*1+0] + x[1]*cm[4*1+1] + x[2]*cm[4*1+2] + x[3]*cm[4*1+3])/CM(1),
- (x[0]*cm[4*2+0] + x[1]*cm[4*2+1] + x[2]*cm[4*2+2] + x[3]*cm[4*2+3])/CM(1),
+ (x[0]*cm[4*0+0] + x[1]*cm[4*0+1] + x[2]*cm[4*0+2] + 0xff*cm[4*0+3])/CM(1),
+ (x[0]*cm[4*1+0] + x[1]*cm[4*1+1] + x[2]*cm[4*1+2] + 0xff*cm[4*1+3])/CM(1),
+ (x[0]*cm[4*2+0] + x[1]*cm[4*2+1] + x[2]*cm[4*2+2] + 0xff*cm[4*2+3])/CM(1),
0xff,
};
- u8int z[4] = {
+ u32int z[4] = {
clamp(y[0], 0, 255),
clamp(y[1], 0, 255),
clamp(y[2], 0, 255),
0xff,
};
- *out++ = z[0]<<0 | z[1]<<8 | z[2]<<16 | (pixel_t)z[3]<<24;
+ *out++ = z[0]<<0 | z[1]<<8 | z[2]<<16 | z[3]<<24;
}
}
--- a/colormatrix.c
+++ b/colormatrix.c
@@ -12,7 +12,7 @@
CM(0), CM(0), CM(1), CM(0),
CM(0), CM(0), CM(0), CM(1),
};
-static bool cmident = true;
+int cmkind = -1;
static float cmf0[4*4] = {
1, 0, 0, 0,
@@ -48,7 +48,16 @@
mmul(t, t2, cmvblend);
for(i = 0; i < 4*4; i++)
cm[i] = CM(t[i]);
- cmident = memcmp(cm, cm0, sizeof(cm)) == 0;
+ cmkind = (
+ cm[4*0] >= CM(1) &&
+ cm[4*0+0] == cm[4*1+1] &&
+ cm[4*1+1] == cm[4*2+2] &&
+ cm[4*0+1] == 0 && cm[4*0+2] == 0 && cm[4*0+3] == 0 &&
+ cm[4*1+0] == 0 && cm[4*1+2] == 0 && cm[4*1+3] == 0 &&
+ cm[4*2+0] == 0 && cm[4*2+1] == 0 && cm[4*2+3] == 0
+ )
+ ? (cm[4*0] == CM(1) ? CmIdent : CmBright)
+ : -1;
}
void
--- a/colormatrix.h
+++ b/colormatrix.h
@@ -1,3 +1,9 @@
+/* cmkind values for optimized special-casing */
+enum {
+ CmIdent, /* identity (== 1) */
+ CmBright, /* only brightness is changed (> 1) */
+};
+
#define CM(v) ((v)*(1<<12))
extern s16int cm[4*4];
@@ -4,6 +10,7 @@
extern cvar_t v_saturation;
extern cvar_t v_contrast;
extern cvar_t v_brightness;
+extern int cmkind;
void cmsetvblend(float blend[4]);
void cmprocess(s16int cm[4*4], void *in, void *out, int n);