[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
On 2005-11-14, Vincent Penecherc'h <Vincent.Penecherch@xxxxxxxxxx> wrote:
> How's that for an attention grabbing subject ? :)
>
> In 24 bit modes, when the last pixel of a memory BITMAP
> is right on the end of a page, the assembler getpixel will
> trigger a page fault by reading an unaligned int for the
> three bytes of the pixel (in the last page) and a random
> byte (in the next page) which will then get masked out,
> but the damage is done.
>
> I've tried changing the code to either read 3 bytes and
> or the results, or read aligned and shift for odd addresses,
> but both are slower than the unaligned reads, so I've
> just added 1 to the allocated memory for 24 bit BITMAPs.
I don't understand the rationale behind adding just one byte. Say
I wanted a bitmap of 3x1 pixels, which will malloc 3 * 1 * 3 =
9 bytes. Adding one makes it 10, but wouldn't alignment rules
require 12? How about 64bit machines? I guess we haven't asm for
them, but surely that will be a problem too (some day)?
Besides, you could comment it better:
Index: src/graphics.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/graphics.c,v
retrieving revision 1.66
diff -u -p -r1.66 graphics.c
--- src/graphics.c 12 Nov 2005 16:59:33 -0000 1.66
+++ src/graphics.c 26 Nov 2005 21:35:38 -0000
@@ -1042,7 +1042,7 @@ BITMAP *create_bitmap_ex(int color_depth
{
GFX_VTABLE *vtable;
BITMAP *bitmap;
- int i;
+ int padding = 0;
ASSERT(width >= 0);
ASSERT(height > 0);
ASSERT(system_driver);
@@ -1058,7 +1058,11 @@ BITMAP *create_bitmap_ex(int color_depth
if (!bitmap)
return NULL;
- bitmap->dat = malloc(width * height * BYTES_PER_PIXEL(color_depth));
+ /* This avoids a crash for assembler code accessing the last pixel. */
+ if (color_depth == 24)
+ padding = 1;
+
+ bitmap->dat = malloc(width * height * BYTES_PER_PIXEL(color_depth) + padding);
if (!bitmap->dat) {
free(bitmap);
return NULL;