Add damage handling code.
authorSung-jae Park <nicesj.park@samsung.com>
Sun, 28 Sep 2014 12:07:39 +0000 (21:07 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Sun, 28 Sep 2014 12:07:39 +0000 (21:07 +0900)
To save a time for synchronizing new frame.

[model] Redwood,Kiran,B3(Wearable)
[binary_type] AP
[customer] Docomo/Orange/ATT/Open
[issue#] N/A
[problem]
[cause]
[solution]
[team] HomeTF
[request]
[horizontal_expansion]

Change-Id: Id9f62929491d2643c1d69444b15614bb261e8c25

include/dynamicbox.h
include/dynamicbox_internal.h
include/fb.h
src/client.c
src/dynamicbox.c
src/dynamicbox_internal.c
src/fb.c
src/fb_wayland.c

index 10beacb..481d9ad 100644 (file)
@@ -291,6 +291,13 @@ struct dynamicbox_access_event_info {
     int info;
 };
 
+typedef struct dynamicbox_damage_region {
+       int x;
+       int y;
+       int w;
+       int h;
+} dynamicbox_damage_region_t;
+
 /**
  * @brief Mouse Event Information
  * @since_tizen 2.3
@@ -1380,7 +1387,7 @@ extern int dynamicbox_is_active_update(dynamicbox_h handler);
  * @param[in] gbar 1 for Glance Bar or 0
  * @privlevel public
  * @privilege %http://tizen.org/privilege/dynamicbox.viewer
- * @return void
+ * @return int
  * @retval #DBOX_STATUS_ERROR_NONE If success
  * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid handle
  * @see dynamicbox_set_manual_sync()
@@ -1390,6 +1397,19 @@ extern int dynamicbox_sync_fb(dynamicbox_h handler, int gbar);
 
 /**
  * @internal
+ * @brief Getting the damaged region info
+ * @since_tizen 2.3
+ * @param[in] handler Handler of a dynamicbox instance
+ * @param[in] gbar 1 for Glance Bar or 0
+ * @param[out] region Readonly information for damaged area
+ * @return int
+ * @retval #DBOX_STATUS_ERROR_NONE if success
+ * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid handle
+ */
+extern int dynamicbox_damage_region_get(dynamicbox_h handler, int gbar, const dynamicbox_damage_region_t *region);
+
+/**
+ * @internal
  * @brief Gets an alternative icon of the given dynamicbox instance.
  * @details If the box should be represented as a shortcut icon, this function will get the alternative icon.
  * @since_tizen 2.3
@@ -1504,6 +1524,19 @@ extern int dynamicbox_option(enum dynamicbox_option_type option);
 extern int dynamicbox_set_auto_launch_handler(dynamicbox_auto_launch_handler_cb cb, void *data);
 
 /**
+ * @internal
+ * @brief get a damaged region from handler if a handler has buffer type dbox or gbar
+ * @since_tizen 2.3
+ * @param[in] handler Handler of a dbox
+ * @param[in] gbar 1 if you want to get a damaged region of glance bar or 0
+ * @param[out] region Region information, x, y, w, h
+ * @return int
+ * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DBOX_STATUS_ERROR_NONE If sucess
+ */
+extern int dynamicbox_damage_region_get(dynamicbox_h handler, int gbar, const dynamicbox_damage_region_t *region);
+
+/**
  * @}
  */
 
index 7320561..51bf782 100644 (file)
@@ -150,6 +150,7 @@ struct dynamicbox_common {
                double y;
                char *lock;
                int lock_fd;
+               struct dynamicbox_damage_region last_damage;
        } dbox;
 
        struct {
@@ -167,6 +168,7 @@ struct dynamicbox_common {
                double y;
                char *lock;
                int lock_fd;
+               struct dynamicbox_damage_region last_damage;
        } gbar;
 
        int nr_of_sizes;
index 6f02268..e7b8543 100644 (file)
@@ -20,7 +20,7 @@ extern int fb_init(void *disp);
 extern int fb_fini(void);
 extern const char *fb_id(struct fb_info *info);
 extern int fb_get_size(struct fb_info *info, int *w, int *h);
-extern int fb_sync(struct fb_info *info);
+extern int fb_sync(struct fb_info *info, int x, int y, int w, int h);
 extern int fb_size(struct fb_info *info);
 extern int fb_refcnt(void *data);
 extern int fb_is_created(struct fb_info *info);
index ee6f6a5..020fbd7 100644 (file)
@@ -670,12 +670,10 @@ static struct packet *master_dbox_updated(pid_t pid, int handle, const struct pa
        const char *safe_file;
        dynamicbox_h handler;
        struct dynamicbox_common *common;
-       int dbox_w;
-       int dbox_h;
        int ret;
 
-       ret = packet_get(packet, "ssssii", &pkgname, &id, &fbfile, &safe_file, &dbox_w, &dbox_h);
-       if (ret != 6) {
+       ret = packet_get(packet, "ssssiiii", &pkgname, &id, &fbfile, &safe_file, &common->dbox.last_damage.x, &common->dbox.last_damage.y, &common->dbox.last_damage.w, &common->dbox.last_damage.h);
+       if (ret != 8) {
                ErrPrint("Invalid argument\n");
                goto out;
        }
@@ -697,7 +695,6 @@ static struct packet *master_dbox_updated(pid_t pid, int handle, const struct pa
                goto out;
        }
 
-       dbox_set_size(common, dbox_w, dbox_h);
        dbox_set_filename(common, safe_file);
 
        if (dbox_text_dbox(common)) {
@@ -947,19 +944,17 @@ static struct packet *master_gbar_updated(pid_t pid, int handle, const struct pa
        dynamicbox_h handler;
        struct dynamicbox_common *common;
        struct dlist *l;
-       int gbar_w;
-       int gbar_h;
 
-       ret = packet_get(packet, "ssssii",
+       ret = packet_get(packet, "ssssiiii",
                                &pkgname, &id,
                                &descfile, &fbfile,
-                               &gbar_w, &gbar_h);
-       if (ret != 6) {
+                               &common->gbar.last_damage.x, &common->gbar.last_damage.y,
+                               &common->gbar.last_damage.w, &common->gbar.last_damage.h);
+       if (ret != 8) {
                ErrPrint("Invalid argument\n");
                goto out;
        }
 
-       DbgPrint("[%s]\n", pkgname);
        common = dbox_find_common_handle(pkgname, id);
        if (!common) {
                ErrPrint("Instance(%s) is not exists\n", id);
@@ -977,8 +972,6 @@ static struct packet *master_gbar_updated(pid_t pid, int handle, const struct pa
                goto out;
        }
 
-       dbox_set_gbarsize(common, gbar_w, gbar_h);
-
        if (dbox_text_gbar(common)) {
                (void)parse_desc(common, descfile, 1);
        } else {
index 9a38d9c..45bb84e 100644 (file)
@@ -3749,4 +3749,30 @@ EAPI int dynamicbox_set_auto_launch_handler(int (*dbox_launch_handler)(dynamicbo
        return DBOX_STATUS_ERROR_NONE;
 }
 
+EAPI int dynamicbox_damage_region_get(dynamicbox_h handler, int gbar, const dynamicbox_damage_region_t *region)
+{
+       if (!handler || handler->state != DBOX_STATE_CREATE) {
+               ErrPrint("Invalid handle\n");
+               return DBOX_STATUS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!handler->common || handler->common->state != DBOX_STATE_CREATE) {
+               ErrPrint("Invalid handle\n");
+               return DBOX_STATUS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!handler->common->id) {
+               ErrPrint("Handler is not valid[%p]\n", handler);
+               return DBOX_STATUS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (gbar) {
+               region = &handler->common->dbox.last_damage;
+       } else {
+               region = &handler->common->gbar.last_damage;
+       }
+
+       return DBOX_STATUS_ERROR_NONE;
+}
+
 /* End of a file */
index efd3188..26d7be1 100644 (file)
@@ -889,10 +889,10 @@ int dbox_sync_dbox_fb(struct dynamicbox_common *common)
 
        if (fb_type(dbox_get_dbox_fb(common)) == DBOX_FB_TYPE_FILE && common->dbox.lock_fd >= 0) {
                (void)dbox_fb_lock(common->dbox.lock_fd);
-               ret = fb_sync(dbox_get_dbox_fb(common));
+               ret = fb_sync(dbox_get_dbox_fb(common), common->dbox.last_damage.x, common->dbox.last_damage.y, common->dbox.last_damage.w, common->dbox.last_damage.h);
                (void)dbox_fb_unlock(common->dbox.lock_fd);
        } else {
-               ret = fb_sync(dbox_get_dbox_fb(common));
+               ret = fb_sync(dbox_get_dbox_fb(common), common->dbox.last_damage.x, common->dbox.last_damage.y, common->dbox.last_damage.w, common->dbox.last_damage.h);
        }
 
        return ret;
@@ -904,10 +904,10 @@ int dbox_sync_gbar_fb(struct dynamicbox_common *common)
 
        if (fb_type(dbox_get_gbar_fb(common)) == DBOX_FB_TYPE_FILE && common->gbar.lock_fd >= 0) {
                (void)dbox_fb_lock(common->gbar.lock_fd);
-               ret = fb_sync(dbox_get_gbar_fb(common));
+               ret = fb_sync(dbox_get_gbar_fb(common), common->gbar.last_damage.x, common->gbar.last_damage.y, common->gbar.last_damage.w, common->gbar.last_damage.h);
                (void)dbox_fb_unlock(common->gbar.lock_fd);
        } else {
-               ret = fb_sync(dbox_get_gbar_fb(common));
+               ret = fb_sync(dbox_get_gbar_fb(common), common->gbar.last_damage.x, common->gbar.last_damage.y, common->gbar.last_damage.w, common->gbar.last_damage.h);
        }
 
        return ret;
index fd1f915..041bf09 100644 (file)
--- a/src/fb.c
+++ b/src/fb.c
@@ -97,7 +97,7 @@ static inline void update_fb_size(struct fb_info *info)
        info->bufsz = info->w * info->h * info->pixels;
 }
 
-static int sync_for_file(struct fb_info *info)
+static int sync_for_file(struct fb_info *info, int x, int y, int w, int h)
 {
        int fd;
        dynamicbox_fb_t buffer;
@@ -123,8 +123,8 @@ static int sync_for_file(struct fb_info *info)
                ErrPrint("Failed to open a file (%s) because of (%s)\n",
                                        util_uri_to_path(info->id), strerror(errno));
 
-               /*!
-                * \note
+               /**
+                * @note
                 * But return ZERO, even if we couldn't get a buffer file,
                 * the viewer can draw empty screen.
                 *
@@ -133,20 +133,64 @@ static int sync_for_file(struct fb_info *info)
                return DBOX_STATUS_ERROR_NONE;
        }
 
-       if (read(fd, buffer->data, info->bufsz) != info->bufsz) {
-               ErrPrint("read: %s\n", strerror(errno));
-               if (close(fd) < 0) {
-                       ErrPrint("close: %s\n", strerror(errno));
+       /**
+        * @note
+        * Could we get some advantage if we load a part of file instead of loading all of them?
+        */
+       if (x != 0 || y != 0 || info->w != w || info->h != h) {
+               int iy;
+               register int index;
+               register int width;
+
+               for (iy = y; iy < h; iy++) {
+                       index = iy * info->w + x;
+                       width = w * info->pixels;
+
+                       if (lseek(fd, index * info->pixels, SEEK_SET) != index * info->pixels) {
+                               ErrPrint("lseek: %s\n", strerror(errno));
+                               if (close(fd) < 0) {
+                                       ErrPrint("close: %s\n", strerror(errno));
+                               }
+                               /**
+                                * @note
+                                * But return ZERO, even if we couldn't get a buffer file,
+                                * the viewer can draw empty screen.
+                                *
+                                * and then update it after it gots update events
+                                */
+                               return DBOX_STATUS_ERROR_NONE;
+                       }
+
+                       if (read(fd, ((unsigned int *)buffer->data) + index, width) != width) {
+                               if (close(fd) < 0) {
+                                       ErrPrint("close: %s\n", strerror(errno));
+                               }
+                               /**
+                                * @note
+                                * But return ZERO, even if we couldn't get a buffer file,
+                                * the viewer can draw empty screen.
+                                *
+                                * and then update it after it gots update events
+                                */
+                               return DBOX_STATUS_ERROR_NONE;
+                       }
                }
+       } else {
+               if (read(fd, buffer->data, info->bufsz) != info->bufsz) {
+                       ErrPrint("read: %s\n", strerror(errno));
+                       if (close(fd) < 0) {
+                               ErrPrint("close: %s\n", strerror(errno));
+                       }
 
-               /*!
-                * \note
-                * But return ZERO, even if we couldn't get a buffer file,
-                * the viewer can draw empty screen.
-                *
-                * and then update it after it gots update events
-                */
-               return DBOX_STATUS_ERROR_NONE;
+                       /**
+                        * @note
+                        * But return ZERO, even if we couldn't get a buffer file,
+                        * the viewer can draw empty screen.
+                        *
+                        * and then update it after it gots update events
+                        */
+                       return DBOX_STATUS_ERROR_NONE;
+               }
        }
 
        if (close(fd) < 0) {
@@ -155,7 +199,7 @@ static int sync_for_file(struct fb_info *info)
        return DBOX_STATUS_ERROR_NONE;
 }
 
-static int sync_for_pixmap(struct fb_info *info)
+static int sync_for_pixmap(struct fb_info *info, int x, int y, int w, int h)
 {
        dynamicbox_fb_t buffer;
        XShmSegmentInfo si;
@@ -251,7 +295,20 @@ static int sync_for_pixmap(struct fb_info *info)
        XShmGetImage(s_info.disp, info->handle, xim, 0, 0, 0xFFFFFFFF);
        XSync(s_info.disp, False);
 
-       memcpy(buffer->data, xim->data, info->bufsz);
+       if (x != 0 || y != 0 || info->w != w || info->h != h) {
+               int ix;
+               int iy;
+               register int index;
+
+               for (iy = y; iy < h; iy++) {
+                       for (ix = x; ix < w; ix++) {
+                               index = iy * info->w + x;
+                               *(((unsigned int *)buffer->data) + index) = *(((unsigned int *)xim->data) + index);
+                       }
+               }
+       } else {
+               memcpy(buffer->data, xim->data, info->bufsz);
+       }
 
        XShmDetach(s_info.disp, &si);
        XDestroyImage(xim);
@@ -267,7 +324,7 @@ static int sync_for_pixmap(struct fb_info *info)
        return DBOX_STATUS_ERROR_NONE;
 }
 
-int fb_sync(struct fb_info *info)
+int fb_sync(struct fb_info *info, int x, int y, int w, int h)
 {
        if (!info) {
                ErrPrint("FB Handle is not valid\n");
@@ -280,9 +337,9 @@ int fb_sync(struct fb_info *info)
        }
 
        if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) {
-               return sync_for_file(info);
+               return sync_for_file(info, x, y, w, h);
        } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
-               return sync_for_pixmap(info);
+               return sync_for_pixmap(info, x, y, w, h);
        } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) {
                /* No need to do sync */ 
                return DBOX_STATUS_ERROR_NONE;
@@ -404,7 +461,7 @@ void *fb_acquire_buffer(struct fb_info *info)
                         * \note
                         * Just update from here.
                         */
-                       sync_for_pixmap(info);
+                       sync_for_pixmap(info, 0, 0, info->w, info->h);
                } else if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) {
                        update_fb_size(info);
 
@@ -421,7 +478,7 @@ void *fb_acquire_buffer(struct fb_info *info)
                        buffer->info = info;
                        info->buffer = buffer;
 
-                       sync_for_file(info);
+                       sync_for_file(info, 0, 0, info->w, info->h);
                } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) {
                        buffer = shmat(info->handle, NULL, 0);
                        if (buffer == (void *)-1) {
index 88d3059..e90f769 100644 (file)
@@ -125,7 +125,7 @@ static inline int sync_for_file(struct fb_info *info)
        return DBOX_STATUS_ERROR_NONE;
 }
 
-int fb_sync(struct fb_info *info)
+int fb_sync(struct fb_info *info, int x, int y, int w, int h)
 {
        if (!info) {
                ErrPrint("FB Handle is not valid\n");