Re: [AD] update bitmap drawing after addition of transformations

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


On Fri, 2010-08-13 at 10:29 -0400, Pavel Sountsov wrote:
> > I have not benchmarked it yet, but I imagine the performance loss 
> will be
> > significant.  If it is, can we not make the memory draw_bitmap_region
> > implementation infer the rotate/scale special cases from the 
> transformation
> > matrix and call the specialised functions?
> >
> > Peter
> 
> As Elias said, there are only the pure scaling and identity special 
> cases that need to be detected. Everything else (rotated/rotated + 
> scaled/affine) is sent to the parallelogram drawer.
> 

Oh, and I also just saw, you already did the same thing as my patch with
using transformations - except only for memory bitmaps. Anyway, new
patch attached. This should now detect when the transformation consists
only of scales and translates and uses the faster memory blitting in
such cases.

-- 
Elias Pschernig <elias.pschernig@xxxxxxxxxx>
diff --git a/include/allegro5/internal/aintern_bitmap.h b/include/allegro5/internal/aintern_bitmap.h
index a5bffef..8a61582 100644
--- a/include/allegro5/internal/aintern_bitmap.h
+++ b/include/allegro5/internal/aintern_bitmap.h
@@ -73,21 +73,11 @@ struct ALLEGRO_BITMAP
 struct ALLEGRO_BITMAP_INTERFACE
 {
    int id;
-   void (*draw_bitmap)(struct ALLEGRO_BITMAP *bitmap,
-      ALLEGRO_COLOR tint, float x, float y, int flags);
+
    void (*draw_bitmap_region)(ALLEGRO_BITMAP *bitmap,
       ALLEGRO_COLOR tint,float sx, float sy,
       float sw, float sh, float dx, float dy, int flags);
-   void (*draw_scaled_bitmap)(ALLEGRO_BITMAP *bitmap,
-      ALLEGRO_COLOR tint, float sx, float sy,
-      float sw, float sh, float dx, float dy, float dw, float dh, int flags);
-   void (*draw_rotated_bitmap)(ALLEGRO_BITMAP *bitmap,
-      ALLEGRO_COLOR tint, float cx, float cy,
-      float angle, float dx, float dy, int flags);
-   void (*draw_rotated_scaled_bitmap)(ALLEGRO_BITMAP *bitmap,
-      ALLEGRO_COLOR tint, float cx, float cy,
-      float angle, float dx, float dy, float xscale, float yscale,
-      int flags);
+
    /* After the memory-copy of the bitmap has been modified, need to call this
     * to update the display-specific copy. E.g. with an OpenGL driver, this
     * might create/update a texture. Returns false on failure.
@@ -131,37 +121,13 @@ void _al_draw_bitmap_region_memory(ALLEGRO_BITMAP *bitmap,
    ALLEGRO_COLOR tint,
    int sx, int sy, int sw, int sh,
    int dx, int dy, int flags);
-void _al_draw_bitmap_memory(ALLEGRO_BITMAP *bitmap,
-   ALLEGRO_COLOR tint,
-   int dx, int dy, int flags);
-void _al_draw_scaled_bitmap_memory(ALLEGRO_BITMAP *bitmap,
-   ALLEGRO_COLOR tint,
-   int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int flags);
-void _al_draw_rotated_bitmap_memory(ALLEGRO_BITMAP *bitmap,
-   ALLEGRO_COLOR tint,
-   int center_x, int center_y, int dx, int dy, float angle, int flags);
-void _al_draw_rotated_bitmap_memory(ALLEGRO_BITMAP *bitmap,
-   ALLEGRO_COLOR tint,
-   int center_x, int center_y, int dx, int dy,
-   float angle, int flags);
-void _al_draw_rotated_scaled_bitmap_memory(ALLEGRO_BITMAP *bitmap,
-   ALLEGRO_COLOR tint,
-   int center_x, int center_y, int dx, int dy,
-   float xscale, float yscale, float angle, int flags);
 
 void _al_draw_bitmap_region_memory_fast(ALLEGRO_BITMAP *bitmap,
    int sx, int sy, int sw, int sh,
    int dx, int dy, int flags);
+
 void _al_draw_bitmap_memory_fast(ALLEGRO_BITMAP *bitmap,
   int dx, int dy, int flags);
-void _al_draw_scaled_bitmap_memory_fast(ALLEGRO_BITMAP *bitmap,
-   int sx, int sy, int sw, int sh,
-   int dx, int dy, int dw, int dh, int flags);
-void _al_draw_rotated_scaled_bitmap_memory_fast(ALLEGRO_BITMAP *bitmap,
-   int cx, int cy, int dx, int dy, float xscale, float yscale,
-   float angle, int flags);
-void _al_draw_rotated_bitmap_memory_fast(ALLEGRO_BITMAP *bitmap,
-   int cx, int cy, int dx, int dy, float angle, int flags);
 
 
 /* For blending memory bitmaps */
diff --git a/src/bitmap.c b/src/bitmap.c
index ecc3b0e..4205669 100644
--- a/src/bitmap.c
+++ b/src/bitmap.c
@@ -180,31 +180,8 @@ void al_destroy_bitmap(ALLEGRO_BITMAP *bitmap)
 void al_draw_tinted_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint,
    float dx, float dy, int flags)
 {
-   ALLEGRO_BITMAP *dest = al_get_target_bitmap();
-   ALLEGRO_DISPLAY *display = dest->display;
-   
-   /* If destination is memory, do a memory bitmap */
-   if (dest->flags & ALLEGRO_MEMORY_BITMAP) {
-      _al_draw_bitmap_memory(bitmap, tint, dx, dy, flags);
-   }
-   else {
-      /* if source is memory or incompatible */
-      if ((bitmap->flags & ALLEGRO_MEMORY_BITMAP) ||
-          (!al_is_compatible_bitmap(bitmap)))
-      {
-         if (display && display->vt->draw_memory_bitmap_region) {
-            display->vt->draw_memory_bitmap_region(display, bitmap,
-               0, 0, bitmap->w, bitmap->h, dx, dy, flags);
-         }
-         else {
-            _al_draw_bitmap_memory(bitmap, tint, dx, dy, flags);
-         }
-      }
-      else {
-         /* Compatible display bitmap, use full acceleration */
-         bitmap->vt->draw_bitmap(bitmap, tint, dx, dy, flags);
-      }
-   }
+   al_draw_tinted_bitmap_region(bitmap, tint, 0, 0,
+      bitmap->w, bitmap->h, dx, dy, flags);
 }
 
 
@@ -251,6 +228,42 @@ void al_draw_tinted_bitmap_region(ALLEGRO_BITMAP *bitmap,
    }
 }
 
+void al_draw_tinted_rotated_scaled_bitmap_region(ALLEGRO_BITMAP *bitmap,
+   ALLEGRO_COLOR tint, float cx, float cy, float angle,
+   float xscale, float yscale,
+   float sx, float sy, float sw, float sh, float dx, float dy, int flags)
+{
+   ALLEGRO_TRANSFORM backup;
+	ALLEGRO_TRANSFORM t, t2;
+   al_copy_transform(&backup, al_get_current_transform());
+	al_identity_transform(&t);
+
+   if (flags & ALLEGRO_FLIP_HORIZONTAL)
+	{
+      al_scale_transform(&t, -1, 1);
+      al_translate_transform(&t, sw, 0);
+      flags &= ~ALLEGRO_FLIP_HORIZONTAL;
+	}
+
+   if (flags & ALLEGRO_FLIP_VERTICAL)
+	{
+      al_scale_transform(&t, 1, -1);
+      al_translate_transform(&t, 0, sh);
+      flags &= ~ALLEGRO_FLIP_VERTICAL;
+	}
+
+	al_translate_transform(&t, -cx, -cy);
+   al_scale_transform(&t, xscale, yscale);
+	al_rotate_transform(&t, angle);
+   al_translate_transform(&t, dx, dy);
+   al_copy_transform(&t2, &backup);
+   al_compose_transform(&t2, &t);
+
+	al_use_transform(&t2);
+   al_draw_tinted_bitmap_region(bitmap, tint, sx, sy, sw, sh, 0, 0, flags);
+	al_use_transform(&backup);
+}
+
 
 /* Function: al_draw_bitmap_region
  */
@@ -269,21 +282,10 @@ void al_draw_tinted_scaled_bitmap(ALLEGRO_BITMAP *bitmap,
    float sx, float sy, float sw, float sh,
    float dx, float dy, float dw, float dh, int flags)
 {
-   ALLEGRO_BITMAP *dest = al_get_target_bitmap();
-   ALLEGRO_BITMAP *back = al_get_backbuffer(al_get_current_display());
-
-   if ((bitmap->flags & ALLEGRO_MEMORY_BITMAP) ||
-       (dest->flags & ALLEGRO_MEMORY_BITMAP) ||
-       (!al_is_compatible_bitmap(bitmap)) ||
-       (bitmap == back) || (bitmap->parent == back))
-   {
-      _al_draw_scaled_bitmap_memory(bitmap, tint, sx, sy, sw, sh,
-         dx, dy, dw, dh, flags);
-   }
-   else {
-      bitmap->vt->draw_scaled_bitmap(bitmap, tint, sx, sy, sw, sh,
-         dx, dy, dw, dh, flags);
-   }
+   al_draw_tinted_rotated_scaled_bitmap_region(bitmap, tint,
+      0, 0, 0,
+      dw / sw, dh / sh,
+      sx, sy, sw, sh, dx, dy, flags);
 }
 
 /* Function: al_draw_scaled_bitmap
@@ -307,22 +309,8 @@ void al_draw_tinted_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
    ALLEGRO_COLOR tint,
    float cx, float cy, float dx, float dy, float angle, int flags)
 {
-   ALLEGRO_BITMAP *dest = al_get_target_bitmap();
-   ALLEGRO_BITMAP *back = al_get_backbuffer(al_get_current_display());
-
-   /* If one is a memory bitmap, do memory blit */
-   if ((bitmap->flags & ALLEGRO_MEMORY_BITMAP) ||
-       (dest->flags & ALLEGRO_MEMORY_BITMAP) ||
-       (!al_is_compatible_bitmap(bitmap)) ||
-       (bitmap == back) || (bitmap->parent == back))
-   {
-      _al_draw_rotated_bitmap_memory(bitmap, tint, cx, cy,
-         dx, dy, angle, flags);
-   }
-   else {
-      bitmap->vt->draw_rotated_bitmap(bitmap, tint, cx, cy, dx, dy,
-         angle, flags);
-   }
+   al_draw_tinted_rotated_scaled_bitmap(bitmap, tint, cx, cy, dx, dy,
+      1, 1, angle, flags);
 }
 
 /* Function: al_draw_rotated_bitmap
@@ -342,22 +330,10 @@ void al_draw_tinted_rotated_scaled_bitmap(ALLEGRO_BITMAP *bitmap,
    float cx, float cy, float dx, float dy, float xscale, float yscale,
    float angle, int flags)
 {
-   ALLEGRO_BITMAP *dest = al_get_target_bitmap();
-   ALLEGRO_BITMAP *back = al_get_backbuffer(al_get_current_display());
-
-   /* If one is a memory bitmap, do memory blit */
-    if ((bitmap->flags & ALLEGRO_MEMORY_BITMAP) ||
-       (dest->flags & ALLEGRO_MEMORY_BITMAP) ||
-       (!al_is_compatible_bitmap(bitmap)) ||
-       (bitmap == back) || (bitmap->parent == back))
-   {
-      _al_draw_rotated_scaled_bitmap_memory(bitmap, tint, cx, cy,
-         dx, dy, xscale, yscale, angle, flags);
-   }
-   else {
-      bitmap->vt->draw_rotated_scaled_bitmap(bitmap, tint, cx, cy,
-         dx, dy, xscale, yscale, angle, flags);
-   }
+    al_draw_tinted_rotated_scaled_bitmap_region(bitmap, tint,
+      cx, cy, angle,
+      xscale, yscale,
+      0, 0, bitmap->w, bitmap->h, dx, dy, flags);
 }
 
 
diff --git a/src/memblit.c b/src/memblit.c
index b1e59ea..7326673 100644
--- a/src/memblit.c
+++ b/src/memblit.c
@@ -26,11 +26,6 @@
 #define MIN _ALLEGRO_MIN
 #define MAX _ALLEGRO_MAX
 
-static void _al_draw_transformed_rotated_bitmap_memory(
-   ALLEGRO_BITMAP *src, ALLEGRO_COLOR tint,
-   int cx, int cy, int dx, int dy, float xscale, float yscale,
-   float angle, int flags);
-
 static void _al_draw_transformed_scaled_bitmap_memory(
    ALLEGRO_BITMAP *src, ALLEGRO_COLOR tint,
    int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh,
@@ -61,6 +56,30 @@ static bool is_identity(const ALLEGRO_TRANSFORM* trans)
 }
 
 
+static bool is_scale_trans(const ALLEGRO_TRANSFORM* trans,
+   float *sx, float *sy, float *tx, float *ty)
+{
+   if (   trans->m[1][0] == 0 &&
+          trans->m[2][0] == 0 &&
+          trans->m[0][1] == 0 &&
+          trans->m[2][1] == 0 &&
+          trans->m[0][2] == 0 &&
+          trans->m[1][2] == 0 &&
+          trans->m[2][2] == 1 &&
+          trans->m[3][2] == 0 &&
+          trans->m[0][3] == 0 &&
+          trans->m[1][3] == 0 &&
+          trans->m[2][3] == 0 &&
+          trans->m[3][3] == 1) {
+      *sx = trans->m[0][0];
+      *sy = trans->m[1][1];
+      *tx = trans->m[3][0] / *sx;
+      *ty = trans->m[3][1] / *sy;
+   }
+   return false;
+}
+
+
 static INLINE float get_factor(enum ALLEGRO_BLEND_MODE operation, float alpha)
 {
    switch (operation) {
@@ -321,160 +340,109 @@ static void _al_blend_inline_dest_zero_add(
   if (dh <= 0 || sh <= 0 || dw <= 0 || sw <= 0) return;                  \
 }
 
-void _al_draw_bitmap_region_memory(ALLEGRO_BITMAP *src,
-   ALLEGRO_COLOR tint,
+
+void _al_draw_scaled_bitmap_memory_fast(ALLEGRO_BITMAP *src,
    int sx, int sy, int sw, int sh,
-   int dx, int dy, int flags)
+   int dx, int dy, int dw, int dh, int flags)
 {
+   ALLEGRO_BITMAP *dest = al_get_target_bitmap();
    ALLEGRO_LOCKED_REGION *src_region;
    ALLEGRO_LOCKED_REGION *dst_region;
-   ALLEGRO_BITMAP *dest = al_get_target_bitmap();
-   int x, y;
-   int op, src_mode, dst_mode;
-   int op_alpha, src_alpha, dst_alpha;
-   int xinc, yinc;
-   int yd;
-   int sxd;
-   int dw = sw, dh = sh;
 
-   if(!is_identity(al_get_current_transform()))
-   {
-      _al_draw_transformed_scaled_bitmap_memory(src, tint, sx, sy,
-         sw, sh, dx, dy, sw, sh, flags);
-      return;
-   }
-
-   al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha);
+   float sxinc;
+   float syinc;
+   float _sx;
+   float _sy;
+   float dxinc;
+   float dyinc;
+   float _dx;
+   float _dy;
+   int x, y;
+   int xend;
+   int yend;
+   int size;
 
-   if (DEST_IS_ZERO && SRC_NOT_MODIFIED)
-   {
-      _al_draw_bitmap_region_memory_fast(src, sx, sy, sw, sh, dx, dy, flags);
+   if ((sw <= 0) || (sh <= 0))
       return;
-   }
 
-   ASSERT(_al_pixel_format_is_real(src->format));
-   ASSERT(_al_pixel_format_is_real(dest->format));
+   /* This must be calculated before clipping dw, dh. */
+   sxinc = fabs((float)sw / dw);
+   syinc = fabs((float)sh / dh);
 
-   CLIPPER(src, sx, sy, sw, sh, dest, dx, dy, dw, dh, 1, 1, flags)
+   CLIPPER(src, sx, sy, sw, sh, dest, dx, dy, dw, dh, sxinc, syinc, flags)
 
-#ifdef ALLEGRO_GP2XWIZ
-   if (src_mode == ALLEGRO_ALPHA &&
-	 dst_mode == ALLEGRO_INVERSE_ALPHA &&
-	 src_alpha == ALLEGRO_ALPHA &&
-	 dst_alpha == ALLEGRO_INVERSE_ALPHA) {
-      switch (src->format) {
-	 case ALLEGRO_PIXEL_FORMAT_RGBA_4444: {
-	    switch (dest->format) {
-	       case ALLEGRO_PIXEL_FORMAT_RGB_565: {
-		  _al_draw_bitmap_region_optimized_rgba_4444_to_rgb_565(src, sx, sy, sw, sh, dest, dx, dy, flags);
-		  return;
-               }
-	       case ALLEGRO_PIXEL_FORMAT_RGBA_4444: {
-		  _al_draw_bitmap_region_optimized_rgba_4444_to_rgba_4444(src, sx, sy, sw, sh, dest, dx, dy, flags);
-		  return;
-	       }
-	    }
-	 }
-         case ALLEGRO_PIXEL_FORMAT_RGB_565: {
-            switch (dest->format) {
-               case ALLEGRO_PIXEL_FORMAT_RGB_565: {
-		  _al_draw_bitmap_region_optimized_rgb_565_to_rgb_565(src, sx, sy, sw, sh, dest, dx, dy, flags);
-                  return;
-               }
-            }
-         }
+   if (src->format == dest->format) {
+      if (!(src_region = al_lock_bitmap(src, ALLEGRO_PIXEL_FORMAT_ANY,
+            ALLEGRO_LOCK_READONLY))) {
+         return;
       }
+      /* XXX we should be able to lock less of the destination and use
+       * ALLEGRO_LOCK_WRITEONLY
+       */
+      if (!(dst_region = al_lock_bitmap(dest, ALLEGRO_PIXEL_FORMAT_ANY, 0))) {
+         al_unlock_bitmap(src);
+         return;
+      }
+      size = al_get_pixel_size(src->format);
    }
-#endif
-   /* Blitting to a locked bitmap is a user mistake. */
-   ASSERT(!al_is_bitmap_locked(dest));
-
-   /* Lock the bitmaps */
-   if (!(src_region = al_lock_bitmap_region(src, sx, sy, sw, sh, ALLEGRO_PIXEL_FORMAT_ANY,
-      ALLEGRO_LOCK_READONLY)))
-   {
-      return;
+   else {
+      if (!(src_region = al_lock_bitmap(src, ALLEGRO_PIXEL_FORMAT_ARGB_8888,
+            ALLEGRO_LOCK_READONLY))) {
+         return;
+      }
+      /* XXX we should be able to lock less of the destination and use
+       * ALLEGRO_LOCK_WRITEONLY
+       */
+      if (!(dst_region = al_lock_bitmap(dest, ALLEGRO_PIXEL_FORMAT_ARGB_8888, 0))) {
+         al_unlock_bitmap(src);
+         return;
+      }
+      size = 4;
    }
 
-   if (!(dst_region = al_lock_bitmap_region(dest, dx, dy, sw, sh, ALLEGRO_PIXEL_FORMAT_ANY, 0))) {
-      al_unlock_bitmap(src);
-      return;
+   dxinc = dw < 0 ? -1 : 1;
+   dyinc = dh < 0 ? -1 : 1;
+   xend = abs(dw);
+   yend = abs(dh);
+
+   if (flags & ALLEGRO_FLIP_HORIZONTAL) {
+      sxinc = -sxinc;
+      sx = sx + sw - 1;
    }
 
    if (flags & ALLEGRO_FLIP_VERTICAL) {
-      yd = sh-1;
-      yinc = -1;
-   }
-   else {
-      yd = 0;
-      yinc = 1;
-   }
-   if (flags & ALLEGRO_FLIP_HORIZONTAL) {
-      xinc = -1;
-      sxd = sw-1;
+      syinc = -syinc;
+      _sy = sy + sh - 1;
    }
    else {
-      xinc = 1;
-      sxd = 0;
+      _sy = sy;
    }
 
-   ASSERT(!src->parent);
-   ASSERT(!dest->parent);
-
-   {
-      const int src_data_inc = xinc * al_get_pixel_size(src_region->format);
-      ALLEGRO_COLOR src_color = {0, 0, 0, 0};   /* avoid bogus warnings */
-      ALLEGRO_COLOR dst_color = {0, 0, 0, 0};
-      ALLEGRO_COLOR result;
-
-      for (y = 0; y < sh; y++, yd += yinc) {
-         char *dest_data =
-            (((char *) dst_region->data)
-             + yd * dst_region->pitch);
-
-         char *src_data =
-            (((char *) src_region->data)
-             + y * src_region->pitch);
-
-         if (src_data_inc < 0)
-            src_data += (sw - 1) * -src_data_inc;
-
-         /* Special case this for two reasons:
-          * - we don't need to read and blend with the destination pixel;
-          * - the destination may be uninitialised and may contain NaNs, Inf
-          *   which would not be clobbered when multiplied with zero.
-          */
-         if (dst_mode == ALLEGRO_ZERO && dst_alpha == ALLEGRO_ZERO &&
-            op != ALLEGRO_DEST_MINUS_SRC && op_alpha != ALLEGRO_DEST_MINUS_SRC) {
-            for (x = 0; x < sw; x++) {
-               _AL_INLINE_GET_PIXEL(src_region->format, src_data, src_color, false);
-               src_color.r *= tint.r;
-               src_color.g *= tint.g;
-               src_color.b *= tint.b;
-               src_color.a *= tint.a;
-               _al_blend_inline_dest_zero_add(&src_color, src_mode, src_alpha,
-                  &result);
-               _AL_INLINE_PUT_PIXEL(dst_region->format, dest_data, result, true);
-
-               src_data += src_data_inc;
-            }
-         }
-         else {
-            for (x = 0; x < sw; x++) {
-               _AL_INLINE_GET_PIXEL(src_region->format, src_data, src_color, false);
-               _AL_INLINE_GET_PIXEL(dst_region->format, dest_data, dst_color, false);
-               src_color.r *= tint.r;
-               src_color.g *= tint.g;
-               src_color.b *= tint.b;
-               src_color.a *= tint.a;
-               _al_blend_inline(&src_color, &dst_color,
-                  op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &result);
-               _AL_INLINE_PUT_PIXEL(dst_region->format, dest_data, result, true);
+   #define INNER(t, s, r, w) \
+      for (x = 0; x < xend; x++) { \
+         t pix = r((char *)src_region->data+(int)_sy*src_region->pitch+(int)_sx*s); \
+         w((char *)dst_region->data+(int)_dy*dst_region->pitch+(int)_dx*s, pix); \
+	_sx += sxinc; \
+	_dx += dxinc; \
+      } \
 
-               src_data += src_data_inc;
-            }
-         }
+   _dy = dy;
+   for (y = 0; y < yend; y++) {
+      _sx = sx;
+      _dx = dx;
+      switch (size) {
+         case 2:
+            INNER(uint16_t, size, bmp_read16, bmp_write16)
+            break;
+         case 3:
+            INNER(uint32_t, size, READ3BYTES, WRITE3BYTES)
+            break;
+         default:
+            INNER(uint32_t, size, bmp_read32, bmp_write32)
+            break;
       }
+      _sy += syinc;
+      _dy += dyinc;
    }
 
    al_unlock_bitmap(src);
@@ -482,14 +450,6 @@ void _al_draw_bitmap_region_memory(ALLEGRO_BITMAP *src,
 }
 
 
-
-void _al_draw_bitmap_memory(ALLEGRO_BITMAP *bitmap,
-   ALLEGRO_COLOR tint, int dx, int dy, int flags)
-{
-   _al_draw_bitmap_region_memory(bitmap, tint, 0, 0,
-      bitmap->w, bitmap->h, dx, dy, flags);
-}
-
 void _al_draw_scaled_bitmap_memory(ALLEGRO_BITMAP *src,
    ALLEGRO_COLOR tint,
    int sx, int sy, int sw, int sh,
@@ -512,13 +472,6 @@ void _al_draw_scaled_bitmap_memory(ALLEGRO_BITMAP *src,
    int xend;
    int yend;
 
-   if(!is_identity(al_get_current_transform()))
-   {
-      _al_draw_transformed_scaled_bitmap_memory(src, tint, sx, sy,
-         sw, sh, dx, dy, dw, dh, flags);
-      return;
-   }
-
    al_get_separate_blender(&op, &src_mode, &dst_mode,
       &op_alpha, &src_alpha, &dst_alpha);
 
@@ -634,6 +587,174 @@ void _al_draw_scaled_bitmap_memory(ALLEGRO_BITMAP *src,
 }
 
 
+void _al_draw_bitmap_region_memory(ALLEGRO_BITMAP *src,
+   ALLEGRO_COLOR tint,
+   int sx, int sy, int sw, int sh,
+   int dx, int dy, int flags)
+{
+   ALLEGRO_LOCKED_REGION *src_region;
+   ALLEGRO_LOCKED_REGION *dst_region;
+   ALLEGRO_BITMAP *dest = al_get_target_bitmap();
+   int x, y;
+   int op, src_mode, dst_mode;
+   int op_alpha, src_alpha, dst_alpha;
+   int xinc, yinc;
+   int yd;
+   int sxd;
+   int dw = sw, dh = sh;
+
+   if(!is_identity(al_get_current_transform()))
+   {
+      float xscale, yscale, xtrans, ytrans;
+      if (is_scale_trans(al_get_current_transform(), &xscale, &yscale,
+         &xtrans, &ytrans)) {
+         _al_draw_scaled_bitmap_memory(src, tint, sx, sy, sw, sh,
+            dx + xtrans, dy + ytrans, sw * xscale, sy * yscale, flags);
+      }
+      else {
+         _al_draw_transformed_scaled_bitmap_memory(src, tint, sx, sy,
+            sw, sh, dx, dy, sw, sh, flags);
+      }
+      return;
+   }
+
+   al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha);
+
+   if (DEST_IS_ZERO && SRC_NOT_MODIFIED)
+   {
+      _al_draw_bitmap_region_memory_fast(src, sx, sy, sw, sh, dx, dy, flags);
+      return;
+   }
+
+   ASSERT(_al_pixel_format_is_real(src->format));
+   ASSERT(_al_pixel_format_is_real(dest->format));
+
+   CLIPPER(src, sx, sy, sw, sh, dest, dx, dy, dw, dh, 1, 1, flags)
+
+#ifdef ALLEGRO_GP2XWIZ
+   if (src_mode == ALLEGRO_ALPHA &&
+	 dst_mode == ALLEGRO_INVERSE_ALPHA &&
+	 src_alpha == ALLEGRO_ALPHA &&
+	 dst_alpha == ALLEGRO_INVERSE_ALPHA) {
+      switch (src->format) {
+	 case ALLEGRO_PIXEL_FORMAT_RGBA_4444: {
+	    switch (dest->format) {
+	       case ALLEGRO_PIXEL_FORMAT_RGB_565: {
+		  _al_draw_bitmap_region_optimized_rgba_4444_to_rgb_565(src, sx, sy, sw, sh, dest, dx, dy, flags);
+		  return;
+               }
+	       case ALLEGRO_PIXEL_FORMAT_RGBA_4444: {
+		  _al_draw_bitmap_region_optimized_rgba_4444_to_rgba_4444(src, sx, sy, sw, sh, dest, dx, dy, flags);
+		  return;
+	       }
+	    }
+	 }
+         case ALLEGRO_PIXEL_FORMAT_RGB_565: {
+            switch (dest->format) {
+               case ALLEGRO_PIXEL_FORMAT_RGB_565: {
+		  _al_draw_bitmap_region_optimized_rgb_565_to_rgb_565(src, sx, sy, sw, sh, dest, dx, dy, flags);
+                  return;
+               }
+            }
+         }
+      }
+   }
+#endif
+   /* Blitting to a locked bitmap is a user mistake. */
+   ASSERT(!al_is_bitmap_locked(dest));
+
+   /* Lock the bitmaps */
+   if (!(src_region = al_lock_bitmap_region(src, sx, sy, sw, sh, ALLEGRO_PIXEL_FORMAT_ANY,
+      ALLEGRO_LOCK_READONLY)))
+   {
+      return;
+   }
+
+   if (!(dst_region = al_lock_bitmap_region(dest, dx, dy, sw, sh, ALLEGRO_PIXEL_FORMAT_ANY, 0))) {
+      al_unlock_bitmap(src);
+      return;
+   }
+
+   if (flags & ALLEGRO_FLIP_VERTICAL) {
+      yd = sh-1;
+      yinc = -1;
+   }
+   else {
+      yd = 0;
+      yinc = 1;
+   }
+   if (flags & ALLEGRO_FLIP_HORIZONTAL) {
+      xinc = -1;
+      sxd = sw-1;
+   }
+   else {
+      xinc = 1;
+      sxd = 0;
+   }
+
+   ASSERT(!src->parent);
+   ASSERT(!dest->parent);
+
+   {
+      const int src_data_inc = xinc * al_get_pixel_size(src_region->format);
+      ALLEGRO_COLOR src_color = {0, 0, 0, 0};   /* avoid bogus warnings */
+      ALLEGRO_COLOR dst_color = {0, 0, 0, 0};
+      ALLEGRO_COLOR result;
+
+      for (y = 0; y < sh; y++, yd += yinc) {
+         char *dest_data =
+            (((char *) dst_region->data)
+             + yd * dst_region->pitch);
+
+         char *src_data =
+            (((char *) src_region->data)
+             + y * src_region->pitch);
+
+         if (src_data_inc < 0)
+            src_data += (sw - 1) * -src_data_inc;
+
+         /* Special case this for two reasons:
+          * - we don't need to read and blend with the destination pixel;
+          * - the destination may be uninitialised and may contain NaNs, Inf
+          *   which would not be clobbered when multiplied with zero.
+          */
+         if (dst_mode == ALLEGRO_ZERO && dst_alpha == ALLEGRO_ZERO &&
+            op != ALLEGRO_DEST_MINUS_SRC && op_alpha != ALLEGRO_DEST_MINUS_SRC) {
+            for (x = 0; x < sw; x++) {
+               _AL_INLINE_GET_PIXEL(src_region->format, src_data, src_color, false);
+               src_color.r *= tint.r;
+               src_color.g *= tint.g;
+               src_color.b *= tint.b;
+               src_color.a *= tint.a;
+               _al_blend_inline_dest_zero_add(&src_color, src_mode, src_alpha,
+                  &result);
+               _AL_INLINE_PUT_PIXEL(dst_region->format, dest_data, result, true);
+
+               src_data += src_data_inc;
+            }
+         }
+         else {
+            for (x = 0; x < sw; x++) {
+               _AL_INLINE_GET_PIXEL(src_region->format, src_data, src_color, false);
+               _AL_INLINE_GET_PIXEL(dst_region->format, dest_data, dst_color, false);
+               src_color.r *= tint.r;
+               src_color.g *= tint.g;
+               src_color.b *= tint.b;
+               src_color.a *= tint.a;
+               _al_blend_inline(&src_color, &dst_color,
+                  op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha, &result);
+               _AL_INLINE_PUT_PIXEL(dst_region->format, dest_data, result, true);
+
+               src_data += src_data_inc;
+            }
+         }
+      }
+   }
+
+   al_unlock_bitmap(src);
+   al_unlock_bitmap(dest);
+}
+
 /*
 * Get scanline starts, ends and deltas, and clipping coordinates.
 */
@@ -1183,52 +1304,6 @@ do {                                                                         \
 } while (0)
 
 
-void _al_draw_rotated_scaled_bitmap_memory(ALLEGRO_BITMAP *src,
-   ALLEGRO_COLOR tint,
-   int cx, int cy, int dx, int dy, float xscale, float yscale,
-   float angle, int flags)
-{
-   ALLEGRO_BITMAP *dst = al_get_target_bitmap();
-   int op, src_mode, dst_mode;
-   int op_alpha, src_alpha, dst_alpha;
-
-   if(!is_identity(al_get_current_transform()))
-   {
-      _al_draw_transformed_rotated_bitmap_memory(src, tint,
-         cx, cy, dx, dy, xscale, yscale, angle,
-          flags);
-      return;
-   }
-
-   al_get_separate_blender(&op, &src_mode, &dst_mode,
-      &op_alpha, &src_alpha, &dst_alpha);
-
-   if (src_mode == ALLEGRO_ONE && dst_mode == ALLEGRO_ZERO &&
-      tint.r == 1.0f && tint.g == 1.0f && tint.b == 1.0f && tint.a == 1.0f &&
-      (src->format == dst->format)) {
-      _al_draw_rotated_scaled_bitmap_memory_fast(src,
-         cx, cy, dx, dy, xscale, yscale, angle, flags);
-      return;
-   }
-
-   angle = -angle;
-
-   ASSERT(_al_pixel_format_is_real(src->format));
-   ASSERT(_al_pixel_format_is_real(dst->format));
-
-   DO_DRAW_ROTATED_SCALED(src, dst,
-      cx, cy, dx, dy, xscale, yscale, -angle, flags);
-}
-
-
-void _al_draw_rotated_bitmap_memory(ALLEGRO_BITMAP *src,
-   ALLEGRO_COLOR tint,
-   int cx, int cy, int dx, int dy, float angle, int flags)
-{
-   _al_draw_rotated_scaled_bitmap_memory(src, tint,
-      cx, cy, dx, dy, 1.0f, 1.0f, angle, flags);
-}
-
 static void _al_draw_transformed_bitmap_memory(ALLEGRO_BITMAP *src,
    ALLEGRO_COLOR tint,
    int sx, int sy, int sw, int sh, int dw, int dh,
@@ -1303,28 +1378,6 @@ static void _al_draw_transformed_bitmap_memory(ALLEGRO_BITMAP *src,
    DO_PARALLELOGRAM_MAP(true, flags);
 }
 
-static void _al_draw_transformed_rotated_bitmap_memory(
-   ALLEGRO_BITMAP *src, ALLEGRO_COLOR tint,
-   int cx, int cy, int dx, int dy, float xscale, float yscale,
-   float angle, int flags)
-{
-   ALLEGRO_TRANSFORM local_trans;
-   int w, h;
-
-   al_identity_transform(&local_trans);
-   al_translate_transform(&local_trans, -cx, -cy);
-   al_scale_transform(&local_trans, xscale, yscale);
-   al_rotate_transform(&local_trans, angle);
-   al_translate_transform(&local_trans, dx, dy);
-   al_compose_transform(&local_trans, al_get_current_transform());
-
-   w = al_get_bitmap_width(src);
-   h = al_get_bitmap_height(src);
-
-   _al_draw_transformed_bitmap_memory(src, tint, 0, 0, w, h, w, h,
-      &local_trans, flags);
-}
-
 static void _al_draw_transformed_scaled_bitmap_memory(
    ALLEGRO_BITMAP *src, ALLEGRO_COLOR tint,
    int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int flags)
@@ -1439,114 +1492,6 @@ void _al_draw_bitmap_region_memory_fast(ALLEGRO_BITMAP *bitmap,
 }
 
 
-void _al_draw_scaled_bitmap_memory_fast(ALLEGRO_BITMAP *src,
-   int sx, int sy, int sw, int sh,
-   int dx, int dy, int dw, int dh, int flags)
-{
-   ALLEGRO_BITMAP *dest = al_get_target_bitmap();
-   ALLEGRO_LOCKED_REGION *src_region;
-   ALLEGRO_LOCKED_REGION *dst_region;
-
-   float sxinc;
-   float syinc;
-   float _sx;
-   float _sy;
-   float dxinc;
-   float dyinc;
-   float _dx;
-   float _dy;
-   int x, y;
-   int xend;
-   int yend;
-   int size;
-
-   if ((sw <= 0) || (sh <= 0))
-      return;
-
-   /* This must be calculated before clipping dw, dh. */
-   sxinc = fabs((float)sw / dw);
-   syinc = fabs((float)sh / dh);
-
-   CLIPPER(src, sx, sy, sw, sh, dest, dx, dy, dw, dh, sxinc, syinc, flags)
-
-   if (src->format == dest->format) {
-      if (!(src_region = al_lock_bitmap(src, ALLEGRO_PIXEL_FORMAT_ANY,
-            ALLEGRO_LOCK_READONLY))) {
-         return;
-      }
-      /* XXX we should be able to lock less of the destination and use
-       * ALLEGRO_LOCK_WRITEONLY
-       */
-      if (!(dst_region = al_lock_bitmap(dest, ALLEGRO_PIXEL_FORMAT_ANY, 0))) {
-         al_unlock_bitmap(src);
-         return;
-      }
-      size = al_get_pixel_size(src->format);
-   }
-   else {
-      if (!(src_region = al_lock_bitmap(src, ALLEGRO_PIXEL_FORMAT_ARGB_8888,
-            ALLEGRO_LOCK_READONLY))) {
-         return;
-      }
-      /* XXX we should be able to lock less of the destination and use
-       * ALLEGRO_LOCK_WRITEONLY
-       */
-      if (!(dst_region = al_lock_bitmap(dest, ALLEGRO_PIXEL_FORMAT_ARGB_8888, 0))) {
-         al_unlock_bitmap(src);
-         return;
-      }
-      size = 4;
-   }
-
-   dxinc = dw < 0 ? -1 : 1;
-   dyinc = dh < 0 ? -1 : 1;
-   xend = abs(dw);
-   yend = abs(dh);
-
-   if (flags & ALLEGRO_FLIP_HORIZONTAL) {
-      sxinc = -sxinc;
-      sx = sx + sw - 1;
-   }
-
-   if (flags & ALLEGRO_FLIP_VERTICAL) {
-      syinc = -syinc;
-      _sy = sy + sh - 1;
-   }
-   else {
-      _sy = sy;
-   }
-
-   #define INNER(t, s, r, w) \
-      for (x = 0; x < xend; x++) { \
-         t pix = r((char *)src_region->data+(int)_sy*src_region->pitch+(int)_sx*s); \
-         w((char *)dst_region->data+(int)_dy*dst_region->pitch+(int)_dx*s, pix); \
-	_sx += sxinc; \
-	_dx += dxinc; \
-      } \
-
-   _dy = dy;
-   for (y = 0; y < yend; y++) {
-      _sx = sx;
-      _dx = dx;
-      switch (size) {
-         case 2:
-            INNER(uint16_t, size, bmp_read16, bmp_write16)
-            break;
-         case 3:
-            INNER(uint32_t, size, READ3BYTES, WRITE3BYTES)
-            break;
-         default:
-            INNER(uint32_t, size, bmp_read32, bmp_write32)
-            break;
-      }
-      _sy += syinc;
-      _dy += dyinc;
-   }
-
-   al_unlock_bitmap(src);
-   al_unlock_bitmap(dest);
-}
-
 /*
 * Get scanline starts, ends and deltas, and clipping coordinates.
 */
@@ -2040,34 +1985,4 @@ static void _al_parallelogram_map_fast(ALLEGRO_BITMAP *src, al_fixed xs[4],
    al_unlock_bitmap(dst);
 }
 
-void _al_draw_rotated_scaled_bitmap_memory_fast(ALLEGRO_BITMAP *src,
-   int cx, int cy, int dx, int dy, float xscale, float yscale,
-   float angle, int flags)
-{
-   al_fixed xs[4], ys[4];
-   al_fixed fix_dx;
-   al_fixed fix_dy;
-   al_fixed fix_cx;
-   al_fixed fix_cy;
-   al_fixed fix_angle;
-   al_fixed fix_xscale;
-   al_fixed fix_yscale;
-
-   angle = -angle;
-
-   fix_dx = al_ftofix(dx);
-   fix_dy = al_ftofix(dy);
-   fix_cx = al_ftofix(cx);
-   fix_cy = al_ftofix(cy);
-   fix_angle = al_ftofix(-angle*256/(ALLEGRO_PI*2));
-   fix_xscale = al_ftofix(xscale);
-   fix_yscale = al_ftofix(yscale);
-
-   _al_rotate_scale_flip_coordinates(src->w << 16, src->h << 16,
-      fix_dx, fix_dy, fix_cx, fix_cy, fix_angle, fix_xscale, fix_yscale,
-      flags & ALLEGRO_FLIP_HORIZONTAL, flags & ALLEGRO_FLIP_VERTICAL, xs, ys);
-
-   _al_parallelogram_map_fast(src, xs, ys, 0, 0, src->w, src->h);
-}
-
 /* vim: set sts=3 sw=3 et: */
diff --git a/src/opengl/ogl_bitmap.c b/src/opengl/ogl_bitmap.c
index 1ea1f8c..c55b5a8 100644
--- a/src/opengl/ogl_bitmap.c
+++ b/src/opengl/ogl_bitmap.c
@@ -354,33 +354,6 @@ static void draw_quad(ALLEGRO_BITMAP *bitmap,
 #undef SWAP
 
 
-
-static void ogl_draw_scaled_bitmap(ALLEGRO_BITMAP *bitmap,
-   ALLEGRO_COLOR tint, float sx, float sy,
-   float sw, float sh, float dx, float dy, float dw, float dh, int flags)
-{
-   // FIXME: hack
-   // FIXME: need format conversion if they don't match
-   ALLEGRO_BITMAP *target = al_get_target_bitmap();
-   ALLEGRO_BITMAP_OGL *ogl_target = (ALLEGRO_BITMAP_OGL *)target;
-   ALLEGRO_DISPLAY *disp = al_get_current_display();
-   
-   if (target->parent) {
-      ogl_target = (ALLEGRO_BITMAP_OGL *)target->parent;
-   }
-      
-   if (disp->ogl_extras->opengl_target != ogl_target ||
-         !setup_blending(disp) || target->locked) {
-      _al_draw_scaled_bitmap_memory(bitmap, tint, sx, sy, sw, sh,
-         dx, dy, dw, dh, flags);
-      return;
-   }
-
-   draw_quad(bitmap, tint, sx, sy, sw, sh, 0, 0, dx, dy, dw, dh, 1, 1, 0, flags);
-}
-
-
-
 static void ogl_draw_bitmap_region(ALLEGRO_BITMAP *bitmap,
    ALLEGRO_COLOR tint, float sx, float sy,
    float sw, float sh, float dx, float dy, int flags)
@@ -483,71 +456,6 @@ static void ogl_draw_bitmap_region(ALLEGRO_BITMAP *bitmap,
 }
 
 
-
-/* Draw the bitmap at the specified position. */
-static void ogl_draw_bitmap(ALLEGRO_BITMAP *bitmap,
-   ALLEGRO_COLOR tint, float x, float y,
-   int flags)
-{
-   ogl_draw_bitmap_region(bitmap, tint, 0, 0, bitmap->w, bitmap->h, x, y, flags);
-}
-
-
-
-static void ogl_draw_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
-   ALLEGRO_COLOR tint, float cx, float cy,
-   float dx, float dy, float angle, int flags)
-{
-   // FIXME: hack
-   // FIXME: need format conversion if they don't match
-   ALLEGRO_BITMAP *target = al_get_target_bitmap();
-   ALLEGRO_BITMAP_OGL *ogl_target = (ALLEGRO_BITMAP_OGL *)target;
-   ALLEGRO_DISPLAY *disp = target->display;
-   
-   if (target->parent) {
-       ogl_target = (ALLEGRO_BITMAP_OGL *)target->parent;
-   }
-   
-   if (disp->ogl_extras->opengl_target != ogl_target ||
-      !setup_blending(disp) || target->locked) {
-      _al_draw_rotated_bitmap_memory(bitmap, tint, cx, cy, dx, dy, angle, flags);
-      return;
-   }
-
-   draw_quad(bitmap, tint, 0, 0, bitmap->w, bitmap->h, cx, cy,
-      dx, dy, bitmap->w, bitmap->h, 1, 1, angle, flags);
-}
-
-
-
-static void ogl_draw_rotated_scaled_bitmap(ALLEGRO_BITMAP *bitmap,
-   ALLEGRO_COLOR tint, 
-   float cx, float cy, float dx, float dy, float xscale, float yscale,
-   float angle, int flags)
-{
-   // FIXME: hack
-   // FIXME: need format conversion if they don't match
-   ALLEGRO_BITMAP *target = al_get_target_bitmap();
-   ALLEGRO_BITMAP_OGL *ogl_target = (ALLEGRO_BITMAP_OGL *)target;
-   ALLEGRO_DISPLAY *disp = target->display;
-   
-   if (target->parent) {
-       ogl_target = (ALLEGRO_BITMAP_OGL *)target->parent;
-   }
-   
-   if (disp->ogl_extras->opengl_target != ogl_target ||
-      !setup_blending(disp) || target->locked) {
-      _al_draw_rotated_scaled_bitmap_memory(bitmap, tint, cx, cy,
-         dx, dy, xscale, yscale, angle, flags);
-      return;
-   }
-
-   draw_quad(bitmap, tint, 0, 0, bitmap->w, bitmap->h, cx, cy, dx, dy,
-      bitmap->w, bitmap->h, xscale, yscale, angle, flags);
-}
-
-
-
 /* Helper to get smallest fitting power of two. */
 static int pot(int x)
 {
@@ -557,7 +465,6 @@ static int pot(int x)
 }
 
 
-
 // FIXME: need to do all the logic AllegroGL does, checking extensions,
 // proxy textures, formats, limits ...
 static bool ogl_upload_bitmap(ALLEGRO_BITMAP *bitmap)
@@ -1026,11 +933,7 @@ static ALLEGRO_BITMAP_INTERFACE *ogl_bitmap_driver(void)
    glbmp_vt = al_malloc(sizeof *glbmp_vt);
    memset(glbmp_vt, 0, sizeof *glbmp_vt);
 
-   glbmp_vt->draw_bitmap = ogl_draw_bitmap;
    glbmp_vt->draw_bitmap_region = ogl_draw_bitmap_region;
-   glbmp_vt->draw_scaled_bitmap = ogl_draw_scaled_bitmap;
-   glbmp_vt->draw_rotated_bitmap = ogl_draw_rotated_bitmap;
-   glbmp_vt->draw_rotated_scaled_bitmap = ogl_draw_rotated_scaled_bitmap;
    glbmp_vt->upload_bitmap = ogl_upload_bitmap;
    glbmp_vt->update_clipping_rectangle = ogl_update_clipping_rectangle;
    glbmp_vt->destroy_bitmap = ogl_destroy_bitmap;
diff --git a/src/rotate.c b/src/rotate.c
index b5e7e16..09a8e7b 100644
--- a/src/rotate.c
+++ b/src/rotate.c
@@ -23,84 +23,3 @@
 #include "allegro5/allegro.h"
 #include "allegro5/internal/aintern.h"
 #include <math.h>
-
-/* _al_rotate_scale_flip_coordinates:
- *  Calculates the coordinates for the rotated, scaled and flipped sprite,
- *  and passes them on to the given function.
- */
-void _al_rotate_scale_flip_coordinates(al_fixed w, al_fixed h,
-				    al_fixed x, al_fixed y, al_fixed cx, al_fixed cy,
-				    al_fixed angle,
-				    al_fixed scale_x, al_fixed scale_y,
-				    int h_flip, int v_flip,
-				    al_fixed xs[4], al_fixed ys[4])
-{
-   al_fixed fix_cos, fix_sin;
-   int tl = 0, tr = 1, bl = 3, br = 2;
-   int tmp;
-   double cos_angle, sin_angle;
-   al_fixed xofs, yofs;
-
-   /* Setting angle to the range -180...180 degrees makes sin & cos
-      more numerically stable. (Yes, this does have an effect for big
-      angles!) Note that using "real" sin() and cos() gives much better
-      precision than al_fixsin() and al_fixcos(). */
-   angle = angle & 0xffffff;
-   if (angle >= 0x800000)
-      angle -= 0x1000000;
-
-   _AL_SINCOS(angle * (ALLEGRO_PI / (double)0x800000), sin_angle, cos_angle);
-
-   if (cos_angle >= 0)
-      fix_cos = (int)(cos_angle * 0x10000 + 0.5);
-   else
-      fix_cos = (int)(cos_angle * 0x10000 - 0.5);
-   if (sin_angle >= 0)
-      fix_sin = (int)(sin_angle * 0x10000 + 0.5);
-   else
-      fix_sin = (int)(sin_angle * 0x10000 - 0.5);
-
-   /* Decide what order to take corners in. */
-   if (v_flip) {
-      tl = 3;
-      tr = 2;
-      bl = 0;
-      br = 1;
-   }
-   else {
-      tl = 0;
-      tr = 1;
-      bl = 3;
-      br = 2;
-   }
-   if (h_flip) {
-      tmp = tl;
-      tl = tr;
-      tr = tmp;
-      tmp = bl;
-      bl = br;
-      br = tmp;
-   }
-
-   /* Calculate new coordinates of all corners. */
-   w = al_fixmul(w, scale_x);
-   h = al_fixmul(h, scale_y);
-   cx = al_fixmul(cx, scale_x);
-   cy = al_fixmul(cy, scale_y);
-
-   xofs = x - al_fixmul(cx, fix_cos) + al_fixmul(cy, fix_sin);
-
-   yofs = y - al_fixmul(cx, fix_sin) - al_fixmul(cy, fix_cos);
-
-   xs[tl] = xofs;
-   ys[tl] = yofs;
-   xs[tr] = xofs + al_fixmul(w, fix_cos);
-   ys[tr] = yofs + al_fixmul(w, fix_sin);
-   xs[bl] = xofs - al_fixmul(h, fix_sin);
-   ys[bl] = yofs + al_fixmul(h, fix_cos);
-
-   xs[br] = xs[tr] + xs[bl] - xs[tl];
-   ys[br] = ys[tr] + ys[bl] - ys[tl];
-}
-
-
diff --git a/src/win/d3d_bmp.cpp b/src/win/d3d_bmp.cpp
index 9adc62c..892e59c 100644
--- a/src/win/d3d_bmp.cpp
+++ b/src/win/d3d_bmp.cpp
@@ -794,21 +794,6 @@ static void d3d_blit_real(ALLEGRO_BITMAP *src,
 
 /* Blitting functions */
 
-static void d3d_draw_bitmap(ALLEGRO_BITMAP *bitmap,
-   ALLEGRO_COLOR tint,
-   float dx, float dy, int flags)
-{
-   if (!_al_d3d_render_to_texture_supported() || !_al_d3d_supports_separate_alpha_blend(al_get_current_display())) {
-      _al_draw_bitmap_memory(bitmap, tint, (int) dx, (int) dy, flags);
-      return;
-   }
-
-   d3d_blit_real(bitmap, tint, 0, 0, bitmap->w, bitmap->h,
-      bitmap->w/2, bitmap->h/2,
-      dx, dy, bitmap->w, bitmap->h,
-      0.0f, flags, false);
-}
-
 static void d3d_draw_bitmap_region(ALLEGRO_BITMAP *bitmap,
    ALLEGRO_COLOR tint,
    float sx, float sy, float sw, float sh, float dx, float dy, int flags)
@@ -827,60 +812,6 @@ static void d3d_draw_bitmap_region(ALLEGRO_BITMAP *bitmap,
       0.0f, flags, false);
 }
 
-static void d3d_draw_scaled_bitmap(ALLEGRO_BITMAP *bitmap,
-   ALLEGRO_COLOR tint, float sx, float sy,
-   float sw, float sh, float dx, float dy, float dw, float dh, int flags)
-{
-   if (!_al_d3d_render_to_texture_supported() || !_al_d3d_supports_separate_alpha_blend(al_get_current_display())) {
-      _al_draw_scaled_bitmap_memory(bitmap, tint,
-         (int) sx, (int) sy, (int) sw, (int) sh,
-         (int) dx, (int) dy, (int) dw, (int) dh, flags);
-      return;
-   }
-
-   d3d_blit_real(bitmap, tint,
-      sx, sy, sw, sh, (sw-sx)/2, (sh-sy)/2,
-      dx, dy, dw, dh, 0.0f,
-      flags, false);
-}
-
-static void d3d_draw_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
-   ALLEGRO_COLOR tint,
-   float cx, float cy,
-   float dx, float dy, float angle, int flags)
-{
-   if (!_al_d3d_render_to_texture_supported() || !_al_d3d_supports_separate_alpha_blend(al_get_current_display())) {
-      _al_draw_rotated_bitmap_memory(bitmap, tint, (int) cx, (int) cy,
-         (int) dx, (int) dy, angle, flags);
-      return;
-   }
-
-   d3d_blit_real(bitmap, tint,
-      0, 0, bitmap->w, bitmap->h,
-      cx, cy,
-      dx, dy, bitmap->w, bitmap->h,
-      angle, flags, true);
-}
-
-static void d3d_draw_rotated_scaled_bitmap(ALLEGRO_BITMAP *bitmap,
-   ALLEGRO_COLOR tint, float cx, float cy,
-   float dx, float dy, float xscale, float yscale, float angle,
-   int flags)
-{
-   if (!_al_d3d_render_to_texture_supported() || !_al_d3d_supports_separate_alpha_blend(al_get_current_display())) {
-      _al_draw_rotated_scaled_bitmap_memory(bitmap, tint,
-         (int) cx, (int) cy,
-         (int) dx, (int) dy, xscale, yscale, angle, flags);
-      return;
-   }
-
-   d3d_blit_real(bitmap, tint,
-      0, 0, bitmap->w, bitmap->h,
-      cx, cy,
-      dx, dy, bitmap->w*xscale, bitmap->h*yscale,
-      angle, flags, true);
-}
-
 static void d3d_destroy_bitmap(ALLEGRO_BITMAP *bitmap)
 {
    ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap;
@@ -1025,11 +956,7 @@ ALLEGRO_BITMAP_INTERFACE *_al_bitmap_d3d_driver(void)
    vt = (ALLEGRO_BITMAP_INTERFACE *)al_malloc(sizeof *vt);
    memset(vt, 0, sizeof *vt);
 
-   vt->draw_bitmap = d3d_draw_bitmap;
    vt->draw_bitmap_region = d3d_draw_bitmap_region;
-   vt->draw_scaled_bitmap = d3d_draw_scaled_bitmap;
-   vt->draw_rotated_bitmap = d3d_draw_rotated_bitmap;
-   vt->draw_rotated_scaled_bitmap = d3d_draw_rotated_scaled_bitmap;
    vt->upload_bitmap = d3d_upload_bitmap;
    vt->update_clipping_rectangle = NULL;
    vt->destroy_bitmap = d3d_destroy_bitmap;


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