[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
The attached patch adds the ability to convert between memory and video
bitmaps. It has two new functions:
al_convert_bitmap: like al_clone_bitmap, but modifies the bitmap
in-place)
al_convert_all_video_bitmaps: converts all video bitmaps which have
silently been converted to memory bitmaps because there was no display
to actual video bitmaps
I first implemented this with a very small patch, simply making
ALLEGRO_BITMAP big enough to hold either the OpenGL or D3D version with
some static asserts to ensure it. But since that felt a bit messy I then
changed ALLEGRO_BITMAP to have an .extra field which OpenGL/D3D now use
to allocate their additional required storage, with no more driver
specific bitmap structs. This however made the patch grow huge :P
--
Elias Pschernig <elias.pschernig@xxxxxxxxxx>
diff --git a/addons/primitives/prim_opengl.c b/addons/primitives/prim_opengl.c
index ed5288c..d37dec3 100644
--- a/addons/primitives/prim_opengl.c
+++ b/addons/primitives/prim_opengl.c
@@ -323,16 +323,19 @@ int _al_draw_prim_opengl(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const
int num_primitives = 0;
ALLEGRO_DISPLAY *ogl_disp = target->display;
- ALLEGRO_BITMAP_OGL *ogl_target = (ALLEGRO_BITMAP_OGL *)target;
+ ALLEGRO_BITMAP *opengl_target = target;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *extra;
const void* vtx;
int stride = decl ? decl->stride : (int)sizeof(ALLEGRO_VERTEX);
int num_vtx;
if (target->parent) {
- ogl_target = (ALLEGRO_BITMAP_OGL *)target->parent;
+ opengl_target = target->parent;
}
+ extra = opengl_target->extra;
- if ((!ogl_target->is_backbuffer && ogl_disp->ogl_extras->opengl_target != ogl_target) || al_is_bitmap_locked(target)) {
+ if ((!extra->is_backbuffer && ogl_disp->ogl_extras->opengl_target !=
+ opengl_target) || al_is_bitmap_locked(target)) {
return _al_draw_prim_soft(texture, vtxs, decl, start, end, type);
}
@@ -461,7 +464,8 @@ int _al_draw_prim_indexed_opengl(ALLEGRO_BITMAP *target, ALLEGRO_BITMAP* texture
int num_primitives = 0;
ALLEGRO_DISPLAY *ogl_disp = target->display;
- ALLEGRO_BITMAP_OGL *ogl_target = (ALLEGRO_BITMAP_OGL *)target;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *extra;
+ ALLEGRO_BITMAP *ogl_target = target;
const void* vtx;
const void* idx = indices;
GLenum idx_size;
@@ -472,10 +476,11 @@ int _al_draw_prim_indexed_opengl(ALLEGRO_BITMAP *target, ALLEGRO_BITMAP* texture
#endif
if (target->parent) {
- ogl_target = (ALLEGRO_BITMAP_OGL *)target->parent;
+ ogl_target = target->parent;
}
+ extra = ogl_target->extra;
- if ((!ogl_target->is_backbuffer && ogl_disp->ogl_extras->opengl_target != ogl_target) || al_is_bitmap_locked(target)) {
+ if ((!extra->is_backbuffer && ogl_disp->ogl_extras->opengl_target != ogl_target) || al_is_bitmap_locked(target)) {
return _al_draw_prim_indexed_soft(texture, decl, vtxs, indices, num_vtx, type);
}
diff --git a/docs/src/refman/graphics.txt b/docs/src/refman/graphics.txt
index 3cf9f96..c7d75fc 100644
--- a/docs/src/refman/graphics.txt
+++ b/docs/src/refman/graphics.txt
@@ -288,11 +288,34 @@ See also: [al_create_bitmap]
### API: al_clone_bitmap
-Create a new bitmap with [al_create_bitmap], and copy the pixel data from the
-old bitmap across.
+Create a new bitmap with [al_create_bitmap], and copy the pixel data
+from the old bitmap across.
See also: [al_create_bitmap], [al_set_new_bitmap_format],
-[al_set_new_bitmap_flags]
+[al_set_new_bitmap_flags], [al_convert_bitmap]
+
+### API: al_convert_bitmap
+
+Converts the bitmap to the current bitmap flags and format. The bitmap
+will be as if it was created with al_create_bitmap but retain its
+contents.
+
+If the bitmap has sub-bitmaps, you alst must call al_convert_bitmap on
+all its sub-bitmaps. If the bitmap is a sub-bitmap, you must also call
+al_convert_bitmap on the parent.
+
+See also: [al_create_bitmap], [al_set_new_bitmap_format],
+[al_set_new_bitmap_flags], [al_clone_bitmap]
+
+### API: al_convert_all_video_bitmaps
+
+If you create a video bitmap when there is no current display (for
+example because you have not called al_create_display in the current
+thread) the video bitmap will be created successfully, but really be
+a memory bitmap. This function converts all such bitmaps to proper
+video bitmaps belonging to the current display.
+
+See also: [al_convert_bitmap]
### API: al_destroy_bitmap
diff --git a/include/allegro5/bitmap.h b/include/allegro5/bitmap.h
index e4051e5..4a354f1 100644
--- a/include/allegro5/bitmap.h
+++ b/include/allegro5/bitmap.h
@@ -178,6 +178,8 @@ AL_FUNC(bool, al_is_sub_bitmap, (ALLEGRO_BITMAP *bitmap));
/* Miscellaneous */
AL_FUNC(ALLEGRO_BITMAP *, al_clone_bitmap, (ALLEGRO_BITMAP *bitmap));
+AL_FUNC(void, al_convert_bitmap, (ALLEGRO_BITMAP *bitmap));
+AL_FUNC(void, al_convert_all_video_bitmaps, (void));
AL_FUNC(bool, al_is_bitmap_locked, (ALLEGRO_BITMAP *bitmap));
/* Blending */
diff --git a/include/allegro5/internal/aintern_bitmap.h b/include/allegro5/internal/aintern_bitmap.h
index 3089884..7c12c70 100644
--- a/include/allegro5/internal/aintern_bitmap.h
+++ b/include/allegro5/internal/aintern_bitmap.h
@@ -65,11 +65,10 @@ struct ALLEGRO_BITMAP
/* A memory copy of the bitmap data. May be NULL for an empty bitmap. */
unsigned char *memory;
- /* Size of the bitmap object. Used only by functions to convert bitmap
- storage type. Can be missleading. */
- size_t size;
-
bool preserve_texture;
+
+ /* Extra data for display bitmaps, like texture id and so on. */
+ void *extra;
};
struct ALLEGRO_BITMAP_INTERFACE
@@ -149,6 +148,8 @@ bool _al_transform_is_translation(const ALLEGRO_TRANSFORM* trans,
float *dx, float *dy);
void _al_init_iio_table(void);
+void _al_init_to_be_converted_bitmaps(void);
+void _al_cleanup_to_be_converted_bitmaps(void);
#ifdef __cplusplus
}
diff --git a/include/allegro5/internal/aintern_direct3d.h b/include/allegro5/internal/aintern_direct3d.h
index 0202b80..cdf7f19 100644
--- a/include/allegro5/internal/aintern_direct3d.h
+++ b/include/allegro5/internal/aintern_direct3d.h
@@ -9,10 +9,8 @@
extern "C" {
#endif
-typedef struct ALLEGRO_BITMAP_D3D
+typedef struct ALLEGRO_BITMAP_EXTRA_D3D
{
- ALLEGRO_BITMAP bitmap; /* This must be the first member. */
-
/* Driver specifics. */
unsigned int texture_w;
@@ -31,7 +29,7 @@ typedef struct ALLEGRO_BITMAP_D3D
IDirect3DSurface9 *render_target;
bool modified;
-} ALLEGRO_BITMAP_D3D;
+} ALLEGRO_BITMAP_EXTRA_D3D;
typedef struct ALLEGRO_DISPLAY_D3D
{
@@ -47,7 +45,8 @@ typedef struct ALLEGRO_DISPLAY_D3D
bool reset_done;
bool reset_success;
- ALLEGRO_BITMAP_D3D backbuffer_bmp;
+ ALLEGRO_BITMAP backbuffer_bmp;
+ ALLEGRO_BITMAP_EXTRA_D3D backbuffer_bmp_extra;
bool device_lost;
diff --git a/include/allegro5/internal/aintern_opengl.h b/include/allegro5/internal/aintern_opengl.h
index 9766197..2ef8d26 100644
--- a/include/allegro5/internal/aintern_opengl.h
+++ b/include/allegro5/internal/aintern_opengl.h
@@ -25,8 +25,6 @@ enum {
#define ALLEGRO_MAX_OPENGL_FBOS 8
-struct ALLEGRO_BITMAP_OGL;
-
enum {
FBO_INFO_UNUSED = 0,
FBO_INFO_TRANSIENT = 1, /* may be destroyed for another bitmap */
@@ -37,14 +35,12 @@ typedef struct ALLEGRO_FBO_INFO
{
int fbo_state;
GLuint fbo;
- struct ALLEGRO_BITMAP_OGL *owner;
+ ALLEGRO_BITMAP *owner;
double last_use_time;
} ALLEGRO_FBO_INFO;
-typedef struct ALLEGRO_BITMAP_OGL
+typedef struct ALLEGRO_BITMAP_EXTRA_OPENGL
{
- ALLEGRO_BITMAP bitmap; /* This must be the first member. */
-
/* Driver specifics. */
int true_w;
@@ -65,8 +61,7 @@ typedef struct ALLEGRO_BITMAP_OGL
float left, top, right, bottom; /* Texture coordinates. */
bool is_backbuffer; /* This is not a real bitmap, but the backbuffer. */
-} ALLEGRO_BITMAP_OGL;
-
+} ALLEGRO_BITMAP_EXTRA_OPENGL;
typedef struct OPENGL_INFO {
uint32_t version; /* OpenGL version */
@@ -91,9 +86,9 @@ typedef struct ALLEGRO_OGL_EXTRAS
/* Various info about OpenGL implementation. */
OPENGL_INFO ogl_info;
- ALLEGRO_BITMAP_OGL *opengl_target;
+ ALLEGRO_BITMAP *opengl_target;
- ALLEGRO_BITMAP_OGL *backbuffer;
+ ALLEGRO_BITMAP *backbuffer;
/* True if display resources are shared among displays. */
bool is_shared;
@@ -160,9 +155,9 @@ ALLEGRO_FBO_INFO *_al_ogl_persist_fbo(ALLEGRO_DISPLAY *display,
void _al_ogl_set_target_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap);
void _al_ogl_setup_bitmap_clipping(const ALLEGRO_BITMAP *bitmap);
ALLEGRO_BITMAP *_al_ogl_get_backbuffer(ALLEGRO_DISPLAY *d);
-ALLEGRO_BITMAP_OGL* _al_ogl_create_backbuffer(ALLEGRO_DISPLAY *disp);
-void _al_ogl_destroy_backbuffer(ALLEGRO_BITMAP_OGL *b);
-bool _al_ogl_resize_backbuffer(ALLEGRO_BITMAP_OGL *b, int w, int h);
+ALLEGRO_BITMAP* _al_ogl_create_backbuffer(ALLEGRO_DISPLAY *disp);
+void _al_ogl_destroy_backbuffer(ALLEGRO_BITMAP *b);
+bool _al_ogl_resize_backbuffer(ALLEGRO_BITMAP *b, int w, int h);
struct ALLEGRO_DISPLAY_INTERFACE;
diff --git a/src/bitmap.c b/src/bitmap.c
index 10c1df2..d984cff 100644
--- a/src/bitmap.c
+++ b/src/bitmap.c
@@ -31,6 +31,25 @@ ALLEGRO_DEBUG_CHANNEL("bitmap")
static ALLEGRO_COLOR solid_white = {1, 1, 1, 1};
+struct TO_BE_CONVERTED_LIST {
+ ALLEGRO_MUTEX *mutex;
+ _AL_VECTOR bitmaps;
+};
+
+static struct TO_BE_CONVERTED_LIST to_be_converted;
+
+void _al_init_to_be_converted_bitmaps(void)
+{
+ to_be_converted.mutex = al_create_mutex();
+ _al_vector_init(&to_be_converted.bitmaps, sizeof(ALLEGRO_BITMAP *));
+}
+
+void _al_cleanup_to_be_converted_bitmaps(void)
+{
+ _al_vector_free(&to_be_converted.bitmaps);
+ al_destroy_mutex(to_be_converted.mutex);
+}
+
/* Creates a memory bitmap.
*/
static ALLEGRO_BITMAP *_al_create_memory_bitmap(int w, int h)
@@ -43,14 +62,23 @@ static ALLEGRO_BITMAP *_al_create_memory_bitmap(int w, int h)
bitmap = al_malloc(sizeof *bitmap);
memset(bitmap, 0, sizeof(*bitmap));
- bitmap->size = sizeof(*bitmap);
pitch = w * al_get_pixel_size(format);
bitmap->vt = NULL;
bitmap->format = format;
- bitmap->flags = (al_get_new_bitmap_flags() | ALLEGRO_MEMORY_BITMAP) &
- ~ALLEGRO_VIDEO_BITMAP;
+
+ /* If this is really a video bitmap, we add it to the list of to
+ * be converted bitmaps.
+ */
+ bitmap->flags = (al_get_new_bitmap_flags() | ALLEGRO_MEMORY_BITMAP);
+ if (bitmap->flags & ALLEGRO_VIDEO_BITMAP) {
+ ALLEGRO_BITMAP **back;
+ al_lock_mutex(to_be_converted.mutex);
+ back = _al_vector_alloc_back(&to_be_converted.bitmaps);
+ *back = bitmap;
+ al_unlock_mutex(to_be_converted.mutex);
+ }
bitmap->w = w;
bitmap->h = h;
bitmap->pitch = pitch;
@@ -100,10 +128,6 @@ static ALLEGRO_BITMAP *do_create_bitmap(int w, int h)
return NULL;
}
- /* XXX the ogl_display driver sets some of these variables. It's not clear
- * who should be responsible for setting what.
- * The pitch must be set by the driver.
- */
bitmap->display = current_display;
bitmap->w = w;
bitmap->h = h;
@@ -659,17 +683,15 @@ ALLEGRO_BITMAP *al_create_sub_bitmap(ALLEGRO_BITMAP *parent,
y += parent->yofs;
parent = parent->parent;
}
-
+
if (parent->display && parent->display->vt &&
- parent->display->vt->create_sub_bitmap)
- {
+ parent->display->vt->create_sub_bitmap) {
bitmap = parent->display->vt->create_sub_bitmap(
parent->display, parent, x, y, w, h);
}
else {
bitmap = al_malloc(sizeof *bitmap);
memset(bitmap, 0, sizeof *bitmap);
- bitmap->size = sizeof *bitmap;
bitmap->vt = parent->vt;
}
@@ -709,37 +731,118 @@ bool al_is_sub_bitmap(ALLEGRO_BITMAP *bitmap)
}
-/* Function: al_clone_bitmap
- */
-ALLEGRO_BITMAP *al_clone_bitmap(ALLEGRO_BITMAP *bitmap)
+static void transfer_bitmap_data(ALLEGRO_BITMAP *src, ALLEGRO_BITMAP *dst)
{
- ALLEGRO_BITMAP *clone = al_create_bitmap(bitmap->w, bitmap->h);
ALLEGRO_LOCKED_REGION *dst_region;
ALLEGRO_LOCKED_REGION *src_region;
- if (!clone)
- return NULL;
-
- if (!(src_region = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY)))
- return NULL;
+ if (!(src_region = al_lock_bitmap(src, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY)))
+ return;
- if (!(dst_region = al_lock_bitmap(clone, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY))) {
- al_unlock_bitmap(bitmap);
- return NULL;
+ if (!(dst_region = al_lock_bitmap(dst, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY))) {
+ al_unlock_bitmap(src);
+ return;
}
_al_convert_bitmap_data(
src_region->data, src_region->format, src_region->pitch,
dst_region->data, dst_region->format, dst_region->pitch,
- 0, 0, 0, 0, bitmap->w, bitmap->h);
+ 0, 0, 0, 0, src->w, src->h);
+
+ al_unlock_bitmap(src);
+ al_unlock_bitmap(dst);
+}
- al_unlock_bitmap(bitmap);
- al_unlock_bitmap(clone);
+/* Function: al_clone_bitmap
+ */
+ALLEGRO_BITMAP *al_clone_bitmap(ALLEGRO_BITMAP *bitmap)
+{
+ ALLEGRO_BITMAP *clone = al_create_bitmap(bitmap->w, bitmap->h);
+ if (!clone)
+ return NULL;
+ transfer_bitmap_data(bitmap, clone);
return clone;
}
+/* Function: al_convert_bitmap
+ */
+void al_convert_bitmap(ALLEGRO_BITMAP *bitmap)
+{
+ ALLEGRO_BITMAP temp = *bitmap;
+ ALLEGRO_BITMAP *clone;
+ bool want_memory = al_get_new_bitmap_flags() & ALLEGRO_MEMORY_BITMAP;
+ bool is_memory = bitmap->flags & ALLEGRO_MEMORY_BITMAP;
+
+ if (bitmap->parent) {
+ bool parent_mem = bitmap->parent->flags & ALLEGRO_MEMORY_BITMAP;
+ if (parent_mem != is_memory)
+ al_convert_bitmap(bitmap->parent);
+ clone = al_create_sub_bitmap(bitmap->parent,
+ bitmap->xofs, bitmap->yofs, bitmap->w, bitmap->h);
+ }
+ else {
+ clone = al_clone_bitmap(bitmap);
+ }
+
+ /* If we convert from a display bitmap, we need to manually remove
+ * the bitmap pointer from the display list.
+ */
+ if (!is_memory && want_memory && bitmap->display) {
+ _al_vector_find_and_delete(&bitmap->display->bitmaps, &bitmap);
+ }
+
+ /* If we convert to a display bitmap, we need to manually remove
+ * the created pointer for the clone.
+ */
+ if (!want_memory && clone->display) {
+ _al_vector_find_and_delete(&clone->display->bitmaps, &clone);
+ }
+
+ /* Preserve bitmap state. */
+ clone->cl = bitmap->cl;
+ clone->ct = bitmap->ct;
+ clone->cr_excl = bitmap->cr_excl;
+ clone->cb_excl = bitmap->cb_excl;
+ clone->transform = bitmap->transform;
+ clone->inverse_transform = bitmap->inverse_transform;
+ clone->inverse_transform_dirty = bitmap->inverse_transform_dirty;
+ *bitmap = *clone; /* We get the new bitmap's extra pointer. */
+
+ *clone = temp; /* So everything can be deleted properly. */
+ al_destroy_bitmap(clone);
+}
+
+
+/* Function: al_convert_all_video_bitmaps
+ */
+void al_convert_all_video_bitmaps(void)
+{
+ ALLEGRO_STATE backup;
+ ALLEGRO_DISPLAY *display = al_get_current_display();
+ if (!display) return;
+
+ al_store_state(&backup, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS);
+ al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
+
+ al_lock_mutex(to_be_converted.mutex);
+
+ while (!_al_vector_is_empty(&to_be_converted.bitmaps)) {
+ ALLEGRO_BITMAP **back;
+ back = _al_vector_ref_back(&to_be_converted.bitmaps);
+ al_convert_bitmap(*back);
+
+ _al_vector_delete_at(&to_be_converted.bitmaps,
+ _al_vector_size(&to_be_converted.bitmaps) - 1);
+ }
+
+ al_unlock_mutex(to_be_converted.mutex);
+
+ al_restore_state(&backup);
+}
+
+
/* Function: al_is_bitmap_locked
*/
bool al_is_bitmap_locked(ALLEGRO_BITMAP *bitmap)
@@ -749,140 +852,49 @@ bool al_is_bitmap_locked(ALLEGRO_BITMAP *bitmap)
/* Converts a memory bitmap to a display bitmap preserving its contents.
- * The created bitmap belongs to the current display. A converted sub
- * bitmap is invalid until its parent is converted.
- * WARNING: This function will fail for any memory bitmap not previously
- * processed by _al_convert_to_memory_bitmap().
+ * The created bitmap belongs to the current display.
+ *
+ * If this is called for a sub-bitmap, the parent also is converted.
*/
void _al_convert_to_display_bitmap(ALLEGRO_BITMAP *bitmap)
{
- ALLEGRO_BITMAP *tmp;
- ALLEGRO_BITMAP **vid;
ALLEGRO_STATE backup;
- ALLEGRO_DISPLAY *d = al_get_current_display();
/* Do nothing if it is a display bitmap already. */
if (!(bitmap->flags & ALLEGRO_MEMORY_BITMAP))
return;
- if (bitmap->parent) {
- /* FIXME
- * We cannot safely assume that the backbuffer and bitmaps use the same
- * vtable.
- */
- bitmap->vt = al_get_backbuffer(d)->vt;
- bitmap->display = d;
- bitmap->flags &= !ALLEGRO_MEMORY_BITMAP;
- return;
- }
-
ALLEGRO_DEBUG("converting memory bitmap %p to display bitmap\n", bitmap);
- /* Allocate a temporary bitmap which will hold the data during the
- * conversion process.
- */
- al_store_state(&backup, ALLEGRO_STATE_BITMAP | ALLEGRO_STATE_BLENDER);
-
+ al_store_state(&backup, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS);
al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
al_set_new_bitmap_format(bitmap->format);
- tmp = do_create_bitmap(bitmap->w, bitmap->h);
-
- /* Preserve bitmap contents. */
- al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
- al_set_target_bitmap(tmp);
- al_draw_bitmap(bitmap, 0, 0, 0);
- tmp->cb_excl = bitmap->cb_excl;
- tmp->cr_excl = bitmap->cr_excl;
- tmp->cl = bitmap->cl;
- tmp->ct = bitmap->ct;
-
+ al_convert_bitmap(bitmap);
al_restore_state(&backup);
-
- /* Free the memory bitmap's memory. */
- al_free(bitmap->memory);
-
- /* Put the contents back to the bitmap. */
- ASSERT(tmp->size > sizeof(ALLEGRO_BITMAP));
- ASSERT(bitmap->size > sizeof(ALLEGRO_BITMAP));
- ASSERT(tmp->size == bitmap->size);
- memcpy(bitmap, tmp, tmp->size);
-
- vid = _al_vector_alloc_back(&d->bitmaps);
- *vid = bitmap;
-
- /* Remove the temporary bitmap from the display bitmap list, added
- * automatically by al_create_bitmap()
- */
- _al_vector_find_and_delete(&d->bitmaps, &tmp);
- al_free(tmp);
}
/* Converts a display bitmap to a memory bitmap preserving its contents.
- * Driver specific resources occupied by the display bitmap are freed.
- * A converted sub bitmap is invalid until its parent is converted.
+ * If this is called for a sub-bitmap, the parent also is converted.
*/
void _al_convert_to_memory_bitmap(ALLEGRO_BITMAP *bitmap)
{
- ALLEGRO_BITMAP *tmp;
ALLEGRO_STATE backup;
- size_t old_size;
/* Do nothing if it is a memory bitmap already. */
if (bitmap->flags & ALLEGRO_MEMORY_BITMAP)
return;
- if (bitmap->parent) {
- _al_vector_find_and_delete(&bitmap->display->bitmaps, &bitmap);
-
- //al_realloc(bitmap, sizeof(ALLEGRO_BITMAP));
- bitmap->display = NULL;
- bitmap->flags |= ALLEGRO_MEMORY_BITMAP;
- return;
- }
-
ALLEGRO_DEBUG("converting display bitmap %p to memory bitmap\n", bitmap);
- /* Allocate a temporary bitmap which will hold the data
- * during the conversion process. */
-
- al_store_state(&backup, ALLEGRO_STATE_BITMAP | ALLEGRO_STATE_BLENDER);
-
+ al_store_state(&backup, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS);
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
al_set_new_bitmap_format(bitmap->format);
- tmp = _al_create_memory_bitmap(bitmap->w, bitmap->h);
-
- /* Preserve bitmap contents. */
- al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
- al_set_target_bitmap(tmp);
- al_draw_bitmap(bitmap, 0, 0, 0);
- tmp->cb_excl = bitmap->cb_excl;
- tmp->cr_excl = bitmap->cr_excl;
- tmp->cl = bitmap->cl;
- tmp->ct = bitmap->ct;
-
+ al_convert_bitmap(bitmap);
al_restore_state(&backup);
-
- /* Destroy the display bitmap to free driver-specific resources. */
- if (bitmap->vt)
- bitmap->vt->destroy_bitmap(bitmap);
-
- _al_vector_find_and_delete(&bitmap->display->bitmaps, &bitmap);
-
- /* Do not shrink the bitmap object. This way we can convert back to the
- * display bitmap.
- */
- /*al_realloc(bitmap, tmp->size);
- bitmap->size = tmp->size*/
-
- /* Put the contents back to the bitmap. */
- old_size = bitmap->size;
- memcpy(bitmap, tmp, tmp->size);
- bitmap->size = old_size;
-
- al_free(tmp);
}
+
void _al_convert_bitmap_data(
void *src, int src_format, int src_pitch,
void *dst, int dst_format, int dst_pitch,
diff --git a/src/iphone/iphone_display.c b/src/iphone/iphone_display.c
index cd9ca90..ec168af 100644
--- a/src/iphone/iphone_display.c
+++ b/src/iphone/iphone_display.c
@@ -115,9 +115,10 @@ void _al_iphone_translate_to_screen(ALLEGRO_DISPLAY *d, int *ox, int *oy)
void _al_iphone_clip(ALLEGRO_BITMAP const *bitmap, int x_1, int y_1, int x_2, int y_2)
{
- ALLEGRO_BITMAP_OGL *oglb = (void *)(bitmap->parent ? bitmap->parent : bitmap);
- int h = oglb->bitmap.h;
- if (_screen_hack && oglb->is_backbuffer) {
+ ALLEGRO_BITMAP *oglb = (void *)(bitmap->parent ? bitmap->parent : bitmap);
+ ALLEGRO_BITMAP_EXTRA_OPENGL *e = oglb->extra;
+ int h = oglb->h;
+ if (_screen_hack && e->is_backbuffer) {
_al_iphone_translate_to_screen(bitmap->display, &x_1, &y_1);
_al_iphone_translate_to_screen(bitmap->display, &x_2, &y_2);
if (x_1 > x_2) {
diff --git a/src/opengl/ogl_bitmap.c b/src/opengl/ogl_bitmap.c
index 64d2bd1..8fd4f2c 100644
--- a/src/opengl/ogl_bitmap.c
+++ b/src/opengl/ogl_bitmap.c
@@ -232,7 +232,7 @@ static void draw_quad(ALLEGRO_BITMAP *bitmap,
{
float tex_l, tex_t, tex_r, tex_b, w, h, tex_w, tex_h;
float dw = sw, dh = sh;
- ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra;
ALLEGRO_OGL_BITMAP_VERTEX *verts;
ALLEGRO_DISPLAY *disp = al_get_current_display();
@@ -319,7 +319,7 @@ static void ogl_draw_bitmap_region(ALLEGRO_BITMAP *bitmap,
// 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_EXTRA_OPENGL *ogl_target;
ALLEGRO_DISPLAY *disp = target->display;
/* For sub-bitmaps */
@@ -327,11 +327,11 @@ static void ogl_draw_bitmap_region(ALLEGRO_BITMAP *bitmap,
target = target->parent;
}
- ogl_target = (ALLEGRO_BITMAP_OGL *)target;
+ ogl_target = target->extra;
if (!(bitmap->flags & ALLEGRO_MEMORY_BITMAP)) {
#if !defined ALLEGRO_GP2XWIZ
- ALLEGRO_BITMAP_OGL *ogl_source = (void *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_source = bitmap->extra;
if (ogl_source->is_backbuffer) {
/* Our source bitmap is the OpenGL backbuffer, the target
* is an OpenGL texture.
@@ -392,7 +392,7 @@ static void ogl_draw_bitmap_region(ALLEGRO_BITMAP *bitmap,
return;
#endif
}
- if (disp->ogl_extras->opengl_target == ogl_target) {
+ if (disp->ogl_extras->opengl_target == target) {
if (setup_blending(disp)) {
draw_quad(bitmap, tint, sx, sy, sw, sh, flags);
return;
@@ -417,7 +417,7 @@ static int pot(int x)
// proxy textures, formats, limits ...
static bool ogl_upload_bitmap(ALLEGRO_BITMAP *bitmap)
{
- ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra;
int w = bitmap->w;
int h = bitmap->h;
bool post_generate_mipmap = false;
@@ -550,13 +550,13 @@ static bool ogl_upload_bitmap(ALLEGRO_BITMAP *bitmap)
static void ogl_update_clipping_rectangle(ALLEGRO_BITMAP *bitmap)
{
ALLEGRO_DISPLAY *ogl_disp = al_get_current_display();
- ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap;
+ ALLEGRO_BITMAP *target_bitmap = bitmap;
if (bitmap->parent) {
- ogl_bitmap = (ALLEGRO_BITMAP_OGL *)bitmap->parent;
+ target_bitmap = bitmap->parent;
}
- if (ogl_disp->ogl_extras->opengl_target == ogl_bitmap) {
+ if (ogl_disp->ogl_extras->opengl_target == target_bitmap) {
_al_ogl_setup_bitmap_clipping(bitmap);
}
}
@@ -604,7 +604,7 @@ static bool exactly_15bpp(int pixel_format)
static ALLEGRO_LOCKED_REGION *ogl_lock_region(ALLEGRO_BITMAP *bitmap,
int x, int y, int w, int h, int format, int flags)
{
- ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra;
int pixel_size;
int pixel_alignment;
int pitch;
@@ -787,7 +787,7 @@ static ALLEGRO_LOCKED_REGION *ogl_lock_region(ALLEGRO_BITMAP *bitmap,
*/
static void ogl_unlock_region(ALLEGRO_BITMAP *bitmap)
{
- ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra;
const int lock_format = bitmap->locked_region.format;
ALLEGRO_DISPLAY *disp;
ALLEGRO_DISPLAY *old_disp = NULL;
@@ -1015,7 +1015,7 @@ Done:
static void ogl_destroy_bitmap(ALLEGRO_BITMAP *bitmap)
{
- ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra;
ALLEGRO_DISPLAY *disp;
ALLEGRO_DISPLAY *old_disp = NULL;
@@ -1036,6 +1036,8 @@ static void ogl_destroy_bitmap(ALLEGRO_BITMAP *bitmap)
if (old_disp) {
_al_set_current_display_only(old_disp);
}
+
+ al_free(ogl_bitmap);
}
@@ -1063,7 +1065,8 @@ static ALLEGRO_BITMAP_INTERFACE *ogl_bitmap_driver(void)
ALLEGRO_BITMAP *_al_ogl_create_bitmap(ALLEGRO_DISPLAY *d, int w, int h)
{
- ALLEGRO_BITMAP_OGL *bitmap;
+ ALLEGRO_BITMAP *bitmap;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *extra;
int format = al_get_new_bitmap_format();
const int flags = al_get_new_bitmap_flags();
int true_w;
@@ -1107,97 +1110,91 @@ ALLEGRO_BITMAP *_al_ogl_create_bitmap(ALLEGRO_DISPLAY *d, int w, int h)
pitch = true_w * al_get_pixel_size(format);
- bitmap = al_malloc(sizeof *bitmap);
+ bitmap = al_calloc(1, sizeof *bitmap);
ASSERT(bitmap);
- memset(bitmap, 0, sizeof *bitmap);
- bitmap->bitmap.size = sizeof *bitmap;
- bitmap->bitmap.vt = ogl_bitmap_driver();
- bitmap->bitmap.w = w;
- bitmap->bitmap.h = h;
- bitmap->bitmap.pitch = pitch;
- bitmap->bitmap.format = format;
- bitmap->bitmap.flags = flags | _ALLEGRO_INTERNAL_OPENGL;
- bitmap->bitmap.cl = 0;
- bitmap->bitmap.ct = 0;
- bitmap->bitmap.cr_excl = w;
- bitmap->bitmap.cb_excl = h;
- /* Back and front buffers should share a transform, which they do
- * because our OpenGL driver returns the same pointer for both.
- */
- al_identity_transform(&bitmap->bitmap.transform);
+ bitmap->extra = al_calloc(1, sizeof(ALLEGRO_BITMAP_EXTRA_OPENGL));
+ ASSERT(bitmap->extra);
+ extra = bitmap->extra;
+
+ bitmap->vt = ogl_bitmap_driver();
+ bitmap->pitch = pitch;
+ bitmap->format = format;
+ bitmap->flags = flags | _ALLEGRO_INTERNAL_OPENGL;
- bitmap->true_w = true_w;
- bitmap->true_h = true_h;
+ extra->true_w = true_w;
+ extra->true_h = true_h;
#if !defined(ALLEGRO_IPHONE) && !defined(ALLEGRO_GP2XWIZ)
- bitmap->bitmap.memory = NULL;
+ bitmap->memory = NULL;
#else
/* iPhone/Wiz ports still expect the buffer to be present. */
{
size_t bytes = pitch * true_h;
- bitmap->bitmap.memory = al_malloc(bytes);
+ bitmap->memory = al_malloc(bytes);
/* We never allow un-initialized memory for OpenGL bitmaps, if it
* is uploaded to a floating point texture it can lead to Inf and
* NaN values which break all subsequent blending.
*/
- memset(bitmap->bitmap.memory, 0, bytes);
+ memset(bitmap->memory, 0, bytes);
}
#endif
- return &bitmap->bitmap;
+ return bitmap;
}
-
ALLEGRO_BITMAP *_al_ogl_create_sub_bitmap(ALLEGRO_DISPLAY *d,
ALLEGRO_BITMAP *parent,
int x, int y, int w, int h)
{
- ALLEGRO_BITMAP_OGL* ogl_bmp;
- ALLEGRO_BITMAP_OGL* ogl_parent = (void*)parent;
+ ALLEGRO_BITMAP *bmp;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *extra;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *parent_extra = parent->extra;
(void)d;
- ogl_bmp = al_malloc(sizeof *ogl_bmp);
- memset(ogl_bmp, 0, sizeof *ogl_bmp);
+ bmp = al_calloc(1, sizeof *bmp);
+ extra = al_calloc(1, sizeof *extra);
+ bmp->extra = extra;
- ogl_bmp->true_w = ogl_parent->true_w;
- ogl_bmp->true_h = ogl_parent->true_h;
- ogl_bmp->texture = ogl_parent->texture;
+ extra->true_w = parent_extra->true_w;
+ extra->true_h = parent_extra->true_h;
+ extra->texture = parent_extra->texture;
#if !defined ALLEGRO_GP2XWIZ
- ogl_bmp->fbo_info = ogl_parent->fbo_info;
+ extra->fbo_info = parent_extra->fbo_info;
#endif
- ogl_bmp->left = x / (float)ogl_parent->true_w;
- ogl_bmp->right = (x + w) / (float)ogl_parent->true_w;
- ogl_bmp->top = (parent->h - y) / (float)ogl_parent->true_h;
- ogl_bmp->bottom = (parent->h - y - h) / (float)ogl_parent->true_h;
+ extra->left = x / (float)parent_extra->true_w;
+ extra->right = (x + w) / (float)parent_extra->true_w;
+ extra->top = (parent->h - y) / (float)parent_extra->true_h;
+ extra->bottom = (parent->h - y - h) / (float)parent_extra->true_h;
- ogl_bmp->is_backbuffer = ogl_parent->is_backbuffer;
+ extra->is_backbuffer = parent_extra->is_backbuffer;
- ogl_bmp->bitmap.vt = parent->vt;
+ bmp->vt = parent->vt;
- ogl_bmp->bitmap.flags |= _ALLEGRO_INTERNAL_OPENGL;
+ bmp->flags |= _ALLEGRO_INTERNAL_OPENGL;
- return (void*)ogl_bmp;
+ return bmp;
}
+
/* Function: al_get_opengl_texture
*/
GLuint al_get_opengl_texture(ALLEGRO_BITMAP *bitmap)
{
- ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *extra = bitmap->extra;
if (!(bitmap->flags & _ALLEGRO_INTERNAL_OPENGL))
return 0;
- return ogl_bitmap->texture;
+ return extra->texture;
}
/* Function: al_remove_opengl_fbo
*/
void al_remove_opengl_fbo(ALLEGRO_BITMAP *bitmap)
{
- ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra;
if (!(bitmap->flags & _ALLEGRO_INTERNAL_OPENGL))
return;
@@ -1229,7 +1226,7 @@ void al_remove_opengl_fbo(ALLEGRO_BITMAP *bitmap)
GLuint al_get_opengl_fbo(ALLEGRO_BITMAP *bitmap)
{
#if !defined ALLEGRO_GP2XWIZ
- ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra;
if (!(bitmap->flags & _ALLEGRO_INTERNAL_OPENGL))
return 0;
@@ -1259,7 +1256,7 @@ void al_get_opengl_texture_size(ALLEGRO_BITMAP *bitmap, int *w, int *h)
* texture sizes, so this will be the only way there to get the texture
* size. On normal OpenGL also glGetTexLevelParameter could be used.
*/
- ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap = bitmap->extra;
if (!(bitmap->flags & _ALLEGRO_INTERNAL_OPENGL)) {
*w = 0;
*h = 0;
diff --git a/src/opengl/ogl_display.c b/src/opengl/ogl_display.c
index 42e30bb..14b965d 100644
--- a/src/opengl/ogl_display.c
+++ b/src/opengl/ogl_display.c
@@ -57,13 +57,13 @@ void _al_ogl_reset_fbo_info(ALLEGRO_FBO_INFO *info)
bool _al_ogl_create_persistent_fbo(ALLEGRO_BITMAP *bitmap)
{
- ALLEGRO_BITMAP_OGL *ogl_bitmap;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap;
ALLEGRO_FBO_INFO *info;
GLint old_fbo;
if (bitmap->parent)
bitmap = bitmap->parent;
- ogl_bitmap = (void *)bitmap;
+ ogl_bitmap = bitmap->extra;
/* Don't continue if the bitmap does not belong to the current display. */
if (bitmap->display->ogl_extras->is_shared == false &&
@@ -102,7 +102,7 @@ bool _al_ogl_create_persistent_fbo(ALLEGRO_BITMAP *bitmap)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, old_fbo);
info->fbo_state = FBO_INFO_PERSISTENT;
- info->owner = ogl_bitmap;
+ info->owner = bitmap;
info->last_use_time = al_get_time();
ogl_bitmap->fbo_info = info;
ALLEGRO_DEBUG("Persistent FBO: %u\n", info->fbo);
@@ -155,11 +155,11 @@ static ALLEGRO_FBO_INFO *ogl_find_unused_fbo(ALLEGRO_DISPLAY *display)
static void setup_fbo(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap)
{
- ALLEGRO_BITMAP_OGL *ogl_bitmap;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap;
if (bitmap->parent)
bitmap = bitmap->parent;
- ogl_bitmap = (void *)bitmap;
+ ogl_bitmap = bitmap->extra;
#if !defined ALLEGRO_GP2XWIZ
if (!ogl_bitmap->is_backbuffer) {
@@ -184,7 +184,8 @@ static void setup_fbo(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap)
ASSERT(info->fbo_state != FBO_INFO_PERSISTENT);
if (info->fbo_state == FBO_INFO_TRANSIENT) {
- info->owner->fbo_info = NULL;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *extra = info->owner->extra;
+ extra->fbo_info = NULL;
ALLEGRO_DEBUG("Deleting FBO: %u\n", info->fbo);
glDeleteFramebuffersEXT(1, &info->fbo);
_al_ogl_reset_fbo_info(info);
@@ -206,7 +207,7 @@ static void setup_fbo(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap)
#endif
if (info->fbo_state == FBO_INFO_UNUSED)
info->fbo_state = FBO_INFO_TRANSIENT;
- info->owner = ogl_bitmap;
+ info->owner = bitmap;
info->last_use_time = al_get_time();
ogl_bitmap->fbo_info = info;
@@ -230,7 +231,7 @@ static void setup_fbo(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap)
ogl_bitmap->fbo_info = NULL;
}
else {
- display->ogl_extras->opengl_target = ogl_bitmap;
+ display->ogl_extras->opengl_target = bitmap;
glViewport(0, 0, bitmap->w, bitmap->h);
@@ -242,7 +243,7 @@ static void setup_fbo(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap)
}
}
else {
- display->ogl_extras->opengl_target = ogl_bitmap;
+ display->ogl_extras->opengl_target = bitmap;
#ifndef ALLEGRO_IPHONE
if (display->ogl_extras->extension_list->ALLEGRO_GL_EXT_framebuffer_object ||
@@ -302,14 +303,14 @@ static void setup_fbo(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap)
void _al_ogl_set_target_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap)
{
- ALLEGRO_BITMAP_OGL *ogl_bitmap = (void *)bitmap;
+ ALLEGRO_BITMAP *target = bitmap;
if (bitmap->parent)
- ogl_bitmap = (void *)bitmap->parent;
+ target = bitmap->parent;
if (!bitmap->locked) {
setup_fbo(display, bitmap);
- if (display->ogl_extras->opengl_target == ogl_bitmap) {
+ if (display->ogl_extras->opengl_target == target) {
_al_ogl_setup_bitmap_clipping(bitmap);
}
}
@@ -391,42 +392,43 @@ ALLEGRO_BITMAP *_al_ogl_get_backbuffer(ALLEGRO_DISPLAY *d)
}
-bool _al_ogl_resize_backbuffer(ALLEGRO_BITMAP_OGL *b, int w, int h)
+bool _al_ogl_resize_backbuffer(ALLEGRO_BITMAP *b, int w, int h)
{
int pitch;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *extra = b->extra;
- pitch = w * al_get_pixel_size(b->bitmap.format);
+ pitch = w * al_get_pixel_size(b->format);
- b->bitmap.w = w;
- b->bitmap.h = h;
- b->bitmap.pitch = pitch;
- b->bitmap.cl = 0;
- b->bitmap.ct = 0;
- b->bitmap.cr_excl = w;
- b->bitmap.cb_excl = h;
+ b->w = w;
+ b->h = h;
+ b->pitch = pitch;
+ b->cl = 0;
+ b->ct = 0;
+ b->cr_excl = w;
+ b->cb_excl = h;
/* There is no texture associated with the backbuffer so no need to care
* about texture size limitations. */
- b->true_w = w;
- b->true_h = h;
+ extra->true_w = w;
+ extra->true_h = h;
/* This code below appears to be unneccessary on platforms other than
* OS X.
*/
#ifdef ALLEGRO_MACOSX
- b->bitmap.display->vt->set_projection(b->bitmap.display);
+ b->bitmap.display->vt->set_projection(b->display);
#endif
#if !defined(ALLEGRO_IPHONE) && !defined(ALLEGRO_GP2XWIZ)
- b->bitmap.memory = NULL;
+ b->memory = NULL;
#else
/* iPhone/Wiz ports still expect the buffer to be present. */
{
/* FIXME: lazily manage memory */
size_t bytes = pitch * h;
- al_free(b->bitmap.memory);
- b->bitmap.memory = al_malloc(bytes);
- memset(b->bitmap.memory, 0, bytes);
+ al_free(b->memory);
+ b->memory = al_malloc(bytes);
+ memset(b->memory, 0, bytes);
}
#endif
@@ -434,9 +436,9 @@ bool _al_ogl_resize_backbuffer(ALLEGRO_BITMAP_OGL *b, int w, int h)
}
-ALLEGRO_BITMAP_OGL* _al_ogl_create_backbuffer(ALLEGRO_DISPLAY *disp)
+ALLEGRO_BITMAP* _al_ogl_create_backbuffer(ALLEGRO_DISPLAY *disp)
{
- ALLEGRO_BITMAP_OGL *ogl_backbuffer;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_backbuffer;
ALLEGRO_BITMAP *backbuffer;
ALLEGRO_STATE backup;
int format;
@@ -477,6 +479,13 @@ ALLEGRO_BITMAP_OGL* _al_ogl_create_backbuffer(ALLEGRO_DISPLAY *disp)
al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
backbuffer = _al_ogl_create_bitmap(disp, disp->w, disp->h);
al_restore_state(&backup);
+
+ backbuffer->w = disp->w;
+ backbuffer->h = disp->h;
+ backbuffer->cl = 0;
+ backbuffer->ct = 0;
+ backbuffer->cr_excl = disp->w;
+ backbuffer->cb_excl = disp->h;
if (!backbuffer) {
ALLEGRO_DEBUG("Backbuffer bitmap creation failed.\n");
@@ -487,19 +496,19 @@ ALLEGRO_BITMAP_OGL* _al_ogl_create_backbuffer(ALLEGRO_DISPLAY *disp)
"Created backbuffer bitmap (actual format: %s)\n",
_al_format_name(backbuffer->format));
- ogl_backbuffer = (ALLEGRO_BITMAP_OGL*)backbuffer;
+ ogl_backbuffer = backbuffer->extra;
ogl_backbuffer->is_backbuffer = 1;
backbuffer->display = disp;
al_identity_transform(&disp->view_transform);
- return ogl_backbuffer;
+ return backbuffer;
}
-void _al_ogl_destroy_backbuffer(ALLEGRO_BITMAP_OGL *b)
+void _al_ogl_destroy_backbuffer(ALLEGRO_BITMAP *b)
{
- al_destroy_bitmap((ALLEGRO_BITMAP *)b);
+ al_destroy_bitmap(b);
}
diff --git a/src/opengl/ogl_draw.c b/src/opengl/ogl_draw.c
index e0408e5..0f71e9c 100644
--- a/src/opengl/ogl_draw.c
+++ b/src/opengl/ogl_draw.c
@@ -165,15 +165,15 @@ static void ogl_clear(ALLEGRO_DISPLAY *d, ALLEGRO_COLOR *color)
{
ALLEGRO_DISPLAY *ogl_disp = (void *)d;
ALLEGRO_BITMAP *target = al_get_target_bitmap();
- ALLEGRO_BITMAP_OGL *ogl_target;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_target;
float r, g, b, a;
if (target->parent) target = target->parent;
- ogl_target = (void *)target;
+ ogl_target = target->extra;
if ((!ogl_target->is_backbuffer &&
- ogl_disp->ogl_extras->opengl_target != ogl_target) ||
+ ogl_disp->ogl_extras->opengl_target != target) ||
target->locked) {
_al_clear_memory(color);
return;
@@ -190,12 +190,12 @@ static void ogl_draw_pixel(ALLEGRO_DISPLAY *d, float x, float y,
ALLEGRO_COLOR *color)
{
ALLEGRO_BITMAP *target = al_get_target_bitmap();
- ALLEGRO_BITMAP_OGL *ogl_target = (void *)target;
+ ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_target = target->extra;
GLfloat vert[2];
GLfloat color_array[4];
if ((!ogl_target->is_backbuffer &&
- d->ogl_extras->opengl_target != ogl_target) ||
+ d->ogl_extras->opengl_target != target) ||
target->locked || !set_opengl_blending(d)) {
_al_draw_pixel_memory(target, x, y, color);
return;
diff --git a/src/system.c b/src/system.c
index b8a8258..f5e6e93 100644
--- a/src/system.c
+++ b/src/system.c
@@ -280,6 +280,8 @@ bool al_install_system(int version, int (*atexit_ptr)(void (*)(void)))
_al_init_pixels();
_al_init_iio_table();
+
+ _al_init_to_be_converted_bitmaps();
if (atexit_ptr && atexit_virgin) {
atexit_ptr(al_uninstall_system);
@@ -298,6 +300,7 @@ bool al_install_system(int version, int (*atexit_ptr)(void (*)(void)))
*/
void al_uninstall_system(void)
{
+ _al_cleanup_to_be_converted_bitmaps();
_al_run_destructors(_al_dtor_list);
_al_run_exit_funcs();
_al_shutdown_destructors(_al_dtor_list);
diff --git a/src/win/d3d_bmp.cpp b/src/win/d3d_bmp.cpp
index 660e82e..ee5e536 100644
--- a/src/win/d3d_bmp.cpp
+++ b/src/win/d3d_bmp.cpp
@@ -35,10 +35,12 @@ ALLEGRO_DEBUG_CHANNEL("d3d")
static ALLEGRO_BITMAP_INTERFACE *vt;
static _AL_VECTOR created_bitmaps;
+// C++ needs to cast void pointers
+#define get_extra(b) ((ALLEGRO_BITMAP_EXTRA_D3D *)b->extra)
void al_get_d3d_texture_size(ALLEGRO_BITMAP *bitmap, int *width, int *height)
{
- ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap);
*width = d3d_bmp->texture_w;
*height = d3d_bmp->texture_h;
}
@@ -46,7 +48,7 @@ void al_get_d3d_texture_size(ALLEGRO_BITMAP *bitmap, int *width, int *height)
void _al_d3d_bmp_init(void)
{
- _al_vector_init(&created_bitmaps, sizeof(ALLEGRO_BITMAP_D3D *));
+ _al_vector_init(&created_bitmaps, sizeof(ALLEGRO_BITMAP *));
}
@@ -70,7 +72,7 @@ static INLINE void transform_vertex(float* x, float* y)
* Draw a textured quad
*/
static void d3d_draw_textured_quad(
- ALLEGRO_DISPLAY_D3D *disp, ALLEGRO_BITMAP_D3D *bmp, ALLEGRO_COLOR tint,
+ ALLEGRO_DISPLAY_D3D *disp, ALLEGRO_BITMAP *bmp, ALLEGRO_COLOR tint,
float sx, float sy, float sw, float sh, int flags)
{
float right;
@@ -81,6 +83,7 @@ static void d3d_draw_textured_quad(
float tv_end;
int texture_w;
int texture_h;
+ ALLEGRO_BITMAP_EXTRA_D3D *extra = get_extra(bmp);
const float z = 0.0f;
@@ -94,8 +97,8 @@ static void d3d_draw_textured_quad(
right = sw;
bottom = sh;
- texture_w = bmp->texture_w;
- texture_h = bmp->texture_h;
+ texture_w = extra->texture_w;
+ texture_h = extra->texture_h;
tu_start = sx / texture_w;
tv_start = sy / texture_h;
tu_end = sw / texture_w + tu_start;
@@ -172,7 +175,7 @@ static void d3d_draw_textured_quad(
static void d3d_sync_bitmap_memory(ALLEGRO_BITMAP *bitmap)
{
D3DLOCKED_RECT locked_rect;
- ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap);
LPDIRECT3DTEXTURE9 texture;
if (_al_d3d_render_to_texture_supported())
@@ -197,7 +200,7 @@ static void d3d_sync_bitmap_texture(ALLEGRO_BITMAP *bitmap,
{
D3DLOCKED_RECT locked_rect;
RECT rect;
- ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap);
LPDIRECT3DTEXTURE9 texture;
rect.left = x;
@@ -252,10 +255,10 @@ static void d3d_sync_bitmap_texture(ALLEGRO_BITMAP *bitmap,
}
}
-static void d3d_do_upload(ALLEGRO_BITMAP_D3D *d3d_bmp, int x, int y, int width,
+static void d3d_do_upload(ALLEGRO_BITMAP *bmp, int x, int y, int width,
int height, bool sync_from_memory)
{
- ALLEGRO_BITMAP *bmp = (ALLEGRO_BITMAP *)d3d_bmp;
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bmp);
if (sync_from_memory) {
d3d_sync_bitmap_texture(bmp, x, y, width, height);
@@ -282,10 +285,10 @@ void _al_d3d_release_default_pool_textures(void)
for (i = 0; i < created_bitmaps._size; i++) {
ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref(&created_bitmaps, i);
ALLEGRO_BITMAP *albmp = *bptr;
- ALLEGRO_BITMAP_D3D *d3d_bmp;
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp;
if (albmp->flags & ALLEGRO_MEMORY_BITMAP)
continue;
- d3d_bmp = (ALLEGRO_BITMAP_D3D *)albmp;
+ d3d_bmp = get_extra(albmp);
if (!d3d_bmp->is_backbuffer && d3d_bmp->render_target) {
d3d_bmp->render_target->Release();
d3d_bmp->render_target = NULL;
@@ -363,7 +366,7 @@ static ALLEGRO_BITMAP *d3d_create_bitmap_from_surface(LPDIRECT3DSURFACE9 surface
int flags)
{
ALLEGRO_BITMAP *bitmap;
- ALLEGRO_BITMAP_D3D *d3d_bmp;
+ ALLEGRO_BITMAP_EXTRA_D3D *extra;
D3DSURFACE_DESC desc;
D3DLOCKED_RECT surf_locked_rect;
D3DLOCKED_RECT sys_locked_rect;
@@ -389,7 +392,7 @@ static ALLEGRO_BITMAP *d3d_create_bitmap_from_surface(LPDIRECT3DSURFACE9 surface
al_set_new_bitmap_flags(flags);
bitmap = al_create_bitmap(desc.Width, desc.Height);
- d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap;
+ extra = get_extra(bitmap);
al_restore_state(&backup);
@@ -398,7 +401,7 @@ static ALLEGRO_BITMAP *d3d_create_bitmap_from_surface(LPDIRECT3DSURFACE9 surface
return NULL;
}
- if (d3d_bmp->system_texture->LockRect(0, &sys_locked_rect, 0, 0) != D3D_OK) {
+ if (extra->system_texture->LockRect(0, &sys_locked_rect, 0, 0) != D3D_OK) {
surface->UnlockRect();
al_destroy_bitmap(bitmap);
ALLEGRO_ERROR("d3d_create_bitmap_from_surface: Lock system texture failed.\n");
@@ -414,11 +417,11 @@ static ALLEGRO_BITMAP *d3d_create_bitmap_from_surface(LPDIRECT3DSURFACE9 surface
}
surface->UnlockRect();
- d3d_bmp->system_texture->UnlockRect(0);
+ extra->system_texture->UnlockRect(0);
- if (d3d_bmp->display->device->UpdateTexture(
- (IDirect3DBaseTexture9 *)d3d_bmp->system_texture,
- (IDirect3DBaseTexture9 *)d3d_bmp->video_texture) != D3D_OK) {
+ if (extra->display->device->UpdateTexture(
+ (IDirect3DBaseTexture9 *)extra->system_texture,
+ (IDirect3DBaseTexture9 *)extra->video_texture) != D3D_OK) {
ALLEGRO_ERROR("d3d_create_bitmap_from_texture: Couldn't update texture.\n");
}
@@ -428,7 +431,7 @@ static ALLEGRO_BITMAP *d3d_create_bitmap_from_surface(LPDIRECT3DSURFACE9 surface
/* Copies video texture to system texture and bitmap->memory */
static void _al_d3d_sync_bitmap(ALLEGRO_BITMAP *dest)
{
- ALLEGRO_BITMAP_D3D *d3d_dest;
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_dest;
LPDIRECT3DSURFACE9 system_texture_surface;
LPDIRECT3DSURFACE9 video_texture_surface;
UINT i;
@@ -440,7 +443,7 @@ static void _al_d3d_sync_bitmap(ALLEGRO_BITMAP *dest)
return;
}
- d3d_dest = (ALLEGRO_BITMAP_D3D *)dest;
+ d3d_dest = get_extra(dest);
if (d3d_dest->system_texture == NULL || d3d_dest->video_texture == NULL) {
return;
@@ -499,17 +502,17 @@ void _al_d3d_prepare_bitmaps_for_reset(ALLEGRO_DISPLAY_D3D *disp)
al_lock_mutex(_al_d3d_lost_device_mutex);
for (i = 0; i < created_bitmaps._size; i++) {
- ALLEGRO_BITMAP_D3D **bptr = (ALLEGRO_BITMAP_D3D **)_al_vector_ref(&created_bitmaps, i);
- ALLEGRO_BITMAP_D3D *bmp = *bptr;
- ALLEGRO_BITMAP *al_bmp = (ALLEGRO_BITMAP *)bmp;
- if (bmp->display == disp) {
+ ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref(&created_bitmaps, i);
+ ALLEGRO_BITMAP *bmp = *bptr;
+ ALLEGRO_BITMAP_EXTRA_D3D *extra = get_extra(bmp);
+ if ((void *)bmp->display == (void *)disp) {
//d3d_sync_bitmap_memory(al_bmp);
- if (!al_bmp->preserve_texture) {
- bmp->modified = false;
+ if (!bmp->preserve_texture) {
+ extra->modified = false;
}
- else if (!bmp->is_backbuffer && bmp->modified && !(al_bmp->flags & ALLEGRO_MEMORY_BITMAP)) {
- _al_d3d_sync_bitmap(al_bmp);
- bmp->modified = false;
+ else if (!extra->is_backbuffer && extra->modified && !(bmp->flags & ALLEGRO_MEMORY_BITMAP)) {
+ _al_d3d_sync_bitmap(bmp);
+ extra->modified = false;
}
}
}
@@ -525,19 +528,19 @@ bool _al_d3d_recreate_bitmap_textures(ALLEGRO_DISPLAY_D3D *disp)
unsigned int i;
for (i = 0; i < created_bitmaps._size; i++) {
- ALLEGRO_BITMAP_D3D **bptr = (ALLEGRO_BITMAP_D3D **)_al_vector_ref(&created_bitmaps, i);
- ALLEGRO_BITMAP_D3D *bmp = *bptr;
- ALLEGRO_BITMAP *al_bmp = (ALLEGRO_BITMAP *)bmp;
-
- if (bmp->display == disp) {
- if (!d3d_create_textures(disp, bmp->texture_w,
- bmp->texture_h,
- al_bmp->flags,
- &bmp->video_texture,
- &bmp->system_texture,
- al_bmp->format))
- return false;
- d3d_do_upload(bmp, 0, 0, al_bmp->w, al_bmp->h, true);
+ ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref(&created_bitmaps, i);
+ ALLEGRO_BITMAP *bmp = *bptr;
+ ALLEGRO_BITMAP_EXTRA_D3D *extra = get_extra(bmp);
+
+ if ((void *)bmp->display == (void *)disp) {
+ if (!d3d_create_textures(disp, extra->texture_w,
+ extra->texture_h,
+ bmp->flags,
+ &extra->video_texture,
+ &extra->system_texture,
+ bmp->format))
+ return false;
+ d3d_do_upload(bmp, 0, 0, bmp->w, bmp->h, true);
}
}
@@ -553,27 +556,27 @@ void _al_d3d_refresh_texture_memory(void)
unsigned int i;
for (i = 0; i < created_bitmaps._size; i++) {
- ALLEGRO_BITMAP_D3D **bptr = (ALLEGRO_BITMAP_D3D **)_al_vector_ref(&created_bitmaps, i);
- ALLEGRO_BITMAP_D3D *bmp = *bptr;
- ALLEGRO_BITMAP *al_bmp = (ALLEGRO_BITMAP *)bmp;
- ALLEGRO_DISPLAY_D3D *bmps_display = (ALLEGRO_DISPLAY_D3D *)al_bmp->display;
-
- d3d_create_textures(bmps_display, bmp->texture_w, bmp->texture_h,
- al_bmp->flags,
- &bmp->video_texture, /*&bmp->system_texture*/0, al_bmp->format);
- d3d_sync_bitmap_texture(al_bmp,
- 0, 0, al_bmp->w, al_bmp->h);
+ ALLEGRO_BITMAP **bptr = (ALLEGRO_BITMAP **)_al_vector_ref(&created_bitmaps, i);
+ ALLEGRO_BITMAP *bmp = *bptr;
+ ALLEGRO_BITMAP_EXTRA_D3D *extra = get_extra(bmp);
+ ALLEGRO_DISPLAY_D3D *bmps_display = (ALLEGRO_DISPLAY_D3D *)bmp->display;
+
+ d3d_create_textures(bmps_display, extra->texture_w,
+ extra->texture_h, bmp->flags,
+ &extra->video_texture, /*&bmp->system_texture*/0, bmp->format);
+ d3d_sync_bitmap_texture(bmp,
+ 0, 0, bmp->w, bmp->h);
if (_al_d3d_render_to_texture_supported()) {
bmps_display->device->UpdateTexture(
- (IDirect3DBaseTexture9 *)bmp->system_texture,
- (IDirect3DBaseTexture9 *)bmp->video_texture);
+ (IDirect3DBaseTexture9 *)extra->system_texture,
+ (IDirect3DBaseTexture9 *)extra->video_texture);
}
}
}
static bool d3d_upload_bitmap(ALLEGRO_BITMAP *bitmap)
{
- ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap);
int w = bitmap->w;
int h = bitmap->h;
@@ -587,7 +590,7 @@ static bool d3d_upload_bitmap(ALLEGRO_BITMAP *bitmap)
if (non_pow2 && non_square) {
// Any shape and size
d3d_bmp->texture_w = w;
- d3d_bmp->texture_h = h;
+ d3d_bmp->texture_h = h;
}
else if (non_pow2) {
// Must be sqaure
@@ -608,7 +611,7 @@ static bool d3d_upload_bitmap(ALLEGRO_BITMAP *bitmap)
if (d3d_bmp->video_texture == 0)
if (!d3d_create_textures(d3d_bmp->display, d3d_bmp->texture_w,
d3d_bmp->texture_h,
- d3d_bmp->bitmap.flags,
+ bitmap->flags,
&d3d_bmp->video_texture,
&d3d_bmp->system_texture,
bitmap->format)) {
@@ -619,12 +622,12 @@ static bool d3d_upload_bitmap(ALLEGRO_BITMAP *bitmap)
* Keep track of created bitmaps, in case the display is lost
* or resized.
*/
- *(ALLEGRO_BITMAP_D3D **)_al_vector_alloc_back(&created_bitmaps) = d3d_bmp;
+ *(ALLEGRO_BITMAP **)_al_vector_alloc_back(&created_bitmaps) = bitmap;
d3d_bmp->initialized = true;
}
- d3d_do_upload(d3d_bmp, 0, 0, w, h, false);
+ d3d_do_upload(bitmap, 0, 0, w, h, false);
return true;
}
@@ -635,8 +638,10 @@ static void d3d_draw_bitmap_region(
float sx, float sy, float sw, float sh, int flags)
{
ALLEGRO_BITMAP *dest = al_get_target_bitmap();
- ALLEGRO_BITMAP_D3D *d3d_dest = (ALLEGRO_BITMAP_D3D *)dest;
- ALLEGRO_BITMAP_D3D *d3d_src = (ALLEGRO_BITMAP_D3D *)src;
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_dest = get_extra(dest);
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_src = get_extra(src);
+
+ ASSERT(src->parent == NULL);
if (!_al_d3d_render_to_texture_supported() || !_al_d3d_supports_separate_alpha_blend(al_get_current_display())) {
_al_draw_bitmap_region_memory(src, tint,
@@ -651,27 +656,19 @@ static void d3d_draw_bitmap_region(
_al_d3d_set_bitmap_clip(dest);
/* For sub-bitmaps */
- if (src->parent) {
- sx += src->xofs;
- sy += src->yofs;
- src = src->parent;
- d3d_src = (ALLEGRO_BITMAP_D3D *)src;
- }
if (dest->parent) {
dest = dest->parent;
- d3d_dest = (ALLEGRO_BITMAP_D3D *)dest;
+ d3d_dest = get_extra(dest);
}
if (d3d_src->is_backbuffer) {
- ALLEGRO_BITMAP_D3D *tmp_bmp = NULL;
- tmp_bmp =
- (ALLEGRO_BITMAP_D3D *)d3d_create_bitmap_from_surface(
- ((ALLEGRO_BITMAP_D3D *)d3d_src)->display->render_target,
+ ALLEGRO_BITMAP *tmp_bmp = d3d_create_bitmap_from_surface(
+ d3d_src->display->render_target,
src->flags);
if (tmp_bmp) {
- d3d_draw_bitmap_region((ALLEGRO_BITMAP *)tmp_bmp, tint,
+ d3d_draw_bitmap_region(tmp_bmp, tint,
sx, sy, sw, sh, flags);
- al_destroy_bitmap((ALLEGRO_BITMAP *)tmp_bmp);
+ al_destroy_bitmap(tmp_bmp);
}
return;
}
@@ -679,7 +676,7 @@ static void d3d_draw_bitmap_region(
_al_d3d_set_blender(d3d_dest->display);
d3d_draw_textured_quad(
- d3d_dest->display, d3d_src, tint,
+ d3d_dest->display, src, tint,
sx, sy, sw, sh, flags);
d3d_dest->modified = true;
@@ -687,7 +684,7 @@ static void d3d_draw_bitmap_region(
static void d3d_destroy_bitmap(ALLEGRO_BITMAP *bitmap)
{
- ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap);
if (!al_is_sub_bitmap(bitmap)) {
if (d3d_bmp->video_texture) {
@@ -709,13 +706,15 @@ static void d3d_destroy_bitmap(ALLEGRO_BITMAP *bitmap)
}
_al_vector_find_and_delete(&created_bitmaps, &d3d_bmp);
+
+ al_free(bitmap->extra);
}
static ALLEGRO_LOCKED_REGION *d3d_lock_region(ALLEGRO_BITMAP *bitmap,
int x, int y, int w, int h, int format,
int flags)
{
- ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap);
if (d3d_bmp->display->device_lost)
return NULL;
@@ -783,7 +782,7 @@ static ALLEGRO_LOCKED_REGION *d3d_lock_region(ALLEGRO_BITMAP *bitmap,
static void d3d_unlock_region(ALLEGRO_BITMAP *bitmap)
{
- ALLEGRO_BITMAP_D3D *d3d_bmp = (ALLEGRO_BITMAP_D3D *)bitmap;
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap);
d3d_bmp->modified = true;
@@ -810,7 +809,7 @@ static void d3d_unlock_region(ALLEGRO_BITMAP *bitmap)
texture->UnlockRect(0);
if (bitmap->lock_flags & ALLEGRO_LOCK_READONLY)
return;
- d3d_do_upload(d3d_bmp, bitmap->lock_x, bitmap->lock_y,
+ d3d_do_upload(bitmap, bitmap->lock_x, bitmap->lock_y,
bitmap->lock_w, bitmap->lock_h, false);
}
}
diff --git a/src/win/d3d_disp.cpp b/src/win/d3d_disp.cpp
index 4fbcd7e..a227031 100644
--- a/src/win/d3d_disp.cpp
+++ b/src/win/d3d_disp.cpp
@@ -35,6 +35,9 @@
#include "d3d.h"
+// C++ needs to cast void pointers
+#define get_extra(b) ((ALLEGRO_BITMAP_EXTRA_D3D *)b->extra)
+
static const char* _al_d3d_module_name = "d3d9.dll";
ALLEGRO_DEBUG_CHANNEL("d3d")
@@ -1927,18 +1930,19 @@ static bool d3d_create_display_internals(ALLEGRO_DISPLAY_D3D *d3d_display)
d3d_reset_state(d3d_display);
//d3d_display->backbuffer_bmp.render_target = d3d_display->render_target;
- d3d_display->backbuffer_bmp.is_backbuffer = true;
- d3d_display->backbuffer_bmp.bitmap.display = al_display;
- d3d_display->backbuffer_bmp.bitmap.format = _al_deduce_color_format(&al_display->extra_settings);
- d3d_display->backbuffer_bmp.bitmap.flags = 0;
- d3d_display->backbuffer_bmp.bitmap.w = al_display->w;
- d3d_display->backbuffer_bmp.bitmap.h = al_display->h;
- d3d_display->backbuffer_bmp.bitmap.cl = 0;
- d3d_display->backbuffer_bmp.bitmap.ct = 0;
- d3d_display->backbuffer_bmp.bitmap.cr_excl = al_display->w;
- d3d_display->backbuffer_bmp.bitmap.cb_excl = al_display->h;
- d3d_display->backbuffer_bmp.bitmap.vt = (ALLEGRO_BITMAP_INTERFACE *)_al_bitmap_d3d_driver();
- d3d_display->backbuffer_bmp.display = d3d_display;
+ d3d_display->backbuffer_bmp.extra = &d3d_display->backbuffer_bmp_extra;
+ d3d_display->backbuffer_bmp_extra.is_backbuffer = true;
+ d3d_display->backbuffer_bmp.display = al_display;
+ d3d_display->backbuffer_bmp.format = _al_deduce_color_format(&al_display->extra_settings);
+ d3d_display->backbuffer_bmp.flags = 0;
+ d3d_display->backbuffer_bmp.w = al_display->w;
+ d3d_display->backbuffer_bmp.h = al_display->h;
+ d3d_display->backbuffer_bmp.cl = 0;
+ d3d_display->backbuffer_bmp.ct = 0;
+ d3d_display->backbuffer_bmp.cr_excl = al_display->w;
+ d3d_display->backbuffer_bmp.cb_excl = al_display->h;
+ d3d_display->backbuffer_bmp.vt = (ALLEGRO_BITMAP_INTERFACE *)_al_bitmap_d3d_driver();
+ d3d_display->backbuffer_bmp_extra.display = d3d_display;
/* Alpha blending is the default */
d3d_display->device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
@@ -2289,7 +2293,8 @@ static void d3d_update_display_region(ALLEGRO_DISPLAY *al_display,
*/
void _al_d3d_set_bitmap_clip(ALLEGRO_BITMAP *bitmap)
{
- ALLEGRO_DISPLAY_D3D *disp = ((ALLEGRO_BITMAP_D3D *)bitmap)->display;
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(bitmap);
+ ALLEGRO_DISPLAY_D3D *disp = d3d_bmp->display;
RECT rect;
if (!disp)
@@ -2340,12 +2345,12 @@ static bool d3d_acknowledge_resize(ALLEGRO_DISPLAY *d)
d->h = h;
}
- disp->backbuffer_bmp.bitmap.w = d->w;
- disp->backbuffer_bmp.bitmap.h = d->h;
- disp->backbuffer_bmp.bitmap.cl = 0;
- disp->backbuffer_bmp.bitmap.ct = 0;
- disp->backbuffer_bmp.bitmap.cr_excl = w;
- disp->backbuffer_bmp.bitmap.cb_excl = h;
+ disp->backbuffer_bmp.w = d->w;
+ disp->backbuffer_bmp.h = d->h;
+ disp->backbuffer_bmp.cl = 0;
+ disp->backbuffer_bmp.ct = 0;
+ disp->backbuffer_bmp.cr_excl = w;
+ disp->backbuffer_bmp.cb_excl = h;
disp->do_reset = true;
while (!disp->reset_done) {
@@ -2439,18 +2444,18 @@ static bool d3d_resize_helper(ALLEGRO_DISPLAY *d, int width, int height)
* changed to match the new size.
*/
al_store_state(&backup, ALLEGRO_STATE_TARGET_BITMAP);
- al_set_target_bitmap(&disp->backbuffer_bmp.bitmap);
- disp->backbuffer_bmp.bitmap.w = width;
- disp->backbuffer_bmp.bitmap.h = height;
+ al_set_target_bitmap(&disp->backbuffer_bmp);
+ disp->backbuffer_bmp.w = width;
+ disp->backbuffer_bmp.h = height;
al_set_clipping_rectangle(0, 0, width, height);
- _al_d3d_set_bitmap_clip(&disp->backbuffer_bmp.bitmap);
+ _al_d3d_set_bitmap_clip(&disp->backbuffer_bmp);
al_restore_state(&backup);
ret = true;
}
- disp->backbuffer_bmp.bitmap.w = width;
- disp->backbuffer_bmp.bitmap.h = height;
+ disp->backbuffer_bmp.w = width;
+ disp->backbuffer_bmp.h = height;
return ret;
}
@@ -2480,15 +2485,14 @@ static bool d3d_resize_display(ALLEGRO_DISPLAY *d, int width, int height)
ALLEGRO_BITMAP *_al_d3d_create_bitmap(ALLEGRO_DISPLAY *d,
int w, int h)
{
- ALLEGRO_BITMAP_D3D *bitmap = (ALLEGRO_BITMAP_D3D*)al_malloc(sizeof *bitmap);
+ ALLEGRO_BITMAP *bitmap = (ALLEGRO_BITMAP *)al_malloc(sizeof *bitmap);
+ ALLEGRO_BITMAP_EXTRA_D3D *extra;
int format;
int flags;
ASSERT(bitmap);
(void)h;
- bitmap->bitmap.size = sizeof *bitmap;
-
format = al_get_new_bitmap_format();
flags = al_get_new_bitmap_flags();
@@ -2506,56 +2510,61 @@ ALLEGRO_BITMAP *_al_d3d_create_bitmap(ALLEGRO_DISPLAY *d,
ALLEGRO_INFO("Chose bitmap format %d\n", format);
- bitmap->bitmap.vt = _al_bitmap_d3d_driver();
- bitmap->bitmap.memory = NULL;
- bitmap->bitmap.format = format;
- bitmap->bitmap.flags = flags;
- bitmap->bitmap.pitch = w * al_get_pixel_size(format);
- al_identity_transform(&bitmap->bitmap.transform);
+ bitmap->vt = _al_bitmap_d3d_driver();
+ bitmap->memory = NULL;
+ bitmap->format = format;
+ bitmap->flags = flags;
+ bitmap->pitch = w * al_get_pixel_size(format);
+ al_identity_transform(&bitmap->transform);
- bitmap->bitmap.memory = (unsigned char *)al_malloc(bitmap->bitmap.pitch * h);
+ bitmap->memory = (unsigned char *)al_malloc(bitmap->pitch * h);
- bitmap->video_texture = 0;
- bitmap->system_texture = 0;
- bitmap->initialized = false;
- bitmap->is_backbuffer = false;
- bitmap->render_target = NULL;
- bitmap->modified = true;
+ extra = (ALLEGRO_BITMAP_EXTRA_D3D *)al_calloc(1, sizeof *extra);
+ bitmap->extra = extra;
+ extra->video_texture = 0;
+ extra->system_texture = 0;
+ extra->initialized = false;
+ extra->is_backbuffer = false;
+ extra->render_target = NULL;
+ extra->modified = true;
- bitmap->display = (ALLEGRO_DISPLAY_D3D *)d;
+ extra->display = (ALLEGRO_DISPLAY_D3D *)d;
- return &bitmap->bitmap;
+ return bitmap;
}
static ALLEGRO_BITMAP *d3d_create_sub_bitmap(ALLEGRO_DISPLAY *display,
ALLEGRO_BITMAP *parent, int x, int y, int width, int height)
{
- ALLEGRO_BITMAP_D3D *bitmap = (ALLEGRO_BITMAP_D3D*)al_malloc(sizeof *bitmap);
+ ALLEGRO_BITMAP *bitmap = (ALLEGRO_BITMAP *)al_malloc(sizeof *bitmap);
+ ALLEGRO_BITMAP_EXTRA_D3D *extra;
+ ALLEGRO_BITMAP_EXTRA_D3D *pextra = get_extra(parent);
+ extra = (ALLEGRO_BITMAP_EXTRA_D3D *)al_calloc(1, sizeof *extra);
+ bitmap->extra = extra;
(void)x;
(void)y;
(void)width;
(void)height;
- bitmap->texture_w = 0;
- bitmap->texture_h = 0;
- bitmap->video_texture = ((ALLEGRO_BITMAP_D3D *)parent)->video_texture;
- bitmap->system_texture = ((ALLEGRO_BITMAP_D3D *)parent)->system_texture;
- bitmap->initialized = false;
- bitmap->is_backbuffer = ((ALLEGRO_BITMAP_D3D *)parent)->is_backbuffer;
- bitmap->display = (ALLEGRO_DISPLAY_D3D *)display;
- bitmap->render_target = ((ALLEGRO_BITMAP_D3D *)parent)->render_target;
- bitmap->modified = true;
- al_identity_transform(&bitmap->bitmap.transform);
+ extra->texture_w = 0;
+ extra->texture_h = 0;
+ extra->video_texture = pextra->video_texture;
+ extra->system_texture = pextra->system_texture;
+ extra->initialized = false;
+ extra->is_backbuffer = pextra->is_backbuffer;
+ extra->display = (ALLEGRO_DISPLAY_D3D *)display;
+ extra->render_target = pextra->render_target;
+ extra->modified = true;
- bitmap->bitmap.vt = parent->vt;
- return (ALLEGRO_BITMAP *)bitmap;
+ bitmap->vt = parent->vt;
+ return bitmap;
}
static void d3d_set_target_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitmap)
{
ALLEGRO_BITMAP *target;
- ALLEGRO_BITMAP_D3D *d3d_target;
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_target;
ALLEGRO_DISPLAY_D3D *d3d_display = (ALLEGRO_DISPLAY_D3D *)display;
D3DVIEWPORT9 viewport;
viewport.X = 0;
@@ -2572,14 +2581,17 @@ static void d3d_set_target_bitmap(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *bitm
else {
target = bitmap;
}
- d3d_target = (ALLEGRO_BITMAP_D3D *)target;
+ d3d_target = get_extra(target);
/* Release the previous target bitmap if it was not the backbuffer */
- ALLEGRO_BITMAP_D3D *currtarget = (ALLEGRO_BITMAP_D3D *)al_get_target_bitmap();
- if (currtarget && !currtarget->is_backbuffer && currtarget->render_target) {
- currtarget->render_target->Release();
- currtarget->render_target = NULL;
+ ALLEGRO_BITMAP *currtarget = al_get_target_bitmap();
+ if (currtarget) {
+ ALLEGRO_BITMAP_EXTRA_D3D *cextra = get_extra(currtarget);
+ if (!cextra->is_backbuffer && cextra->render_target) {
+ cextra->render_target->Release();
+ cextra->render_target = NULL;
+ }
}
/* Set the render target */
@@ -2679,14 +2691,16 @@ LPDIRECT3DDEVICE9 al_get_d3d_device(ALLEGRO_DISPLAY *display)
*/
LPDIRECT3DTEXTURE9 al_get_d3d_system_texture(ALLEGRO_BITMAP *bitmap)
{
- return ((ALLEGRO_BITMAP_D3D *)bitmap)->system_texture;
+ ALLEGRO_BITMAP_EXTRA_D3D *e = get_extra(bitmap);
+ return e->system_texture;
}
/* Function: al_get_d3d_video_texture
*/
LPDIRECT3DTEXTURE9 al_get_d3d_video_texture(ALLEGRO_BITMAP *bitmap)
{
- return ((ALLEGRO_BITMAP_D3D *)bitmap)->video_texture;
+ ALLEGRO_BITMAP_EXTRA_D3D *e = get_extra(bitmap);
+ return e->video_texture;
}
/* Function: al_get_d3d_texture_position
@@ -2779,7 +2793,7 @@ static void d3d_flush_vertex_cache(ALLEGRO_DISPLAY* disp)
ALLEGRO_DISPLAY_D3D* d3d_disp = (ALLEGRO_DISPLAY_D3D*)disp;
ALLEGRO_BITMAP* cache_bmp = (ALLEGRO_BITMAP*)disp->cache_texture;
- ALLEGRO_BITMAP_D3D* d3d_bmp = (ALLEGRO_BITMAP_D3D*)cache_bmp;
+ ALLEGRO_BITMAP_EXTRA_D3D *d3d_bmp = get_extra(cache_bmp);
if (cache_bmp->flags & ALLEGRO_MIN_LINEAR) {
d3d_disp->device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
diff --git a/src/win/wgl_disp.c b/src/win/wgl_disp.c
index b559bd2..82af2d3 100644
--- a/src/win/wgl_disp.c
+++ b/src/win/wgl_disp.c
@@ -1372,8 +1372,10 @@ static bool wgl_resize_helper(ALLEGRO_DISPLAY *d, int width, int height)
size_t i;
target_bmp = al_get_target_bitmap();
- if (target_bmp->vt)
- was_backbuffer = ((ALLEGRO_BITMAP_OGL*)target_bmp)->is_backbuffer;
+ if (target_bmp->vt) {
+ ALLEGRO_BITMAP_EXTRA_OPENGL *extra = target_bmp->extra;
+ was_backbuffer = extra->is_backbuffer;
+ }
/* Remeber display bitmaps. */
_al_vector_init(&disp_bmps, sizeof(ALLEGRO_BITMAP*));