[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
See the following threads for some background information on the following
patches:
http://www.allegro.cc/forums/thread/558465
http://www.allegro.cc/forums/thread/560782
The first one adds a hardware-accelerated stretch_blit() to the DirectX
driver (the documentation will need to be updated accordingly). This
should probably be tested more, but unless it's applied and put into a
release version no one will use it and it won't get tested, so I propose
it for 4.2.1, if we're adding minor enhancements there anyway.
Credits for Thomas Harte and Neil Walker.
The second is a genuine bugfix where destroying a subbitmap of a system
bitmap also destroyed (or at least garbled) the parent bitmap. This I
think could be applied without problems.
Credits for Neil Walker and myself.
Evert
Index: src/i386/istretch.c
===================================================================
--- src/i386/istretch.c (revision 5662)
+++ src/i386/istretch.c (working copy)
@@ -287,8 +287,8 @@
char flags;
int i;
- /* vtable hook */
- if (source->vtable->do_stretch_blit) {
+ /* vtable hook; not called if dest is a memory surface */
+ if (source->vtable->do_stretch_blit && !is_memory_bitmap(dest)) {
source->vtable->do_stretch_blit(source, dest, source_x, source_y, source_width, source_height, dest_x, dest_y, dest_width, dest_height, masked);
return;
}
Index: src/win/wddaccel.c
===================================================================
--- src/win/wddaccel.c (revision 5662)
+++ src/win/wddaccel.c (working copy)
@@ -15,6 +15,7 @@
* Bugfixes by Isaac Cruz.
*
* Accelerated rectfill() and hline() added by Shawn Hargreaves.
+ * Accelerated stretch_blit() and friends by Thomas Harte
*
* See readme.txt for copyright information.
*/
@@ -34,6 +35,7 @@
static void (*_orig_rectfill) (BITMAP * bmp, int x1, int y1, int x2, int y2, int color);
static void (*_orig_draw_sprite) (BITMAP * bmp, BITMAP * sprite, int x, int y);
static void (*_orig_masked_blit) (BITMAP * source, BITMAP * dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
+static void (*_orig_stretch_blit) (BITMAP *source, BITMAP *dest, int source_x, int source_y, int source_width, int source_height, int dest_x, int dest_y, int dest_width, int dest_height, int masked);
@@ -193,6 +195,70 @@
+/* ddraw_do_stretch_blit:
+ * Accelerated stretch_blit, stretch_sprite, stretch_masked_blit
+ */
+static void ddraw_do_stretch_blit(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int source_width, int source_height, int dest_x, int dest_y, int dest_width, int dest_height, int masked)
+{
+ RECT dest_rect, source_rect;
+ DDCOLORKEY src_key;
+ HRESULT hr;
+ BITMAP *dest_parent;
+ BITMAP *source_parent;
+
+ dest_rect.left = dest_x + dest->x_ofs;
+ dest_rect.top = dest_y + dest->y_ofs;
+ dest_rect.right = dest_x + dest->x_ofs + dest_width;
+ dest_rect.bottom = dest_y + dest->y_ofs + dest_height;
+
+ source_rect.left = source_x + source->x_ofs;
+ source_rect.top = source_y + source->y_ofs;
+ source_rect.right = source_x + source->x_ofs + source_width;
+ source_rect.bottom = source_y + source->y_ofs + source_height;
+
+ src_key.dwColorSpaceLowValue = source->vtable->mask_color;
+ src_key.dwColorSpaceHighValue = source->vtable->mask_color;
+
+ if ( ( (masked && (gfx_capabilities & GFX_HW_STRETCH_BLIT_MASKED)) ||
+ (!masked && (gfx_capabilities & GFX_HW_STRETCH_BLIT))
+ ) && ( is_video_bitmap(source) || is_system_bitmap(source) ) ) {
+
+ /* find parents */
+ dest_parent = dest;
+ while (dest_parent->id & BMP_ID_SUB)
+ dest_parent = (BITMAP *)dest_parent->extra;
+
+ source_parent = source;
+ while (source_parent->id & BMP_ID_SUB)
+ source_parent = (BITMAP *)source_parent->extra;
+
+ _enter_gfx_critical();
+ gfx_directx_release_lock(dest);
+ gfx_directx_release_lock(source);
+
+ IDirectDrawSurface2_SetColorKey(DDRAW_SURFACE_OF(source_parent)->id,
+ DDCKEY_SRCBLT, &src_key);
+
+ hr = IDirectDrawSurface2_Blt(DDRAW_SURFACE_OF(dest_parent)->id, &dest_rect,
+ DDRAW_SURFACE_OF(source_parent)->id, &source_rect,
+ (masked ? DDBLT_KEYSRC : 0) | DDBLT_WAIT, NULL);
+ _exit_gfx_critical();
+
+ if (FAILED(hr))
+ _TRACE(PREFIX_E "Blt failed (%x)\n", hr);
+
+ /* only for windowed mode */
+ if ((gfx_driver->id == GFX_DIRECTX_WIN) && (dest_parent == gfx_directx_forefront_bitmap))
+ win_gfx_driver->paint(&dest_rect);
+ }
+ else {
+ /* have to use the original software version */
+ _orig_stretch_blit(source, dest, source_x, source_y, source_width, source_height, dest_x, dest_y, dest_width, dest_height, masked);
+ }
+}
+
+
+
/* ddraw_clear_to_color:
* Accelerated screen clear routine.
*/
@@ -458,6 +524,7 @@
_orig_rectfill = _screen_vtable.rectfill;
_orig_draw_sprite = _screen_vtable.draw_sprite;
_orig_masked_blit = _screen_vtable.masked_blit;
+ _orig_stretch_blit = _screen_vtable.do_stretch_blit;
/* accelerated video to video blits? */
if (ddcaps.dwCaps & DDCAPS_BLT) {
@@ -467,6 +534,11 @@
_screen_vtable.blit_from_system = ddraw_blit_to_self;
_screen_vtable.blit_to_system = ddraw_blit_to_self;
+ if (ddcaps.dwCaps&DDCAPS_BLTSTRETCH) {
+ _screen_vtable.do_stretch_blit = ddraw_do_stretch_blit;
+ gfx_capabilities |= GFX_HW_STRETCH_BLIT;
+ }
+
gfx_capabilities |= (GFX_HW_VRAM_BLIT | GFX_HW_SYS_TO_VRAM_BLIT);
}
@@ -486,6 +558,11 @@
_screen_vtable.masked_blit = ddraw_masked_blit;
_screen_vtable.draw_sprite = ddraw_draw_sprite;
+ if (ddcaps.dwCaps&DDCAPS_BLTSTRETCH) {
+ _screen_vtable.do_stretch_blit = ddraw_do_stretch_blit;
+ gfx_capabilities |= GFX_HW_STRETCH_BLIT_MASKED;
+ }
+
if (_screen_vtable.color_depth == 8)
_screen_vtable.draw_256_sprite = ddraw_draw_sprite;
Index: src/c/cstretch.c
===================================================================
--- src/c/cstretch.c (revision 5662)
+++ src/c/cstretch.c (working copy)
@@ -255,8 +255,8 @@
ASSERT(src);
ASSERT(dst);
- /* vtable hook */
- if (src->vtable->do_stretch_blit) {
+ /* vtable hook; not called if dest is a memory surface */
+ if (src->vtable->do_stretch_blit && !is_memory_bitmap(dst)) {
src->vtable->do_stretch_blit(src, dst, sx, sy, sw, sh, dx, dy, dw, dh, masked);
return;
}
Index: include/allegro/gfx.h
===================================================================
--- include/allegro/gfx.h (revision 5662)
+++ include/allegro/gfx.h (working copy)
@@ -142,6 +142,8 @@
#define GFX_HW_SYS_TO_VRAM_BLIT 0x00100000
#define GFX_HW_SYS_TO_VRAM_BLIT_MASKED 0x00200000
#define GFX_SYSTEM_CURSOR 0x00400000
+#define GFX_HW_STRETCH_BLIT 0x00800000
+#define GFX_HW_STRETCH_BLIT_MASKED 0x01000000
AL_VAR(int, gfx_capabilities); /* current driver capabilities */
Index: tests/test.c
===================================================================
--- tests/test.c (revision 5662)
+++ tests/test.c (working copy)
@@ -1748,6 +1748,9 @@
"masked mem->screen blit:",
"system->screen blit:",
"masked system->screen blit:",
+ "Mouse pointer:",
+ "stretch vram->vram blit:",
+ "masked stretch vram->vram blit:",
NULL
};
@@ -3385,6 +3388,8 @@
if (gfx_capabilities & GFX_HW_MEM_BLIT_MASKED) fprintf(f, " masked mem->vram blits\n");
if (gfx_capabilities & GFX_HW_SYS_TO_VRAM_BLIT) fprintf(f, " system->vram blits\n");
if (gfx_capabilities & GFX_HW_SYS_TO_VRAM_BLIT_MASKED) fprintf(f, " masked system->vram blits\n");
+ if (gfx_capabilities & GFX_HW_STRETCH_BLIT) fprintf(f, " stretch blits\n");
+ if (gfx_capabilities & GFX_HW_STRETCH_BLIT_MASKED) fprintf(f, " masked stretch blits\n");
if (!(gfx_capabilities & ~(GFX_CAN_SCROLL | GFX_CAN_TRIPLE_BUFFER | GFX_HW_CURSOR)))
fprintf(f, " <none>\n");
Index: src/win/wddbmp.c
===================================================================
--- src/win/wddbmp.c (revision 5662)
+++ src/win/wddbmp.c (working copy)
@@ -655,6 +655,24 @@
*/
void gfx_directx_destroy_system_bitmap(BITMAP *bmp)
{
+ /* Special case: use normal destroy_bitmap() for subbitmaps of system bitmaps.
+ * Checked here rather than in destroy_bitmap() because that function should
+ * not make assumptions about the relation between system bitmaps and
+ * subbitmaps thereof.
+ */
+ if (is_sub_bitmap(bmp)) {
+ if (system_driver->destroy_bitmap) {
+ if (system_driver->destroy_bitmap(bmp))
+ return;
+ }
+
+ if (bmp->dat)
+ _AL_FREE(bmp->dat);
+
+ _AL_FREE(bmp);
+
+ return;
+ }
/* destroy the surface */
gfx_directx_destroy_surface(DDRAW_SURFACE_OF(bmp));