shithub: qk1

Download patch

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);