From: giwoong.kim Date: Fri, 13 Jul 2012 05:41:33 +0000 (+0900) Subject: [Title] convert sdl surface to opengl surface X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~1528^2~117 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7451d8896feede7ac17196eea0ff88976e37e944;p=sdk%2Femulator%2Fqemu.git [Title] convert sdl surface to opengl surface [Type] enhancement [Module] Emulator / skin [Priority] major [Jira#] BOT-821, N_SE-1482, S1-4376 [Redmine#] [Problem] [Cause] anti-aliasing [Solution] using OpenGL [TestCase] --- diff --git a/tizen/src/maru_sdl.c b/tizen/src/maru_sdl.c index 8a357df9a6..39e08f71e6 100644 --- a/tizen/src/maru_sdl.c +++ b/tizen/src/maru_sdl.c @@ -36,18 +36,26 @@ #include "maru_finger.h" #include "hw/maru_pm.h" #include "debug_ch.h" -//#include "SDL_opengl.h" +#include "SDL_opengl.h" MULTI_DEBUG_CHANNEL(tizen, maru_sdl); -// TODO : organize +DisplaySurface* qemu_display_surface = NULL; + SDL_Surface *surface_screen; SDL_Surface *surface_qemu; +GLuint texture; + +static double current_scale_factor = 1.0; +static double current_screen_degree = 0.0; +static int current_screen_width; +static int current_screen_height; -static double scale_factor = 1.0; -static double screen_degree = 0.0; static int sdl_initialized = 0; +static int sdl_alteration = 0; +static int sdl_opengl = 0; //0 : just SDL surface, 1 : using SDL with OpenGL + #define SDL_THREAD @@ -60,50 +68,225 @@ static int sdl_thread_initialized = 0; #define SDL_FLAGS (SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL | SDL_NOFRAME) #define SDL_BPP 32 -DisplaySurface* qemu_display_surface = NULL; -static void qemu_update(void) +static void _sdl_init(void) { - int i; - SDL_Surface *processing_screen = NULL; + int w, h, temp; - if (surface_qemu != NULL) { - if (scale_factor != 1.0 || screen_degree != 0.0) { + INFO("Set up a video mode with the specified width, height and bits-per-pixel\n"); + + //get current setting information and calculate screen size + current_scale_factor = get_emul_win_scale(); + w = current_screen_width = get_emul_lcd_width() * current_scale_factor; + h = current_screen_height = get_emul_lcd_height() * current_scale_factor; + + short rotaton_type = get_emul_rotation(); + if (rotaton_type == ROTATION_PORTRAIT) { + current_screen_degree = 0.0; + } else if (rotaton_type == ROTATION_LANDSCAPE) { + current_screen_degree = 90.0; + temp = w; + w = h; + h = temp; + } else if (rotaton_type == ROTATION_REVERSE_PORTRAIT) { + current_screen_degree = 180.0; + } else if (rotaton_type == ROTATION_REVERSE_LANDSCAPE) { + current_screen_degree = 270.0; + temp = w; + w = h; + h = temp; + } - // workaround - // set color key 'magenta' - surface_qemu->format->colorkey = 0xFF00FF; + surface_screen = SDL_SetVideoMode(w, h, get_emul_sdl_bpp(), SDL_OPENGL); + if (surface_screen == NULL) { + sdl_opengl = 0; + INFO("No OpenGL support on this system!??\n"); + ERR("%s\n", SDL_GetError()); - //image processing - processing_screen = rotozoomSurface(surface_qemu, screen_degree, scale_factor, 1); - SDL_BlitSurface(processing_screen, NULL, surface_screen, NULL); - } else { - SDL_BlitSurface(surface_qemu, NULL, surface_screen, NULL); + surface_screen = SDL_SetVideoMode(w, h, get_emul_sdl_bpp(), SDL_FLAGS); + if (surface_screen == NULL) { + ERR("Could not open SDL display (%dx%dx%d): %s\n", w, h, get_emul_sdl_bpp(), SDL_GetError()); + return; } + } else { + sdl_opengl = 1; + INFO("OpenGL is supported on this system.\n"); + } + + if (sdl_opengl == 1) { + /* Set the OpenGL state */ + glClearColor(0, 0, 0, 0); + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, w, h, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); + + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } +} + +static int point_degree = 0; +static void draw_outline_circle(int cx, int cy, int r, int num_segments) +{ + int ii; + float theta = 2 * 3.1415926 / (num_segments); + float c = cosf(theta);//precalculate the sine and cosine + float s = sinf(theta); + float t; + + float x = r;//we start at angle = 0 + float y = 0; + + glEnable(GL_LINE_STIPPLE); + glColor3f(0.9, 0.9, 0.9); + glLineStipple(1, 0xcccc); + glLineWidth(3.f); + glLoadIdentity(); + + glTranslatef(cx, cy, 0); + glRotated(point_degree++ % 360, 0, 0, 1); + + glBegin(GL_LINE_LOOP); + for(ii = 0; ii < num_segments; ii++) { + glVertex2f(x, y); //output vertex + + //apply the rotation matrix + t = x; + x = c * x - s * y; + y = s * t + c * y; + } + glEnd(); + + glDisable(GL_LINE_STIPPLE); +} + +static void draw_fill_circle(int cx, int cy, int r) +{ + glEnable(GL_POINT_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0.1, 0.1, 0.1, 0.6); + glPointSize(r - 2); + glLoadIdentity(); + + glBegin(GL_POINTS); + glVertex2f(cx, cy); + glEnd(); + + glDisable(GL_POINT_SMOOTH); + glDisable(GL_BLEND); +} + +static void qemu_update(void) +{ + if (sdl_alteration == 1) { + sdl_alteration = 0; + _sdl_init(); + return; } - /* draw multi-touch finger points */ - MultiTouchState *mts = get_emul_multi_touch_state(); - if (mts->multitouch_enable != 0 && mts->finger_point_surface != NULL) { - FingerPoint *finger = NULL; - int finger_point_size_half = mts->finger_point_size / 2; - SDL_Rect rect; - - for (i = 0; i < mts->finger_cnt; i++) { - finger = get_finger_point_from_slot(i); - if (finger != NULL && finger->id != 0) { - rect.x = finger->origin_x - finger_point_size_half; - rect.y = finger->origin_y - finger_point_size_half; - rect.w = rect.h = mts->finger_point_size; - - SDL_BlitSurface((SDL_Surface *)mts->finger_point_surface, NULL, surface_screen, &rect); + if (surface_qemu != NULL) { + int i; + + if (sdl_opengl == 1) + { //gl surface + glEnable(GL_TEXTURE_2D); //enable server-side GL capabilities + glColor3f(1.0, 1.0, 1.0); + glTexImage2D(GL_TEXTURE_2D, + 0, 3, surface_qemu->w, surface_qemu->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, surface_qemu->pixels); + glBindTexture(GL_TEXTURE_2D, texture); + + glClear(GL_COLOR_BUFFER_BIT); + glLoadIdentity(); + + /* rotation */ + if (current_screen_degree == 270.0) { //reverse landscape + glRotated(90, 0, 0, 1); + glTranslatef(0, -current_screen_height, 0); + } else if (current_screen_degree == 180.0) { //reverse portrait + glRotated(180, 0, 0, 1); + glTranslatef(-current_screen_width, -current_screen_height, 0); + } else if (current_screen_degree == 90.0) { //landscape + glRotated(270, 0, 0, 1); + glTranslatef(-current_screen_width, 0, 0); + } + + glBegin(GL_QUADS); + glTexCoord2i(0, 0); + glVertex3f(0, 0, 0); + glTexCoord2i(1, 0); + glVertex3f(current_screen_width, 0, 0); + glTexCoord2i(1, 1); + glVertex3f(current_screen_width, current_screen_height, 0); + glTexCoord2i(0, 1); + glVertex3f(0, current_screen_height, 0); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + /* draw multi-touch finger points */ + MultiTouchState *mts = get_emul_multi_touch_state(); + if (mts->multitouch_enable != 0) { + FingerPoint *finger = NULL; + int finger_point_size_half = mts->finger_point_size / 2; + + for (i = 0; i < mts->finger_cnt; i++) { + finger = get_finger_point_from_slot(i); + if (finger != NULL && finger->id != 0) { + draw_outline_circle(finger->origin_x, finger->origin_y, finger_point_size_half, 10); //TODO: optimize + draw_fill_circle(finger->origin_x, finger->origin_y, mts->finger_point_size); + } + } + } //end of draw multi-touch + + glFlush(); + + SDL_GL_SwapBuffers(); + } + else + { //sdl surface + SDL_Surface *processing_screen = NULL; + + if (current_scale_factor != 1.0 || current_screen_degree != 0.0) { + // workaround + // set color key 'magenta' + surface_qemu->format->colorkey = 0xFF00FF; + + //image processing + processing_screen = rotozoomSurface(surface_qemu, current_screen_degree, current_scale_factor, 1); + SDL_BlitSurface(processing_screen, NULL, surface_screen, NULL); + } else { + SDL_BlitSurface(surface_qemu, NULL, surface_screen, NULL); } + + SDL_FreeSurface(processing_screen); + + /* draw multi-touch finger points */ + MultiTouchState *mts = get_emul_multi_touch_state(); + if (mts->multitouch_enable != 0 && mts->finger_point_surface != NULL) { + FingerPoint *finger = NULL; + int finger_point_size_half = mts->finger_point_size / 2; + SDL_Rect rect; + + for (i = 0; i < mts->finger_cnt; i++) { + finger = get_finger_point_from_slot(i); + if (finger != NULL && finger->id != 0) { + rect.x = finger->origin_x - finger_point_size_half; + rect.y = finger->origin_y - finger_point_size_half; + rect.w = rect.h = mts->finger_point_size; + + SDL_BlitSurface((SDL_Surface *)mts->finger_point_surface, NULL, surface_screen, &rect); + } + } + } //end of draw multi-touch } } SDL_UpdateRect(surface_screen, 0, 0, 0, 0); - - SDL_FreeSurface(processing_screen); } @@ -162,7 +345,7 @@ static void qemu_ds_resize(DisplayState *ds) #endif if (surface_qemu == NULL) { - ERR( "Unable to set the RGBSurface: %s", SDL_GetError() ); + ERR("Unable to set the RGBSurface: %s\n", SDL_GetError()); return; } @@ -181,8 +364,8 @@ static int maru_sdl_poll_event(SDL_Event *ev) return ret; } -static void put_hardkey_code( SDL_UserEvent event ) { - +static void put_hardkey_code( SDL_UserEvent event ) +{ // use pointer as integer int event_type = (int) event.data1; int keycode = (int) event.data2; @@ -200,13 +383,13 @@ static void put_hardkey_code( SDL_UserEvent event ) { } } else { - ERR( "Unknown hardkey event type.[event_type:%d]", event_type ); + ERR( "Unknown hardkey event type.[event_type:%d]\n", event_type ); } } -static void handle_sdl_user_event ( SDL_UserEvent event ) { - +static void handle_sdl_user_event ( SDL_UserEvent event ) +{ int code = event.code; switch ( code ) { @@ -256,7 +439,7 @@ static void qemu_ds_refresh(DisplayState *ds) void maruskin_display_init(DisplayState *ds) { - INFO( "qemu display initialization\n"); + INFO("qemu display initialization\n"); /* graphics context information */ DisplayChangeListener *dcl; @@ -271,18 +454,19 @@ void maruskin_display_init(DisplayState *ds) void maruskin_sdl_init(uint64 swt_handle, int lcd_size_width, int lcd_size_height, bool is_resize) { - int w, h, temp; gchar SDL_windowhack[32]; SDL_SysWMinfo info; long window_id = swt_handle; + INFO("maru sdl initialization = %d\n", is_resize); + if (is_resize == FALSE) { sprintf(SDL_windowhack, "%ld", window_id); g_setenv("SDL_WINDOWID", SDL_windowhack, 1); INFO("register SDL environment variable. (SDL_WINDOWID = %s)\n", SDL_windowhack); if (SDL_Init(SDL_INIT_VIDEO) < 0 ) { - ERR( "unable to init SDL: %s", SDL_GetError() ); + ERR("unable to init SDL: %s\n", SDL_GetError()); exit(1); } @@ -290,55 +474,31 @@ void maruskin_sdl_init(uint64 swt_handle, int lcd_size_width, int lcd_size_heigh set_emul_sdl_bpp(SDL_BPP); } - //get current setting information and calculate screen size - scale_factor = get_emul_win_scale(); - w = lcd_size_width * scale_factor; - h = lcd_size_height * scale_factor; + if (sdl_initialized == 0) { + sdl_initialized = 1; - short rotaton_type = get_emul_rotation(); - if (rotaton_type == ROTATION_PORTRAIT) { - screen_degree = 0.0; - } else if (rotaton_type == ROTATION_LANDSCAPE) { - screen_degree = 90.0; - temp = w; - w = h; - h = temp; - } else if (rotaton_type == ROTATION_REVERSE_PORTRAIT) { - screen_degree = 180.0; - } else if (rotaton_type == ROTATION_REVERSE_LANDSCAPE) { - screen_degree = 270.0; - temp = w; - w = h; - h = temp; - } + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + init_multi_touch_state(); - INFO( "maru sdl initialization\n"); - surface_screen = SDL_SetVideoMode(w, h, get_emul_sdl_bpp(), SDL_FLAGS); - if (surface_screen == NULL) { - ERR("Could not open SDL display (%dx%dx%d): %s\n", w, h, get_emul_sdl_bpp(), SDL_GetError()); +#ifndef _WIN32 + SDL_VERSION(&info.version); + SDL_GetWMInfo(&info); +#endif } + sdl_alteration = 1; + #ifdef SDL_THREAD if (sdl_thread_initialized == 0) { sdl_thread_initialized = 1; pthread_t thread_id; - INFO( "sdl update thread create\n"); + INFO("sdl update thread create\n"); if (pthread_create(&thread_id, NULL, run_qemu_update, NULL) != 0) { - ERR( "pthread_create fail\n"); + ERR("pthread_create fail\n"); return; } } #endif - -#ifndef _WIN32 - SDL_VERSION(&info.version); - SDL_GetWMInfo(&info); -#endif - - if (sdl_initialized == 0) { - sdl_initialized = 1; - init_multi_touch_state(); - } } void maruskin_sdl_resize(void) @@ -356,3 +516,4 @@ void maruskin_sdl_resize(void) DisplaySurface* get_qemu_display_surface( void ) { return qemu_display_surface; } + diff --git a/tizen/src/skin/maruskin_operation.c b/tizen/src/skin/maruskin_operation.c index a7d204bbeb..3da625a3be 100644 --- a/tizen/src/skin/maruskin_operation.c +++ b/tizen/src/skin/maruskin_operation.c @@ -191,7 +191,7 @@ void do_hardkey_event( int event_type, int keycode ) void do_scale_event( double scale_factor ) { - INFO( "do_scale_event scale_factor:%lf", scale_factor); + INFO("do_scale_event scale_factor:%lf\n", scale_factor); set_emul_win_scale(scale_factor);