From: Kitae Kim Date: Tue, 5 Aug 2014 02:33:17 +0000 (+0900) Subject: tethering: add a function to get framebuffer in maru_sdl. X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~263^2~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3ec33506f1f3e1544776b83d7828032e5e7b078e;p=sdk%2Femulator%2Fqemu.git tethering: add a function to get framebuffer in maru_sdl. 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: I68cf166df6bf774cebc6bc317024c54561e8383e Signed-off-by: Kitae Kim --- diff --git a/tizen/src/maru_sdl.c b/tizen/src/maru_sdl.c index 35be462273..9076c172fc 100644 --- a/tizen/src/maru_sdl.c +++ b/tizen/src/maru_sdl.c @@ -39,6 +39,13 @@ #include "hw/maru_brightness.h" #include "debug_ch.h" +#include "tethering/touch.h" + +#include +#ifndef CONFIG_WIN32 +#include +#endif + MULTI_DEBUG_CHANNEL(tizen, maru_sdl); static QEMUBH *sdl_init_bh; @@ -82,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) { @@ -96,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, @@ -607,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; +} diff --git a/tizen/src/maru_sdl.h b/tizen/src/maru_sdl.h index 342f4d24d1..5345c78476 100644 --- a/tizen/src/maru_sdl.h +++ b/tizen/src/maru_sdl.h @@ -32,8 +32,6 @@ #ifndef MARU_SDL_H_ #define MARU_SDL_H_ -#include -#include #include "ui/console.h" extern DisplayChangeListenerOps maru_dcl_ops; @@ -48,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_ */ diff --git a/tizen/src/maru_shm.c b/tizen/src/maru_shm.c index 8c49cf2b5c..dacf35fa73 100644 --- a/tizen/src/maru_shm.c +++ b/tizen/src/maru_shm.c @@ -36,8 +36,8 @@ #include "emul_state.h" #include "hw/maru_brightness.h" #include "skin/maruskin_server.h" -#include "debug_ch.h" #include "maru_err_table.h" +#include "debug_ch.h" MULTI_DEBUG_CHANNEL(tizen, maru_shm); @@ -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; +} diff --git a/tizen/src/maru_shm.h b/tizen/src/maru_shm.h index d24b1b69e0..7beebee399 100644 --- a/tizen/src/maru_shm.h +++ b/tizen/src/maru_shm.h @@ -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_ */ diff --git a/tizen/src/tethering/encode_fb.c b/tizen/src/tethering/encode_fb.c index b47de983d6..049f97c33b 100644 --- a/tizen/src/tethering/encode_fb.c +++ b/tizen/src/tethering/encode_fb.c @@ -5,6 +5,7 @@ * * Contact: * Kitae Kim + * SangHo Park * YeongKyoon Lee * * This program is free software; you can redistribute it and/or @@ -30,8 +31,21 @@ #include #include "emul_state.h" + +#ifdef CONFIG_SDL +#include "maru_sdl.h" +#endif +#ifdef CONFIG_USE_SHM +#include "maru_shm.h" +#endif + #include "skin/maruskin_operation.h" #include "encode_fb.h" + +#if defined(CONFIG_LINUX) && defined(ENCODE_DEBUG) +#include +#endif + #include "debug_ch.h" MULTI_DEBUG_CHANNEL(tizen, app_tethering); @@ -53,7 +67,7 @@ void *encode_framebuffer(void) #if defined(CONFIG_LINUX) && defined(ENCODE_DEBUG) clock_gettime(CLOCK_MONOTONIC, &end); - INFO("encoding time: %.5f seconds\n", + TRACE("encoding time: %.5f seconds\n", ((double)end.tv_sec + (1.0e-9 * end.tv_nsec)) - ((double)start.tv_sec + (1.0e-9 * start.tv_nsec))); #endif @@ -94,19 +108,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) { - ERR("failed to get framebuffer\n"); - return NULL; - } - width = get_emul_resolution_width(); height = get_emul_resolution_height(); @@ -114,11 +122,24 @@ static void *encode_png(void) 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) { + ERR("failed to allocate framebuffer\n"); + return NULL; + } + + if (!maru_extract_framebuffer(surface)) { + ERR("failed to extract framebuffer\n"); + g_free(surface); + return NULL; + } + TRACE("png_create_write_struct\n"); png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { ERR("png_create_write_struct failure\n"); - g_free(surface->data); g_free(surface); return NULL; } @@ -127,7 +148,6 @@ static void *encode_png(void) info_ptr = png_create_info_struct(png_ptr); if (!png_ptr) { ERR("png_create_info_struct failure\n"); - g_free(surface->data); g_free(surface); png_destroy_write_struct(&png_ptr, &info_ptr); return NULL; @@ -136,7 +156,6 @@ static void *encode_png(void) TRACE("try png_jmpbuf\n"); if (setjmp(png_jmpbuf(png_ptr))) { ERR("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); @@ -147,7 +166,6 @@ static void *encode_png(void) container = g_malloc(sizeof(struct encode_mem)); if (!container) { ERR("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); @@ -174,7 +192,6 @@ static void *encode_png(void) row_pointers = png_malloc(png_ptr, sizeof(png_bytep) * height); if (row_pointers == NULL) { ERR("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); @@ -182,7 +199,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); } TRACE("png_write_image\n"); @@ -191,7 +208,6 @@ static void *encode_png(void) TRACE("png_write_end\n"); png_write_end(png_ptr, info_ptr); - g_free(surface->data); g_free(surface); TRACE("png image size %d\n", container->length); diff --git a/tizen/src/tethering/encode_fb.h b/tizen/src/tethering/encode_fb.h index 9697bf17b2..fdb9f23fa0 100644 --- a/tizen/src/tethering/encode_fb.h +++ b/tizen/src/tethering/encode_fb.h @@ -28,8 +28,6 @@ * */ -#include - struct encode_mem { uint8_t *buffer; uint32_t length; diff --git a/tizen/src/tethering/touch.c b/tizen/src/tethering/touch.c index cf728241bf..0af096a8d9 100644 --- a/tizen/src/tethering/touch.c +++ b/tizen/src/tethering/touch.c @@ -43,7 +43,6 @@ typedef struct touch_state { bool is_touch_supported; // int touch_max_point; - // display_state *display; } touch_event; @@ -53,7 +52,6 @@ static int touch_device_status; // static void set_touch_event_status(bool status); static bool send_display_image_data(void); - #if 0 touch_state *init_touch_state(void) { @@ -246,6 +244,14 @@ static void set_hwkey_data(Tethering__HWKeyMsg *msg) } #endif +static bool is_display_dirty = false; + +void set_display_dirty(bool dirty) +{ + 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) { @@ -279,7 +285,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 @@ -307,6 +316,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; @@ -317,35 +339,28 @@ static bool send_display_image_data(void) TRACE("enter: %s\n", __func__); +#ifdef CONFIG_PNG image = (struct encode_mem *)encode_framebuffer(); if (!image) { ERR("failed to encode framebuffer\n"); return false; } +#else + INFO("not support display feature\n"); + return false; +#endif + dump_display_image_data(image); 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); - INFO("send display message: %d\n", ret); + TRACE("send display message: %d\n", ret); g_free(image->buffer); g_free(image); diff --git a/tizen/src/tethering/touch.h b/tizen/src/tethering/touch.h index 3fbd6c92b7..251a68b9fe 100644 --- a/tizen/src/tethering/touch.h +++ b/tizen/src/tethering/touch.h @@ -28,11 +28,15 @@ * */ -// #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);