[AD] fix for using transformations without a display and make blending mode a per-display state

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


This patch does not move the current transformation out of the display
into TLS (it was the solution Trent agreed to in the opengl fix thread)
but instead makes the blending mode a per-display property just as the
current transformations already was.

For something like drawing into a memory bitmap to still work when there
is no current display, I used a trick suggested by Evert on allegro.cc -
as a special case store the per-display state in TLS anyway if there is
no display. (In the code an empty ALLEGRO_DISPLAY is put into
tls->memory_display, which has no other function but to contain a
current transformation and blending state.)

I also added ALLEGRO_TRANSFORM as new option to al_[re]store_state and
removed some outdated code.

I didn't yet try to copy over the TLS state to a newly created display,
or save the state of the last destroyed display to TLS, as is done in
Evert's suggestion - it's probably not very common to hit one of those
circumstances and it's hard to say what the expected behavior should be.

-- 
Elias Pschernig <elias.pschernig@xxxxxxxxxx>
diff --git a/docs/src/refman/state.txt b/docs/src/refman/state.txt
index 5c29668..96fce2e 100644
--- a/docs/src/refman/state.txt
+++ b/docs/src/refman/state.txt
@@ -8,6 +8,32 @@ These functions are declared in the main Allegro header file:
 
 Opaque type which is passed to [al_store_state]/[al_restore_state].
 
+The various state kept internally by Allegro can be displayed like this:
+
+      global
+          active system driver
+              current config
+      per thread
+          new bitmap params
+          new display params
+          active file interface
+          errno
+          current display
+              current transformation
+              current blending mode
+              deferred drawing
+          current target bitmap
+              current clipping rectangle
+              bitmap locking
+
+In general, the only real global state is the active system driver. All
+other global state is per-thread, so if your application has multiple
+separate threads they never will interfere with each other. (Except if
+there are objects accessed by multiple threads of course. Usually you
+want to minimize that though and for the remaining cases use
+synchronization primitives described in the threads section or events
+described in the events section to control inter-thread communication.)
+
 ## API: ALLEGRO_STATE_FLAGS
 
 Flags which can be passed to [al_store_state]/[al_restore_state] as bit
@@ -20,6 +46,7 @@ to the following al_set\_/al_get\_ calls:
 * ALLEGRO_STATE_DISPLAY - current_display
 * ALLEGRO_STATE_TARGET_BITMAP - target_bitmap 
 * ALLEGRO_STATE_BLENDER - blender
+* ALLEGRO_STATE_TRANSFORMATION - current_transformation
 * ALLEGRO_STATE_NEW_FILE_INTERFACE - new_file_interface 
 * ALLEGRO_STATE_BITMAP - same as ALLEGRO_STATE_NEW_BITMAP_PARAMETERS and
                          ALLEGRO_STATE_TARGET_BITMAP
diff --git a/include/allegro5/internal/aintern_display.h b/include/allegro5/internal/aintern_display.h
index 351510c..6d788d5 100644
--- a/include/allegro5/internal/aintern_display.h
+++ b/include/allegro5/internal/aintern_display.h
@@ -77,6 +77,17 @@ struct ALLEGRO_DISPLAY_INTERFACE
 
 struct ALLEGRO_OGL_EXTRAS;
 
+typedef struct ALLEGRO_BLENDER
+{
+   int blend_op;
+   int blend_source;
+   int blend_dest;
+   int blend_alpha_op;
+   int blend_alpha_source;
+   int blend_alpha_dest;
+   ALLEGRO_COLOR blend_color;
+} ALLEGRO_BLENDER;
+
 /* These are settings Allegro itself doesn't really care about on its
  * own, but which users may want to specify for a display anyway.
  */
@@ -113,6 +124,7 @@ struct ALLEGRO_DISPLAY
    uintptr_t cache_texture;
    
    ALLEGRO_TRANSFORM cur_transform;
+   ALLEGRO_BLENDER cur_blender;
 };
 
 int  _al_score_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref);
@@ -130,6 +142,8 @@ void _al_destroy_display_bitmaps(ALLEGRO_DISPLAY *d);
 /* Defined in tls.c */
 void _al_set_new_display_settings(ALLEGRO_EXTRA_DISPLAY_SETTINGS *settings);
 ALLEGRO_EXTRA_DISPLAY_SETTINGS *_al_get_new_display_settings(void);
+ALLEGRO_DISPLAY *_al_get_current_display(void);
+void _al_initialize_blender(ALLEGRO_BLENDER *blender);
 
 #ifdef __cplusplus
 }
diff --git a/include/allegro5/tls.h b/include/allegro5/tls.h
index e537bd3..98b0ab0 100644
--- a/include/allegro5/tls.h
+++ b/include/allegro5/tls.h
@@ -36,6 +36,7 @@ typedef enum ALLEGRO_STATE_FLAGS
     ALLEGRO_STATE_TARGET_BITMAP          = 0x0008,
     ALLEGRO_STATE_BLENDER                = 0x0010,
     ALLEGRO_STATE_NEW_FILE_INTERFACE     = 0x0020,
+    ALLEGRO_STATE_TRANSFORM              = 0x0040,
 
     ALLEGRO_STATE_BITMAP                 = ALLEGRO_STATE_TARGET_BITMAP +\
                                            ALLEGRO_STATE_NEW_BITMAP_PARAMETERS,
@@ -52,8 +53,7 @@ typedef struct ALLEGRO_STATE ALLEGRO_STATE;
 struct ALLEGRO_STATE
 {
    /* Internally, a thread_local_state structure is placed here. */
-   char _tls[256];
-   int flags;
+   char _tls[512];
 };
 
 
diff --git a/src/blenders.c b/src/blenders.c
index c6ace34..11efcfb 100644
--- a/src/blenders.c
+++ b/src/blenders.c
@@ -18,251 +18,96 @@
 #include "allegro5/allegro5.h"
 #include "allegro5/internal/aintern.h"
 #include "allegro5/internal/aintern_bitmap.h"
+#include "allegro5/internal/aintern_display.h"
 #include <string.h>
 
 #define MIN _ALLEGRO_MIN
 #define MAX _ALLEGRO_MAX
 
-/* TODO: Commented out optimized version without alpha separation.
- * Note the optimization is per-pixel only - so whenever these functions
- * get used things are going to be slow anyway (as the function is
- * called for each single pixel). Things like drawing an alpha
- * blended bitmap or a fully opaque filled rectangle have much more
- * potential for optimization on a higher level.
- */
-#if 0
-void _al_blender_zero_zero(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
-{
-   memset(result, 0, sizeof(ALLEGRO_COLOR));
-}
-
-
-
-void _al_blender_zero_one(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
-{
-   memcpy(result, dcol, sizeof(ALLEGRO_COLOR));
-}
-
-
-
-void _al_blender_zero_alpha(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
-{
-   ALLEGRO_COLOR *bc = _al_get_blend_color();
-
-   *result = al_map_rgba_f(
-      dcol->r*scol->a*bc->a,
-      dcol->g*scol->a*bc->a,
-      dcol->b*scol->a*bc->a,
-      dcol->a*scol->a*bc->a);
-}
-
-
-
-void _al_blender_zero_inverse_alpha(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
-{
-   ALLEGRO_COLOR *bc = _al_get_blend_color();
-
-   *result = al_map_rgba_f(
-      dcol->r*(1.0f-(scol->a*bc->a)),
-      dcol->g*(1.0f-(scol->a*bc->a)),
-      dcol->b*(1.0f-(scol->a*bc->a)),
-      dcol->a*(1.0f-(scol->a*bc->a)));
-}
-
-
-
-void _al_blender_one_zero(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
-{
-   ALLEGRO_COLOR *bc = _al_get_blend_color();
-
-   *result = al_map_rgba_f(
-      scol->r*bc->r,
-      scol->g*bc->g,
-      scol->b*bc->b,
-      scol->a*bc->a);
-}
-
-
-
-void _al_blender_one_one(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
-{
-   float r, g, b, a;
-   ALLEGRO_COLOR *bc = _al_get_blend_color();
-
-   r = MIN(1.0f, dcol->r + scol->r * bc->r);
-   g = MIN(1.0f, dcol->g + scol->g * bc->g);
-   b = MIN(1.0f, dcol->b + scol->b * bc->b);
-   a = MIN(1.0f, dcol->a + scol->a * bc->a);
-
-   *result = al_map_rgba_f(r, g, b, a);
-}
-
-
-
-void _al_blender_one_alpha(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
-{
-   float r, g, b, a;
-   ALLEGRO_COLOR *bc = _al_get_blend_color();
-
-   r = MIN(1.0f, dcol->r*scol->a*bc->a + scol->r * bc->r);
-   g = MIN(1.0f, dcol->g*scol->a*bc->a + scol->g * bc->g);
-   b = MIN(1.0f, dcol->b*scol->a*bc->a + scol->b * bc->b);
-   a = MIN(1.0f, dcol->a*scol->a*bc->a + scol->a * bc->a);
-
-   *result = al_map_rgba_f(r, g, b, a);
-}
 
-
-
-void _al_blender_one_inverse_alpha(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
-{
-   float r, g, b, a;
-   ALLEGRO_COLOR *bc = _al_get_blend_color();
-
-   r = MIN(1.0f, dcol->r*(1.0f-(scol->a*bc->a)) + scol->r * bc->r);
-   g = MIN(1.0f, dcol->g*(1.0f-(scol->a*bc->a)) + scol->g * bc->g);
-   b = MIN(1.0f, dcol->b*(1.0f-(scol->a*bc->a)) + scol->b * bc->b);
-   a = MIN(1.0f, dcol->a*(1.0f-(scol->a*bc->a)) + scol->a * bc->a);
-
-   *result = al_map_rgba_f(r, g, b, a);
-}
-
-
-
-void _al_blender_alpha_zero(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
-{
-   ALLEGRO_COLOR *bc = _al_get_blend_color();
-
-   *result = al_map_rgba_f(
-      scol->r*scol->a*bc->r*bc->a,
-      scol->g*scol->a*bc->g*bc->a,
-      scol->b*scol->a*bc->b*bc->a,
-      scol->a*scol->a*bc->a*bc->a);
-}
-
-
-
-void _al_blender_alpha_one(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
-{
-   ALLEGRO_COLOR *bc = _al_get_blend_color();
-
-   *result = al_map_rgba_f(
-      MIN(1.0f, scol->r*scol->a*bc->r*bc->a + dcol->r),
-      MIN(1.0f, scol->g*scol->a*bc->g*bc->a + dcol->g),
-      MIN(1.0f, scol->b*scol->a*bc->b*bc->a + dcol->b),
-      MIN(1.0f, scol->a*scol->a*bc->a*bc->a + dcol->a));
-}
-
-
-
-void _al_blender_alpha_alpha(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
+/* Function: al_set_blender
+ */
+void al_set_blender(int op, int src, int dst, ALLEGRO_COLOR color)
 {
-   ALLEGRO_COLOR *bc = _al_get_blend_color();
-
-   *result = al_map_rgba_f(
-      MIN(1.0f, scol->r*scol->a*bc->r*bc->a + dcol->r*scol->a*bc->a),
-      MIN(1.0f, scol->g*scol->a*bc->g*bc->a + dcol->g*scol->a*bc->a),
-      MIN(1.0f, scol->b*scol->a*bc->b*bc->a + dcol->b*scol->a*bc->a),
-      MIN(1.0f, scol->a*scol->a*bc->a*bc->a + dcol->a*scol->a*bc->a));
+   al_set_separate_blender(op, src, dst, op, src, dst, color);
 }
 
 
-
-void _al_blender_alpha_inverse_alpha(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
+/* Function: al_set_separate_blender
+ */
+void al_set_separate_blender(int op, int src, int dst,
+   int alpha_op, int alpha_src, int alpha_dst, ALLEGRO_COLOR color)
 {
-   ALLEGRO_COLOR *bc = _al_get_blend_color();
+   ALLEGRO_DISPLAY *display = _al_get_current_display();
+   ALLEGRO_BLENDER *b = &display->cur_blender;
 
-   *result = al_map_rgba_f(
-      MIN(1.0f, scol->r*scol->a*bc->a*bc->r + dcol->r*(1.0f-(bc->a*scol->a))),
-      MIN(1.0f, scol->g*scol->a*bc->a*bc->g + dcol->g*(1.0f-(bc->a*scol->a))),
-      MIN(1.0f, scol->b*scol->a*bc->a*bc->b + dcol->b*(1.0f-(bc->a*scol->a))),
-      MIN(1.0f, scol->a*scol->a*bc->a*bc->a + dcol->a*(1.0f-(bc->a*scol->a))));
+   b->blend_op = op;
+   b->blend_source = src;
+   b->blend_dest = dst;
+   b->blend_alpha_op = alpha_op;
+   b->blend_alpha_source = alpha_src;
+   b->blend_alpha_dest = alpha_dst;
+   b->blend_color = color;
 }
 
 
-
-void _al_blender_inverse_alpha_zero(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
+/* Function: al_get_blender
+ */
+void al_get_blender(int *op, int *src, int *dst, ALLEGRO_COLOR *color)
 {
-   ALLEGRO_COLOR *bc = _al_get_blend_color();
-
-   *result = al_map_rgba_f(
-      scol->r*(1.0f-(scol->a*bc->a))*bc->r,
-      scol->g*(1.0f-(scol->a*bc->a))*bc->g,
-      scol->b*(1.0f-(scol->a*bc->a))*bc->b,
-      scol->a*(1.0f-(scol->a*bc->a))*bc->a);
+   al_get_separate_blender(op, src, dst, NULL, NULL, NULL, color);
 }
 
 
-
-void _al_blender_inverse_alpha_one(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
+/* Function: al_get_separate_blender
+ */
+void al_get_separate_blender(int *op, int *src, int *dst,
+   int *alpha_op, int *alpha_src, int *alpha_dst, ALLEGRO_COLOR *color)
 {
-   ALLEGRO_COLOR *bc = _al_get_blend_color();
+   ALLEGRO_DISPLAY *display = _al_get_current_display();
+   ALLEGRO_BLENDER *b = &display->cur_blender;
+   
+   if (op)
+      *op = b->blend_op;
 
-   *result = al_map_rgba_f(
-      MIN(1.0f, scol->r*(1.0f-(scol->a*bc->a))*bc->r + dcol->r),
-      MIN(1.0f, scol->g*(1.0f-(scol->a*bc->a))*bc->g + dcol->g),
-      MIN(1.0f, scol->b*(1.0f-(scol->a*bc->a))*bc->b + dcol->b),
-      MIN(1.0f, scol->a*(1.0f-(scol->a*bc->a))*bc->a + dcol->a));
-}
+   if (src)
+      *src = b->blend_source;
 
+   if (dst)
+      *dst = b->blend_dest;
+   
+   if (alpha_op)
+      *alpha_op = b->blend_alpha_op;
 
+   if (alpha_src)
+      *alpha_src = b->blend_alpha_source;
 
-void _al_blender_inverse_alpha_alpha(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
-{
-   ALLEGRO_COLOR *bc = _al_get_blend_color();
+   if (alpha_dst)
+      *alpha_dst = b->blend_alpha_dest;
 
-   *result = al_map_rgba_f(
-      MIN(1.0f, scol->r*(1.0f-(scol->a*bc->a))*bc->r + dcol->r*scol->a*bc->a),
-      MIN(1.0f, scol->g*(1.0f-(scol->a*bc->a))*bc->g + dcol->g*scol->a*bc->a),
-      MIN(1.0f, scol->b*(1.0f-(scol->a*bc->a))*bc->b + dcol->b*scol->a*bc->a),
-      MIN(1.0f, scol->a*(1.0f-(scol->a*bc->a))*bc->a + dcol->a*scol->a*bc->a));
+   if (color)
+      *color = b->blend_color;
 }
 
 
-
-void _al_blender_inverse_alpha_inverse_alpha(ALLEGRO_COLOR *scol,
-   ALLEGRO_COLOR *dcol, ALLEGRO_COLOR *result)
+ALLEGRO_COLOR *_al_get_blend_color(void)
 {
-   ALLEGRO_COLOR *bc = _al_get_blend_color();
-
-   *result = al_map_rgba_f(
-      MIN(1.0f, scol->r*(1.0f-(scol->a*bc->a))*bc->r + dcol->r*(1.0f-(scol->a*bc->a))),
-      MIN(1.0f, scol->g*(1.0f-(scol->a*bc->a))*bc->g + dcol->g*(1.0f-(scol->a*bc->a))),
-      MIN(1.0f, scol->b*(1.0f-(scol->a*bc->a))*bc->b + dcol->b*(1.0f-(scol->a*bc->a))),
-      MIN(1.0f, scol->a*(1.0f-(scol->a*bc->a))*bc->a + dcol->a*(1.0f-(scol->a*bc->a))));
+   ALLEGRO_DISPLAY *display = _al_get_current_display();
+   ALLEGRO_BLENDER *b = &display->cur_blender;
+   return &b->blend_color;
 }
 
 
-// FIXME
-void _al_blend_combined_optimized(ALLEGRO_COLOR *scol,
-   ALLEGRO_BITMAP *dest,
-   int dx, int dy, ALLEGRO_COLOR *result)
+void _al_initialize_blender(ALLEGRO_BLENDER *b)
 {
-   ALLEGRO_MEMORY_BLENDER blender = _al_get_memory_blender();
-   ALLEGRO_COLOR dcol;
-
-   // FIXME: some blenders won't need this and it may be slow, should
-   // optimize it away for those?
-   dcol = al_get_pixel(dest, dx, dy);
-
-   blender(scol, &dcol, result);
+   b->blend_op = ALLEGRO_ADD;
+   b->blend_source = ALLEGRO_ALPHA;
+   b->blend_dest = ALLEGRO_INVERSE_ALPHA;
+   b->blend_alpha_op = ALLEGRO_ADD;
+   b->blend_alpha_source = ALLEGRO_ALPHA;
+   b->blend_alpha_dest = ALLEGRO_INVERSE_ALPHA;
+   b->blend_color = al_map_rgb_f(1, 1, 1);
 }
-#endif
 
 
 static float get_factor(int operation, float alpha)
diff --git a/src/display_new.c b/src/display_new.c
index f7393d6..0e2286d 100644
--- a/src/display_new.c
+++ b/src/display_new.c
@@ -71,6 +71,7 @@ ALLEGRO_DISPLAY *al_create_display(int w, int h)
    display->cache_texture = 0;
    
    al_identity_transform(&display->cur_transform);
+   _al_initialize_blender(&display->cur_blender);
 
    _al_vector_init(&display->bitmaps, sizeof(ALLEGRO_BITMAP*));
 
diff --git a/src/tls.c b/src/tls.c
index c2566f9..023d4e5 100644
--- a/src/tls.c
+++ b/src/tls.c
@@ -41,21 +41,15 @@ typedef struct thread_local_state {
    ALLEGRO_EXTRA_DISPLAY_SETTINGS new_display_settings;
    /* Current display */
    ALLEGRO_DISPLAY *current_display;
+   /* This is used for storing current transformation and blenders for
+    * graphics operations while no current display is available.
+    */
+   ALLEGRO_DISPLAY *memory_display;
    /* Target bitmap */
    ALLEGRO_BITMAP *target_bitmap;
    /* Bitmap parameters */
    int new_bitmap_format;
    int new_bitmap_flags;
-   /* Blending modes and color */
-   int blend_op;
-   int blend_source;
-   int blend_dest;
-   int blend_alpha_op;
-   int blend_alpha_source;
-   int blend_alpha_dest;
-   ALLEGRO_COLOR blend_color;
-   //FIXME: Might need this again for optimization purposes.
-   //ALLEGRO_MEMORY_BLENDER memory_blender;
    /* Files */
    const ALLEGRO_FILE_INTERFACE *new_file_interface;
    const ALLEGRO_FS_INTERFACE *fs_interface;
@@ -63,9 +57,15 @@ typedef struct thread_local_state {
    int allegro_errno;
 } thread_local_state;
 
-/* The extra sizeof(int) is for flags. */
+typedef struct INTERNAL_STATE {
+   thread_local_state tls;
+   ALLEGRO_BLENDER stored_blender;
+   ALLEGRO_TRANSFORM stored_transform;
+   int flags;
+} INTERNAL_STATE;
+
 ALLEGRO_STATIC_ASSERT(
-   sizeof(ALLEGRO_STATE) > sizeof(thread_local_state) + sizeof(int));
+   sizeof(ALLEGRO_STATE) > sizeof(INTERNAL_STATE));
 
 
 #if (defined ALLEGRO_MINGW32 && ( \
@@ -118,15 +118,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
              memset(data, 0, sizeof(*data));
 
              data->new_bitmap_format = ALLEGRO_PIXEL_FORMAT_ANY;
-             data->blend_op = ALLEGRO_ADD;
-             data->blend_source = ALLEGRO_ALPHA;
-             data->blend_dest = ALLEGRO_INVERSE_ALPHA;
-             data->blend_alpha_op = ALLEGRO_ADD;
-             data->blend_alpha_source = ALLEGRO_ONE;
-             data->blend_alpha_dest = ALLEGRO_ONE;
-             data->blend_color.r = data->blend_color.g = data->blend_color.b
-                = data->blend_color.a = 1.0f;
-             //data->memory_blender = _al_blender_alpha_inverse_alpha;
              TlsSetValue(tls_index, data);
              _al_fill_display_settings(&data->new_display_settings);
           }
@@ -221,17 +212,10 @@ static THREAD_LOCAL thread_local_state _tls = {
    {0, 0, { 0 },
     NULL, 0, 0},                          /* new_display_settings */
    NULL,                                  /* current_display */
+   NULL,                                  /* memory_display */
    NULL,                                  /* target_bitmap */
    ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA,   /* new_bitmap_format */
    0,                                     /* new_bitmap_flags */
-   ALLEGRO_ADD,                           /* blend_op */
-   ALLEGRO_ALPHA,                         /* blend_source */
-   ALLEGRO_INVERSE_ALPHA,                 /* blend_dest */
-   ALLEGRO_ADD,                           /* blend_alpha_op */
-   ALLEGRO_ONE,                           /* blend_alpha_source */
-   ALLEGRO_ONE,                           /* blend_alpha_dest */
-   { 1.0f, 1.0f, 1.0f, 1.0f },            /* blend_color  */
-   //_al_blender_alpha_inverse_alpha,       /* memory_blender */
    &_al_file_interface_stdio,             /* file_interface */
    &_al_fs_interface_stdio,               /* fs_interface */
    0                                      /* errno */
@@ -367,12 +351,31 @@ ALLEGRO_DISPLAY *al_get_current_display(void)
    thread_local_state *tls;
 
    if ((tls = tls_get()) == NULL)
-      return 0;
+      return NULL;
    return tls->current_display;
 }
 
 
 
+ALLEGRO_DISPLAY *_al_get_current_display(void)
+{
+   thread_local_state *tls;
+
+   if ((tls = tls_get()) == NULL)
+      return NULL;
+   if (tls->current_display)
+      return tls->current_display;
+
+   if (!tls->memory_display) {
+      tls->memory_display = _AL_MALLOC(sizeof *tls->memory_display);
+      memset(tls->memory_display, 0, sizeof *tls->memory_display);
+      _al_initialize_blender(&tls->memory_display->cur_blender);
+   }
+   return tls->memory_display;
+}
+
+
+
 /* Function: al_set_target_bitmap
  */
 void al_set_target_bitmap(ALLEGRO_BITMAP *bitmap)
@@ -459,20 +462,19 @@ int al_get_new_bitmap_flags(void)
 
 
 
-#define _STORE(x) stored->x = tls->x;
+#define _STORE(x) stored->tls.x = tls->x;
 /* Function: al_store_state
  */
 void al_store_state(ALLEGRO_STATE *state, int flags)
 {
    thread_local_state *tls;
-   thread_local_state *stored;
+   INTERNAL_STATE *stored;
 
    if ((tls = tls_get()) == NULL)
       return;
-      
-   state->flags = flags;
-   
-   stored = (void *)&state->_tls;
+
+   stored = (void *)state;
+   stored->flags = flags;
 
    if (flags & ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS) {
       _STORE(new_display_refresh_rate);
@@ -493,39 +495,36 @@ void al_store_state(ALLEGRO_STATE *state, int flags)
    }
 
    if (flags & ALLEGRO_STATE_BLENDER) {
-      _STORE(blend_op);
-      _STORE(blend_source);
-      _STORE(blend_dest);
-      _STORE(blend_alpha_op);
-      _STORE(blend_alpha_source);
-      _STORE(blend_alpha_dest);
-      _STORE(blend_color);
-      //_STORE(memory_blender);
+      stored->stored_blender = _al_get_current_display()->cur_blender;
    }
 
    if (flags & ALLEGRO_STATE_NEW_FILE_INTERFACE) {
       _STORE(new_file_interface);
       _STORE(fs_interface);
    }
+   
+   if (flags & ALLEGRO_STATE_TRANSFORM) {
+      stored->stored_transform = _al_get_current_display()->cur_transform;
+   }
 }
 #undef _STORE
 
 
 
-#define _STORE(x) tls->x = stored->x;
+#define _STORE(x) tls->x = stored->tls.x;
 /* Function: al_restore_state
  */
 void al_restore_state(ALLEGRO_STATE const *state)
 {
    thread_local_state *tls;
-   thread_local_state *stored;
+   INTERNAL_STATE *stored;
    int flags;
 
    if ((tls = tls_get()) == NULL)
       return;
-   flags = state->flags;
    
-   stored = (void *)&state->_tls;
+   stored = (void *)state;
+   flags = stored->flags;
 
    if (flags & ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS) {
       _STORE(new_display_refresh_rate);
@@ -548,204 +547,19 @@ void al_restore_state(ALLEGRO_STATE const *state)
    }
    
    if (flags & ALLEGRO_STATE_BLENDER) {
-      _STORE(blend_op);
-      _STORE(blend_source);
-      _STORE(blend_dest);
-      _STORE(blend_alpha_op);
-      _STORE(blend_alpha_source);
-      _STORE(blend_alpha_dest);
-      _STORE(blend_color);
-      //_STORE(memory_blender);
+      _al_get_current_display()->cur_blender = stored->stored_blender;
    }
 
    if (flags & ALLEGRO_STATE_NEW_FILE_INTERFACE) {
       _STORE(new_file_interface);
       _STORE(fs_interface);
    }
-}
-#undef _STORE
-
-
-
-/* Function: al_set_blender
- */
-void al_set_blender(int op, int src, int dst, ALLEGRO_COLOR color)
-{
-   al_set_separate_blender(op, src, dst, op, src, dst, color);
-}
-
-
-
-/* Function: al_set_separate_blender
- */
-void al_set_separate_blender(int op, int src, int dst,
-   int alpha_op, int alpha_src, int alpha_dst, ALLEGRO_COLOR color)
-{
-   thread_local_state *tls;
-
-   if ((tls = tls_get()) == NULL)
-      return;
-
-   tls->blend_op = op;
-   tls->blend_source = src;
-   tls->blend_dest = dst;
-   tls->blend_alpha_op = alpha_op;
-   tls->blend_alpha_source = alpha_src;
-   tls->blend_alpha_dest = alpha_dst;
-
-   memcpy(&tls->blend_color, &color, sizeof(ALLEGRO_COLOR));
-
-   //_al_set_memory_blender(src, dst, alpha_src, alpha_dst, &color);
-}
-
-
-
-/* Function: al_get_blender
- */
-void al_get_blender(int *op, int *src, int *dst, ALLEGRO_COLOR *color)
-{
-   al_get_separate_blender(op, src, dst, NULL, NULL, NULL, color);
-}
-
-
-
-/* Function: al_get_separate_blender
- */
-void al_get_separate_blender(int *op, int *src, int *dst,
-   int *alpha_op, int *alpha_src, int *alpha_dst, ALLEGRO_COLOR *color)
-{
-   thread_local_state *tls;
-
-   if ((tls = tls_get()) == NULL)
-      return;
    
-   if (op)
-      *op = tls->blend_op;
-
-   if (src)
-      *src = tls->blend_source;
-
-   if (dst)
-      *dst = tls->blend_dest;
-   
-   if (alpha_op)
-      *alpha_op = tls->blend_alpha_op;
-
-   if (alpha_src)
-      *alpha_src = tls->blend_alpha_source;
-
-   if (alpha_dst)
-      *alpha_dst = tls->blend_alpha_dest;
-
-   if (color)
-      memcpy(color, &tls->blend_color, sizeof(ALLEGRO_COLOR));
-}
-
-
-
-ALLEGRO_COLOR *_al_get_blend_color(void)
-{
-   thread_local_state *tls;
-
-   if ((tls = tls_get()) == NULL)
-      return NULL;
-   return &tls->blend_color;
-}
-
-
-
-// FIXME: Do we need this for optimization?
-#if 0
-void _al_set_memory_blender(int src, int dst, ALLEGRO_COLOR *color)
-{
-   thread_local_state *tls;
-
-   if ((tls = tls_get()) == NULL)
-      return;
-
-   switch (src) {
-
-      case ALLEGRO_ZERO:
-         switch (dst) {
-            case ALLEGRO_ZERO:
-               tls->memory_blender = _al_blender_zero_zero;
-               break;
-            case ALLEGRO_ONE:
-               tls->memory_blender = _al_blender_zero_one;
-               break;
-            case ALLEGRO_ALPHA:
-               tls->memory_blender = _al_blender_zero_alpha;
-               break;
-            case ALLEGRO_INVERSE_ALPHA:
-               tls->memory_blender = _al_blender_zero_inverse_alpha;
-               break;
-         }
-         break;
-
-      case ALLEGRO_ONE:
-         switch (dst) {
-            case ALLEGRO_ZERO:
-               tls->memory_blender = _al_blender_one_zero;
-               break;
-            case ALLEGRO_ONE:
-               tls->memory_blender = _al_blender_one_one;
-               break;
-            case ALLEGRO_ALPHA:
-               tls->memory_blender = _al_blender_one_alpha;
-               break;
-            case ALLEGRO_INVERSE_ALPHA:
-               tls->memory_blender = _al_blender_one_inverse_alpha;
-               break;
-         }
-         break;
-
-      case ALLEGRO_ALPHA:
-         switch (dst) {
-            case ALLEGRO_ZERO:
-               tls->memory_blender = _al_blender_alpha_zero;
-               break;
-            case ALLEGRO_ONE:
-               tls->memory_blender = _al_blender_alpha_one;
-               break;
-            case ALLEGRO_ALPHA:
-               tls->memory_blender = _al_blender_alpha_alpha;
-               break;
-            case ALLEGRO_INVERSE_ALPHA:
-               tls->memory_blender = _al_blender_alpha_inverse_alpha;
-               break;
-         }
-         break;
-
-      case ALLEGRO_INVERSE_ALPHA:
-         switch (dst) {
-            case ALLEGRO_ZERO:
-               tls->memory_blender = _al_blender_inverse_alpha_zero;
-               break;
-            case ALLEGRO_ONE:
-               tls->memory_blender = _al_blender_inverse_alpha_one;
-               break;
-            case ALLEGRO_ALPHA:
-               tls->memory_blender = _al_blender_inverse_alpha_alpha;
-               break;
-            case ALLEGRO_INVERSE_ALPHA:
-               tls->memory_blender = _al_blender_inverse_alpha_inverse_alpha;
-               break;
-         }
-         break;
+   if (flags & ALLEGRO_STATE_TRANSFORM) {
+      _al_get_current_display()->cur_transform = stored->stored_transform;
    }
 }
-
-
-
-ALLEGRO_MEMORY_BLENDER _al_get_memory_blender()
-{
-   thread_local_state *tls;
-
-   if ((tls = tls_get()) == NULL)
-      return NULL;
-   return tls->memory_blender;
-}
-#endif
+#undef _STORE
 
 
 
diff --git a/src/transformations.c b/src/transformations.c
index a31b8d9..92ab747 100644
--- a/src/transformations.c
+++ b/src/transformations.c
@@ -38,7 +38,7 @@ void al_copy_transform(const ALLEGRO_TRANSFORM *src, ALLEGRO_TRANSFORM *dest)
  */
 void al_use_transform(const ALLEGRO_TRANSFORM *trans)
 {
-   ALLEGRO_DISPLAY *current_display = al_get_current_display();
+   ALLEGRO_DISPLAY *current_display = _al_get_current_display();
    ASSERT(current_display);
    ASSERT(trans);
 
@@ -50,7 +50,7 @@ void al_use_transform(const ALLEGRO_TRANSFORM *trans)
  */
 const ALLEGRO_TRANSFORM *al_get_current_transform()
 {
-   ALLEGRO_DISPLAY *current_display = al_get_current_display();
+   ALLEGRO_DISPLAY *current_display = _al_get_current_display();
    ASSERT(current_display);
 
    return &current_display->cur_transform;


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