[AD] Two Windows patches

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


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/