diff --git a/configure.ac b/configure.ac index da1c7a9b08..1cbc698d69 100644 --- a/configure.ac +++ b/configure.ac @@ -1239,7 +1239,7 @@ AC_ARG_ENABLE([sdl], [want_sdl="no"]) if test "${want_sdl}" = "yes"; then - EFL_PKG_CHECK_STRICT([sdl >= 1.2.0]) + EFL_PKG_CHECK_STRICT([sdl2 >= 2.0.0]) fi # We only enable SDL with opengl if it is not the full version and not ES @@ -2734,10 +2734,7 @@ EFL_INTERNAL_DEPEND_PKG([ECORE_SDL], [ecore]) EFL_INTERNAL_DEPEND_PKG([ECORE_SDL], [eo]) EFL_INTERNAL_DEPEND_PKG([ECORE_SDL], [eina]) -EFL_DEPEND_PKG([ECORE_SDL], [SDL], [sdl >= 1.2.0]) - -PKG_CHECK_EXISTS([sdl >= 1.3.0], - [AC_DEFINE(BUILD_ECORE_EVAS_SDL_130, 1, [Support for SVN SDL])]) +EFL_DEPEND_PKG([ECORE_SDL], [SDL], [sdl2 >= 2.0.0]) EFL_EVAL_PKGS([ECORE_SDL]) diff --git a/m4/evas_check_engine.m4 b/m4/evas_check_engine.m4 index 05ec1f8d7a..dd7030e5cf 100644 --- a/m4/evas_check_engine.m4 +++ b/m4/evas_check_engine.m4 @@ -419,10 +419,10 @@ have_dep="no" evas_engine_[]$1[]_cflags="" evas_engine_[]$1[]_libs="" -PKG_CHECK_EXISTS([sdl >= 1.2.0], +PKG_CHECK_EXISTS([sdl2 >= 2.0.0], [ have_dep="yes" - requirement="sdl >= 1.2.0" + requirement="sdl2 >= 2.0.0" ], [have_dep="no"]) diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index 1687444d68..c2c2f49126 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -949,17 +949,11 @@ modules_evas_engines_gl_sdl_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ -I$(top_srcdir)/src/modules/evas/engines/gl_common \ @EVAS_CFLAGS@ \ @evas_engine_gl_sdl_cflags@ -modules_evas_engines_gl_sdl_module_la_LIBADD = -if ! EVAS_STATIC_BUILD_GL_COMMON -modules_evas_engines_gl_sdl_module_la_LIBADD += \ -modules/evas/engines/gl_common/libevas_engine_gl_common.la -endif -modules_evas_engines_gl_sdl_module_la_LIBADD += \ +modules_evas_engines_gl_sdl_module_la_LIBADD = \ @USE_EVAS_LIBS@ \ @evas_engine_gl_sdl_libs@ modules_evas_engines_gl_sdl_module_la_DEPENDENCIES = \ -@USE_EVAS_INTERNAL_LIBS@ \ -modules/evas/engines/gl_common/libevas_engine_gl_common.la +@USE_EVAS_INTERNAL_LIBS@ modules_evas_engines_gl_sdl_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ modules_evas_engines_gl_sdl_module_la_LIBTOOLFLAGS = --tag=disable-static endif diff --git a/src/lib/ecore_sdl/Ecore_Sdl.h b/src/lib/ecore_sdl/Ecore_Sdl.h index 359e974718..ed4bd0f0a9 100644 --- a/src/lib/ecore_sdl/Ecore_Sdl.h +++ b/src/lib/ecore_sdl/Ecore_Sdl.h @@ -41,6 +41,26 @@ EAPI extern int ECORE_SDL_EVENT_LOST_FOCUS; EAPI extern int ECORE_SDL_EVENT_RESIZE; EAPI extern int ECORE_SDL_EVENT_EXPOSE; +typedef struct _Ecore_Sdl_Event_Video_Resize Ecore_Sdl_Event_Video_Resize; +struct _Ecore_Sdl_Event_Video_Resize +{ + unsigned int windowID; + int w; + int h; +}; + +typedef struct _Ecore_Sdl_Event_Window Ecore_Sdl_Event_Window; +struct _Ecore_Sdl_Event_Window +{ + unsigned int windowID; +}; + +EAPI int ecore_sdl_init(const char *name); +EAPI int ecore_sdl_shutdown(void); +EAPI void ecore_sdl_feed_events(void); + + /* The following data structure have been deprecated since a long time */ + typedef struct _Ecore_Sdl_Event_Key_Down Ecore_Sdl_Event_Key_Down; struct _Ecore_Sdl_Event_Key_Down /** SDL Key Down event */ { @@ -96,17 +116,6 @@ struct _Ecore_Sdl_Event_Mouse_Wheel /** SDL Mouse Wheel event */ unsigned int time; }; -typedef struct _Ecore_Sdl_Event_Video_Resize Ecore_Sdl_Event_Video_Resize; -struct _Ecore_Sdl_Event_Video_Resize -{ - int w; - int h; -}; - -EAPI int ecore_sdl_init(const char *name); -EAPI int ecore_sdl_shutdown(void); -EAPI void ecore_sdl_feed_events(void); - #ifdef __cplusplus } #endif diff --git a/src/lib/ecore_sdl/Ecore_Sdl_Keys.h b/src/lib/ecore_sdl/Ecore_Sdl_Keys.h index 4e298d77ea..2ca2069901 100644 --- a/src/lib/ecore_sdl/Ecore_Sdl_Keys.h +++ b/src/lib/ecore_sdl/Ecore_Sdl_Keys.h @@ -3,7 +3,7 @@ struct _ecore_sdl_keys_s { - unsigned int code; + SDL_Keycode code; const char* name; const char* compose; }; @@ -11,9 +11,6 @@ struct _ecore_sdl_keys_s static const struct _ecore_sdl_keys_s keystable[] = { { SDLK_UNKNOWN, "0x00", "" }, -#ifndef BUILD_ECORE_EVAS_SDL_130 - { SDLK_FIRST, "First", "First" }, -#endif { SDLK_BACKSPACE, "BackSpace", "\010" }, { SDLK_TAB, "Tab", "\011" }, { SDLK_CLEAR, "Clear", "Clear" }, @@ -89,116 +86,17 @@ static const struct _ecore_sdl_keys_s keystable[] = { SDLK_DELETE, "Delete", "\177" }, /* End of ASCII mapped keysyms */ -#ifndef BUILD_ECORE_EVAS_SDL_130 - /* International keyboard syms */ - { SDLK_WORLD_0, "w0", "" }, /* 0xA0 */ - { SDLK_WORLD_1, "w1", "" }, - { SDLK_WORLD_2, "w2", "" }, - { SDLK_WORLD_3, "w3", "" }, - { SDLK_WORLD_4, "w4", "" }, - { SDLK_WORLD_5, "w5", "" }, - { SDLK_WORLD_6, "w6", "" }, - { SDLK_WORLD_7, "w7", "" }, - { SDLK_WORLD_8, "w8", "" }, - { SDLK_WORLD_9, "w9", "" }, - { SDLK_WORLD_10, "w10", "" }, - { SDLK_WORLD_11, "w11", "" }, - { SDLK_WORLD_12, "w12", "" }, - { SDLK_WORLD_13, "w13", "" }, - { SDLK_WORLD_14, "w14", "" }, - { SDLK_WORLD_15, "w15", "" }, - { SDLK_WORLD_16, "w16", "" }, - { SDLK_WORLD_17, "w17", "" }, - { SDLK_WORLD_18, "w18", "" }, - { SDLK_WORLD_19, "w19", "" }, - { SDLK_WORLD_20, "w20", "" }, - { SDLK_WORLD_21, "w21", "" }, - { SDLK_WORLD_22, "w22", "" }, - { SDLK_WORLD_23, "w23", "" }, - { SDLK_WORLD_24, "w24", "" }, - { SDLK_WORLD_25, "w25", "" }, - { SDLK_WORLD_26, "w26", "" }, - { SDLK_WORLD_27, "w27", "" }, - { SDLK_WORLD_28, "w28", "" }, - { SDLK_WORLD_29, "w29", "" }, - { SDLK_WORLD_30, "w30", "" }, - { SDLK_WORLD_31, "w31", "" }, - { SDLK_WORLD_32, "w32", "" }, - { SDLK_WORLD_33, "w33", "" }, - { SDLK_WORLD_34, "w34", "" }, - { SDLK_WORLD_35, "w35", "" }, - { SDLK_WORLD_36, "w36", "" }, - { SDLK_WORLD_37, "w37", "" }, - { SDLK_WORLD_38, "w38", "" }, - { SDLK_WORLD_39, "w39", "" }, - { SDLK_WORLD_40, "w40", "" }, - { SDLK_WORLD_41, "w41", "" }, - { SDLK_WORLD_42, "w42", "" }, - { SDLK_WORLD_43, "w43", "" }, - { SDLK_WORLD_44, "w44", "" }, - { SDLK_WORLD_45, "w45", "" }, - { SDLK_WORLD_46, "w46", "" }, - { SDLK_WORLD_47, "w47", "" }, - { SDLK_WORLD_48, "w48", "" }, - { SDLK_WORLD_49, "w49", "" }, - { SDLK_WORLD_50, "w50", "" }, - { SDLK_WORLD_51, "w51", "" }, - { SDLK_WORLD_52, "w52", "" }, - { SDLK_WORLD_53, "w53", "" }, - { SDLK_WORLD_54, "w54", "" }, - { SDLK_WORLD_55, "w55", "" }, - { SDLK_WORLD_56, "w56", "" }, - { SDLK_WORLD_57, "w57", "" }, - { SDLK_WORLD_58, "w58", "" }, - { SDLK_WORLD_59, "w59", "" }, - { SDLK_WORLD_60, "w60", "" }, - { SDLK_WORLD_61, "w61", "" }, - { SDLK_WORLD_62, "w62", "" }, - { SDLK_WORLD_63, "w63", "" }, - { SDLK_WORLD_64, "w64", "" }, - { SDLK_WORLD_65, "w65", "" }, - { SDLK_WORLD_66, "w66", "" }, - { SDLK_WORLD_67, "w67", "" }, - { SDLK_WORLD_68, "w68", "" }, - { SDLK_WORLD_69, "w69", "" }, - { SDLK_WORLD_70, "w70", "" }, - { SDLK_WORLD_71, "w71", "" }, - { SDLK_WORLD_72, "w72", "" }, - { SDLK_WORLD_73, "w73", "" }, - { SDLK_WORLD_74, "w74", "" }, - { SDLK_WORLD_75, "w75", "" }, - { SDLK_WORLD_76, "w76", "" }, - { SDLK_WORLD_77, "w77", "" }, - { SDLK_WORLD_78, "w78", "" }, - { SDLK_WORLD_79, "w79", "" }, - { SDLK_WORLD_80, "w80", "" }, - { SDLK_WORLD_81, "w81", "" }, - { SDLK_WORLD_82, "w82", "" }, - { SDLK_WORLD_83, "w83", "" }, - { SDLK_WORLD_84, "w84", "" }, - { SDLK_WORLD_85, "w85", "" }, - { SDLK_WORLD_86, "w86", "" }, - { SDLK_WORLD_87, "w87", "" }, - { SDLK_WORLD_88, "w88", "" }, - { SDLK_WORLD_89, "w89", "" }, - { SDLK_WORLD_90, "w90", "" }, - { SDLK_WORLD_91, "w91", "" }, - { SDLK_WORLD_92, "w92", "" }, - { SDLK_WORLD_93, "w93", "" }, - { SDLK_WORLD_94, "w94", "" }, - { SDLK_WORLD_95, "w95", "" }, -#endif /* Numeric keypad */ - { SDLK_KP0, "KP0", "0" }, - { SDLK_KP1, "KP1", "1" }, - { SDLK_KP2, "KP2", "2" }, - { SDLK_KP3, "KP3", "3" }, - { SDLK_KP4, "KP4", "4" }, - { SDLK_KP5, "KP5", "5" }, - { SDLK_KP6, "KP6", "6" }, - { SDLK_KP7, "KP7", "7" }, - { SDLK_KP8, "KP8", "8" }, - { SDLK_KP9, "KP9", "9" }, + { SDLK_KP_0, "KP0", "0" }, + { SDLK_KP_1, "KP1", "1" }, + { SDLK_KP_2, "KP2", "2" }, + { SDLK_KP_3, "KP3", "3" }, + { SDLK_KP_4, "KP4", "4" }, + { SDLK_KP_5, "KP5", "5" }, + { SDLK_KP_6, "KP6", "6" }, + { SDLK_KP_7, "KP7", "7" }, + { SDLK_KP_8, "KP8", "8" }, + { SDLK_KP_9, "KP9", "9" }, { SDLK_KP_PERIOD, "period", "." }, { SDLK_KP_DIVIDE, "KP_Divide", "/" }, { SDLK_KP_MULTIPLY, "KP_Multiply", "*" }, @@ -236,30 +134,25 @@ static const struct _ecore_sdl_keys_s keystable[] = { SDLK_F15, "F15", "F15" }, /* Key state modifier keys */ - { SDLK_NUMLOCK, "Num_Lock", "Num_Lock" }, + { SDLK_NUMLOCKCLEAR, "Num_Lock", "Num_Lock" }, { SDLK_CAPSLOCK, "Caps_Lock", "Caps_Lock" }, - { SDLK_SCROLLOCK, "Scroll_Lock", "Scroll_Lock" }, + { SDLK_SCROLLLOCK, "Scroll_Lock", "Scroll_Lock" }, { SDLK_RSHIFT, "Shift_R", "Shift_R" }, { SDLK_LSHIFT, "Shift_L", "Shift_L" }, { SDLK_RCTRL, "Control_R", "Control_R" }, { SDLK_LCTRL, "Control_L", "Control_L" }, { SDLK_RALT, "Alt_R", "Alt_R" }, { SDLK_LALT, "Alt_L", "Alt_L" }, - { SDLK_RMETA, "Meta_R", "Meta_R" }, - { SDLK_LMETA, "Meta_L", "Meta_L" }, - { SDLK_LSUPER, "Super_L", "Super_L" }, /* Left "Windows" key */ - { SDLK_RSUPER, "Super_R", "Super_R" }, /* Right "Windows" key */ + { SDLK_LGUI, "Super_L", "Super_L" }, /* Left "Windows" key */ + { SDLK_RGUI, "Super_R", "Super_R" }, /* Right "Windows" key */ { SDLK_MODE, "Mode", "Mode" }, /* "Alt Gr" key */ - { SDLK_COMPOSE, "Compose", "Compose" }, /* Multi-key compose key */ /* Miscellaneous function keys */ { SDLK_HELP, "Help", "Help" }, - { SDLK_PRINT, "Print", "Print" }, + { SDLK_PRINTSCREEN, "Print", "Print" }, { SDLK_SYSREQ, "SysReq", "SysReq" }, - { SDLK_BREAK, "Break", "Break" }, { SDLK_MENU, "Menu", "Menu" }, { SDLK_POWER, "Power", "Power" }, /* Power Macintosh power key */ - { SDLK_EURO, "Euro", "\200" }, /* Some european keyboards */ { SDLK_UNDO, "Undo", "Undo" } /* Atari keyboard has Undo */ }; diff --git a/src/lib/ecore_sdl/ecore_sdl.c b/src/lib/ecore_sdl/ecore_sdl.c index ab85c75370..8b5897794b 100644 --- a/src/lib/ecore_sdl/ecore_sdl.c +++ b/src/lib/ecore_sdl/ecore_sdl.c @@ -2,7 +2,7 @@ # include #endif -#include +#include #include #include @@ -19,7 +19,7 @@ struct _Ecore_SDL_Pressed { EINA_RBTREE; - SDLKey key; + SDL_Keycode key; }; EAPI int ECORE_SDL_EVENT_GOT_FOCUS = 0; @@ -40,7 +40,7 @@ _ecore_sdl_pressed_key(const Ecore_SDL_Pressed *left, static int _ecore_sdl_pressed_node(const Ecore_SDL_Pressed *node, - const SDLKey *key, + const SDL_Keycode *key, EINA_UNUSED int length, EINA_UNUSED void *data) { @@ -76,13 +76,13 @@ ecore_sdl_init(const char *name EINA_UNUSED) if (!ecore_event_init()) return --_ecore_sdl_init_count; + SDL_Init(SDL_INIT_EVENTS); + ECORE_SDL_EVENT_GOT_FOCUS = ecore_event_type_new(); ECORE_SDL_EVENT_LOST_FOCUS = ecore_event_type_new(); ECORE_SDL_EVENT_RESIZE = ecore_event_type_new(); ECORE_SDL_EVENT_EXPOSE = ecore_event_type_new(); - SDL_EnableKeyRepeat(200, 100); - return _ecore_sdl_init_count; } @@ -98,6 +98,8 @@ ecore_sdl_shutdown(void) if (--_ecore_sdl_init_count != 0) return _ecore_sdl_init_count; + SDL_Quit(); + ecore_event_shutdown(); eina_log_domain_unregister(_ecore_sdl_log_dom); _ecore_sdl_log_dom = -1; @@ -131,7 +133,7 @@ _ecore_sdl_event_key(SDL_Event *event, double timestamp) if (!ev) return NULL; ev->timestamp = timestamp; - ev->window = 0; + ev->window = event->key.windowID; ev->event_window = 0; ev->modifiers = _ecore_sdl_event_modifiers(SDL_GetModState()); ev->key = NULL; @@ -169,8 +171,8 @@ ecore_sdl_feed_events(void) if (!ev) return; ev->timestamp = timestamp; - ev->window = 0; - ev->event_window = 0; + ev->window = event.motion.windowID; + ev->event_window = event.motion.windowID; ev->modifiers = 0; /* FIXME: keep modifier around. */ ev->x = event.motion.x; ev->y = event.motion.y; @@ -188,46 +190,44 @@ ecore_sdl_feed_events(void) } case SDL_MOUSEBUTTONDOWN: { - if (event.button.button == SDL_BUTTON_WHEELUP || - event.button.button == SDL_BUTTON_WHEELDOWN) - { - Ecore_Event_Mouse_Wheel *ev; + Ecore_Event_Mouse_Button *ev; - ev = malloc(sizeof(Ecore_Event_Mouse_Wheel)); - if (!ev) return; + ev = malloc(sizeof(Ecore_Event_Mouse_Button)); + if (!ev) return; - ev->timestamp = timestamp; - ev->window = 0; - ev->event_window = 0; - ev->modifiers = 0; /* FIXME: keep modifier around. */ - ev->direction = 0; - ev->z = event.button.button == SDL_BUTTON_WHEELDOWN ? -1 : 1; + ev->timestamp = timestamp; + ev->window = event.button.windowID; + ev->event_window = event.button.windowID; + ev->modifiers = 0; /* FIXME: keep modifier around. */ + ev->buttons = event.button.button; + ev->double_click = 0; + ev->triple_click = 0; - ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL); - } - else - { - Ecore_Event_Mouse_Button *ev; + /* Must set multi touch device to 0 or it will get ignored */ + ev->multi.device = 0; + ev->multi.radius = ev->multi.radius_x = ev->multi.radius_y = 0; + ev->multi.pressure = ev->multi.angle = 0; + ev->multi.x = ev->multi.y = ev->multi.root.x = ev->multi.root.y = 0; - ev = malloc(sizeof(Ecore_Event_Mouse_Button)); - if (!ev) return; + ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL); + break; + } + case SDL_MOUSEWHEEL: + { + Ecore_Event_Mouse_Wheel *ev; - ev->timestamp = timestamp; - ev->window = 0; - ev->event_window = 0; - ev->modifiers = 0; /* FIXME: keep modifier around. */ - ev->buttons = event.button.button; - ev->double_click = 0; - ev->triple_click = 0; + ev = malloc(sizeof(Ecore_Event_Mouse_Wheel)); + if (!ev) return; - /* Must set multi touch device to 0 or it will get ignored */ - ev->multi.device = 0; - ev->multi.radius = ev->multi.radius_x = ev->multi.radius_y = 0; - ev->multi.pressure = ev->multi.angle = 0; - ev->multi.x = ev->multi.y = ev->multi.root.x = ev->multi.root.y = 0; + ev->timestamp = timestamp; + ev->window = event.wheel.windowID; + ev->event_window = event.wheel.windowID; + ev->modifiers = 0; /* FIXME: keep modifier around. */ + ev->direction = 0; + ev->z = event.wheel.x != 0 ? event.wheel.x : event.wheel.y; + ev->direction = event.wheel.x != 0 ? 0 : 1; - ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL); - } + ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL); break; } case SDL_MOUSEBUTTONUP: @@ -237,8 +237,8 @@ ecore_sdl_feed_events(void) ev = malloc(sizeof(Ecore_Event_Mouse_Button)); if (!ev) return; ev->timestamp = timestamp; - ev->window = 0; - ev->event_window = 0; + ev->window = event.button.windowID; + ev->event_window = event.button.windowID; ev->modifiers = 0; /* FIXME: keep modifier around. */ ev->buttons = event.button.button; ev->double_click = 0; @@ -253,20 +253,6 @@ ecore_sdl_feed_events(void) ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL); break; } - case SDL_VIDEORESIZE: - { - Ecore_Sdl_Event_Video_Resize *ev; - - ev = malloc(sizeof (Ecore_Sdl_Event_Video_Resize)); - ev->w = event.resize.w; - ev->h = event.resize.h; - - ecore_event_add(ECORE_SDL_EVENT_RESIZE, ev, NULL, NULL); - break; - } - case SDL_VIDEOEXPOSE: - ecore_event_add(ECORE_SDL_EVENT_EXPOSE, NULL, NULL, NULL); - break; case SDL_QUIT: ecore_main_loop_quit(); break; @@ -317,8 +303,59 @@ ecore_sdl_feed_events(void) if (ev) ecore_event_add(ECORE_EVENT_KEY_UP, ev, NULL, NULL); break; } - case SDL_ACTIVEEVENT: - /* FIXME: Focus gain. */ + case SDL_WINDOWEVENT: + switch (event.window.event) + { + case SDL_WINDOWEVENT_RESIZED: + { + Ecore_Sdl_Event_Video_Resize *ev; + + ev = calloc(1, sizeof (Ecore_Sdl_Event_Video_Resize)); + ev->windowID = event.window.windowID; + ev->w = event.window.data1; + ev->h = event.window.data2; + + ecore_event_add(ECORE_SDL_EVENT_RESIZE, ev, NULL, NULL); + break; + } + case SDL_WINDOWEVENT_EXPOSED: + { + Ecore_Sdl_Event_Window *ev; + + ev = calloc(1, sizeof (Ecore_Sdl_Event_Window)); + ev->windowID = event.window.windowID; + + ecore_event_add(ECORE_SDL_EVENT_EXPOSE, ev, NULL, NULL); + break; + } + case SDL_WINDOWEVENT_ENTER: + case SDL_WINDOWEVENT_LEAVE: + { + Ecore_Event_Mouse_IO *ev; + + ev = calloc(1, sizeof (Ecore_Event_Mouse_IO)); + ev->window = event.window.windowID; + ev->event_window = event.window.windowID; + + ecore_event_add(event.window.event == SDL_WINDOWEVENT_ENTER ? + ECORE_EVENT_MOUSE_IN : ECORE_EVENT_MOUSE_OUT, + ev, NULL, NULL); + break; + } + case SDL_WINDOWEVENT_FOCUS_GAINED: + case SDL_WINDOWEVENT_FOCUS_LOST: + { + Ecore_Sdl_Event_Window *ev; + + ev = calloc(1, sizeof (Ecore_Sdl_Event_Window)); + ev->windowID = event.window.windowID; + + ecore_event_add(event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED ? + ECORE_SDL_EVENT_GOT_FOCUS : ECORE_SDL_EVENT_LOST_FOCUS, + ev, NULL, NULL); + break; + } + } break; case SDL_SYSWMEVENT: case SDL_USEREVENT: diff --git a/src/modules/ecore_evas/engines/sdl/ecore_evas_sdl.c b/src/modules/ecore_evas/engines/sdl/ecore_evas_sdl.c index dcfa6cf373..218eab0f06 100644 --- a/src/modules/ecore_evas/engines/sdl/ecore_evas_sdl.c +++ b/src/modules/ecore_evas/engines/sdl/ecore_evas_sdl.c @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include "ecore_private.h" @@ -27,9 +27,18 @@ /* static char *ecore_evas_default_display = "0"; */ /* static Ecore_List *ecore_evas_input_devices = NULL; */ +typedef struct _Ecore_Evas_SDL_Switch_Data Ecore_Evas_SDL_Switch_Data; +struct _Ecore_Evas_SDL_Switch_Data +{ + SDL_Texture *pages[2]; + SDL_Renderer *r; + SDL_Window *w; + + unsigned char current; +}; + static int _ecore_evas_init_count = 0; -static Ecore_Evas *sdl_ee = NULL; static Ecore_Event_Handler *ecore_evas_event_handlers[4] = { NULL, NULL, NULL, NULL }; @@ -40,24 +49,38 @@ static int _ecore_evas_fps_debug = 0; static int ecore_evas_sdl_count = 0; static Ecore_Evas * -_ecore_evas_sdl_match(void) +_ecore_evas_sdl_match(unsigned int windowID) { - return sdl_ee; + return SDL_GetWindowData(SDL_GetWindowFromID(windowID), "_Ecore_Evas"); } static void * _ecore_evas_sdl_switch_buffer(void *data, void *dest EINA_UNUSED) { - SDL_Flip(data); - return ((SDL_Surface*)data)->pixels; + Ecore_Evas_SDL_Switch_Data *swd = data; + void *pixels; + int pitch; + + /* Push current buffer to screen */ + SDL_UnlockTexture(swd->pages[swd->current]); + SDL_RenderCopy(swd->r, swd->pages[swd->current], NULL, NULL); + SDL_RenderPresent(swd->r); + + /* Switch to next buffer for rendering */ + swd->current = (swd->current + 1) % 2; + if (SDL_LockTexture(swd->pages[swd->current], NULL, &pixels, &pitch) < 0) + return NULL; + + return pixels; } static Eina_Bool -_ecore_evas_sdl_event_got_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) +_ecore_evas_sdl_event_got_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { - Ecore_Evas *ee; + Ecore_Sdl_Event_Window *ev = event; + Ecore_Evas *ee; - ee = _ecore_evas_sdl_match(); + ee = _ecore_evas_sdl_match(ev->windowID); if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ @@ -70,9 +93,10 @@ _ecore_evas_sdl_event_got_focus(void *data EINA_UNUSED, int type EINA_UNUSED, vo static Eina_Bool _ecore_evas_sdl_event_lost_focus(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) { - Ecore_Evas *ee; + Ecore_Sdl_Event_Window *ev = event; + Ecore_Evas *ee; - ee = _ecore_evas_sdl_match(); + ee = _ecore_evas_sdl_match(ev->windowID); if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ @@ -86,11 +110,11 @@ static Eina_Bool _ecore_evas_sdl_event_video_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { Ecore_Sdl_Event_Video_Resize *e; - Ecore_Evas *ee; - int rmethod; + Ecore_Evas *ee; + int rmethod; e = event; - ee = _ecore_evas_sdl_match(); + ee = _ecore_evas_sdl_match(e->windowID); if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ @@ -102,22 +126,26 @@ _ecore_evas_sdl_event_video_resize(void *data EINA_UNUSED, int type EINA_UNUSED, einfo = (Evas_Engine_Info_Buffer *) evas_engine_info_get(ee->evas); if (einfo) { + Ecore_Evas_SDL_Switch_Data *swd = (Ecore_Evas_SDL_Switch_Data*)(ee + 1); + void *pixels; + int pitch; + + SDL_UnlockTexture(swd->pages[swd->current]); + + SDL_DestroyTexture(swd->pages[0]); + SDL_DestroyTexture(swd->pages[1]); + + SDL_RenderClear(swd->r); + + swd->pages[0] = SDL_CreateTexture(swd->r, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, e->w, e->h); + swd->pages[1] = SDL_CreateTexture(swd->r, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, e->w, e->h); + + SDL_LockTexture(swd->pages[swd->current], NULL, &pixels, &pitch); + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; - einfo->info.switch_data = SDL_SetVideoMode(e->w, e->h, 32, - (ee->prop.hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) - | (ee->prop.fullscreen ? SDL_FULLSCREEN : 0) - | (ee->alpha ? SDL_SRCALPHA : 0) - | SDL_DOUBLEBUF); - if (!einfo->info.switch_data) - { - return EINA_FALSE; - } - - SDL_SetAlpha(einfo->info.switch_data, SDL_SRCALPHA, 0); - SDL_FillRect(einfo->info.switch_data, NULL, 0); - - einfo->info.dest_buffer = ((SDL_Surface*)einfo->info.switch_data)->pixels; - einfo->info.dest_buffer_row_bytes = e->w * sizeof (int); + einfo->info.switch_data = swd; + einfo->info.dest_buffer = pixels; + einfo->info.dest_buffer_row_bytes = pitch; einfo->info.use_color_key = 0; einfo->info.alpha_threshold = 0; einfo->info.func.new_update_region = NULL; @@ -142,13 +170,14 @@ _ecore_evas_sdl_event_video_resize(void *data EINA_UNUSED, int type EINA_UNUSED, } static Eina_Bool -_ecore_evas_sdl_event_video_expose(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) +_ecore_evas_sdl_event_video_expose(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { - Ecore_Evas *ee; - int w; - int h; + Ecore_Sdl_Event_Window *ev = event; + Ecore_Evas *ee; + int w; + int h; - ee = _ecore_evas_sdl_match(); + ee = _ecore_evas_sdl_match(ev->windowID); if (!ee) return ECORE_CALLBACK_PASS_ON; evas_output_size_get(ee->evas, &w, &h); @@ -260,12 +289,27 @@ _ecore_evas_sdl_shutdown(void) static void _ecore_evas_sdl_free(Ecore_Evas *ee) { - if (sdl_ee == ee) sdl_ee = NULL; + Ecore_Evas_SDL_Switch_Data *swd = (Ecore_Evas_SDL_Switch_Data*) (ee + 1); + + ecore_event_window_unregister(SDL_GetWindowID(swd->w)); + + if (swd->pages[swd->current]) + SDL_UnlockTexture(swd->pages[swd->current]); + + if (swd->pages[0]) + SDL_DestroyTexture(swd->pages[0]); + if (swd->pages[1]) + SDL_DestroyTexture(swd->pages[1]); + if (swd->r) + SDL_DestroyRenderer(swd->r); + if (swd->w) + SDL_DestroyWindow(swd->w); - ecore_event_window_unregister(0); _ecore_evas_sdl_shutdown(); ecore_sdl_shutdown(); ecore_evas_sdl_count--; + + SDL_VideoQuit(); } static void @@ -287,22 +331,26 @@ _ecore_evas_resize(Ecore_Evas *ee, int w, int h) einfo = (Evas_Engine_Info_Buffer *) evas_engine_info_get(ee->evas); if (einfo) { + Ecore_Evas_SDL_Switch_Data *swd = (Ecore_Evas_SDL_Switch_Data*)(ee + 1); + void *pixels; + int pitch; + + SDL_UnlockTexture(swd->pages[swd->current]); + + SDL_DestroyTexture(swd->pages[0]); + SDL_DestroyTexture(swd->pages[1]); + + SDL_RenderClear(swd->r); + + swd->pages[0] = SDL_CreateTexture(swd->r, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, w, h); + swd->pages[1] = SDL_CreateTexture(swd->r, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, w, h); + + SDL_LockTexture(swd->pages[swd->current], NULL, &pixels, &pitch); + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; - einfo->info.switch_data = SDL_SetVideoMode(w, h, 32, - (ee->prop.hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) - | (ee->prop.fullscreen ? SDL_FULLSCREEN : 0) - | (ee->alpha ? SDL_SRCALPHA : 0) - | SDL_DOUBLEBUF); - if (!einfo->info.switch_data) - { - return; - } - - SDL_SetAlpha(einfo->info.switch_data, SDL_SRCALPHA, 0); - SDL_FillRect(einfo->info.switch_data, NULL, 0); - - einfo->info.dest_buffer = ((SDL_Surface*)einfo->info.switch_data)->pixels; - einfo->info.dest_buffer_row_bytes = w * sizeof (int); + einfo->info.switch_data = swd; + einfo->info.dest_buffer = pixels; + einfo->info.dest_buffer_row_bytes = pitch; einfo->info.use_color_key = 0; einfo->info.alpha_threshold = 0; einfo->info.func.new_update_region = NULL; @@ -476,15 +524,27 @@ static Ecore_Evas_Engine_Func _ecore_sdl_engine_func = static Ecore_Evas* _ecore_evas_internal_sdl_new(int rmethod, const char* name, int w, int h, int fullscreen, int hwsurface, int noframe, int alpha) { - Ecore_Evas *ee; + Ecore_Evas_SDL_Switch_Data *swd; + Ecore_Evas *ee; + Eina_Bool gl = EINA_FALSE; if (ecore_evas_sdl_count > 0) return NULL; if (!name) name = ecore_evas_sdl_default; - ee = calloc(1, sizeof(Ecore_Evas)); + if (!ecore_sdl_init(name)) return NULL; + + if (SDL_VideoInit(NULL) != 0) + { + ERR("SDL Video initialization failed !"); + return NULL; + } + + ee = calloc(1, sizeof(Ecore_Evas) + sizeof (Ecore_Evas_SDL_Switch_Data)); if (!ee) return NULL; + swd = (Ecore_Evas_SDL_Switch_Data*)(ee + 1); + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_sdl_engine_func; @@ -522,41 +582,51 @@ _ecore_evas_internal_sdl_new(int rmethod, const char* name, int w, int h, int fu evas_output_size_set(ee->evas, w, h); evas_output_viewport_set(ee->evas, 0, 0, w, h); - if (rmethod == evas_render_method_lookup("buffer")) + gl = !(rmethod == evas_render_method_lookup("buffer")); + + swd->w = SDL_CreateWindow(name, + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + w, h, + SDL_WINDOW_RESIZABLE | (gl ? SDL_WINDOW_OPENGL : 0)); + if (!swd->w) + { + ERR("SDL_CreateWindow failed."); + goto on_error; + } + + if (!gl) { Evas_Engine_Info_Buffer *einfo; einfo = (Evas_Engine_Info_Buffer *) evas_engine_info_get(ee->evas); if (einfo) { - SDL_Init(SDL_INIT_NOPARACHUTE); + void *pixels; + int pitch; - if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) + swd->r = SDL_CreateRenderer(swd->w, -1, 0); + if (!swd->r) { - ERR("SDL_Init failed with %s", SDL_GetError()); - SDL_Quit(); - return NULL; + ERR("SDL_CreateRenderer failed."); + goto on_error; } + swd->pages[0] = SDL_CreateTexture(swd->r, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, w, h); + swd->pages[1] = SDL_CreateTexture(swd->r, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, w, h); + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32; - einfo->info.switch_data = SDL_SetVideoMode(w, h, 32, - (hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE) - | (fullscreen ? SDL_FULLSCREEN : 0) - | (noframe ? SDL_NOFRAME : 0) - | (alpha ? SDL_SRCALPHA : 0) - | SDL_DOUBLEBUF); - if (!einfo->info.switch_data) + einfo->info.switch_data = swd; + + SDL_RenderClear(swd->r); + if (SDL_LockTexture(swd->pages[0], NULL, &pixels, &pitch) < 0) { - ERR("SDL_SetVideoMode failed !"); - ecore_evas_free(ee); - return NULL; + ERR("SDL_LockTexture failed."); + goto on_error; } - SDL_SetAlpha(einfo->info.switch_data, SDL_SRCALPHA, 0); - SDL_FillRect(einfo->info.switch_data, NULL, 0); - - einfo->info.dest_buffer = ((SDL_Surface*)einfo->info.switch_data)->pixels; - einfo->info.dest_buffer_row_bytes = w * sizeof (int); + einfo->info.dest_buffer = pixels; + einfo->info.dest_buffer_row_bytes = pitch; einfo->info.use_color_key = 0; einfo->info.alpha_threshold = 0; einfo->info.func.new_update_region = NULL; @@ -576,8 +646,9 @@ _ecore_evas_internal_sdl_new(int rmethod, const char* name, int w, int h, int fu return NULL; } } - else if (rmethod == evas_render_method_lookup("gl_sdl")) + else { + /* FIXME */ #ifdef BUILD_ECORE_EVAS_OPENGL_SDL Evas_Engine_Info_GL_SDL *einfo; @@ -586,6 +657,7 @@ _ecore_evas_internal_sdl_new(int rmethod, const char* name, int w, int h, int fu { einfo->flags.fullscreen = fullscreen; einfo->flags.noframe = noframe; + einfo->window = swd->w; if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) { ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); @@ -601,42 +673,32 @@ _ecore_evas_internal_sdl_new(int rmethod, const char* name, int w, int h, int fu } #endif } - else - { - ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver); - ecore_evas_free(ee); - return NULL; - } - - if (!ecore_sdl_init(name)) - { - evas_free(ee->evas); - if (ee->name) free(ee->name); - free(ee); - return NULL; - } _ecore_evas_sdl_init(w, h); - ecore_event_window_register(0, ee, ee->evas, + ecore_event_window_register(SDL_GetWindowID(swd->w), ee, ee->evas, (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process); + SDL_SetWindowData(swd->w, "_Ecore_Evas", ee); SDL_ShowCursor(SDL_ENABLE); ee->engine.func->fn_render = _ecore_evas_sdl_render; _ecore_evas_register(ee); - sdl_ee = ee; ecore_evas_sdl_count++; return ee; + + on_error: + ecore_evas_free(ee); + return NULL; } EAPI Ecore_Evas * ecore_evas_sdl_new_internal(const char* name, int w, int h, int fullscreen, - int hwsurface, int noframe, int alpha) + int hwsurface, int noframe, int alpha) { Ecore_Evas *ee; int rmethod; @@ -670,4 +732,3 @@ ecore_evas_gl_sdl_new_internal(const char* name, int w, int h, int fullscreen, i return ee; } #endif - diff --git a/src/modules/evas/engines/gl_sdl/Evas_Engine_GL_SDL.h b/src/modules/evas/engines/gl_sdl/Evas_Engine_GL_SDL.h index 3804aa06e5..de2370edd2 100644 --- a/src/modules/evas/engines/gl_sdl/Evas_Engine_GL_SDL.h +++ b/src/modules/evas/engines/gl_sdl/Evas_Engine_GL_SDL.h @@ -11,14 +11,13 @@ struct _Evas_Engine_Info_GL_SDL /* at you and make nasty noises */ Evas_Engine_Info magic; + SDL_Window *window; + /* engine specific data & parameters it needs to set up */ struct { int rotation; int fullscreen : 1; int noframe : 1; } flags; - }; #endif - - diff --git a/src/modules/evas/engines/gl_sdl/evas_engine.c b/src/modules/evas/engines/gl_sdl/evas_engine.c index cfe6ade2ea..b0216f29eb 100644 --- a/src/modules/evas/engines/gl_sdl/evas_engine.c +++ b/src/modules/evas/engines/gl_sdl/evas_engine.c @@ -2,12 +2,256 @@ #include "evas_private.h" #include "evas_engine.h" -static void* _sdl_output_setup (int w, int h, int fullscreen, int noframe); - +#include + +#include + +Evas_GL_Common_Context_New glsym_evas_gl_common_context_new = NULL; +Evas_GL_Common_Context_Call glsym_evas_gl_common_context_free = NULL; +Evas_GL_Common_Context_Call glsym_evas_gl_common_context_use = NULL; +Evas_GL_Common_Context_Call glsym_evas_gl_common_context_flush = NULL; +Evas_GL_Common_Context_Call glsym_evas_gl_common_image_all_unload = NULL; +Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize = NULL; +Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock = NULL; +Evas_Gl_Symbols glsym_evas_gl_symbols = NULL; + +static Outbuf *_sdl_output_setup(int w, int h, int fullscreen, int noframe, Evas_Engine_Info_GL_SDL *info); + int _evas_engine_GL_SDL_log_dom = -1; /* function tables - filled in later (func and parent func) */ static Evas_Func func, pfunc; +static void +_outbuf_reconfigure(Outbuf *ob EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, int rot EINA_UNUSED, Outbuf_Depth depth EINA_UNUSED) +{ +} + +static Eina_Bool +_outbuf_region_first_rect(Outbuf *ob EINA_UNUSED) +{ + return EINA_FALSE; +} + +static void * +_outbuf_new_region_for_update(Outbuf *ob, + int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, + int *cx EINA_UNUSED, int *cy EINA_UNUSED, int *cw EINA_UNUSED, int *ch EINA_UNUSED) +{ + return ob->gl_context->def_surface; +} + +static void +_outbuf_push_updated_region(Outbuf *ob EINA_UNUSED, + RGBA_Image *update EINA_UNUSED, + int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) +{ +} + +static void +_outbuf_free_region_for_update(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED) +{ +} + +static void +_outbuf_free(Outbuf *ob) +{ + glsym_evas_gl_common_context_free(ob->gl_context); +} + +static int +_outbuf_get_rot(Outbuf *ob EINA_UNUSED) +{ + return 0; +} + +static void +_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode EINA_UNUSED) +{ + SDL_GL_SwapWindow(ob->window); +} + +static Eina_Bool +eng_window_make_current(void *data, void *doit EINA_UNUSED) +{ + Outbuf *ob = data; + + SDL_GL_MakeCurrent(ob->window, ob->context); + return EINA_TRUE; +} + +static void +_window_use(Outbuf *ob) +{ + /* With SDL 1.x, only one window, no issue here so only flush evas context */ + glsym_evas_gl_preload_render_lock(eng_window_make_current, ob); + + if (ob) + { + glsym_evas_gl_common_context_use(ob->gl_context); + glsym_evas_gl_common_context_flush(ob->gl_context); + } +} + +static Evas_Engine_GL_Context * +_window_gl_context_get(Outbuf *ob) +{ + return ob->gl_context; +} + +static void * +_window_egl_display_get(Outbuf *ob) +{ +#ifdef GL_GLES + return ob->egl_disp; +#else + (void) ob; + return NULL; +#endif +} + +struct _Context_3D +{ + Outbuf *ob; + SDL_GLContext sdl_context; +}; + +static Context_3D * +_window_gl_context_new(Outbuf *ob) +{ + Context_3D *ctx; + + ctx = calloc(1, sizeof (Context_3D)); + if (!ctx) return NULL; + + ctx->ob = ob; + ctx->sdl_context = SDL_GL_CreateContext(ob->window); + + return ctx; +} + +static void +_window_gl_context_use(Context_3D *ctx) +{ + SDL_GL_MakeCurrent(ctx->ob->window, ctx->sdl_context); +} + +/* FIXME: noway to destroy Context_3D */ + +static void * +evgl_eng_display_get(void *data) +{ + Render_Engine *re = data; + + if (!re->generic.software.ob) return NULL; +#ifdef GL_GLES + return re->generic.software.ob->egl_disp; +#else + return NULL; /* FIXME: what should we do here ? */ +#endif +} + +static void * +evgl_eng_evas_surface_get(void *data) +{ + Render_Engine *re = data; + + return re->generic.software.ob->window; +} + +static int +evgl_eng_make_current(void *data EINA_UNUSED, + void *surface, void *context, + int flush) +{ + if (flush) _window_use(NULL); + SDL_GL_MakeCurrent(surface, context); + return EINA_TRUE; +} + +static void * +evgl_eng_native_window_create(void *data EINA_UNUSED) +{ + /* FIXME: Need to understand how to implement that with SDL */ + return NULL; + /* return SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, */ + /* 2, 2, SDL_WINDOW_OPENGL); */ +} + +static int +evgl_eng_native_window_destroy(void *data EINA_UNUSED, void *native_window) +{ + /* SDL_DestroyWindow(native_window); */ + return 1; +} + +static void * +evgl_eng_window_surface_create(void *data EINA_UNUSED, void *native_window) +{ + return native_window; +} + +static int +evgl_eng_window_surface_destroy(void *data EINA_UNUSED, + void *surface EINA_UNUSED) +{ + return 1; +} + +static void * +evgl_eng_context_create(void *data, void *share_ctx EINA_UNUSED) +{ + Render_Engine *re = data; + + SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); + return SDL_GL_CreateContext(re->generic.software.ob->window); +} + +static int +evgl_eng_context_destroy(void *data EINA_UNUSED, void *context) +{ + SDL_GL_DeleteContext(context); + return 1; +} + +static const char * +evgl_eng_string_get(void *data EINA_UNUSED) +{ + const char *(*glGetString)(GLenum n); + + glGetString = SDL_GL_GetProcAddress("glGetString"); + if (glGetString) return glGetString(GL_EXTENSIONS); + return NULL; +} + +static void * +evgl_eng_proc_address_get(const char *name) +{ + return SDL_GL_GetProcAddress(name); +} + +static int +evgl_eng_rotation_angle_get(void *data EINA_UNUSED) +{ + return 0; +} + +static const EVGL_Interface evgl_funcs = +{ + evgl_eng_display_get, + evgl_eng_evas_surface_get, + evgl_eng_native_window_create, + evgl_eng_native_window_destroy, + evgl_eng_window_surface_create, + evgl_eng_window_surface_destroy, + evgl_eng_context_create, + evgl_eng_context_destroy, + evgl_eng_make_current, + evgl_eng_proc_address_get, + evgl_eng_string_get, + evgl_eng_rotation_angle_get +}; + + static void * eng_info(Evas *e EINA_UNUSED) { @@ -31,232 +275,75 @@ static int eng_setup(Evas *eo_e, void *in) { Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS); - Render_Engine *re; + Render_Engine *re = NULL; + Outbuf *ob = NULL; Evas_Engine_Info_GL_SDL *info; info = (Evas_Engine_Info_GL_SDL *)in; - SDL_Init(SDL_INIT_NOPARACHUTE); + ob = _sdl_output_setup(e->output.w, e->output.h, + info->flags.fullscreen, + info->flags.noframe, + info); + if (!ob) goto on_error; - if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) - { - ERR("SDL_Init failed with %s", SDL_GetError()); - SDL_Quit(); - return 0; - } + re = calloc(1, sizeof (Render_Engine)); + if (!re) goto on_error; + + + if (!evas_render_engine_gl_generic_init(&re->generic, ob, NULL, + _outbuf_get_rot, + _outbuf_reconfigure, + _outbuf_region_first_rect, + _outbuf_new_region_for_update, + _outbuf_push_updated_region, + _outbuf_free_region_for_update, + NULL, + _outbuf_flush, + _outbuf_free, + _window_use, + _window_gl_context_get, + _window_egl_display_get, + _window_gl_context_new, + _window_gl_context_use, + &evgl_funcs, + e->output.w, e->output.h)) + goto on_error; - re = _sdl_output_setup(e->output.w, e->output.h, - info->flags.fullscreen, - info->flags.noframe); - re->info = info; e->engine.data.output = re; if (!e->engine.data.output) return 0; - e->engine.func = &func; e->engine.data.context = e->engine.func->context_new(e->engine.data.output); - + + /* 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_polygon_init(); + evas_common_line_init(); + evas_common_font_init(); + evas_common_draw_init(); + evas_common_tilebuf_init(); + return 1; + + on_error: + if (ob) _outbuf_free(ob); + free(ob); + free(re); + return 0; } static void eng_output_free(void *data) { - Render_Engine *re; + Render_Engine *re = data; - re = (Render_Engine *)data; - - if (re) - { - evas_gl_common_context_free(re->gl_context); - free(re); - - evas_common_font_shutdown(); - evas_common_image_shutdown(); - - SDL_QuitSubSystem(SDL_INIT_VIDEO); - } -} - -static void -eng_output_resize(void *data, int w, int h) -{ - Render_Engine *re; - SDL_Surface *surface; - - re = (Render_Engine *)data; - re->w = w; - re->h = h; - - if(SDL_GetVideoSurface()->flags & SDL_RESIZABLE) - { - surface = SDL_SetVideoMode(w, h, 32, EVAS_SDL_GL_FLAG - | (re->info->flags.fullscreen ? SDL_FULLSCREEN : 0) - | (re->info->flags.noframe ? SDL_NOFRAME : 0)); - if (!surface) - { - ERR("Unable to change the resolution to : %ix%i", w, h); - SDL_Quit(); - exit(-1); - } - } - - evas_gl_common_context_resize(re->gl_context, w, h, re->gl_context->rot); -} - -static void -eng_output_tile_size_set(void *data EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) -{ -} - -static void -eng_output_redraws_rect_add(void *data, int x, int y, int w, int h) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - evas_gl_common_context_resize(re->gl_context, re->w, re->h, re->gl_context->rot); - /* smple bounding box */ - if (!re->draw.redraw) - { -#if 0 - re->draw.x1 = x; - re->draw.y1 = y; - re->draw.x2 = x + w - 1; - re->draw.y2 = y + h - 1; -#else - re->draw.x1 = 0; - re->draw.y1 = 0; - re->draw.x2 = re->w - 1; - re->draw.y2 = re->h - 1; -#endif - } - else - { - if (x < re->draw.x1) re->draw.x1 = x; - if (y < re->draw.y1) re->draw.y1 = y; - if ((x + w - 1) > re->draw.x2) re->draw.x2 = x + w - 1; - if ((y + h - 1) > re->draw.y2) re->draw.y2 = y + h - 1; - } - re->draw.redraw = 1; -} - -static void -eng_output_redraws_rect_del(void *data EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) -{ -} - -static void -eng_output_redraws_clear(void *data) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - re->draw.redraw = 0; -// INF("GL: finish update cycle!"); -} - -/* at least the nvidia drivers are so abysmal that copying from the backbuffer - * to the front using glCopyPixels() that you literally can WATCH it draw the - * pixels slowly across the screen with a window update taking multiple - * seconds - so workaround by doing a full buffer render as frankly GL isn't - * up to doing anything that isn't done by quake (etc.) - */ -#define SLOW_GL_COPY_RECT 1 -/* vsync games - not for now though */ -//#define VSYNC_TO_SCREEN 1 - -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; - - re = (Render_Engine *)data; - evas_gl_common_context_flush(re->gl_context); - evas_gl_common_context_newframe(re->gl_context); - /* get the upate rect surface - return engine data as dummy */ - if (!re->draw.redraw) - { -// printf("GL: NO updates!\n"); - return NULL; - } -// printf("GL: update....!\n"); -#ifdef SLOW_GL_COPY_RECT - /* if any update - just return the whole canvas - works with swap - * buffers then */ - if (x) *x = 0; - if (y) *y = 0; - if (w) *w = re->w; - if (h) *h = re->h; - if (cx) *cx = 0; - if (cy) *cy = 0; - if (cw) *cw = re->w; - if (ch) *ch = re->h; -#else - /* 1 update - INCREDIBLY SLOW if combined with swap_rect in flush. a gl - * problem where there just is no hardware path for somethnig that - * obviously SHOULD be there */ - /* only 1 update to minimise gl context games and rendering multiple update - * regions as evas does with other engines - */ - if (x) *x = re->draw.x1; - if (y) *y = re->draw.y1; - if (w) *w = re->draw.x2 - re->draw.x1 + 1; - if (h) *h = re->draw.y2 - re->draw.y1 + 1; - if (cx) *cx = re->draw.x1; - if (cy) *cy = re->draw.y1; - if (cw) *cw = re->draw.x2 - re->draw.x1 + 1; - if (ch) *ch = re->draw.y2 - re->draw.y1 + 1; -#endif -// clear buffer. only needed for dest alpha -// glClearColor(0.0f, 0.0f, 0.0f, 0.0f); -// glClear(GL_COLOR_BUFFER_BIT); -//x// printf("frame -> new\n"); - return re->gl_context->def_surface; -} - -static void -eng_output_redraws_next_update_push(void *data, void *surface EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, Evas_Render_Mode render_mode) -{ - Render_Engine *re; - - if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; - - re = (Render_Engine *)data; - /* put back update surface.. in this case just unflag redraw */ - re->draw.redraw = 0; - re->draw.drew = 1; - evas_gl_common_context_flush(re->gl_context); -//x// printf("frame -> push\n"); -} - -static void -eng_output_flush(void *data, Evas_Render_Mode render_mode) -{ - Render_Engine *re; - - if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; - - re = (Render_Engine *)data; - if (!re->draw.drew) return; -//x// printf("frame -> flush\n"); - re->draw.drew = 0; - -#if 0 -#ifdef GL_GLES -// glFlush(); - eglSwapBuffers(re->egl_disp, re->egl_surface[0]); -#else - glXSwapBuffers(re->win->disp, re->win); -#endif -#else - SDL_GL_SwapBuffers(); -#endif -} - -static void -eng_output_idle_flush(void *data EINA_UNUSED) -{ + evas_render_engine_software_generic_clean(&re->generic.software); } static void @@ -267,625 +354,39 @@ eng_output_dump(void *data) re = (Render_Engine *)data; evas_common_image_image_all_unload(); evas_common_font_font_all_unload(); - evas_gl_common_image_all_unload(re->gl_context); -} - -static void -eng_context_cutout_add(void *data EINA_UNUSED, void *context, int x, int y, int w, int h) -{ - evas_common_draw_context_add_cutout(context, x, y, w, h); -} - -static void -eng_context_cutout_clear(void *data EINA_UNUSED, void *context) -{ - evas_common_draw_context_clear_cutouts(context); -} - -static void -eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h, Eina_Bool do_async EINA_UNUSED) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - evas_gl_common_context_target_surface_set(re->gl_context, surface); - re->gl_context->dc = context; - evas_gl_common_rect_draw(re->gl_context, x, y, w, h); -} - -static void -eng_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2, Eina_Bool do_async EINA_UNUSED) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - evas_gl_common_context_target_surface_set(re->gl_context, surface); - re->gl_context->dc = context; - evas_gl_common_line_draw(re->gl_context, x1, y1, x2, y2); -} - -static void * -eng_polygon_point_add(void *data EINA_UNUSED, void *context EINA_UNUSED, void *polygon, int x, int y) -{ - return evas_gl_common_poly_point_add(polygon, x, y); -} - -static void * -eng_polygon_points_clear(void *data EINA_UNUSED, void *context EINA_UNUSED, void *polygon) -{ - return evas_gl_common_poly_points_clear(polygon); -} - -static void -eng_polygon_draw(void *data, void *context, void *surface, void *polygon, int x, int y, Eina_Bool do_async EINA_UNUSED) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - evas_gl_common_context_target_surface_set(re->gl_context, surface); - re->gl_context->dc = context; - evas_gl_common_poly_draw(re->gl_context, polygon, x, y); -} - -static int -eng_image_alpha_get(void *data EINA_UNUSED, void *image) -{ - Evas_GL_Image *im = image; - - return im ? im->alpha : 1; -} - -static Evas_Colorspace -eng_image_colorspace_get(void *data EINA_UNUSED, void *image) -{ - Evas_GL_Image *im = image; - - return im ? im->cs.space : EVAS_COLORSPACE_ARGB8888; -} - -static void * -eng_image_alpha_set(void *data EINA_UNUSED, void *image, int has_alpha) -{ - Evas_GL_Image *im; - - if (!image) return NULL; - im = image; - if (im->native.data) - { - im->alpha = has_alpha; - return image; - } - /* FIXME: can move to gl_common */ - if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return im; - if ((has_alpha) && (im->im->cache_entry.flags.alpha)) return image; - else if ((!has_alpha) && (!im->im->cache_entry.flags.alpha)) return image; - if (im->references > 1) - { - Evas_GL_Image *im_new; - - if (!im->im->image.data) - evas_cache_image_load_data(&im->im->cache_entry); - evas_gl_common_image_alloc_ensure(im); - im_new = evas_gl_common_image_new_from_copied_data(im->gc, im->im->cache_entry.w, im->im->cache_entry.h, im->im->image.data, - eng_image_alpha_get(data, image), - eng_image_colorspace_get(data, image)); - if (!im_new) return im; - evas_gl_common_image_free(im); - im = im_new; - } - else - evas_gl_common_image_dirty(im, 0, 0, 0, 0); - im->im->cache_entry.flags.alpha = has_alpha ? 1 : 0; - return image; -} - -static void * -eng_image_border_set(void *data EINA_UNUSED, void *image, int l EINA_UNUSED, int r EINA_UNUSED, int t EINA_UNUSED, int b EINA_UNUSED) -{ - return image; -} - -static void -eng_image_border_get(void *data EINA_UNUSED, void *image EINA_UNUSED, int *l EINA_UNUSED, int *r EINA_UNUSED, int *t EINA_UNUSED, int *b EINA_UNUSED) -{ -} - -static char * -eng_image_comment_get(void *data EINA_UNUSED, void *image, char *key EINA_UNUSED) -{ - Evas_GL_Image *im = image; - - if (im && im->im) return im->im->info.comment; - return NULL; -} - -static char * -eng_image_format_get(void *data EINA_UNUSED, void *image EINA_UNUSED) -{ - return NULL; -} - -static void -eng_image_colorspace_set(void *data EINA_UNUSED, void *image, Evas_Colorspace cspace) -{ - Evas_GL_Image *im; - - if (!image) return; - im = image; - if (im->native.data) return; - /* FIXME: can move to gl_common */ - if (im->cs.space == cspace) return; - evas_gl_common_image_alloc_ensure(im); - evas_cache_image_colorspace(&im->im->cache_entry, cspace); - switch (cspace) - { - case EVAS_COLORSPACE_ARGB8888: - if (im->cs.data) - { - if (!im->cs.no_free) free(im->cs.data); - im->cs.data = NULL; - im->cs.no_free = 0; - } - break; - case EVAS_COLORSPACE_YCBCR422P601_PL: - case EVAS_COLORSPACE_YCBCR422P709_PL: - case EVAS_COLORSPACE_YCBCR422601_PL: - case EVAS_COLORSPACE_YCBCR420NV12601_PL: - case EVAS_COLORSPACE_YCBCR420TM12601_PL: - if (im->tex) evas_gl_common_texture_free(im->tex, EINA_TRUE); - im->tex = NULL; - if (im->cs.data) - { - if (!im->cs.no_free) free(im->cs.data); - } - im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2); - im->cs.no_free = 0; - break; - default: - abort(); - break; - } - im->cs.space = cspace; -} - -///////////////////////////////////////////////////////////////////////// -// -// -typedef struct _Native Native; - -struct _Native -{ - Evas_Native_Surface ns; - -#ifdef GL_GLES - EGLSurface egl_surface; -#endif -}; - -static void * -eng_image_native_set(void *data EINA_UNUSED, void *image EINA_UNUSED, void *native EINA_UNUSED) -{ - return NULL; -} - -static void * -eng_image_native_get(void *data EINA_UNUSED, void *image EINA_UNUSED) -{ - return NULL; -} - -// -// -///////////////////////////////////////////////////////////////////////// - -static void * -eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo) -{ - Render_Engine *re = data; - - *error = EVAS_LOAD_ERROR_NONE; - return evas_gl_common_image_load(re->gl_context, file, key, lo, error); -} - -static void * -eng_image_mmap(void *data, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo) -{ - Render_Engine *re = data; - - *error = EVAS_LOAD_ERROR_NONE; - return evas_gl_common_image_mmap(re->gl_context, f, key, lo, error); -} - -static void * -eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, Evas_Colorspace cspace) -{ - Render_Engine *re = data; - - return evas_gl_common_image_new_from_data(re->gl_context, w, h, image_data, alpha, cspace); -} - -static void * -eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, Evas_Colorspace cspace) -{ - Render_Engine *re = data; - - return evas_gl_common_image_new_from_copied_data(re->gl_context, w, h, image_data, alpha, cspace); -} - -static void -eng_image_free(void *data EINA_UNUSED, void *image) -{ - if (image) evas_gl_common_image_free(image); -} - -static void -eng_image_size_get(void *data EINA_UNUSED, void *image, int *w, int *h) -{ - if (!image) - { - *w = 0; - *h = 0; - return; - } - if (w) *w = ((Evas_GL_Image *)image)->w; - if (h) *h = ((Evas_GL_Image *)image)->h; -} - -static void * -eng_image_size_set(void *data, void *image, int w, int h) -{ - Render_Engine *re; - Evas_GL_Image *im = image; - Evas_GL_Image *im_old; - - re = (Render_Engine *)data; - if (!im) return NULL; - if (im->native.data) - { - im->w = w; - im->h = h; - return image; - } - if ((im->tex) && (im->tex->pt->dyn.img)) - { - evas_gl_common_texture_free(im->tex, EINA_TRUE); - im->tex = NULL; - im->w = w; - im->h = h; - im->tex = evas_gl_common_texture_dynamic_new(im->gc, im); - return image; - } - im_old = image; - - switch (eng_image_colorspace_get(data, image)) - { - case EVAS_COLORSPACE_YCBCR422P601_PL: - case EVAS_COLORSPACE_YCBCR422P709_PL: - case EVAS_COLORSPACE_YCBCR422601_PL: - case EVAS_COLORSPACE_YCBCR420NV12601_PL: - case EVAS_COLORSPACE_YCBCR420TM12601_PL: - w &= ~0x1; - break; - } - - evas_gl_common_image_alloc_ensure(im_old); - if ((im_old->im) && - ((int)im_old->im->cache_entry.w == w) && - ((int)im_old->im->cache_entry.h == h)) - return image; - if (im_old) - { - im = evas_gl_common_image_new(re->gl_context, w, h, - eng_image_alpha_get(data, image), - eng_image_colorspace_get(data, image)); - evas_gl_common_image_free(im_old); - } - else - im = evas_gl_common_image_new(re->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888); - return im; -} - -static void * -eng_image_dirty_region(void *data EINA_UNUSED, void *image, int x, int y, int w, int h) -{ - Evas_GL_Image *im = image; - - if (!image) return NULL; - if (im->native.data) return image; - evas_gl_common_image_dirty(image, x, y, w, h); - return image; -} - -static void * -eng_image_data_get(void *data EINA_UNUSED, void *image, int to_write, DATA32 **image_data, int *err) -{ - Evas_GL_Image *im; - int error; - - if (!image) - { - *image_data = NULL; - if (err) *err = EVAS_LOAD_ERROR_GENERIC; - return NULL; - } - im = image; - if (im->native.data) - { - *image_data = NULL; - if (err) *err = EVAS_LOAD_ERROR_NONE; - return im; - } - error = evas_cache_image_load_data(&im->im->cache_entry); - evas_gl_common_image_alloc_ensure(im); - switch (im->cs.space) - { - case EVAS_COLORSPACE_ARGB8888: - if (to_write) - { - if (im->references > 1) - { - Evas_GL_Image *im_new; - - im_new = evas_gl_common_image_new_from_copied_data(im->gc, im->im->cache_entry.w, im->im->cache_entry.h, im->im->image.data, - eng_image_alpha_get(data, image), - eng_image_colorspace_get(data, image)); - if (!im_new) - { - *image_data = NULL; - if (err) *err = error; - return im; - } - evas_gl_common_image_free(im); - im = im_new; - } - else - evas_gl_common_image_dirty(im, 0, 0, 0, 0); - } - *image_data = im->im->image.data; - break; - case EVAS_COLORSPACE_YCBCR422P601_PL: - case EVAS_COLORSPACE_YCBCR422P709_PL: - case EVAS_COLORSPACE_YCBCR422601_PL: - case EVAS_COLORSPACE_YCBCR420NV12601_PL: - case EVAS_COLORSPACE_YCBCR420TM12601_PL: - *image_data = im->cs.data; - break; - default: - abort(); - break; - } - if (err) *err = error; - return im; -} - -static void * -eng_image_data_put(void *data EINA_UNUSED, void *image, DATA32 *image_data) -{ - Evas_GL_Image *im, *im2; - - if (!image) return NULL; - im = image; - if (im->native.data) return image; - evas_gl_common_image_alloc_ensure(im); - switch (im->cs.space) - { - case EVAS_COLORSPACE_ARGB8888: - if (image_data != im->im->image.data) - { - int w, h; - - w = im->im->cache_entry.w; - h = im->im->cache_entry.h; - im2 = eng_image_new_from_data(data, w, h, image_data, - eng_image_alpha_get(data, image), - eng_image_colorspace_get(data, image)); - if (!im2) return im; - evas_gl_common_image_free(im); - im = im2; - } - break; - case EVAS_COLORSPACE_YCBCR422P601_PL: - case EVAS_COLORSPACE_YCBCR422P709_PL: - case EVAS_COLORSPACE_YCBCR422601_PL: - case EVAS_COLORSPACE_YCBCR420NV12601_PL: - case EVAS_COLORSPACE_YCBCR420TM12601_PL: - if (image_data != im->cs.data) - { - if (im->cs.data) - { - if (!im->cs.no_free) free(im->cs.data); - } - im->cs.data = image_data; - } - break; - default: - abort(); - break; - } - /* hmmm - but if we wrote... why bother? */ - evas_gl_common_image_dirty(im, 0, 0, 0, 0); - return im; -} - -static void -eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const Eo *target) -{ - Evas_GL_Image *gim = image; - RGBA_Image *im; - - if (!gim) return; - if (gim->native.data) return; - im = (RGBA_Image *)gim->im; - if (!im) return; - evas_cache_image_preload_data(&im->cache_entry, target, NULL, NULL, NULL); -} - -static void -eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const Eo *target) -{ - Evas_GL_Image *gim = image; - RGBA_Image *im; - - if (!gim) return; - if (gim->native.data) return; - im = (RGBA_Image *)gim->im; - if (!im) return; - evas_cache_image_preload_cancel(&im->cache_entry, target); -} - -static Eina_Bool -eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async EINA_UNUSED) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - if (!image) return EINA_FALSE; - evas_gl_common_context_target_surface_set(re->gl_context, surface); - re->gl_context->dc = context; - evas_gl_common_image_draw(re->gl_context, image, - src_x, src_y, src_w, src_h, - dst_x, dst_y, dst_w, dst_h, - smooth); - return EINA_FALSE; -} - -static void -eng_image_scale_hint_set(void *data EINA_UNUSED, void *image, int hint) -{ - if (image) evas_gl_common_image_scale_hint_set(image, hint); -} - -static Eina_Bool -eng_image_map_draw(void *data EINA_UNUSED, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level, Eina_Bool do_async) -{ - Evas_GL_Image *gim = image; - Render_Engine *re; - - re = (Render_Engine *)data; - evas_gl_common_context_target_surface_set(re->gl_context, surface); - re->gl_context->dc = context; - if (m->count != 4) - { - // FIXME: nash - you didn't fix this - abort(); - } - if ((m->pts[0].x == m->pts[3].x) && - (m->pts[1].x == m->pts[2].x) && - (m->pts[0].y == m->pts[1].y) && - (m->pts[3].y == m->pts[2].y) && - (m->pts[0].x <= m->pts[1].x) && - (m->pts[0].y <= m->pts[2].y) && - (m->pts[0].u == 0) && - (m->pts[0].v == 0) && - (m->pts[1].u == (gim->w << FP)) && - (m->pts[1].v == 0) && - (m->pts[2].u == (gim->w << FP)) && - (m->pts[2].v == (gim->h << FP)) && - (m->pts[3].u == 0) && - (m->pts[3].v == (gim->h << FP)) && - (m->pts[0].col == 0xffffffff) && - (m->pts[1].col == 0xffffffff) && - (m->pts[2].col == 0xffffffff) && - (m->pts[3].col == 0xffffffff)) - { - int dx, dy, dw, dh; - - dx = m->pts[0].x >> FP; - dy = m->pts[0].y >> FP; - dw = (m->pts[2].x >> FP) - dx; - dh = (m->pts[2].y >> FP) - dy; - eng_image_draw(data, context, surface, image, - 0, 0, gim->w, gim->h, dx, dy, dw, dh, smooth, do_async); - } - else - { - evas_gl_common_image_map_draw(re->gl_context, image, m->count, &m->pts[0], - smooth, level); - } - - return EINA_FALSE; -} - -static void * -eng_image_map_surface_new(void *data EINA_UNUSED, int w, int h, int alpha) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - return evas_gl_common_image_surface_new(re->gl_context, w, h, alpha); -} - -static void -eng_image_map_surface_free(void *data EINA_UNUSED, void *surface) -{ - evas_gl_common_image_free(surface); -} - -static int -eng_image_scale_hint_get(void *data EINA_UNUSED, void *image) -{ - Evas_GL_Image *gim = image; - if (!gim) return EVAS_IMAGE_SCALE_HINT_NONE; - return gim->scale_hint; -} - -static Eina_Bool -eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font EINA_UNUSED, int x, int y, int w EINA_UNUSED, int h EINA_UNUSED, int ow EINA_UNUSED, int oh EINA_UNUSED, Evas_Text_Props *intl_props, Eina_Bool do_async EINA_UNUSED) -{ - Render_Engine *re = data; - - evas_gl_common_context_target_surface_set(re->gl_context, surface); - re->gl_context->dc = context; - { - // FIXME: put im into context so we can free it - static RGBA_Image *im = NULL; - - if (!im) - im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); - im->cache_entry.w = re->w; - im->cache_entry.h = re->h; - evas_common_draw_context_font_ext_set(context, - re->gl_context, - evas_gl_font_texture_new, - evas_gl_font_texture_free, - evas_gl_font_texture_draw); - evas_common_font_draw_prepare(intl_props); - evas_common_font_draw(im, context, x, y, intl_props->glyphs); - evas_common_draw_context_font_ext_set(context, - NULL, - NULL, - NULL, - NULL); - } - - return EINA_FALSE; + glsym_evas_gl_common_image_all_unload(re->generic.software.ob->gl_context); } static Eina_Bool eng_canvas_alpha_get(void *data EINA_UNUSED, void *info EINA_UNUSED) { - // FIXME: support ARGB gl targets!!! - return EINA_FALSE; + return 0; } -static int -eng_image_load_error_get(void *data EINA_UNUSED, void *image) +static void +gl_symbols(void) { - Evas_GL_Image *im; - - if (!image) return EVAS_LOAD_ERROR_NONE; - im = image; - return im->im->cache_entry.load_error; -} +#define LINK2GENERIC(sym) \ + glsym_##sym = dlsym(RTLD_DEFAULT, #sym); + LINK2GENERIC(evas_gl_symbols); + LINK2GENERIC(evas_gl_common_context_new); + LINK2GENERIC(evas_gl_common_context_free); + LINK2GENERIC(evas_gl_common_context_use); + LINK2GENERIC(evas_gl_common_context_flush); + LINK2GENERIC(evas_gl_common_image_all_unload); + LINK2GENERIC(evas_gl_common_context_resize); + LINK2GENERIC(evas_gl_preload_render_lock); + + glsym_evas_gl_symbols((void*)SDL_GL_GetProcAddress); +} static int module_open(Evas_Module *em) { if (!em) return 0; - if (!evas_gl_common_module_open()) return 0; /* get whatever engine module we inherit from */ - if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0; + if (!_evas_module_engine_inherit(&pfunc, "gl_generic")) return 0; if (_evas_engine_GL_SDL_log_dom < 0) _evas_engine_GL_SDL_log_dom = eina_log_domain_register ("evas-gl_sdl", EVAS_DEFAULT_LOG_COLOR); @@ -903,75 +404,10 @@ module_open(Evas_Module *em) ORD(setup); ORD(canvas_alpha_get); 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(context_cutout_add); - ORD(context_cutout_clear); - ORD(output_flush); - ORD(output_idle_flush); ORD(output_dump); - ORD(rectangle_draw); - ORD(line_draw); - ORD(polygon_point_add); - ORD(polygon_points_clear); - ORD(polygon_draw); - ORD(image_load); - ORD(image_mmap); - ORD(image_new_from_data); - ORD(image_new_from_copied_data); - ORD(image_free); - ORD(image_size_get); - ORD(image_size_set); - ORD(image_dirty_region); - ORD(image_data_get); - ORD(image_data_put); - ORD(image_data_preload_request); - ORD(image_data_preload_cancel); - ORD(image_alpha_set); - ORD(image_alpha_get); - ORD(image_border_set); - ORD(image_border_get); - ORD(image_draw); - ORD(image_comment_get); - ORD(image_format_get); - ORD(image_colorspace_set); - ORD(image_colorspace_get); - ORD(image_native_set); - ORD(image_native_get); - ORD(font_draw); - - ORD(image_scale_hint_set); - ORD(image_scale_hint_get); - - ORD(image_map_draw); - ORD(image_map_surface_new); - ORD(image_map_surface_free); + gl_symbols(); -// ORD(image_content_hint_set); -// ORD(image_content_hint_get); - -// ORD(image_cache_flush); -// ORD(image_cache_set); -// ORD(image_cache_get); - -// ORD(gl_surface_create); -// ORD(gl_surface_destroy); -// ORD(gl_context_create); -// ORD(gl_context_destroy); -// ORD(gl_make_current); -// ORD(gl_proc_address_get); -// ORD(gl_native_surface_get); - -// ORD(gl_api_get); - - ORD(image_load_error_get); - /* now advertise out own api */ em->functions = (void *)(&func); return 1; @@ -981,7 +417,6 @@ static void module_close(Evas_Module *em EINA_UNUSED) { eina_log_domain_unregister(_evas_engine_GL_SDL_log_dom); - evas_gl_common_module_close(); } static Evas_Module_Api evas_modapi = @@ -1001,28 +436,16 @@ EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, gl_sdl); EVAS_EINA_MODULE_DEFINE(engine, gl_sdl); #endif -static void* -_sdl_output_setup (int w, int h, int fullscreen, int noframe) +static Outbuf * +_sdl_output_setup(int w, int h, int fullscreen EINA_UNUSED, int noframe EINA_UNUSED, Evas_Engine_Info_GL_SDL *info) { - Render_Engine *re = calloc(1, sizeof(Render_Engine)); - SDL_Surface *surface; - - /* 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_polygon_init(); - evas_common_line_init(); - evas_common_font_init(); - evas_common_draw_init(); - evas_common_tilebuf_init(); + Outbuf *ob = NULL; + const char *(*glGetString)(GLenum n); + if (!info->window) return NULL; if (w <= 0) w = 640; if (h <= 0) h = 480; - + /* GL Initialization */ #ifdef HAVE_SDL_GL_CONTEXT_VERSION SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); @@ -1033,33 +456,37 @@ _sdl_output_setup (int w, int h, int fullscreen, int noframe) SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0); - surface = SDL_SetVideoMode(w, h, 32, EVAS_SDL_GL_FLAG - | (fullscreen ? SDL_FULLSCREEN : 0) - | (noframe ? SDL_NOFRAME : 0)); + ob = calloc(1, sizeof(Outbuf)); + if (!ob) return NULL; - if (!surface) + ob->window = info->window; + ob->w = w; + ob->h = h; + ob->info = info; + ob->context = SDL_GL_CreateContext(ob->window); + if (!ob->context) { - CRI("SDL_SetVideoMode [ %i x %i x 32 ] failed. %s", w, h, SDL_GetError()); - SDL_Quit(); - exit(-1); + ERR("Impossible to create a context for : %p", info->window); + goto on_error; } - INF("Screen Depth: %d, Vendor: '%s', Renderer: '%s', Version: '%s'", SDL_GetVideoSurface()->format->BitsPerPixel, glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION)); + glGetString = SDL_GL_GetProcAddress("glGetString"); - re->gl_context = evas_gl_common_context_new(); - if (!re->gl_context) - { - free(re); - return NULL; - } - evas_gl_common_context_use(re->gl_context); - evas_gl_common_context_resize(re->gl_context, w, h, re->gl_context->rot); + INF("Vendor: '%s', Renderer: '%s', Version: '%s'", + glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION)); + + ob->gl_context = glsym_evas_gl_common_context_new(); + if (!ob->gl_context) goto on_error; + + glsym_evas_gl_common_context_use(ob->gl_context); + glsym_evas_gl_common_context_resize(ob->gl_context, w, h, ob->gl_context->rot); /* End GL Initialization */ - re->w = w; - re->h = h; - return re; -} + return ob; + on_error: + if (ob && ob->window) SDL_DestroyWindow(ob->window); + free(ob); + return NULL; +} diff --git a/src/modules/evas/engines/gl_sdl/evas_engine.h b/src/modules/evas/engines/gl_sdl/evas_engine.h index 459dd7d87a..92c97fd7ba 100644 --- a/src/modules/evas/engines/gl_sdl/evas_engine.h +++ b/src/modules/evas/engines/gl_sdl/evas_engine.h @@ -4,17 +4,16 @@ #define _EVAS_ENGINE_SDL_H #include "config.h" -#include +#include #ifdef GL_GLES -# include -# include +# include # ifdef HAVE_SDL_FLAG_OPENGLES # define EVAS_SDL_GL_FLAG SDL_OPENGLES # else # define EVAS_SDL_GL_FLAG SDL_OPENGL /* This probably won't work? */ # endif #else -# include +# include # define EVAS_SDL_GL_FLAG SDL_OPENGL #endif #include "evas_common_private.h" @@ -23,6 +22,8 @@ #include "Evas.h" #include "Evas_Engine_GL_SDL.h" +#include "../gl_generic/Evas_Engine_GL_Generic.h" + extern int _evas_engine_GL_SDL_log_dom ; #ifdef ERR # undef ERR @@ -50,10 +51,12 @@ extern int _evas_engine_GL_SDL_log_dom ; #define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_GL_SDL_log_dom, __VA_ARGS__) typedef struct _Render_Engine Render_Engine; -struct _Render_Engine + +struct _Outbuf { - Evas_Engine_Info_GL_SDL *info; - int w, h; + Evas_Engine_Info_GL_SDL *info; + SDL_Window *window; + SDL_GLContext *context; Evas_Engine_GL_Context *gl_context; struct { @@ -68,6 +71,12 @@ struct _Render_Engine EGLDisplay egl_disp; #endif + int w, h; +}; + +struct _Render_Engine +{ + Render_Engine_GL_Generic generic; }; #endif