/src/ftk_display_mem.c

http://ftk.googlecode.com/ · C · 262 lines · 196 code · 36 blank · 30 comment · 33 complexity · 916d21a152566ba24bcfb2571da8dc9b MD5 · raw file

  1. /*
  2. * File: ftk_display_mem.c
  3. * Author: Li XianJing <xianjimli@hotmail.com>
  4. * Brief: memory based display.
  5. *
  6. * Copyright (c) 2009 - 2010 Li XianJing <xianjimli@hotmail.com>
  7. *
  8. * Licensed under the Academic Free License version 2.1
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. */
  24. /*
  25. * History:
  26. * ================================================================
  27. * 2010-03-21 Li XianJing <xianjimli@hotmail.com> from ftk_display_fb.c
  28. *
  29. */
  30. #include "ftk_log.h"
  31. #include "ftk_display_mem.h"
  32. typedef struct _DisplayMemPrivInfo
  33. {
  34. int bpp;
  35. int width;
  36. int height;
  37. void* bits;
  38. FtkDestroy on_destroy;
  39. void* on_destroy_ctx;
  40. FtkPixelFormat format;
  41. FtkBitmapCopyFromData copy_from_data;
  42. FtkBitmapCopyToData copy_to_data;
  43. FtkDisplaySync sync;
  44. void* sync_ctx;
  45. }PrivInfo;
  46. static Ret ftk_display_mem_update(FtkDisplay* thiz, FtkBitmap* bitmap, FtkRect* rect, int xoffset, int yoffset)
  47. {
  48. Ret ret = RET_OK;
  49. DECL_PRIV(thiz, priv);
  50. int display_width = priv->width;
  51. int display_height = priv->height;
  52. return_val_if_fail(priv != NULL, RET_FAIL);
  53. ftk_logd("%s: ox=%d oy=%d (%d %d %d %d)\n", __func__, xoffset, yoffset,
  54. rect->x, rect->y, rect->width, rect->height);
  55. ret = priv->copy_to_data(bitmap, rect,
  56. priv->bits, xoffset, yoffset, display_width, display_height);
  57. if(priv->sync != NULL && ret == RET_OK)
  58. {
  59. FtkRect r;
  60. r.x = xoffset;
  61. r.y = yoffset;
  62. r.width = rect->width;
  63. r.height = rect->height;
  64. priv->sync(priv->sync_ctx, &r);
  65. }
  66. return ret;
  67. }
  68. static int ftk_display_mem_width(FtkDisplay* thiz)
  69. {
  70. DECL_PRIV(thiz, priv);
  71. return_val_if_fail(priv != NULL, 0);
  72. return priv->width;
  73. }
  74. static int ftk_display_mem_height(FtkDisplay* thiz)
  75. {
  76. DECL_PRIV(thiz, priv);
  77. return_val_if_fail(priv != NULL, 0);
  78. return priv->height;
  79. }
  80. static Ret ftk_display_mem_snap(FtkDisplay* thiz, FtkRect* r, FtkBitmap* bitmap)
  81. {
  82. FtkRect rect = {0};
  83. DECL_PRIV(thiz, priv);
  84. int w = ftk_display_width(thiz);
  85. int h = ftk_display_height(thiz);
  86. int bw = ftk_bitmap_width(bitmap);
  87. int bh = ftk_bitmap_height(bitmap);
  88. return_val_if_fail(priv != NULL, RET_FAIL);
  89. rect.x = r->x;
  90. rect.y = r->y;
  91. rect.width = FTK_MIN(bw, r->width);
  92. rect.height = FTK_MIN(bh, r->height);
  93. return priv->copy_from_data(bitmap, priv->bits, w, h, &rect);
  94. }
  95. static void ftk_display_mem_destroy(FtkDisplay* thiz)
  96. {
  97. if(thiz != NULL)
  98. {
  99. DECL_PRIV(thiz, priv);
  100. if(priv->on_destroy != NULL)
  101. {
  102. priv->on_destroy(priv->on_destroy_ctx);
  103. }
  104. FTK_ZFREE(thiz, sizeof(FtkDisplay) + sizeof(PrivInfo));
  105. }
  106. return;
  107. }
  108. FtkDisplay* ftk_display_mem_create(FtkPixelFormat format,
  109. int width, int height, void* bits, FtkDestroy on_destroy, void* ctx)
  110. {
  111. FtkDisplay* thiz = NULL;
  112. thiz = (FtkDisplay*)FTK_ZALLOC(sizeof(FtkDisplay) + sizeof(PrivInfo));
  113. if(thiz != NULL)
  114. {
  115. DECL_PRIV(thiz, priv);
  116. thiz->update = ftk_display_mem_update;
  117. thiz->width = ftk_display_mem_width;
  118. thiz->height = ftk_display_mem_height;
  119. thiz->snap = ftk_display_mem_snap;
  120. thiz->destroy = ftk_display_mem_destroy;
  121. priv->bits = bits;
  122. priv->width = width;
  123. priv->height = height;
  124. priv->format = format;
  125. priv->on_destroy = on_destroy;
  126. priv->on_destroy_ctx = ctx;
  127. switch(format)
  128. {
  129. case FTK_PIXEL_RGB565:
  130. {
  131. priv->bpp = 2;
  132. priv->copy_to_data = ftk_bitmap_copy_to_data_rgb565;
  133. priv->copy_from_data = ftk_bitmap_copy_from_data_rgb565;
  134. break;
  135. }
  136. case FTK_PIXEL_BGR24:
  137. {
  138. priv->bpp = 3;
  139. priv->copy_to_data = ftk_bitmap_copy_to_data_bgr24;
  140. priv->copy_from_data = ftk_bitmap_copy_from_data_bgr24;
  141. break;
  142. }
  143. case FTK_PIXEL_BGRA32:
  144. {
  145. priv->bpp = 4;
  146. #ifdef WORDS_BIGENDIAN
  147. priv->copy_to_data = ftk_bitmap_copy_to_data_argb32;
  148. priv->copy_from_data = ftk_bitmap_copy_from_data_argb32;
  149. #else
  150. priv->copy_to_data = ftk_bitmap_copy_to_data_bgra32;
  151. priv->copy_from_data = ftk_bitmap_copy_from_data_bgra32;
  152. #endif
  153. break;
  154. }
  155. case FTK_PIXEL_RGBA32:
  156. {
  157. priv->bpp = 4;
  158. priv->copy_to_data = ftk_bitmap_copy_to_data_rgba32;
  159. priv->copy_from_data = ftk_bitmap_copy_from_data_rgba32;
  160. break;
  161. }
  162. default:
  163. {
  164. assert(!"not supported framebuffer format.");
  165. break;
  166. }
  167. }
  168. }
  169. return thiz;
  170. }
  171. Ret ftk_display_mem_set_sync_func(FtkDisplay* thiz, FtkDisplaySync sync, void* ctx)
  172. {
  173. DECL_PRIV(thiz, priv);
  174. return_val_if_fail(thiz != NULL && thiz->update == ftk_display_mem_update, RET_FAIL);
  175. priv->sync = sync;
  176. priv->sync_ctx = ctx;
  177. return RET_OK;
  178. }
  179. int ftk_display_mem_is_active(FtkDisplay* thiz)
  180. {
  181. return (thiz != NULL && thiz->update == ftk_display_mem_update);
  182. }
  183. FtkPixelFormat ftk_display_mem_get_pixel_format(FtkDisplay* thiz)
  184. {
  185. DECL_PRIV(thiz, priv);
  186. return priv != NULL ? priv->format : FTK_PIXEL_NONE;
  187. }
  188. Ret ftk_display_mem_update_directly(FtkDisplay* thiz, FtkPixelFormat format,
  189. void* bits, int width, int height, int xoffset, int yoffset)
  190. {
  191. int w = 0;
  192. int h = 0;
  193. char* src = NULL;
  194. char* dst = NULL;
  195. DECL_PRIV(thiz, priv);
  196. return_val_if_fail(bits != NULL, RET_FAIL);
  197. return_val_if_fail(ftk_display_mem_is_active(thiz), RET_FAIL);
  198. return_val_if_fail(xoffset < priv->width && yoffset < priv->height, RET_FAIL);
  199. w = (xoffset + width) < priv->width ? width : priv->width - xoffset;
  200. h = (yoffset + height) < priv->height ? height : priv->height - yoffset;
  201. if(format == priv->format)
  202. {
  203. src = (char*)bits;
  204. dst = (char*)priv->bits + priv->width * priv->bpp + xoffset;
  205. for(; h; h--)
  206. {
  207. memcpy(dst, src, priv->bpp * w);
  208. dst += priv->width * priv->bpp;
  209. src += width * priv->bpp;
  210. }
  211. }
  212. else
  213. {
  214. /*TODO*/
  215. assert(!"not supprted yet");
  216. }
  217. return RET_OK;
  218. }
  219. void* ftk_display_bits(FtkDisplay* thiz, int* bpp)
  220. {
  221. DECL_PRIV(thiz, priv);
  222. return_val_if_fail(thiz != NULL && priv != NULL && priv->bits != NULL, NULL);
  223. return_val_if_fail(bpp != NULL, NULL);
  224. *bpp = priv->bpp;
  225. return priv->bits;
  226. }