For true color map images, the color query is impressively optimized.

git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@2296 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
master
Jun FURUSE / 古瀬 淳 1999-02-19 17:08:27 +00:00
parent 0ecbd9a5ab
commit 6feb22a648
3 changed files with 45 additions and 7 deletions

View File

@ -29,6 +29,11 @@ static struct color_cache_entry color_cache[Color_cache_size];
static int num_overflows = 0; static int num_overflows = 0;
Bool direct_rgb = False;
int byte_order;
int bitmap_unit;
int bits_per_pixel;
void gr_init_color_cache(void) void gr_init_color_cache(void)
{ {
int i; int i;
@ -46,10 +51,22 @@ unsigned long gr_pixel_rgb(int rgb)
unsigned int r, g, b; unsigned int r, g, b;
int h, i; int h, i;
XColor color; XColor color;
unsigned short tmp;
r = (rgb >> 16) & 0xFF; r = (rgb >> 16) & 0xFF;
g = (rgb >> 8) & 0xFF; g = (rgb >> 8) & 0xFF;
b = rgb & 0xFF; b = rgb & 0xFF;
if (direct_rgb){
switch ( bits_per_pixel ){
case 16:
tmp = ((r >> 3) << 11) + ((g >> 2) << 5) + ((b >> 3) << 0);
return (unsigned long) tmp;
case 32:
return (r << 16) + (g << 8) + (b << 0);
}
}
h = Hash_rgb(r, g, b); h = Hash_rgb(r, g, b);
i = h; i = h;
while(1) { while(1) {
@ -57,13 +74,13 @@ unsigned long gr_pixel_rgb(int rgb)
if (color_cache[i].rgb == rgb) return color_cache[i].pixel; if (color_cache[i].rgb == rgb) return color_cache[i].pixel;
i = (i + 1) & (Color_cache_size - 1); i = (i + 1) & (Color_cache_size - 1);
if (i == h) { if (i == h) {
/* Cache is full. Instead of inserting at slot h, which causes /* Cache is full. Instead of inserting at slot h, which causes
thrasing if many colors hash to the same value, thrasing if many colors hash to the same value,
insert at h + n where n is pseudo-random and insert at h + n where n is pseudo-random and
smaller than Color_cache_slack */ smaller than Color_cache_slack */
int slack = num_overflows++ & (Color_cache_slack - 1); int slack = num_overflows++ & (Color_cache_slack - 1);
i = (i + slack) & (Color_cache_size - 1); i = (i + slack) & (Color_cache_size - 1);
break; break;
} }
} }
color.red = r * 0x101; color.red = r * 0x101;

View File

@ -32,6 +32,11 @@ extern int grx, gry; /* Coordinates of the current point */
extern unsigned long grcolor; /* Current drawing color */ extern unsigned long grcolor; /* Current drawing color */
extern XFontStruct * grfont; /* Current font */ extern XFontStruct * grfont; /* Current font */
extern Bool direct_rgb;
extern int byte_order;
extern int bitmap_unit;
extern int bits_per_pixel;
#define Wcvt(y) (grwindow.h - 1 - (y)) #define Wcvt(y) (grwindow.h - 1 - (y))
#define Bcvt(y) (grbstore.h - 1 - (y)) #define Bcvt(y) (grbstore.h - 1 - (y))
#define WtoB(y) ((y) + grbstore.h - grwindow.h) #define WtoB(y) ((y) + grbstore.h - grwindow.h)

View File

@ -40,6 +40,22 @@ value gr_make_image(value m)
XDefaultDepth(grdisplay, grscreen), XDefaultDepth(grdisplay, grscreen),
ZPixmap, 0, NULL, width, height, ZPixmap, 0, NULL, width, height,
BitmapPad(grdisplay), 0); BitmapPad(grdisplay), 0);
/* To optimize RGB => color id calculation */
if( !direct_rgb ){
/* they are declared in color.c */
byte_order = idata->byte_order;
bitmap_unit = idata->bitmap_unit;
bits_per_pixel = idata->bits_per_pixel;
#ifdef DIRECT_RGB_DEBUG
fprintf(stderr, "Byte_order: %d = %s\n", byte_order,
byte_order ? "LSBFirst" : "MSBFirst");
fprintf(stderr, "Bitmp_unit: %d\n", bitmap_unit);
fprintf(stderr, "Bits per pixel: %d\n", idata->bits_per_pixel);
#endif
direct_rgb = True;
}
bdata = (char *) stat_alloc(height * idata->bytes_per_line); bdata = (char *) stat_alloc(height * idata->bytes_per_line);
idata->data = bdata; idata->data = bdata;
has_transp = False; has_transp = False;