struct _ecore_sdl_keys_s
{
- unsigned int code;
+ SDL_Keycode code;
const char* name;
const char* compose;
};
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" },
{ 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", "*" },
{ 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 */
};
#include <stdlib.h>
#include <string.h>
-#include <SDL/SDL.h>
+#include <SDL2/SDL.h>
#include <Ecore.h>
#include "ecore_private.h"
/* 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
};
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 */
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 */
_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 */
einfo = (Evas_Engine_Info_Buffer *) evas_engine_info_get(ee->evas);
if (einfo)
{
- 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;
- }
+ Ecore_Evas_SDL_Switch_Data *swd = (Ecore_Evas_SDL_Switch_Data*)(ee + 1);
+ void *pixels;
+ int pitch;
+
+ SDL_UnlockTexture(swd->pages[swd->current]);
- SDL_SetAlpha(einfo->info.switch_data, SDL_SRCALPHA, 0);
- SDL_FillRect(einfo->info.switch_data, NULL, 0);
+ SDL_DestroyTexture(swd->pages[0]);
+ SDL_DestroyTexture(swd->pages[1]);
- einfo->info.dest_buffer = ((SDL_Surface*)einfo->info.switch_data)->pixels;
- einfo->info.dest_buffer_row_bytes = e->w * sizeof (int);
+ 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 = 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;
}
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);
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
einfo = (Evas_Engine_Info_Buffer *) evas_engine_info_get(ee->evas);
if (einfo)
{
- 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;
- }
+ 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);
- SDL_SetAlpha(einfo->info.switch_data, SDL_SRCALPHA, 0);
- SDL_FillRect(einfo->info.switch_data, NULL, 0);
+ 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.dest_buffer = ((SDL_Surface*)einfo->info.switch_data)->pixels;
- einfo->info.dest_buffer_row_bytes = w * sizeof (int);
+ SDL_LockTexture(swd->pages[swd->current], NULL, &pixels, &pitch);
+
+ einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_RGB32;
+ 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;
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;
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;
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;
{
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);
}
#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;
return ee;
}
#endif
-
#include "evas_private.h"
#include "evas_engine.h"
-static void* _sdl_output_setup (int w, int h, int fullscreen, int noframe);
-
+#include <dlfcn.h>
+
+#include <SDL2/SDL_opengl.h>
+
+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 *
-eng_info(Evas *e EINA_UNUSED)
+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)
{
- Evas_Engine_Info_GL_SDL *info;
-
- info = calloc(1, sizeof(Evas_Engine_Info_GL_SDL));
- if (!info) return NULL;
- info->magic.magic = rand();
- return info;
}
-static void
-eng_info_free(Evas *e EINA_UNUSED, void *info)
+static Eina_Bool
+_outbuf_region_first_rect(Outbuf *ob EINA_UNUSED)
{
- Evas_Engine_Info_GL_SDL *in;
- in = (Evas_Engine_Info_GL_SDL *)info;
- free(in);
+ return EINA_FALSE;
}
-static int
-eng_setup(Evas *eo_e, void *in)
+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)
{
- Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
- Render_Engine *re;
- Evas_Engine_Info_GL_SDL *info;
-
- info = (Evas_Engine_Info_GL_SDL *)in;
-
- SDL_Init(SDL_INIT_NOPARACHUTE);
-
- if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
- {
- ERR("SDL_Init failed with %s", SDL_GetError());
- SDL_Quit();
- return 0;
- }
-
- 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);
-
- return 1;
+ return ob->gl_context->def_surface;
}
static void
-eng_output_free(void *data)
+_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)
{
- Render_Engine *re;
-
- 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)
+_outbuf_free_region_for_update(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED)
{
- 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)
+_outbuf_free(Outbuf *ob)
{
+ glsym_evas_gl_common_context_free(ob->gl_context);
}
-static void
-eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
+static int
+_outbuf_get_rot(Outbuf *ob EINA_UNUSED)
{
- 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;
+ return 0;
}
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)
+_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode EINA_UNUSED)
{
+ SDL_GL_SwapWindow(ob->window);
}
-static void
-eng_output_redraws_clear(void *data)
+static Eina_Bool
+eng_window_make_current(void *data, void *doit EINA_UNUSED)
{
- Render_Engine *re;
+ Outbuf *ob = data;
- re = (Render_Engine *)data;
- re->draw.redraw = 0;
-// INF("GL: finish update cycle!");
+ SDL_GL_MakeCurrent(ob->window, ob->context);
+ return EINA_TRUE;
}
-/* 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)
+static void
+_window_use(Outbuf *ob)
{
- Render_Engine *re;
+ /* 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);
- 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)
+ if (ob)
{
-// printf("GL: NO updates!\n");
- return NULL;
+ glsym_evas_gl_common_context_use(ob->gl_context);
+ glsym_evas_gl_common_context_flush(ob->gl_context);
}
-// 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)
+static Evas_Engine_GL_Context *
+_window_gl_context_get(Outbuf *ob)
{
- 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");
+ return ob->gl_context;
}
-static void
-eng_output_flush(void *data, Evas_Render_Mode render_mode)
+static void *
+_window_egl_display_get(Outbuf *ob)
{
- 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]);
+ return ob->egl_disp;
#else
- glXSwapBuffers(re->win->disp, re->win);
-#endif
-#else
- SDL_GL_SwapBuffers();
+ (void) ob;
+ return NULL;
#endif
}
-static void
-eng_output_idle_flush(void *data EINA_UNUSED)
+struct _Context_3D
{
-}
+ Outbuf *ob;
+ SDL_GLContext sdl_context;
+};
-static void
-eng_output_dump(void *data)
+static Context_3D *
+_window_gl_context_new(Outbuf *ob)
{
- Render_Engine *re;
+ Context_3D *ctx;
- 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);
-}
+ ctx = calloc(1, sizeof (Context_3D));
+ if (!ctx) return NULL;
-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);
-}
+ ctx->ob = ob;
+ ctx->sdl_context = SDL_GL_CreateContext(ob->window);
-static void
-eng_context_cutout_clear(void *data EINA_UNUSED, void *context)
-{
- evas_common_draw_context_clear_cutouts(context);
+ return ctx;
}
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)
+_window_gl_context_use(Context_3D *ctx)
{
- 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);
+ SDL_GL_MakeCurrent(ctx->ob->window, ctx->sdl_context);
}
-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);
-}
+/* FIXME: noway to destroy Context_3D */
static void *
-eng_polygon_point_add(void *data EINA_UNUSED, void *context EINA_UNUSED, void *polygon, int x, int y)
+evgl_eng_display_get(void *data)
{
- return evas_gl_common_poly_point_add(polygon, x, y);
-}
+ Render_Engine *re = data;
-static void *
-eng_polygon_points_clear(void *data EINA_UNUSED, void *context EINA_UNUSED, void *polygon)
-{
- return evas_gl_common_poly_points_clear(polygon);
+ 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
-eng_polygon_draw(void *data, void *context, void *surface, void *polygon, int x, int y, Eina_Bool do_async EINA_UNUSED)
+static void *
+evgl_eng_evas_surface_get(void *data)
{
- Render_Engine *re;
+ Render_Engine *re = data;
- 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);
+ return re->generic.software.ob->window;
}
static int
-eng_image_alpha_get(void *data EINA_UNUSED, void *image)
+evgl_eng_make_current(void *data EINA_UNUSED,
+ void *surface, void *context,
+ int flush)
{
- Evas_GL_Image *im = image;
-
- return im ? im->alpha : 1;
+ if (flush) _window_use(NULL);
+ SDL_GL_MakeCurrent(surface, context);
+ return EINA_TRUE;
}
-static Evas_Colorspace
-eng_image_colorspace_get(void *data EINA_UNUSED, void *image)
+static void *
+evgl_eng_native_window_create(void *data EINA_UNUSED)
{
- Evas_GL_Image *im = image;
-
- return im ? im->cs.space : EVAS_COLORSPACE_ARGB8888;
+ /* 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 void *
-eng_image_alpha_set(void *data EINA_UNUSED, void *image, int has_alpha)
+static int
+evgl_eng_native_window_destroy(void *data EINA_UNUSED, void *native_window)
{
- 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;
+ /* SDL_DestroyWindow(native_window); */
+ return 1;
}
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)
+evgl_eng_window_surface_create(void *data EINA_UNUSED, void *native_window)
{
- return image;
+ return native_window;
}
-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 int
+evgl_eng_window_surface_destroy(void *data EINA_UNUSED,
+ void *surface EINA_UNUSED)
{
+ return 1;
}
-static char *
-eng_image_comment_get(void *data EINA_UNUSED, void *image, char *key EINA_UNUSED)
+static void *
+evgl_eng_context_create(void *data, void *share_ctx EINA_UNUSED)
{
- Evas_GL_Image *im = image;
-
- if (im && im->im) return im->im->info.comment;
- return NULL;
-}
+ Render_Engine *re = data;
-static char *
-eng_image_format_get(void *data EINA_UNUSED, void *image EINA_UNUSED)
-{
- return NULL;
+ SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
+ return SDL_GL_CreateContext(re->generic.software.ob->window);
}
-static void
-eng_image_colorspace_set(void *data EINA_UNUSED, void *image, Evas_Colorspace cspace)
+static int
+evgl_eng_context_destroy(void *data EINA_UNUSED, void *context)
{
- 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;
+ SDL_GL_DeleteContext(context);
+ return 1;
}
-/////////////////////////////////////////////////////////////////////////
-//
-//
-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)
+static const char *
+evgl_eng_string_get(void *data EINA_UNUSED)
{
- return NULL;
-}
+ const char *(*glGetString)(GLenum n);
-static void *
-eng_image_native_get(void *data EINA_UNUSED, void *image EINA_UNUSED)
-{
+ glGetString = SDL_GL_GetProcAddress("glGetString");
+ if (glGetString) return glGetString(GL_EXTENSIONS);
return NULL;
}
-//
-//
-/////////////////////////////////////////////////////////////////////////
-
static void *
-eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
+evgl_eng_proc_address_get(const char *name)
{
- Render_Engine *re = data;
-
- *error = EVAS_LOAD_ERROR_NONE;
- return evas_gl_common_image_load(re->gl_context, file, key, lo, error);
+ return SDL_GL_GetProcAddress(name);
}
-static void *
-eng_image_mmap(void *data, Eina_File *f, const char *key, int *error, Evas_Image_Load_Opts *lo)
+static int
+evgl_eng_rotation_angle_get(void *data EINA_UNUSED)
{
- Render_Engine *re = data;
-
- *error = EVAS_LOAD_ERROR_NONE;
- return evas_gl_common_image_mmap(re->gl_context, f, key, lo, error);
+ return 0;
}
-static void *
-eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, Evas_Colorspace cspace)
+static const EVGL_Interface evgl_funcs =
{
- Render_Engine *re = data;
+ 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
+};
- 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)
+eng_info(Evas *e EINA_UNUSED)
{
- Render_Engine *re = data;
-
- return evas_gl_common_image_new_from_copied_data(re->gl_context, w, h, image_data, alpha, cspace);
-}
+ Evas_Engine_Info_GL_SDL *info;
-static void
-eng_image_free(void *data EINA_UNUSED, void *image)
-{
- if (image) evas_gl_common_image_free(image);
+ info = calloc(1, sizeof(Evas_Engine_Info_GL_SDL));
+ if (!info) return NULL;
+ info->magic.magic = rand();
+ return info;
}
static void
-eng_image_size_get(void *data EINA_UNUSED, void *image, int *w, int *h)
+eng_info_free(Evas *e EINA_UNUSED, void *info)
{
- if (!image)
- {
- *w = 0;
- *h = 0;
- return;
- }
- if (w) *w = ((Evas_GL_Image *)image)->w;
- if (h) *h = ((Evas_GL_Image *)image)->h;
+ Evas_Engine_Info_GL_SDL *in;
+ in = (Evas_Engine_Info_GL_SDL *)info;
+ free(in);
}
-static void *
-eng_image_size_set(void *data, void *image, int w, int h)
+static int
+eng_setup(Evas *eo_e, void *in)
{
- 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;
-}
+ Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
+ Render_Engine *re = NULL;
+ Outbuf *ob = NULL;
+ Evas_Engine_Info_GL_SDL *info;
-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;
+ info = (Evas_Engine_Info_GL_SDL *)in;
- if (!image) return NULL;
- if (im->native.data) return image;
- evas_gl_common_image_dirty(image, x, y, w, h);
- return image;
-}
+ ob = _sdl_output_setup(e->output.w, e->output.h,
+ info->flags.fullscreen,
+ info->flags.noframe,
+ info);
+ if (!ob) goto on_error;
+
+ 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;
-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;
-}
+ 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);
-static void *
-eng_image_data_put(void *data EINA_UNUSED, void *image, DATA32 *image_data)
-{
- Evas_GL_Image *im, *im2;
+ /* 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();
- 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;
-}
+ return 1;
-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);
+ on_error:
+ if (ob) _outbuf_free(ob);
+ free(ob);
+ free(re);
+ return 0;
}
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)
+eng_output_free(void *data)
{
- Render_Engine *re;
+ Render_Engine *re = data;
- 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;
+ evas_render_engine_software_generic_clean(&re->generic.software);
}
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)
+eng_output_dump(void *data)
{
- 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;
+ evas_common_image_image_all_unload();
+ evas_common_font_font_all_unload();
+ glsym_evas_gl_common_image_all_unload(re->generic.software.ob->gl_context);
}
-static void *
-eng_image_map_surface_new(void *data EINA_UNUSED, int w, int h, int alpha)
+static Eina_Bool
+eng_canvas_alpha_get(void *data EINA_UNUSED, void *info EINA_UNUSED)
{
- Render_Engine *re;
-
- re = (Render_Engine *)data;
- return evas_gl_common_image_surface_new(re->gl_context, w, h, alpha);
+ return 0;
}
static void
-eng_image_map_surface_free(void *data EINA_UNUSED, void *surface)
+gl_symbols(void)
{
- evas_gl_common_image_free(surface);
-}
+#define LINK2GENERIC(sym) \
+ glsym_##sym = dlsym(RTLD_DEFAULT, #sym);
-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;
-}
+ 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);
-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;
-}
-
-static Eina_Bool
-eng_canvas_alpha_get(void *data EINA_UNUSED, void *info EINA_UNUSED)
-{
- // FIXME: support ARGB gl targets!!!
- return EINA_FALSE;
-}
-
-static int
-eng_image_load_error_get(void *data EINA_UNUSED, void *image)
-{
- Evas_GL_Image *im;
-
- if (!image) return EVAS_LOAD_ERROR_NONE;
- im = image;
- return im->im->cache_entry.load_error;
+ 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);
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);
-
-// 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);
-
+
+ gl_symbols();
+
/* now advertise out own api */
em->functions = (void *)(&func);
return 1;
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 =
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);
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;
+}