display : Modified to use the pixman library.
authorjinhyung.jo <jinhyung.jo@samsung.com>
Fri, 14 Jun 2013 08:18:54 +0000 (17:18 +0900)
committerjinhyung.jo <jinhyung.jo@samsung.com>
Fri, 14 Jun 2013 08:18:54 +0000 (17:18 +0900)
Now, display update function makes a scaled/rotated screen using the pixman APIs.

Signed-off-by: Jinhyung Jo <jinhyung.jo@samsung.com>
configure
tizen/src/Makefile.tizen
tizen/src/maru_sdl.c

index 6ca30b9f67460e989f828ed5ff1702d96ba81f96..3b4a42ab374202ccd160e04df2d0f3f7b3158bf1 100755 (executable)
--- a/configure
+++ b/configure
@@ -2195,6 +2195,22 @@ else
     exit 1
 fi
 
+##########################################
+# pixman support probe
+
+if test "$shm" = no; then
+    if $pkg_config pixman-1 > /dev/null 2>&1; then
+        pixman_cflags=`$pkg_config --cflags pixman-1 2>/dev/null`
+        pixman_libs=`$pkg_config --libs pixman-1 2>/dev/null`
+        QEMU_CFLAGS="$pixman_cflags $QEMU_CFLAGS"
+        LIBS="$pixman_libs $LIBS"
+    else
+        echo "Error: pixman-1 check failed"
+        echo "Make sure to have the pixman-1 libs and headers installed"
+        exit 1
+    fi
+fi
+
 ##########################################
 # libcap probe
 
index 60276ccb6616a1611f6d9178c0a5750a110604b2..475c16f5c53708f06af67987370e2146709633ae 100644 (file)
@@ -89,7 +89,7 @@ obj-y += maru_display.o
 ifdef CONFIG_USE_SHM
 obj-y += maru_shm.o
 else
-obj-y += maru_sdl.o SDL_rotozoom.o maru_finger.o
+obj-y += maru_sdl.o maru_finger.o
 endif
 
 # sdb
index ce34f003506c0392794430b1bb92ba48cdd6ea3a..2aaabd57edbfd0492ec681e050ffb042f9366262 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact:
+ * Jinhyung Jo <jinhyung.jo@samsung.com>
  * GiWoong Kim <giwoong.kim@samsung.com>
  * SeokYeon Hwang <syeon.hwang@samsung.com>
  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
 
 #include <pthread.h>
 #include <math.h>
+#include <pixman.h>
 #include "console.h"
 #include "maru_sdl.h"
 #include "maru_display.h"
 #include "emul_state.h"
+/*
 #include "SDL_gfx/SDL_rotozoom.h"
 #include "maru_sdl_rotozoom.h"
+*/
 #include "maru_finger.h"
 #include "hw/maru_pm.h"
 #include "hw/maru_brightness.h"
@@ -49,7 +53,8 @@ DisplaySurface* qemu_display_surface = NULL;
 
 static SDL_Surface *surface_screen;
 static SDL_Surface *surface_qemu;
-static SDL_Surface *processing_screen;
+static SDL_Surface *scaled_screen;
+static SDL_Surface *rotated_screen;
 
 static double current_scale_factor = 1.0;
 static double current_screen_degree;
@@ -81,6 +86,102 @@ extern pthread_cond_t cond_screenshot;
 #define SDL_FLAGS (SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL | SDL_NOFRAME)
 #define SDL_BPP 32
 
+/* Image processing functions using the pixman library */
+static SDL_Surface *maru_do_pixman_scale(SDL_Surface *rz_src,
+                                         SDL_Surface *rz_dst,
+                                         int angle)
+{
+    pixman_image_t *src = NULL;
+    pixman_image_t *dst = NULL;
+    double sx = 0;
+    double sy = 0;
+    pixman_transform_t matrix;
+    struct pixman_f_transform matrix_f;
+
+    SDL_LockSurface(rz_src);
+    SDL_LockSurface(rz_dst);
+
+    src = pixman_image_create_bits(PIXMAN_a8r8g8b8,
+        rz_src->w, rz_src->h, rz_src->pixels, rz_src->w * 4);
+    dst = pixman_image_create_bits(PIXMAN_a8r8g8b8,
+        rz_dst->w, rz_dst->h, rz_dst->pixels, rz_dst->w * 4);
+
+    sx = (double)rz_src->w / (double)rz_dst->w;
+    sy = (double)rz_src->h / (double)rz_dst->h;
+    pixman_f_transform_init_identity(&matrix_f);
+    pixman_f_transform_scale(&matrix_f, NULL, sx, sy);
+    pixman_transform_from_pixman_f_transform(&matrix, &matrix_f);
+    pixman_image_set_transform(src, &matrix);
+    pixman_image_set_filter(src, PIXMAN_FILTER_BILINEAR, NULL, 0);
+    pixman_image_composite(PIXMAN_OP_SRC, src, NULL, dst,
+                           0, 0, 0, 0, 0, 0,
+                           rz_dst->w, rz_dst->h);
+
+    pixman_image_unref(src);
+    pixman_image_unref(dst);
+
+    SDL_UnlockSurface(rz_src);
+    SDL_UnlockSurface(rz_dst);
+
+    return rz_dst;
+}
+
+static SDL_Surface *maru_do_pixman_rotate(SDL_Surface *rz_src,
+                                          SDL_Surface *rz_dst,
+                                          int angle)
+{
+    pixman_image_t *src = NULL;
+    pixman_image_t *dst = NULL;
+    pixman_transform_t matrix;
+    struct pixman_f_transform matrix_f;
+
+    SDL_LockSurface(rz_src);
+    SDL_LockSurface(rz_dst);
+
+    src = pixman_image_create_bits(PIXMAN_a8r8g8b8,
+        rz_src->w, rz_src->h, rz_src->pixels, rz_src->w * 4);
+    dst = pixman_image_create_bits(PIXMAN_a8r8g8b8,
+        rz_dst->w, rz_dst->h, rz_dst->pixels, rz_dst->w * 4);
+
+    pixman_f_transform_init_identity(&matrix_f);
+    switch(angle) {
+        case 0:
+            pixman_f_transform_rotate(&matrix_f, NULL, 1.0, 0.0);
+            pixman_f_transform_translate(&matrix_f, NULL, 0.0, 0.0);
+            break;
+        case 90:
+            pixman_f_transform_rotate(&matrix_f, NULL, 0.0, 1.0);
+            pixman_f_transform_translate(&matrix_f, NULL, (double)rz_dst->h, 0.0);
+            break;
+        case 180:
+            pixman_f_transform_rotate(&matrix_f, NULL, -1.0, 0.0);
+            pixman_f_transform_translate(&matrix_f, NULL,
+                                         (double)rz_dst->w, (double)rz_dst->h);
+            break;
+        case 270:
+            pixman_f_transform_rotate(&matrix_f, NULL, 0.0, -1.0);
+            pixman_f_transform_translate(&matrix_f, NULL, 0.0, (double)rz_dst->w);
+            break;
+        default:
+            fprintf(stdout, "not supported angle factor (angle=%d)\n", angle);
+            break;
+    }
+    pixman_transform_from_pixman_f_transform(&matrix, &matrix_f);
+    pixman_image_set_transform(src, &matrix);
+    pixman_image_set_filter(src, PIXMAN_FILTER_BILINEAR, NULL, 0);
+    pixman_image_composite(PIXMAN_OP_SRC, src, NULL, dst,
+                           0, 0, 0, 0, 0, 0,
+                           rz_dst->w, rz_dst->h);
+
+    pixman_image_unref(src);
+    pixman_image_unref(dst);
+
+    SDL_UnlockSurface(rz_src);
+    SDL_UnlockSurface(rz_dst);
+
+    return rz_dst;
+}
+
 void qemu_ds_sdl_update(DisplayState *ds, int x, int y, int w, int h)
 {
     /* call sdl update */
@@ -238,14 +339,16 @@ void qemu_ds_sdl_refresh(DisplayState *ds)
 //extern int capability_check_gl;
 static void _sdl_init(void)
 {
-    int w, h, temp;
+    int w, h, rwidth, rheight, temp;
 
     INFO("Set up a video mode with the specified width, height and bits-per-pixel\n");
 
     //get current setting information and calculate screen size
+    rwidth = get_emul_lcd_width();
+    rheight = get_emul_lcd_height();
     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;
+    w = current_screen_width = rwidth * current_scale_factor;
+    h = current_screen_height = rheight * current_scale_factor;
 
     short rotaton_type = get_emul_rotation();
     if (rotaton_type == ROTATION_PORTRAIT) {
@@ -255,6 +358,9 @@ static void _sdl_init(void)
         temp = w;
         w = h;
         h = temp;
+        temp = rwidth;
+        rwidth = rheight;
+        rheight = temp;
     } else if (rotaton_type == ROTATION_REVERSE_PORTRAIT) {
         current_screen_degree = 180.0;
     } else if (rotaton_type == ROTATION_REVERSE_LANDSCAPE) {
@@ -262,6 +368,9 @@ static void _sdl_init(void)
         temp = w;
         w = h;
         h = temp;
+        temp = rwidth;
+        rwidth = rheight;
+        rheight = temp;
     }
 
 #if 0
@@ -291,8 +400,14 @@ static void _sdl_init(void)
 #endif
 
     /* create buffer for image processing */
-    SDL_FreeSurface(processing_screen);
-    processing_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, get_emul_sdl_bpp(),
+    SDL_FreeSurface(scaled_screen);
+    scaled_screen = SDL_CreateRGBSurface(SDL_SWSURFACE,
+        w, h, get_emul_sdl_bpp(),
+        surface_qemu->format->Rmask, surface_qemu->format->Gmask,
+        surface_qemu->format->Bmask, surface_qemu->format->Amask);
+    SDL_FreeSurface(rotated_screen);
+    rotated_screen = SDL_CreateRGBSurface(SDL_SWSURFACE,
+        rwidth, rheight, get_emul_sdl_bpp(),
         surface_qemu->format->Rmask, surface_qemu->format->Gmask,
         surface_qemu->format->Bmask, surface_qemu->format->Amask);
 
@@ -382,7 +497,8 @@ static void qemu_update(void)
         sdl_alteration = 0;
         _sdl_init();
     } else if (sdl_alteration == -1) {
-        SDL_FreeSurface(processing_screen);
+        SDL_FreeSurface(scaled_screen);
+        SDL_FreeSurface(rotated_screen);
         SDL_FreeSurface(surface_qemu);
         surface_qemu = NULL;
         SDL_Quit();
@@ -451,40 +567,23 @@ static void qemu_update(void)
         else
         { //sdl surface
 #endif
-            if (current_scale_factor < 0.5)
-            {
-                /* image processing via sdl_gfx for rich interpolating */
-
-                // workaround
-                // set color key 'magenta'
-                surface_qemu->format->colorkey = 0xFF00FF;
-
-                SDL_Surface *temp_surface = NULL;
-
-                temp_surface = rotozoomSurface(
-                    surface_qemu, current_screen_degree, current_scale_factor, 1);
-                SDL_BlitSurface(temp_surface, NULL, surface_screen, NULL);
-
-                SDL_FreeSurface(temp_surface);
-            }
-            else if (current_scale_factor < 1.0)
+            if (current_scale_factor != 1.0)
             {
-                /* image processing with simple algorithm for uniformly interpolation */
-                processing_screen = maru_rotozoom(
-                    surface_qemu, processing_screen,
-                    (int)current_screen_degree, TRUE);
-
-                SDL_BlitSurface(processing_screen, NULL, surface_screen, NULL);
+                rotated_screen = maru_do_pixman_rotate(
+                    surface_qemu, rotated_screen,
+                    (int)current_screen_degree);
+                scaled_screen = maru_do_pixman_scale(
+                    rotated_screen, scaled_screen,
+                    (int)current_screen_degree);
+                SDL_BlitSurface(scaled_screen, NULL, surface_screen, NULL);
             }
             else /* current_scale_factor == 1.0 */
             {
                 if (current_screen_degree != 0.0) {
-                    /* image processing */
-                    processing_screen = maru_rotozoom(
-                        surface_qemu, processing_screen,
-                        (int)current_screen_degree, FALSE);
-
-                    SDL_BlitSurface(processing_screen, NULL, surface_screen, NULL);
+                    rotated_screen = maru_do_pixman_rotate(
+                        surface_qemu, rotated_screen,
+                        (int)current_screen_degree);
+                    SDL_BlitSurface(rotated_screen, NULL, surface_screen, NULL);
                 } else {
                     /* as-is */
                     SDL_BlitSurface(surface_qemu, NULL, surface_screen, NULL);