Commits:
-
13200abe
by Alexei Podtelezhnikov
at 2022-08-28T22:22:49-04:00
[graph] Rework #ifdef GBLENDER_STORE_BYTES.
This also settles on tripling the number of channel keys, which is
a safe bet in all circumstances. Quadrupling might only work on
64-bit architectures or with added key structure padding, without
GBLENDER_STORE_BYTES defined.
* graph/gblender.h (GBlenderCell): Change definition.
* graph/gblblit.c (GDST_STOREB): Updated accordingly.
* graph/gblender.c (gblender_clear, gblender_reset_key,
gblender_lookup, gblender_lookup_channel): Ditto.
3 changed files:
Changes:
graph/gblblit.c
... |
... |
@@ -106,11 +106,11 @@ |
106
|
106
|
#define GDST_PIX(p,d) unsigned int p = *(GBlenderPixel*)(d) & 0xFFFFFF
|
107
|
107
|
#define GDST_COPY(d) *(GBlenderPixel*)(d) = color.value
|
108
|
108
|
#define GDST_STOREP(d,cells,a) *(GBlenderPixel*)(d) = (cells)[(a)]
|
109
|
|
-#define GDST_STOREB(d,cells,a) \
|
110
|
|
- { \
|
111
|
|
- GBlenderCell* _g = (cells) + (a)*3; \
|
112
|
|
- \
|
113
|
|
- GDST_STOREC(d,_g[0],_g[1],_g[2]); \
|
|
109
|
+#define GDST_STOREB(d,cells,a) \
|
|
110
|
+ { \
|
|
111
|
+ GBlenderCell* _g = (cells) + (a); \
|
|
112
|
+ \
|
|
113
|
+ GDST_STOREC(d,(*_g)[0],(*_g)[1],(*_g)[2]); \
|
114
|
114
|
}
|
115
|
115
|
#define GDST_STOREC(d,r,g,b) *(GBlenderPixel*)(d) = GRGB_PACK(r,g,b)
|
116
|
116
|
|
... |
... |
@@ -128,13 +128,13 @@ |
128
|
128
|
#define GDST_COPY(d) GDST_STORE3(d,color.chroma[0],color.chroma[1],color.chroma[2])
|
129
|
129
|
#define GDST_STOREC(d,r,g,b) GDST_STORE3(d,r,g,b)
|
130
|
130
|
|
131
|
|
-#define GDST_STOREB(d,cells,a) \
|
132
|
|
- { \
|
133
|
|
- GBlenderCell* _g = (cells) + (a)*3; \
|
134
|
|
- \
|
135
|
|
- (d)[0] = _g[0]; \
|
136
|
|
- (d)[1] = _g[1]; \
|
137
|
|
- (d)[2] = _g[2]; \
|
|
131
|
+#define GDST_STOREB(d,cells,a) \
|
|
132
|
+ { \
|
|
133
|
+ GBlenderCell* _g = (cells) + (a); \
|
|
134
|
+ \
|
|
135
|
+ (d)[0] = (*_g)[0]; \
|
|
136
|
+ (d)[1] = (*_g)[1]; \
|
|
137
|
+ (d)[2] = (*_g)[2]; \
|
138
|
138
|
}
|
139
|
139
|
|
140
|
140
|
#define GDST_STOREP(d,cells,a) \
|
... |
... |
@@ -158,11 +158,11 @@ |
158
|
158
|
#define GDST_PIX(p,d) unsigned int p = GRGB565_TO_RGB24(*(unsigned short*)(d))
|
159
|
159
|
#define GDST_COPY(d) *(unsigned short*)(d) = (unsigned short)color.value
|
160
|
160
|
|
161
|
|
-#define GDST_STOREB(d,cells,a) \
|
162
|
|
- { \
|
163
|
|
- GBlenderCell* _g = (cells) + (a)*3; \
|
164
|
|
- \
|
165
|
|
- *(unsigned short*)(d) = GRGB_TO_RGB565(_g[0],_g[1],_g[2]); \
|
|
161
|
+#define GDST_STOREB(d,cells,a) \
|
|
162
|
+ { \
|
|
163
|
+ GBlenderCell* _g = (cells) + (a); \
|
|
164
|
+ \
|
|
165
|
+ *(unsigned short*)(d) = GRGB_TO_RGB565((*_g)[0],(*_g)[1],(*_g)[2]); \
|
166
|
166
|
}
|
167
|
167
|
|
168
|
168
|
#define GDST_STOREP(d,cells,a) \
|
... |
... |
@@ -187,11 +187,11 @@ |
187
|
187
|
#define GDST_PIX(p,d) unsigned int p = GRGB555_TO_RGB24(*(unsigned short*)(d))
|
188
|
188
|
#define GDST_COPY(d) *(unsigned short*)(d) = (unsigned short)color.value
|
189
|
189
|
|
190
|
|
-#define GDST_STOREB(d,cells,a) \
|
191
|
|
- { \
|
192
|
|
- GBlenderCell* _g = (cells) + (a)*3; \
|
193
|
|
- \
|
194
|
|
- *(unsigned short*)(d) = GRGB_TO_RGB555(_g[0],_g[1],_g[2]); \
|
|
190
|
+#define GDST_STOREB(d,cells,a) \
|
|
191
|
+ { \
|
|
192
|
+ GBlenderCell* _g = (cells) + (a); \
|
|
193
|
+ \
|
|
194
|
+ *(unsigned short*)(d) = GRGB_TO_RGB555((*_g)[0],(*_g)[1],(*_g)[2]); \
|
195
|
195
|
}
|
196
|
196
|
|
197
|
197
|
#define GDST_STOREP(d,cells,a) \
|
... |
... |
@@ -216,11 +216,11 @@ |
216
|
216
|
#define GDST_PIX(p,d) unsigned int p = GGRAY8_TO_RGB24(*(unsigned char*)(d))
|
217
|
217
|
#define GDST_COPY(d) *(d) = (unsigned char)color.value
|
218
|
218
|
|
219
|
|
-#define GDST_STOREB(d,cells,a) \
|
220
|
|
- { \
|
221
|
|
- GBlenderCell* _g = (cells) + (a)*3; \
|
222
|
|
- \
|
223
|
|
- *(d) = GRGB_TO_GRAY8(_g[0],_g[1],_g[2]); \
|
|
219
|
+#define GDST_STOREB(d,cells,a) \
|
|
220
|
+ { \
|
|
221
|
+ GBlenderCell* _g = (cells) + (a); \
|
|
222
|
+ \
|
|
223
|
+ *(d) = GRGB_TO_GRAY8((*_g)[0],(*_g)[1],(*_g)[2]); \
|
224
|
224
|
}
|
225
|
225
|
|
226
|
226
|
#define GDST_STOREP(d,cells,a) \
|
graph/gblender.c
... |
... |
@@ -126,9 +126,7 @@ gblender_clear( GBlender blender ) |
126
|
126
|
{
|
127
|
127
|
GBlenderChanKey chan_keys = (GBlenderChanKey) blender->keys;
|
128
|
128
|
|
129
|
|
- for ( nn = 0;
|
130
|
|
- nn < GBLENDER_KEY_COUNT*GBLENDER_CELL_SIZE*sizeof(GBlenderCell);
|
131
|
|
- nn++ )
|
|
129
|
+ for ( nn = 0; nn < GBLENDER_KEY_COUNT * 3; nn++ )
|
132
|
130
|
chan_keys[nn].index = -1;
|
133
|
131
|
|
134
|
132
|
blender->cache_r_back = 0;
|
... |
... |
@@ -215,14 +213,13 @@ gblender_reset_key( GBlender blender, |
215
|
213
|
b2 = ( fore ) & 255;
|
216
|
214
|
|
217
|
215
|
#ifdef GBLENDER_STORE_BYTES
|
218
|
|
- gr[0] = (unsigned char)r1;
|
219
|
|
- gr[1] = (unsigned char)g1;
|
220
|
|
- gr[2] = (unsigned char)b1;
|
221
|
|
- gr += 3;
|
|
216
|
+ (*gr)[0] = (unsigned char)r1;
|
|
217
|
+ (*gr)[1] = (unsigned char)g1;
|
|
218
|
+ (*gr)[2] = (unsigned char)b1;
|
222
|
219
|
#else
|
223
|
220
|
gr[0] = back;
|
224
|
|
- gr += 1;
|
225
|
221
|
#endif
|
|
222
|
+ gr++;
|
226
|
223
|
|
227
|
224
|
r1 = gamma_ramp[r1] << 10;
|
228
|
225
|
g1 = gamma_ramp[g1] << 10;
|
... |
... |
@@ -250,14 +247,13 @@ gblender_reset_key( GBlender blender, |
250
|
247
|
b = gamma_ramp_inv[b1 >> 10];
|
251
|
248
|
|
252
|
249
|
#ifdef GBLENDER_STORE_BYTES
|
253
|
|
- gr[0] = r;
|
254
|
|
- gr[1] = g;
|
255
|
|
- gr[2] = b;
|
256
|
|
- gr += 3;
|
|
250
|
+ (*gr)[0] = r;
|
|
251
|
+ (*gr)[1] = g;
|
|
252
|
+ (*gr)[2] = b;
|
257
|
253
|
#else
|
258
|
254
|
gr[0] = ( r << 16 ) | ( g << 8 ) | b;
|
259
|
|
- gr += 1;
|
260
|
255
|
#endif
|
|
256
|
+ gr++;
|
261
|
257
|
}
|
262
|
258
|
}
|
263
|
259
|
|
... |
... |
@@ -294,8 +290,7 @@ gblender_lookup( GBlender blender, |
294
|
290
|
NewNode:
|
295
|
291
|
key->background = background;
|
296
|
292
|
key->foreground = foreground;
|
297
|
|
- key->cells = blender->cells +
|
298
|
|
- idx*(GBLENDER_SHADE_COUNT*GBLENDER_CELL_SIZE);
|
|
293
|
+ key->cells = blender->cells + idx * GBLENDER_SHADE_COUNT;
|
299
|
294
|
|
300
|
295
|
gblender_reset_key( blender, key );
|
301
|
296
|
|
... |
... |
@@ -354,8 +349,7 @@ gblender_lookup_channel( GBlender blender, |
354
|
349
|
blender->stat_lookups++;
|
355
|
350
|
#endif
|
356
|
351
|
|
357
|
|
- idx = ( background ^ foreground * 59 ) %
|
358
|
|
- ( GBLENDER_KEY_COUNT*GBLENDER_CELL_SIZE*sizeof(GBlenderCell) - 1);
|
|
352
|
+ idx = ( background ^ foreground * 59 ) % ( GBLENDER_KEY_COUNT * 3 - 1 );
|
359
|
353
|
|
360
|
354
|
key = (GBlenderChanKey)blender->keys + idx;
|
361
|
355
|
|
... |
... |
@@ -390,7 +384,7 @@ Exit: |
390
|
384
|
GBLENDER_APIDEF( void )
|
391
|
385
|
gblender_dump_stats( GBlender blender )
|
392
|
386
|
{
|
393
|
|
- printf( "GBlender cache statistics:\n" );
|
|
387
|
+ printf( "GBlender cache (%zu bytes) statistics:\n", sizeof blender->cells );
|
394
|
388
|
printf( " Hit rate: %.2f%% ( %ld out of %ld )\n",
|
395
|
389
|
100.0f * blender->stat_hits /
|
396
|
390
|
( blender->stat_hits + blender->stat_lookups ),
|
graph/gblender.h
... |
... |
@@ -38,11 +38,9 @@ |
38
|
38
|
typedef unsigned int GBlenderPixel; /* needs 32-bits here !! */
|
39
|
39
|
|
40
|
40
|
#ifdef GBLENDER_STORE_BYTES
|
41
|
|
- typedef unsigned char GBlenderCell;
|
42
|
|
-# define GBLENDER_CELL_SIZE 3
|
|
41
|
+ typedef unsigned char GBlenderCell[3];
|
43
|
42
|
#else
|
44
|
43
|
typedef GBlenderPixel GBlenderCell;
|
45
|
|
-# define GBLENDER_CELL_SIZE 1
|
46
|
44
|
#endif
|
47
|
45
|
|
48
|
46
|
|
... |
... |
@@ -70,10 +68,12 @@ |
70
|
68
|
} GBlenderChanKeyRec, *GBlenderChanKey;
|
71
|
69
|
|
72
|
70
|
|
|
71
|
+ /* sizeof GBlenderKeyRec is at least 3x sizeof GBlenderChanKeyRec */
|
|
72
|
+ /* Therefore, we can safely use 3x as many channel keys */
|
73
|
73
|
typedef struct GBlenderRec_
|
74
|
74
|
{
|
75
|
75
|
GBlenderKeyRec keys [ GBLENDER_KEY_COUNT ];
|
76
|
|
- GBlenderCell cells[ GBLENDER_KEY_COUNT*GBLENDER_SHADE_COUNT*GBLENDER_CELL_SIZE ];
|
|
76
|
+ GBlenderCell cells[ GBLENDER_KEY_COUNT*GBLENDER_SHADE_COUNT ];
|
77
|
77
|
|
78
|
78
|
/* a small cache for normal modes
|
79
|
79
|
*/
|
|