From 2bbb2619f97f9c10671a35df49a654ae27063059 Mon Sep 17 00:00:00 2001 From: doursse Date: Sun, 27 May 2007 06:43:23 +0000 Subject: [PATCH] add the DirectDraw engine. Evas is now available on Windows (tm) SVN revision: 30089 --- legacy/evas/configure.in | 60 +++ legacy/evas/src/lib/Makefile.am | 1 + legacy/evas/src/lib/canvas/evas_main.c | 3 + legacy/evas/src/lib/file/evas_module.c | 4 + legacy/evas/src/modules/engines/Makefile.am | 1 + .../Evas_Engine_Software_DDraw.h | 28 ++ .../engines/software_ddraw/Makefile.am | 33 ++ .../software_ddraw/evas_ddraw_buffer.c | 86 ++++ .../engines/software_ddraw/evas_ddraw_main.c | 5 + .../engines/software_ddraw/evas_engine.c | 358 +++++++++++++++++ .../engines/software_ddraw/evas_engine.h | 119 ++++++ .../engines/software_ddraw/evas_outbuf.c | 371 ++++++++++++++++++ .../engines/software_generic/Makefile.am | 2 +- 13 files changed, 1070 insertions(+), 1 deletion(-) create mode 100644 legacy/evas/src/modules/engines/software_ddraw/Evas_Engine_Software_DDraw.h create mode 100644 legacy/evas/src/modules/engines/software_ddraw/Makefile.am create mode 100644 legacy/evas/src/modules/engines/software_ddraw/evas_ddraw_buffer.c create mode 100644 legacy/evas/src/modules/engines/software_ddraw/evas_ddraw_main.c create mode 100644 legacy/evas/src/modules/engines/software_ddraw/evas_engine.c create mode 100644 legacy/evas/src/modules/engines/software_ddraw/evas_engine.h create mode 100644 legacy/evas/src/modules/engines/software_ddraw/evas_outbuf.c diff --git a/legacy/evas/configure.in b/legacy/evas/configure.in index c130fd1a45..97fd9f155b 100644 --- a/legacy/evas/configure.in +++ b/legacy/evas/configure.in @@ -135,9 +135,65 @@ case "$host_os" in esac AC_SUBST(dlopen_libs) +AC_CHECK_HEADER(fnmatch.h,, AC_MSG_ERROR([Cannot find fnmatch.h. Make sure your CFLAGS environment variable contains include lines for the location of this file. MinGW users: see the INSTALL file])) + +fnmatch_libs="" +AC_CHECK_FUNCS(fnmatch, res=yes, res=no) +if test "x$res" = "xno"; then + AC_CHECK_LIB(fnmatch, fnmatch, res=yes fnmatch_libs="-lfnmatch", res=no) +dnl Test for compilation with MinGW. +dnl fnmatch function is in the libiberty library + if test "x$res" = "xno"; then + AC_CHECK_LIB(iberty, fnmatch, res=yes fnmatch_libs="-liberty", res=no) + fi + if test "x$res" = "xno"; then + AC_MSG_ERROR([Cannot find fnmatch() in neither libc nor libfnmatch, nor libiberty]) + fi +fi + +AC_SUBST(fnmatch_libs) + ##################################################################### ## Engines +####################################### +## Check if we should build the software_ddraw engine +have_evas_software_ddraw="no"; +## Automatic check... +AC_CHECK_HEADER(ddraw.h, + [ have_evas_software_ddraw="yes" ], + [ have_evas_software_ddraw="no" ] +) +## Manual override +AC_MSG_CHECKING(whether software directdraw backend is to be built) +AC_ARG_ENABLE(software-ddraw, AC_HELP_STRING([--enable-software-ddraw],[enable the Software DirectDraw rendering backend]), [ + if test x"$enableval" = x"yes" ; then + AC_MSG_RESULT(yes) + have_evas_software_ddraw="yes" + else + AC_MSG_RESULT(no) + have_evas_software_ddraw="no" + fi + ], [ + AC_MSG_RESULT($have_evas_software_ddraw) + ] +) +if test "x$have_evas_software_ddraw" = "xyes"; then + AC_PATH_XTRA + AC_CHECK_HEADER(ddraw.h, + [ + AC_DEFINE(BUILD_ENGINE_SOFTWARE_DDRAW, 1, [Software DirectDraw Rendering Backend]) + ddraw_libs="-lddraw" + ], + [ + AC_MSG_RESULT(disabling software DirectDraw engine) + have_evas_software_ddraw="no" + ] + ) +fi +AM_CONDITIONAL(BUILD_ENGINE_SOFTWARE_DDRAW, test "x$have_evas_software_ddraw" = "xyes") + + ####################################### ## Check if we should build the software_x11 engine have_evas_software_x11="no"; @@ -1953,6 +2009,8 @@ fi AC_SUBST(VALGRIND_CFLAGS) +AC_SUBST(ddraw_libs) + AC_SUBST(x_cflags) AC_SUBST(x_libs) @@ -2018,6 +2076,7 @@ src/lib/engines/common/evas_op_sub/Makefile src/modules/Makefile src/modules/engines/Makefile src/modules/engines/software_generic/Makefile +src/modules/engines/software_ddraw/Makefile src/modules/engines/software_x11/Makefile src/modules/engines/software_xcb/Makefile src/modules/engines/fb/Makefile @@ -2071,6 +2130,7 @@ echo echo "Configuration Options Summary:" echo echo "Engines:" +echo " Software DirectDraw.....: $have_evas_software_ddraw" echo " Software X11............: $have_evas_software_x11" echo " Software XCB............: $have_evas_software_xcb" echo " Software Framebuffer....: $have_evas_fb" diff --git a/legacy/evas/src/lib/Makefile.am b/legacy/evas/src/lib/Makefile.am index cb11c3e124..32e7e0dd81 100644 --- a/legacy/evas/src/lib/Makefile.am +++ b/legacy/evas/src/lib/Makefile.am @@ -27,6 +27,7 @@ libevas_la_LIBADD = \ imaging/libevas_imaging.la \ engines/common/libevas_engine_common.la \ -lm \ + @fnmatch_libs@ \ @dlopen_libs@ \ @FREETYPE_LIBS@ \ @EET_LIBS@ \ diff --git a/legacy/evas/src/lib/canvas/evas_main.c b/legacy/evas/src/lib/canvas/evas_main.c index 4523839140..8d397032b0 100644 --- a/legacy/evas/src/lib/canvas/evas_main.c +++ b/legacy/evas/src/lib/canvas/evas_main.c @@ -703,6 +703,9 @@ evas_render_method_list(void) Evas_List *methods = NULL; /* FIXME: get from modules - this is currently coded-in */ +#ifdef BUILD_ENGINE_SOFTWARE_DDRAW + methods = evas_list_append(methods, strdup("software_ddraw")); +#endif #ifdef BUILD_ENGINE_SOFTWARE_X11 methods = evas_list_append(methods, strdup("software_x11")); #endif diff --git a/legacy/evas/src/lib/file/evas_module.c b/legacy/evas/src/lib/file/evas_module.c index 9cb9016a0d..a598416b86 100644 --- a/legacy/evas/src/lib/file/evas_module.c +++ b/legacy/evas/src/lib/file/evas_module.c @@ -299,7 +299,11 @@ evas_module_load(Evas_Module *em) if (em->loaded) return 1; // printf("LOAD %s\n", em->name); +#ifdef WIN32 + snprintf(buf, sizeof(buf), "%s/%s/%s/module.dll", em->path, em->name, MODULE_ARCH); +#else snprintf(buf, sizeof(buf), "%s/%s/%s/module.so", em->path, em->name, MODULE_ARCH); +#endif if (!evas_file_path_exists(buf)) { printf("[evas module] error loading the module %s. It doesnt exists\n", buf); diff --git a/legacy/evas/src/modules/engines/Makefile.am b/legacy/evas/src/modules/engines/Makefile.am index 5dad225d72..deaeee32af 100644 --- a/legacy/evas/src/modules/engines/Makefile.am +++ b/legacy/evas/src/modules/engines/Makefile.am @@ -11,6 +11,7 @@ gl_common \ gl_x11 \ software_qtopia \ software_win32_gdi \ +software_ddraw \ software_x11 \ software_xcb \ xrender_x11 \ diff --git a/legacy/evas/src/modules/engines/software_ddraw/Evas_Engine_Software_DDraw.h b/legacy/evas/src/modules/engines/software_ddraw/Evas_Engine_Software_DDraw.h new file mode 100644 index 0000000000..83048a0cb8 --- /dev/null +++ b/legacy/evas/src/modules/engines/software_ddraw/Evas_Engine_Software_DDraw.h @@ -0,0 +1,28 @@ +#ifndef __EVAS_ENGINE_SOFTWARE_DDRAW_H__ +#define __EVAS_ENGINE_SOFTWARE_DDRAW_H__ + + +#include +#include + +typedef struct _Evas_Engine_Info_Software_DDraw Evas_Engine_Info_Software_DDraw; + +struct _Evas_Engine_Info_Software_DDraw +{ + /* PRIVATE - don't mess with this baby or evas will poke its tongue out */ + /* at you and make nasty noises */ + Evas_Engine_Info magic; + + struct { + HWND window; + LPDIRECTDRAW object; /* DirectDraw object */ + LPDIRECTDRAWSURFACE surface_primary; /* DirectDraw primary surface */ + LPDIRECTDRAWSURFACE surface_back; /* DirectDraw back surface */ + + int depth; + int rotation; + } info; +}; + + +#endif /* __EVAS_ENGINE_SOFTWARE_DDRAW_H__ */ diff --git a/legacy/evas/src/modules/engines/software_ddraw/Makefile.am b/legacy/evas/src/modules/engines/software_ddraw/Makefile.am new file mode 100644 index 0000000000..636ca1926b --- /dev/null +++ b/legacy/evas/src/modules/engines/software_ddraw/Makefile.am @@ -0,0 +1,33 @@ +AUTOMAKE_OPTIONS = 1.4 foreign + +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = -I. -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/lib/include -I$(top_srcdir)/src/modules/engines @FREETYPE_CFLAGS@ + +if BUILD_ENGINE_SOFTWARE_DDRAW + +pkgdir = $(libdir)/evas/modules/engines/software_ddraw/$(MODULE_ARCH) + +pkg_LTLIBRARIES = module.la +module_la_SOURCES = \ +evas_engine.h \ +evas_engine.c \ +evas_outbuf.c \ +evas_ddraw_buffer.c \ +evas_ddraw_main.c + +module_la_LIBADD = @ddraw_libs@ $(top_builddir)/src/lib/libevas.la +module_la_LDFLAGS = @create_shared_lib@ -module -avoid-version -L$(top_builddir)/src/lib -L$(top_builddir)/src/lib/.libs +module_la_DEPENDENCIES = $(top_builddir)/config.h + +include_HEADERS = Evas_Engine_Software_DDraw.h + +endif + +EXTRA_DIST = \ +evas_engine.h \ +evas_engine.c \ +evas_outbuf.c \ +evas_ddraw_buffer.c \ +evas_ddraw_main.c \ +Evas_Engine_Software_DDraw.h diff --git a/legacy/evas/src/modules/engines/software_ddraw/evas_ddraw_buffer.c b/legacy/evas/src/modules/engines/software_ddraw/evas_ddraw_buffer.c new file mode 100644 index 0000000000..9e03defa13 --- /dev/null +++ b/legacy/evas/src/modules/engines/software_ddraw/evas_ddraw_buffer.c @@ -0,0 +1,86 @@ +#include + +#include "evas_engine.h" + + +DDraw_Output_Buffer * +evas_software_ddraw_output_buffer_new(int depth, + int width, + int height, + void *data) +{ + DDraw_Output_Buffer *ddob; + + ddob = calloc(1, sizeof(DDraw_Output_Buffer)); + if (!ddob) return NULL; + + ddob->image = data; + ddob->depth = depth; + ddob->width = width; + ddob->height = height; + ddob->pitch = width * depth / 8; + + if (!ddob->image) + { + ddob->image = malloc(ddob->pitch * height); + if (!ddob->image) + { + free(ddob); + return NULL; + } + } + + return ddob; +} + +void +evas_software_ddraw_output_buffer_free(DDraw_Output_Buffer *ddob) +{ + if (ddob->image) free(ddob->image); + free(ddob); +} + +void +evas_software_ddraw_output_buffer_paste(DDraw_Output_Buffer *ddob, + DDSURFACEDESC2 *surface_desc, + int x, + int y) +{ + DATA8 *dd_data; + DATA8 *evas_data; + int width; + int height; + int pitch; + int j; + + if ((x >= surface_desc->dwWidth) || (y >= surface_desc->dwHeight)) + return; + + /* compute the size of the data to copy on the back surface */ + width = ((x + ddob->width) > surface_desc->dwWidth) + ? surface_desc->dwWidth - x + : ddob->width; + height = ((y + ddob->height) > surface_desc->dwHeight) + ? surface_desc->dwHeight - y + : ddob->height; + pitch = width * ddob->depth / 8; + + dd_data = (DATA8 *)surface_desc->lpSurface + y * surface_desc->lPitch + x * surface_desc->ddpfPixelFormat.dwRGBBitCount / 8; + evas_data = (unsigned char *)ddob->image; + for (j = 0; j < height; j++, evas_data += ddob->pitch, dd_data += surface_desc->lPitch) + memcpy(dd_data, evas_data, pitch); +} + +DATA8 * +evas_software_ddraw_output_buffer_data(DDraw_Output_Buffer *ddob, + int *bytes_per_line_ret) +{ + if (bytes_per_line_ret) *bytes_per_line_ret = ddob->pitch; + return ddob->image; +} + +int +evas_software_ddraw_output_buffer_depth(DDraw_Output_Buffer *ddob) +{ + return ddob->depth; +} diff --git a/legacy/evas/src/modules/engines/software_ddraw/evas_ddraw_main.c b/legacy/evas/src/modules/engines/software_ddraw/evas_ddraw_main.c new file mode 100644 index 0000000000..3da13c9b3e --- /dev/null +++ b/legacy/evas/src/modules/engines/software_ddraw/evas_ddraw_main.c @@ -0,0 +1,5 @@ + +void +evas_software_ddraw_init(void) +{ +} diff --git a/legacy/evas/src/modules/engines/software_ddraw/evas_engine.c b/legacy/evas/src/modules/engines/software_ddraw/evas_engine.c new file mode 100644 index 0000000000..fff1dcd95d --- /dev/null +++ b/legacy/evas/src/modules/engines/software_ddraw/evas_engine.c @@ -0,0 +1,358 @@ +#include "evas_engine.h" +#include "evas_private.h" +#include "Evas_Engine_Software_DDraw.h" + +/* engine struct data */ +typedef struct _Render_Engine Render_Engine; + +struct _Render_Engine +{ + Tilebuf *tb; + Outbuf *ob; + Tilebuf_Rect *rects; + Evas_Object_List *cur_rect; + int end : 1; +}; + + +/* function tables - filled in later (func and parent func) */ +static Evas_Func func, pfunc; + +/* prototypes we will use here */ +static void *_output_setup(int width, + int height, + int rotation, + HWND window, + LPDIRECTDRAW lpDD, + LPDIRECTDRAWSURFACE surface_primary, + LPDIRECTDRAWSURFACE surface_back, + int w_depth); + +static void *eng_info(Evas *e); +static void eng_info_free(Evas *e, + void *info); +static void eng_setup(Evas *e, + void *info); +static void eng_output_free(void *data); +static void eng_output_resize(void *data, + int width, + int height); +static void eng_output_tile_size_set(void *data, + int width, + int height); +static void eng_output_redraws_rect_add(void *data, + int x, + int y, + int width, + int height); +static void eng_output_redraws_rect_del(void *data, + int x, + int y, + int width, + int height); +static void eng_output_redraws_clear(void *data); + +/* internal engine routines */ +static void * +_output_setup(int width, + int height, + int rotation, + HWND window, + LPDIRECTDRAW object, + LPDIRECTDRAWSURFACE surface_primary, + LPDIRECTDRAWSURFACE surface_back, + int w_depth) +{ + Render_Engine *re; + + re = (Render_Engine *)calloc(1, sizeof(Render_Engine)); + if (!re) return NULL; + + /* if we haven't initialized - init (automatic abort if already done) */ + evas_common_cpu_init(); + + evas_common_blend_init(); + evas_common_image_init(); + evas_common_convert_init(); + evas_common_scale_init(); + evas_common_rectangle_init(); + evas_common_gradient_init(); + evas_common_polygon_init(); + evas_common_line_init(); + evas_common_font_init(); + evas_common_draw_init(); + evas_common_tilebuf_init(); + + evas_software_ddraw_outbuf_init(); + + /* get any stored performance metrics from device */ + re->ob = evas_software_ddraw_outbuf_setup_dd(width, height, rotation, OUTBUF_DEPTH_INHERIT, window, object, surface_primary, surface_back, w_depth); + if (!re->ob) + { + free(re); + return NULL; + } + + re->tb = evas_common_tilebuf_new(width, height); + if (!re->tb) + { + evas_software_ddraw_outbuf_free(re->ob); + free(re); + return NULL; + } + + /* FIXME: that comment :) */ + /* in preliminary tests 16x16 gave highest framerates */ + evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + + return re; +} + +/* engine api this module provides */ +static void * +eng_info(Evas *e) +{ + Evas_Engine_Info_Software_DDraw *info; + + info = (Evas_Engine_Info_Software_DDraw *)calloc(1, sizeof(Evas_Engine_Info_Software_DDraw)); + if (!info) return NULL; + info->magic.magic = rand(); + return info; + e = NULL; +} + +static void +eng_info_free(Evas *e, + void *info) +{ + Evas_Engine_Info_Software_DDraw *in; + + in = (Evas_Engine_Info_Software_DDraw *)info; + free(in); +} + +static void +eng_setup(Evas *e, + void *info) +{ + Render_Engine *re; + Evas_Engine_Info_Software_DDraw *in; + + in = (Evas_Engine_Info_Software_DDraw *)info; + if (!e->engine.data.output) + e->engine.data.output = + _output_setup(e->output.w, + e->output.h, + in->info.rotation, + in->info.window, + in->info.object, + in->info.surface_primary, + in->info.surface_back, + in->info.depth); + if (!e->engine.data.output) return; + if (!e->engine.data.context) + e->engine.data.context = + e->engine.func->context_new(e->engine.data.output); + + re = (Render_Engine *)e->engine.data.output; +} + +static void +eng_output_free(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_software_ddraw_outbuf_free(re->ob); + evas_common_tilebuf_free(re->tb); + if (re->rects) evas_common_tilebuf_free_render_rects(re->rects); + free(re); + + evas_common_font_shutdown(); + evas_common_image_shutdown(); +} + +static void +eng_output_resize(void *data, + int width, + int height) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_software_ddraw_outbuf_reconfigure(re->ob, + width, + height, + evas_software_ddraw_outbuf_rot_get(re->ob), + OUTBUF_DEPTH_INHERIT); + evas_common_tilebuf_free(re->tb); + re->tb = evas_common_tilebuf_new(width, height); + if (re->tb) + evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); +} + +static void +eng_output_tile_size_set(void *data, + int width, + int height) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_set_tile_size(re->tb, width, height); +} + +static void +eng_output_redraws_rect_add(void *data, + int x, + int y, + int width, + int height) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_add_redraw(re->tb, x, y, width, height); +} + +static void +eng_output_redraws_rect_del(void *data, + int x, + int y, + int width, + int height) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_del_redraw(re->tb, x, y, width, height); +} + +static void +eng_output_redraws_clear(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_clear(re->tb); +} + +static void * +eng_output_redraws_next_update_get(void *data, + int *x, + int *y, + int *w, + int *h, + int *cx, + int *cy, + int *cw, + int *ch) +{ + Render_Engine *re; + RGBA_Image *surface; + Tilebuf_Rect *rect; + int ux; + int uy; + int uw; + int uh; + + re = (Render_Engine *)data; + if (re->end) + { + re->end = 0; + return NULL; + } + if (!re->rects) + { + re->rects = evas_common_tilebuf_get_render_rects(re->tb); + re->cur_rect = (Evas_Object_List *)re->rects; + } + if (!re->cur_rect) return NULL; + rect = (Tilebuf_Rect *)re->cur_rect; + ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h; + re->cur_rect = re->cur_rect->next; + if (!re->cur_rect) + { + evas_common_tilebuf_free_render_rects(re->rects); + re->rects = NULL; + re->end = 1; + } + + surface = evas_software_ddraw_outbuf_new_region_for_update(re->ob, + ux, uy, + uw, uh, + cx, cy, + cw, ch); + *x = ux; *y = uy; *w = uw; *h = uh; + + return surface; +} + +static void +eng_output_redraws_next_update_push(void *data, + void *surface, + int x, + int y, + int w, + int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_pipe_begin((RGBA_Image *)surface); + evas_common_pipe_flush((RGBA_Image *)surface); + evas_software_ddraw_outbuf_push_updated_region(re->ob, (RGBA_Image *)surface, x, y, w, h); + evas_software_ddraw_outbuf_free_region_for_update(re->ob, (RGBA_Image *)surface); + evas_common_cpu_end_opt(); +} + +static void +eng_output_flush(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_software_ddraw_outbuf_flush(re->ob); +} + +/* module advertising code */ +EAPI int +module_open(Evas_Module *em) +{ + if (!em) return 0; + /* get whatever engine module we inherit from */ + if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0; + /* store it for later use */ + func = pfunc; + /* now to override methods */ +#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_) + ORD(info); + ORD(info_free); + ORD(setup); + ORD(output_free); + ORD(output_resize); + ORD(output_tile_size_set); + ORD(output_redraws_rect_add); + ORD(output_redraws_rect_del); + ORD(output_redraws_clear); + ORD(output_redraws_next_update_get); + ORD(output_redraws_next_update_push); + ORD(output_flush); + /* now advertise out own api */ + em->functions = (void *)(&func); + return 1; +} + +EAPI void +module_close(void) +{ +} + +EAPI Evas_Module_Api evas_modapi = +{ + EVAS_MODULE_API_VERSION, + EVAS_MODULE_TYPE_ENGINE, + "software_ddraw", + "none" +}; + diff --git a/legacy/evas/src/modules/engines/software_ddraw/evas_engine.h b/legacy/evas/src/modules/engines/software_ddraw/evas_engine.h new file mode 100644 index 0000000000..7646e8aeb2 --- /dev/null +++ b/legacy/evas/src/modules/engines/software_ddraw/evas_engine.h @@ -0,0 +1,119 @@ +#ifndef __EVAS_ENGINE_H__ +#define __EVAS_ENGINE_H__ + + +#include +#include + +#include "evas_common.h" + +typedef struct _Outbuf Outbuf; +typedef struct _DDraw_Output_Buffer DDraw_Output_Buffer; + + +enum _Outbuf_Depth +{ + OUTBUF_DEPTH_NONE, + OUTBUF_DEPTH_INHERIT, + OUTBUF_DEPTH_RGB_16BPP_565_565_DITHERED, + OUTBUF_DEPTH_RGB_16BPP_555_555_DITHERED, + OUTBUF_DEPTH_RGB_16BPP_444_444_DITHERED, + OUTBUF_DEPTH_RGB_16BPP_565_444_DITHERED, + OUTBUF_DEPTH_RGB_32BPP_888_8888, + OUTBUF_DEPTH_LAST +}; + +typedef enum _Outbuf_Depth Outbuf_Depth; + + +struct _Outbuf +{ + int width; + int height; + int rot; + Outbuf_Depth depth; + + struct { + struct { + HWND window; + LPDIRECTDRAW object; + LPDIRECTDRAWSURFACE surface_primary; + LPDIRECTDRAWSURFACE surface_back; + int depth; + } dd; + struct { + DATA32 r, g, b; + } mask; + + /* a list of pending regions to write to the target */ + Evas_List *pending_writes; + } priv; +}; + +struct _DDraw_Output_Buffer +{ + void *image; + int x; + int y; + int width; + int height; + int depth; + int pitch; +}; + + +/* Outbuf functions */ +void evas_software_ddraw_outbuf_init(void); +void evas_software_ddraw_outbuf_free(Outbuf *buf); +Outbuf *evas_software_ddraw_outbuf_setup_dd(int width, + int height, + int rotation, + Outbuf_Depth depth, + HWND window, + LPDIRECTDRAW object, + LPDIRECTDRAWSURFACE surface_primary, + LPDIRECTDRAWSURFACE surface_back, + int w_depth); +RGBA_Image *evas_software_ddraw_outbuf_new_region_for_update(Outbuf *buf, + int x, + int y, + int width, + int height, + int *cx, + int *cy, + int *cw, + int *ch); +void evas_software_ddraw_outbuf_free_region_for_update(Outbuf *buf, + RGBA_Image *update); +void evas_software_ddraw_outbuf_push_updated_region(Outbuf *buf, + RGBA_Image *update, + int x, + int y, + int width, + int height); +void evas_software_ddraw_outbuf_reconfigure(Outbuf *buf, + int width, + int height, + int rotation, + Outbuf_Depth depth); +int evas_software_ddraw_outbuf_width_get(Outbuf *buf); +int evas_software_ddraw_outbuf_height_get(Outbuf *buf); +Outbuf_Depth evas_software_ddraw_outbuf_depth_get(Outbuf *buf); +int evas_software_ddraw_outbuf_rot_get(Outbuf *buf); + +/* Output Buffer functions */ +DDraw_Output_Buffer *evas_software_ddraw_output_buffer_new(int depth, + int width, + int height, + void *data); +void evas_software_ddraw_output_buffer_free(DDraw_Output_Buffer *ddob); +void evas_software_ddraw_output_buffer_paste(DDraw_Output_Buffer *ddob, + DDSURFACEDESC2 *surface_desc, + int x, + int y); +DATA8 *evas_software_ddraw_output_buffer_data(DDraw_Output_Buffer *ddob, + int *bytes_per_line_ret); +int evas_software_ddraw_output_buffer_depth(DDraw_Output_Buffer *ddob); + + +#endif /* __EVAS_ENGINE_H__ */ diff --git a/legacy/evas/src/modules/engines/software_ddraw/evas_outbuf.c b/legacy/evas/src/modules/engines/software_ddraw/evas_outbuf.c new file mode 100644 index 0000000000..d3231ff0d8 --- /dev/null +++ b/legacy/evas/src/modules/engines/software_ddraw/evas_outbuf.c @@ -0,0 +1,371 @@ +#include "evas_engine.h" + + +static void +_ddraw_surface_flip(HWND window, + LPDIRECTDRAWSURFACE surface_primary, + LPDIRECTDRAWSURFACE surface_back, + int width, + int height) +{ + HRESULT res; + RECT dst_rect; + RECT src_rect; + POINT p; + + /* we figure out where on the primary surface our window lives */ + p.x = 0; + p.y = 0; + ClientToScreen (window, &p); + GetClientRect (window, &dst_rect); + OffsetRect (&dst_rect, p.x, p.y); + SetRect (&src_rect, 0, 0, width, height); + res = IDirectDrawSurface7_Blt (surface_primary, &dst_rect, + surface_back, &src_rect, + DDBLT_WAIT, NULL); + if (FAILED(res)) + { + } +} + + +void +evas_software_ddraw_outbuf_init(void) +{ +} + +void +evas_software_ddraw_outbuf_free(Outbuf *buf) +{ + free(buf); +} + +Outbuf * +evas_software_ddraw_outbuf_setup_dd(int width, + int height, + int rotation, + Outbuf_Depth depth, + HWND window, + LPDIRECTDRAW object, + LPDIRECTDRAWSURFACE surface_primary, + LPDIRECTDRAWSURFACE surface_back, + int w_depth) +{ + Outbuf *buf; + + buf = (Outbuf *)calloc(1, sizeof(Outbuf)); + if (!buf) + return NULL; + + buf->width = width; + buf->height = height; + buf->depth = depth; + buf->rot = rotation; + + buf->priv.dd.window = window; + buf->priv.dd.object = object; + buf->priv.dd.surface_primary = surface_primary; + buf->priv.dd.surface_back = surface_back; + buf->priv.dd.depth = w_depth; + + { + Gfx_Func_Convert conv_func; + DDraw_Output_Buffer *ddob; + + ddob = evas_software_ddraw_output_buffer_new(w_depth, 1, 1, NULL); + + conv_func = NULL; + if (ddob) + { + DDPIXELFORMAT pixel_format; + + ZeroMemory(&pixel_format, sizeof(pixel_format)); + pixel_format.dwSize = sizeof(pixel_format); + IDirectDrawSurface7_GetPixelFormat(surface_primary, &pixel_format); + buf->priv.mask.r = pixel_format.dwRBitMask; + buf->priv.mask.g = pixel_format.dwGBitMask; + buf->priv.mask.b = pixel_format.dwBBitMask; + + if ((rotation == 0) || (rotation == 180)) + conv_func = evas_common_convert_func_get(0, + width, + height, + evas_software_ddraw_output_buffer_depth (ddob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + PAL_MODE_NONE, + rotation); + else if ((rotation == 90) || (rotation == 270)) + conv_func = evas_common_convert_func_get(0, + height, + width, + evas_software_ddraw_output_buffer_depth (ddob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + PAL_MODE_NONE, + rotation); + evas_software_ddraw_output_buffer_free(ddob); + if (!conv_func) + { + printf(".[ Evas Error ].\n" + " {\n" + " At depth %i:\n" + " RGB format mask: %08x, %08x, %08x\n" + " Not supported by and compiled in converters!\n" + " }\n", + buf->priv.dd.depth, + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b); + } + } + } + + return buf; +} + +RGBA_Image * +evas_software_ddraw_outbuf_new_region_for_update(Outbuf *buf, + int x, + int y, + int width, + int height, + int *cx, + int *cy, + int *cw, + int *ch) +{ + RGBA_Image *im; + DDraw_Output_Buffer *ddob = NULL; + int bpl = 0; + + *cx = 0; + *cy = 0; + *cw = width; + *ch = height; + + if ((buf->rot == 0) && + (buf->priv.mask.r == 0xff0000) && + (buf->priv.mask.g == 0x00ff00) && + (buf->priv.mask.b == 0x0000ff)) + { + im = evas_common_image_new(); + im->image = evas_common_image_surface_new(im); + im->image->w = width; + im->image->h = height; + im->image->data = NULL; + im->image->no_free = 1; + ddob = evas_software_ddraw_output_buffer_new(buf->priv.dd.depth, + width, + height, + NULL); + im->extended_info = ddob; + im->image->data = (DATA32 *)evas_software_ddraw_output_buffer_data(ddob, &bpl); + } + else + { + im = evas_common_image_create(width, height); + im->extended_info = ddob; + if ((buf->rot == 0) || (buf->rot == 180)) + ddob = evas_software_ddraw_output_buffer_new(buf->priv.dd.depth, + width, + height, + NULL); + else if ((buf->rot == 90) || (buf->rot == 270)) + ddob = evas_software_ddraw_output_buffer_new(buf->priv.dd.depth, + width, + height, + NULL); + im->extended_info = ddob; + } + + buf->priv.pending_writes = evas_list_append(buf->priv.pending_writes, im); + + return im; +} + +void +evas_software_ddraw_outbuf_free_region_for_update(Outbuf *buf, + RGBA_Image *update) +{ + /* no need to do anything - they are cleaned up on flush */ +} + +void +evas_software_ddraw_outbuf_flush(Outbuf *buf) +{ + DDSURFACEDESC2 surface_desc; + HRESULT res; + Evas_List *l; + + ZeroMemory(&surface_desc, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + + /* lock the back surface */ + res = IDirectDrawSurface7_Lock (buf->priv.dd.surface_back, NULL, &surface_desc, + DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL); + if (FAILED(res)) goto free_images; + + /* copy safely the images that need to be drawn onto the back surface */ + for (l = buf->priv.pending_writes; l; l = l->next) + { + RGBA_Image *im; + DDraw_Output_Buffer *ddob; + + im = l->data; + ddob = im->extended_info; + /* paste now */ + evas_software_ddraw_output_buffer_paste(ddob, + &surface_desc, + ddob->x, + ddob->y); + } + + /* unlock the back surface */ + res = IDirectDrawSurface7_Unlock (buf->priv.dd.surface_back, NULL); + if (FAILED(res)) goto free_images; + + /* flip the surfaces */ + _ddraw_surface_flip(buf->priv.dd.window, + buf->priv.dd.surface_primary, + buf->priv.dd.surface_back, + buf->width, + buf->height); + + free_images: + while (buf->priv.pending_writes) + { + RGBA_Image *im; + DDraw_Output_Buffer *ddob; + + im = buf->priv.pending_writes->data; + buf->priv.pending_writes = evas_list_remove_list(buf->priv.pending_writes, + buf->priv.pending_writes); + ddob = im->extended_info; + evas_common_image_free(im); + if (ddob) evas_software_ddraw_output_buffer_free(ddob); + } + evas_common_cpu_end_opt(); +} + +void +evas_software_ddraw_outbuf_push_updated_region(Outbuf *buf, + RGBA_Image *update, + int x, + int y, + int width, + int height) +{ + Gfx_Func_Convert conv_func; + DDraw_Output_Buffer *ddob; + DATA32 *src_data; + void *data; + int bpl = 0; + + conv_func = NULL; + ddob = update->extended_info; + + if ((buf->rot == 0) || (buf->rot == 180)) + conv_func = evas_common_convert_func_get(NULL, + width, + height, + evas_software_ddraw_output_buffer_depth(ddob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + PAL_MODE_NONE, + buf->rot); + else if ((buf->rot == 90) || (buf->rot == 270)) + conv_func = evas_common_convert_func_get(NULL, + height, + width, + evas_software_ddraw_output_buffer_depth(ddob), + buf->priv.mask.r, + buf->priv.mask.g, + buf->priv.mask.b, + PAL_MODE_NONE, + buf->rot); + + if (!conv_func) return; + + data = evas_software_ddraw_output_buffer_data(ddob, &bpl); + src_data = update->image->data; + if (buf->rot == 0) + { + ddob->x = x; + ddob->y = y; + } + else if (buf->rot == 90) + { + ddob->x = y; + ddob->y = buf->width - x - width; + } + else if (buf->rot == 180) + { + ddob->x = buf->width - x - width; + ddob->y = buf->height - y - height; + } + else if (buf->rot == 270) + { + ddob->x = buf->height - y - height; + ddob->y = x; + } + if ((buf->rot == 0) || (buf->rot == 180)) + { + ddob->width = width; + ddob->height = height; + } + else if ((buf->rot == 90) || (buf->rot == 270)) + { + ddob->width = height; + ddob->height = width; + } + + if (data != src_data) + conv_func(src_data, data, + 0, + bpl / + ((evas_software_ddraw_output_buffer_depth(ddob))) - ddob->width, + ddob->width, ddob->height, x, y, NULL); +} + +void +evas_software_ddraw_outbuf_reconfigure(Outbuf *buf, + int width, + int height, + int rotation, + Outbuf_Depth depth) +{ + if ((width == buf->width) && (height == buf->height) && + (rotation == buf->rot) && (depth == buf->depth)) + return; + buf->width = width; + buf->height = height; + buf->rot = rotation; +} + +int +evas_software_ddraw_outbuf_width_get(Outbuf *buf) +{ + return buf->width; +} + +int +evas_software_ddraw_outbuf_height_get(Outbuf *buf) +{ + return buf->height; +} + +Outbuf_Depth +evas_software_ddraw_outbuf_depth_get(Outbuf *buf) +{ + return buf->depth; +} + +int +evas_software_ddraw_outbuf_rot_get(Outbuf *buf) +{ + return buf->rot; +} diff --git a/legacy/evas/src/modules/engines/software_generic/Makefile.am b/legacy/evas/src/modules/engines/software_generic/Makefile.am index 2b7e080e31..f11f295a3a 100644 --- a/legacy/evas/src/modules/engines/software_generic/Makefile.am +++ b/legacy/evas/src/modules/engines/software_generic/Makefile.am @@ -11,5 +11,5 @@ module_la_SOURCES = \ evas_engine.c module_la_LIBADD = $(top_builddir)/src/lib/libevas.la -module_la_LDFLAGS = -module -avoid-version -L$(top_builddir)/src/lib -L$(top_builddir)/src/lib/.libs +module_la_LDFLAGS = @create_shared_lib@ -module -avoid-version -L$(top_builddir)/src/lib -L$(top_builddir)/src/lib/.libs module_la_DEPENDENCIES = $(top_builddir)/config.h