tethering: add a function to get framebuffer in maru_sdl. 41/25041/7
authorKitae Kim <kt920.kim@samsung.com>
Mon, 28 Jul 2014 02:40:46 +0000 (11:40 +0900)
committerKitae Kim <kt920.kim@samsung.com>
Wed, 30 Jul 2014 06:33:16 +0000 (15:33 +0900)
When request_screenshot function is called by tethering module
it makes qemu update display. So, this function has to be implemented
to extract framebuffer because of unnecessary display update.

Change-Id: I642119a430261f0176be47445b3b6fe5630920cc
Signed-off-by: Kitae Kim <kt920.kim@samsung.com>
tizen/src/display/maru_sdl.c
tizen/src/display/maru_sdl.h
tizen/src/display/maru_shm.c
tizen/src/display/maru_shm.h
tizen/src/tethering/encode_fb.c
tizen/src/tethering/encode_fb.h
tizen/src/tethering/touch.c
tizen/src/tethering/touch.h

index cdc099d..04bf1a7 100644 (file)
@@ -39,6 +39,8 @@
 #include "hw/pci/maru_brightness.h"
 #include "debug_ch.h"
 
+#include "tethering/touch.h"
+
 #include <SDL.h>
 #ifndef CONFIG_WIN32
 #include <SDL_syswm.h>
@@ -87,7 +89,6 @@ static bool sdl_thread_exit;
 
 static void qemu_update(void);
 
-
 static void qemu_ds_sdl_update(DisplayChangeListener *dcl,
                                int x, int y, int w, int h)
 {
@@ -101,6 +102,8 @@ static void qemu_ds_sdl_update(DisplayChangeListener *dcl,
 #else
     qemu_update();
 #endif
+
+    set_display_dirty(true);
 }
 
 static void qemu_ds_sdl_switch(DisplayChangeListener *dcl,
@@ -612,3 +615,26 @@ void maru_sdl_invalidate(bool on)
 {
     sdl_invalidate = on;
 }
+
+bool maru_extract_framebuffer(void *buffer)
+{
+    uint32_t buffer_size = 0;
+
+    if (!buffer) {
+        ERR("given buffer is null\n");
+        return false;
+    }
+
+    if (!surface_qemu) {
+        ERR("surface_qemu is null\n");
+        return false;
+    }
+
+    maru_do_pixman_dpy_surface(dpy_surface->image);
+
+    buffer_size = surface_stride(dpy_surface) * surface_height(dpy_surface);
+    INFO("extract framebuffer %d\n", buffer_size);
+
+    memcpy(buffer, surface_data(dpy_surface), buffer_size);
+    return true;
+}
index 87e4ec8..5345c78 100644 (file)
@@ -46,4 +46,6 @@ void maru_sdl_invalidate(bool on);
 void maru_sdl_interpolation(bool on);
 void maru_sdl_quit(void);
 
+bool maru_extract_framebuffer(void *buffer);
+
 #endif /* MARU_SDL_H_ */
index 77a9cba..cb0f6dc 100644 (file)
@@ -287,3 +287,9 @@ void maru_shm_resize(void)
 {
     shm_skip_update = 0;
 }
+
+bool maru_extract_framebuffer(void* buffer)
+{
+    INFO("not support on Mac OS X\n");
+    return false;
+}
index d24b1b6..7beebee 100644 (file)
@@ -40,5 +40,6 @@ void maru_shm_init(uint64 swt_handle,
     bool blank_guide);
 void maru_shm_resize(void);
 void maru_shm_quit(void);
+bool maru_extract_framebuffer(void *buffer);
 
 #endif /* MARU_SHM_H_ */
index 9ecc50a..8f4f717 100644 (file)
@@ -5,6 +5,7 @@
  *
  * Contact:
  *  Kitae Kim <kt920.kim@samsung.com>
+ *  SangHo Park <sangho1206.park@samsung.com>
  *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
  *
  * This program is free software; you can redistribute it and/or
  */
 
 #include <png.h>
-#ifdef CONFIG_WEBP
-#include <webp/types.h>
-#include <webp/encode.h>
-#endif
 
 #include "emulator_common.h"
 #include "emul_state.h"
+
+#ifdef CONFIG_SDL
+#include "display/maru_sdl.h"
+#endif
+#ifdef CONFIG_USE_SHM
+#include "display/maru_shm.h"
+#endif
+
 #include "skin/maruskin_operation.h"
 #include "encode_fb.h"
+
+#if defined(CONFIG_LINUX) && defined(ENCODE_DEBUG)
+#include <time.h>
+#endif
+#ifdef CONFIG_WEBP
+#include <webp/types.h>
+#include <webp/encode.h>
+#endif
+
 #include "util/new_debug_ch.h"
 
 DECLARE_DEBUG_CHANNEL(app_tethering);
@@ -110,19 +124,13 @@ static void *encode_png(void)
      */
     int bit_depth = 8;
     struct encode_mem *container = NULL;
+    uint8_t *surface = NULL;
+    uint32_t surface_size = 0;
 
     png_structp png_ptr = NULL;
     png_infop info_ptr = NULL;
     png_bytepp row_pointers = NULL;
 
-    Framebuffer *surface = NULL;
-
-    surface = request_screenshot();
-    if (!surface) {
-        LOG_SEVERE("failed to get framebuffer\n");
-        return NULL;
-    }
-
     width = get_emul_resolution_width();
     height = get_emul_resolution_height();
 
@@ -130,11 +138,24 @@ static void *encode_png(void)
     LOG_TRACE("width %d, height %d, stride %d, raw image %d\n",
         width, height, image_stride, (image_stride * height));
 
+    surface_size = width * height * 4;
+
+    surface = g_malloc0(surface_size);
+    if (!surface) {
+        LOG_SEVERE("failed to allocate framebuffer\n");
+        return NULL;
+    }
+
+    if (!maru_extract_framebuffer(surface)) {
+        LOG_SEVERE("failed to extract framebuffer\n");
+        g_free(surface);
+        return NULL;
+    }
+
     LOG_TRACE("png_create_write_struct\n");
     png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
     if (!png_ptr) {
         LOG_SEVERE("png_create_write_struct failure\n");
-        g_free(surface->data);
         g_free(surface);
         return NULL;
     }
@@ -143,7 +164,6 @@ static void *encode_png(void)
     info_ptr = png_create_info_struct(png_ptr);
     if (!png_ptr) {
         LOG_SEVERE("png_create_info_struct failure\n");
-        g_free(surface->data);
         g_free(surface);
         png_destroy_write_struct(&png_ptr, &info_ptr);
         return NULL;
@@ -152,7 +172,6 @@ static void *encode_png(void)
     LOG_TRACE("try png_jmpbuf\n");
     if (setjmp(png_jmpbuf(png_ptr))) {
         LOG_SEVERE("png_jmpbuf failure\n");
-        g_free(surface->data);
         g_free(surface);
         png_destroy_write_struct(&png_ptr, &info_ptr);
         png_destroy_info_struct(png_ptr, &info_ptr);
@@ -163,7 +182,6 @@ static void *encode_png(void)
     container = g_malloc(sizeof(struct encode_mem));
     if (!container) {
         LOG_SEVERE("failed to allocate encode_mem\n");
-        g_free(surface->data);
         g_free(surface);
         png_destroy_write_struct(&png_ptr, &info_ptr);
         png_destroy_info_struct(png_ptr, &info_ptr);
@@ -190,7 +208,6 @@ static void *encode_png(void)
     row_pointers = png_malloc(png_ptr, sizeof(png_bytep) * height);
     if (row_pointers == NULL) {
         LOG_SEVERE("failed to allocate png memory\n");
-        g_free(surface->data);
         g_free(surface);
         png_destroy_write_struct(&png_ptr, &info_ptr);
         png_destroy_info_struct(png_ptr, &info_ptr);
@@ -198,7 +215,7 @@ static void *encode_png(void)
     }
 
     for (row_index = 0; row_index < height; row_index++) {
-        row_pointers[row_index] = surface->data + (row_index * image_stride);
+        row_pointers[row_index] = surface + (row_index * image_stride);
     }
 
     LOG_TRACE("png_write_image\n");
@@ -207,7 +224,6 @@ static void *encode_png(void)
     LOG_TRACE("png_write_end\n");
     png_write_end(png_ptr, info_ptr);
 
-    g_free(surface->data);
     g_free(surface);
 
     LOG_TRACE("png image size %d\n", container->length);
@@ -221,11 +237,11 @@ static void *encode_png(void)
 static void *encode_webp(void)
 {
     int width = 0, height = 0, image_stride = 0;
-    // float quality = 0;
     size_t ret = 0;
 
     struct encode_mem *container = NULL;
-    Framebuffer *surface = NULL;
+    uint8_t *surface = NULL;
+    uint32_t surface_size = 0;
 
     container = g_malloc(sizeof(struct encode_mem));
     if (!container) {
@@ -236,13 +252,6 @@ static void *encode_webp(void)
     container->buffer = NULL;
     container->length = 0;
 
-    surface = request_screenshot();
-    if (!surface) {
-        LOG_SEVERE("failed to get framebuffer\n");
-        g_free(container);
-        return NULL;
-    }
-
     width = get_emul_resolution_width();
     height = get_emul_resolution_height();
 
@@ -250,13 +259,36 @@ static void *encode_webp(void)
     LOG_TRACE("width %d, height %d, stride %d, raw image %d\n",
         width, height, image_stride, (image_stride * height));
 
-    ret = WebPEncodeLosslessBGRA((const uint8_t *)surface->data, width,
+    surface_size = width * height * 4;
+
+    surface = g_malloc0(surface_size);
+    if (!surface) {
+        LOG_SEVERE("failed to allocate framebuffer\n");
+        return NULL;
+    }
+
+    if (!maru_extract_framebuffer(surface)) {
+        LOG_SEVERE("failed to extract framebuffer\n");
+        g_free(surface);
+        return NULL;
+    }
+
+    container = g_malloc(sizeof(struct encode_mem));
+    if (!container) {
+        LOG_SEVERE("failed to allocate encode_mem\n");
+        g_free(surface);
+        return NULL;
+    }
+
+    container->buffer = NULL;
+    container->length = 0;
+
+    ret = WebPEncodeLosslessBGRA((const uint8_t *)surface, width,
             height, image_stride, &container->buffer);
     LOG_TRACE("lossless encode framebuffer via webp. result %zu\n", ret);
 
     container->length = (int)ret;
 
-    g_free(surface->data);
     g_free(surface);
 
     return container;
index 235f782..330fc3a 100644 (file)
@@ -28,8 +28,6 @@
  *
  */
 
-#include <time.h>
-
 struct encode_mem {
     uint8_t *buffer;
     uint32_t length;
index f4b9308..625cbbf 100644 (file)
@@ -32,6 +32,7 @@
 #include "emul_state.h"
 #include "common.h"
 #include "touch.h"
+#include "encode_fb.h"
 #include "genmsg/tethering.pb-c.h"
 #include "ecs/ecs_tethering.h"
 #include "util/new_debug_ch.h"
@@ -49,18 +50,8 @@ typedef struct touch_state {
 // static bool is_touch_event;
 static int touch_device_status;
 
-#ifndef DISPLAY_FEATURE
-#include "encode_fb.h"
-
-enum {
-    ENCODE_WEBP = 0,
-    ENCODE_PNG,
-};
-
 // static void set_touch_event_status(bool status);
 static bool send_display_image_data(void);
-#endif
-
 
 #if 0
 touch_state *init_touch_state(void)
@@ -254,6 +245,14 @@ static void set_hwkey_data(Tethering__HWKeyMsg *msg)
 }
 #endif
 
+static bool is_display_dirty = false;
+
+void set_display_dirty(bool dirty)
+{
+    LOG_TRACE("qemu display update: %d\n", is_display_dirty);
+    is_display_dirty = dirty;
+}
+
 // bool msgproc_tethering_touch_msg(Tethering__TouchMsg *msg)
 bool msgproc_tethering_touch_msg(void *message)
 {
@@ -287,7 +286,10 @@ bool msgproc_tethering_touch_msg(void *message)
         break;
 
     case TETHERING__TOUCH_MSG__TYPE__DISPLAY_MSG:
-        send_display_image_data();
+        if (is_display_dirty) {
+            send_display_image_data();
+            is_display_dirty = false;
+        }
         break;
 
 #if 0
@@ -315,6 +317,19 @@ void set_tethering_touch_status(int status)
     send_tethering_touch_status_ecp();
 }
 
+static void dump_display_image_data(struct encode_mem *image)
+{
+#ifdef IMAGE_DUMP
+    FILE *fp = NULL;
+
+    fp = fopen("display_image_dump.png", "wb");
+    if (fp != NULL) {
+        fwrite(image->buffer, 1, image->length, fp);
+        fclose(fp);
+    }
+#endif
+}
+
 static bool send_display_image_data(void)
 {
     bool ret = false;
@@ -325,33 +340,22 @@ static bool send_display_image_data(void)
 
     LOG_TRACE("enter: %s\n", __func__);
 
-    image = (struct encode_mem *)encode_framebuffer(ENCODE_WEBP);
+    image = (struct encode_mem *)encode_framebuffer(ENCODE_PNG);
     if (!image) {
         LOG_SEVERE("failed to encode framebuffer\n");
         return false;
     }
 
+    dump_display_image_data(image);
+
     LOG_TRACE("image data size %d\n", image->length);
     display.has_imagedata = true;
     display.imagedata.len = image->length;
     display.imagedata.data = image->buffer;
 
-#ifdef IMAGE_DUMP
-    {
-        FILE *fp = NULL;
-
-        fp = fopen("test2.png", "wb");
-        if (fp != NULL) {
-            fwrite(image->buffer, 1, image->length, fp);
-            fclose(fp);
-        }
-    }
-#endif
-
     touch.type = TETHERING__TOUCH_MSG__TYPE__DISPLAY_MSG;
     touch.display = &display;
 
-    // ret = build_display_msg(&display);
     ret = build_touch_msg(&touch);
     LOG_TRACE("send display message: %d\n", ret);
 
index 3fbd6c9..251a68b 100644 (file)
  *
  */
 
-// #include "genmsg/tethering.pb-c.h"
+enum {
+    ENCODE_WEBP = 0,
+    ENCODE_PNG,
+};
 
-// bool msgproc_tethering_touch_msg(Tethering__TouchMsg *msg);
 bool msgproc_tethering_touch_msg(void *message);
 
 int get_tethering_touch_status(void);
 
 void set_tethering_touch_status(int status);
+
+void set_display_dirty(bool dirty);