PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/exynos4/hal/libhwcomposer/SecHWC.cpp

https://bitbucket.org/cyanogenmod/android_hardware_samsung
C++ | 957 lines | 781 code | 122 blank | 54 comment | 156 complexity | 7a939520ccca1f11c266c59eb2f5db7f MD5 | raw file
  1. /*
  2. * Copyright (C) 2010 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /*
  17. *
  18. * @author Rama, Meka(v.meka@samsung.com)
  19. Sangwoo, Park(sw5771.park@samsung.com)
  20. Jamie Oh (jung-min.oh@samsung.com)
  21. * @date 2011-03-11
  22. *
  23. */
  24. #include <cutils/log.h>
  25. #include <cutils/atomic.h>
  26. #include <EGL/egl.h>
  27. #include "SecHWCUtils.h"
  28. #include "gralloc_priv.h"
  29. #ifdef HWC_HWOVERLAY
  30. #include <GLES/gl.h>
  31. #endif
  32. #if defined(BOARD_USES_HDMI)
  33. #include "SecHdmiClient.h"
  34. #include "SecTVOutService.h"
  35. #include "SecHdmi.h"
  36. //#define CHECK_EGL_FPS
  37. #ifdef CHECK_EGL_FPS
  38. extern void check_fps();
  39. #endif
  40. static int lcd_width, lcd_height;
  41. static int prev_usage = 0;
  42. #define CHECK_TIME_DEBUG 0
  43. #define SUPPORT_AUTO_UI_ROTATE
  44. #endif
  45. int testRenderNum =0;
  46. static int hwc_device_open(const struct hw_module_t* module, const char* name,
  47. struct hw_device_t** device);
  48. static struct hw_module_methods_t hwc_module_methods = {
  49. open: hwc_device_open
  50. };
  51. hwc_module_t HAL_MODULE_INFO_SYM = {
  52. common: {
  53. tag: HARDWARE_MODULE_TAG,
  54. version_major: 1,
  55. version_minor: 0,
  56. id: HWC_HARDWARE_MODULE_ID,
  57. name: "Samsung S5PC21X hwcomposer module",
  58. author: "SAMSUNG",
  59. methods: &hwc_module_methods,
  60. }
  61. };
  62. /*****************************************************************************/
  63. static void dump_layer(hwc_layer_t const* l) {
  64. ALOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, "
  65. "{%d,%d,%d,%d}, {%d,%d,%d,%d}",
  66. l->compositionType, l->flags, l->handle, l->transform, l->blending,
  67. l->sourceCrop.left,
  68. l->sourceCrop.top,
  69. l->sourceCrop.right,
  70. l->sourceCrop.bottom,
  71. l->displayFrame.left,
  72. l->displayFrame.top,
  73. l->displayFrame.right,
  74. l->displayFrame.bottom);
  75. }
  76. void calculate_rect(struct hwc_win_info_t *win, hwc_layer_t *cur,
  77. sec_rect *rect)
  78. {
  79. rect->x = cur->displayFrame.left;
  80. rect->y = cur->displayFrame.top;
  81. rect->w = cur->displayFrame.right - cur->displayFrame.left;
  82. rect->h = cur->displayFrame.bottom - cur->displayFrame.top;
  83. if (rect->x < 0) {
  84. if (rect->w + rect->x > win->lcd_info.xres)
  85. rect->w = win->lcd_info.xres;
  86. else
  87. rect->w = rect->w + rect->x;
  88. rect->x = 0;
  89. } else {
  90. if (rect->w + rect->x > win->lcd_info.xres)
  91. rect->w = win->lcd_info.xres - rect->x;
  92. }
  93. if (rect->y < 0) {
  94. if (rect->h + rect->y > win->lcd_info.yres)
  95. rect->h = win->lcd_info.yres;
  96. else
  97. rect->h = rect->h + rect->y;
  98. rect->y = 0;
  99. } else {
  100. if (rect->h + rect->y > win->lcd_info.yres)
  101. rect->h = win->lcd_info.yres - rect->y;
  102. }
  103. }
  104. static int set_src_dst_img_rect(hwc_layer_t *cur,
  105. struct hwc_win_info_t *win,
  106. struct sec_img *src_img,
  107. struct sec_img *dst_img,
  108. struct sec_rect *src_rect,
  109. struct sec_rect *dst_rect,
  110. int win_idx)
  111. {
  112. private_handle_t *prev_handle = (private_handle_t *)(cur->handle);
  113. sec_rect rect;
  114. /* 1. Set src_img from prev_handle */
  115. src_img->f_w = prev_handle->width;
  116. src_img->f_h = prev_handle->height;
  117. src_img->w = prev_handle->width;
  118. src_img->h = prev_handle->height;
  119. src_img->format = prev_handle->format;
  120. src_img->base = (uint32_t)prev_handle->base;
  121. src_img->offset = prev_handle->offset;
  122. src_img->mem_id = prev_handle->fd;
  123. src_img->paddr = prev_handle->paddr;
  124. src_img->usage = prev_handle->usage;
  125. src_img->uoffset = prev_handle->uoffset;
  126. src_img->voffset = prev_handle->voffset;
  127. src_img->mem_type = HWC_VIRT_MEM_TYPE;
  128. switch (src_img->format) {
  129. case HAL_PIXEL_FORMAT_YV12: /* To support video editor */
  130. case HAL_PIXEL_FORMAT_YCbCr_420_P: /* To support SW codec */
  131. case HAL_PIXEL_FORMAT_YCrCb_420_SP:
  132. case HAL_PIXEL_FORMAT_YCbCr_420_SP:
  133. case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP:
  134. case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP:
  135. case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED:
  136. case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP:
  137. case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP:
  138. case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I:
  139. case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I:
  140. case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I:
  141. case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I:
  142. src_img->f_w = (src_img->f_w + 15) & ~15;
  143. src_img->f_h = (src_img->f_h + 1) & ~1;
  144. break;
  145. default:
  146. src_img->f_w = src_img->w;
  147. src_img->f_h = src_img->h;
  148. break;
  149. }
  150. /* 2. Set dst_img from window(lcd) */
  151. calculate_rect(win, cur, &rect);
  152. dst_img->f_w = win->lcd_info.xres;
  153. dst_img->f_h = win->lcd_info.yres;
  154. dst_img->w = rect.w;
  155. dst_img->h = rect.h;
  156. switch (win->lcd_info.bits_per_pixel) {
  157. case 32:
  158. dst_img->format = HAL_PIXEL_FORMAT_RGBX_8888;
  159. break;
  160. default:
  161. dst_img->format = HAL_PIXEL_FORMAT_RGB_565;
  162. break;
  163. }
  164. dst_img->base = win->addr[win->buf_index];
  165. dst_img->offset = 0;
  166. dst_img->mem_id = 0;
  167. dst_img->mem_type = HWC_PHYS_MEM_TYPE;
  168. /* 3. Set src_rect(crop rect) */
  169. if (cur->displayFrame.left < 0) {
  170. src_rect->x =
  171. (0 - cur->displayFrame.left)
  172. *(src_img->w)
  173. /(cur->displayFrame.right - cur->displayFrame.left + 1);
  174. if (cur->displayFrame.right + 1 > win->lcd_info.xres) {
  175. src_rect->w =
  176. (cur->sourceCrop.right - cur->sourceCrop.left + 1) -
  177. src_rect->x -
  178. (cur->displayFrame.right - win->lcd_info.xres)
  179. *(src_img->w)
  180. /(cur->displayFrame.right - cur->displayFrame.left + 1);
  181. } else {
  182. src_rect->w =
  183. (cur->sourceCrop.right - cur->sourceCrop.left + 1) -
  184. src_rect->x;
  185. }
  186. } else {
  187. src_rect->x = cur->sourceCrop.left;
  188. if (cur->displayFrame.right + 1 > win->lcd_info.xres) {
  189. src_rect->w =
  190. (cur->sourceCrop.right - cur->sourceCrop.left + 1) -
  191. src_rect->x -
  192. (cur->displayFrame.right - win->lcd_info.xres)
  193. *(src_img->w)
  194. /(cur->displayFrame.right - cur->displayFrame.left + 1);
  195. } else {
  196. src_rect->w =
  197. (cur->sourceCrop.right - cur->sourceCrop.left + 1);
  198. }
  199. }
  200. if (cur->displayFrame.top < 0) {
  201. src_rect->y =
  202. (0 - cur->displayFrame.top)
  203. *(src_img->h)
  204. /(cur->displayFrame.bottom - cur->displayFrame.top + 1);
  205. if (cur->displayFrame.bottom + 1 > win->lcd_info.yres) {
  206. src_rect->h =
  207. (cur->sourceCrop.bottom - cur->sourceCrop.top + 1) -
  208. src_rect->y -
  209. (cur->displayFrame.bottom - win->lcd_info.yres)
  210. *(src_img->h)
  211. /(cur->displayFrame.bottom - cur->displayFrame.top + 1);
  212. } else {
  213. src_rect->h =
  214. (cur->sourceCrop.bottom - cur->sourceCrop.top + 1) -
  215. src_rect->y;
  216. }
  217. } else {
  218. src_rect->y = cur->sourceCrop.top;
  219. if (cur->displayFrame.bottom + 1 > win->lcd_info.yres) {
  220. src_rect->h =
  221. (cur->sourceCrop.bottom - cur->sourceCrop.top + 1) -
  222. src_rect->y -
  223. (cur->displayFrame.bottom - win->lcd_info.yres)
  224. *(src_img->h)
  225. /(cur->displayFrame.bottom - cur->displayFrame.top + 1);
  226. } else {
  227. src_rect->h =
  228. (cur->sourceCrop.bottom - cur->sourceCrop.top + 1);
  229. }
  230. }
  231. SEC_HWC_Log(HWC_LOG_DEBUG,
  232. "crop information()::"
  233. "sourceCrop left(%d),top(%d),right(%d),bottom(%d),"
  234. "src_rect x(%d),y(%d),w(%d),h(%d),"
  235. "prev_handle w(%d),h(%d)",
  236. cur->sourceCrop.left,
  237. cur->sourceCrop.top,
  238. cur->sourceCrop.right,
  239. cur->sourceCrop.bottom,
  240. src_rect->x, src_rect->y, src_rect->w, src_rect->h,
  241. prev_handle->width, prev_handle->height);
  242. src_rect->x = SEC_MAX(src_rect->x, 0);
  243. src_rect->y = SEC_MAX(src_rect->y, 0);
  244. src_rect->w = SEC_MAX(src_rect->w, 0);
  245. src_rect->w = SEC_MIN(src_rect->w, prev_handle->width);
  246. src_rect->h = SEC_MAX(src_rect->h, 0);
  247. src_rect->h = SEC_MIN(src_rect->h, prev_handle->height);
  248. /* 4. Set dst_rect(fb or lcd)
  249. * fimc dst image will be stored from left top corner
  250. */
  251. dst_rect->x = 0;
  252. dst_rect->y = 0;
  253. dst_rect->w = win->rect_info.w;
  254. dst_rect->h = win->rect_info.h;
  255. /* Summery */
  256. SEC_HWC_Log(HWC_LOG_DEBUG,
  257. "set_src_dst_img_rect()::"
  258. "SRC w(%d),h(%d),f_w(%d),f_h(%d),fmt(0x%x),"
  259. "base(0x%x),offset(%d),paddr(0x%X),mem_id(%d),mem_type(%d)=>\r\n"
  260. " DST w(%d),h(%d),f(0x%x),base(0x%x),"
  261. "offset(%d),mem_id(%d),mem_type(%d),"
  262. "rot(%d),win_idx(%d)"
  263. " SRC_RECT x(%d),y(%d),w(%d),h(%d)=>"
  264. "DST_RECT x(%d),y(%d),w(%d),h(%d)",
  265. src_img->w, src_img->h, src_img->f_w, src_img->f_h, src_img->format,
  266. src_img->base, src_img->offset, src_img->paddr, src_img->mem_id, src_img->mem_type,
  267. dst_img->w, dst_img->h, dst_img->format, dst_img->base,
  268. dst_img->offset, dst_img->mem_id, dst_img->mem_type,
  269. cur->transform, win_idx,
  270. src_rect->x, src_rect->y, src_rect->w, src_rect->h,
  271. dst_rect->x, dst_rect->y, dst_rect->w, dst_rect->h);
  272. return 0;
  273. }
  274. static int get_hwc_compos_decision(hwc_layer_t* cur, int iter, int win_cnt)
  275. {
  276. if(cur->flags & HWC_SKIP_LAYER || !cur->handle) {
  277. SEC_HWC_Log(HWC_LOG_DEBUG, "%s::is_skip_layer %d cur->handle %x ",
  278. __func__, cur->flags & HWC_SKIP_LAYER, cur->handle);
  279. return HWC_FRAMEBUFFER;
  280. }
  281. private_handle_t *prev_handle = (private_handle_t *)(cur->handle);
  282. int compositionType = HWC_FRAMEBUFFER;
  283. if (iter == 0) {
  284. /* check here....if we have any resolution constraints */
  285. if (((cur->sourceCrop.right - cur->sourceCrop.left + 1) < 16) ||
  286. ((cur->sourceCrop.bottom - cur->sourceCrop.top + 1) < 8))
  287. return compositionType;
  288. if ((cur->transform == HAL_TRANSFORM_ROT_90) ||
  289. (cur->transform == HAL_TRANSFORM_ROT_270)) {
  290. if (((cur->displayFrame.right - cur->displayFrame.left + 1) < 4) ||
  291. ((cur->displayFrame.bottom - cur->displayFrame.top + 1) < 8))
  292. return compositionType;
  293. } else if (((cur->displayFrame.right - cur->displayFrame.left + 1) < 8) ||
  294. ((cur->displayFrame.bottom - cur->displayFrame.top + 1) < 4)) {
  295. return compositionType;
  296. }
  297. switch (prev_handle->format) {
  298. case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP:
  299. case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP:
  300. case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED:
  301. compositionType = HWC_OVERLAY;
  302. break;
  303. case HAL_PIXEL_FORMAT_YV12: /* YCrCb_420_P */
  304. case HAL_PIXEL_FORMAT_YCbCr_420_P:
  305. case HAL_PIXEL_FORMAT_YCrCb_420_SP:
  306. case HAL_PIXEL_FORMAT_YCbCr_420_SP:
  307. if ((prev_handle->usage & GRALLOC_USAGE_HWC_HWOVERLAY) &&
  308. (cur->blending == HWC_BLENDING_NONE))
  309. compositionType = HWC_OVERLAY;
  310. else
  311. compositionType = HWC_FRAMEBUFFER;
  312. break;
  313. default:
  314. compositionType = HWC_FRAMEBUFFER;
  315. break;
  316. }
  317. }
  318. #ifdef SUB_TITLES_HWC
  319. else if ((win_cnt > 0) &&
  320. (prev_handle->usage & GRALLOC_USAGE_EXTERNAL_DISP)) {
  321. switch (prev_handle->format) {
  322. case HAL_PIXEL_FORMAT_RGBA_8888:
  323. case HAL_PIXEL_FORMAT_RGBX_8888:
  324. case HAL_PIXEL_FORMAT_BGRA_8888:
  325. case HAL_PIXEL_FORMAT_RGB_888:
  326. case HAL_PIXEL_FORMAT_RGB_565:
  327. case HAL_PIXEL_FORMAT_RGBA_5551:
  328. case HAL_PIXEL_FORMAT_RGBA_4444:
  329. compositionType = HWC_OVERLAY;
  330. break;
  331. default:
  332. compositionType = HWC_FRAMEBUFFER;
  333. break;
  334. }
  335. SEC_HWC_Log(HWC_LOG_DEBUG, "2nd iter###%s:: compositionType %d bpp %d"
  336. " format %x src[%d %d %d %d] dst[%d %d %d %d] srcImg[%d %d]",
  337. __func__, compositionType, prev_handle->bpp,
  338. prev_handle->format,
  339. cur->sourceCrop.left, cur->sourceCrop.right,
  340. cur->sourceCrop.top, cur->sourceCrop.bottom,
  341. cur->displayFrame.left, cur->displayFrame.right,
  342. cur->displayFrame.top, cur->displayFrame.bottom,
  343. prev_handle->width, prev_handle->height);
  344. }
  345. #endif
  346. SEC_HWC_Log(HWC_LOG_DEBUG,
  347. "%s::compositionType(%d)=>0:FB,1:OVERLAY \r\n"
  348. " format(0x%x),magic(0x%x),flags(%d),size(%d),offset(%d)"
  349. "b_addr(0x%x),usage(%d),w(%d),h(%d),bpp(%d)",
  350. "get_hwc_compos_decision()", compositionType,
  351. prev_handle->format, prev_handle->magic, prev_handle->flags,
  352. prev_handle->size, prev_handle->offset, prev_handle->base,
  353. prev_handle->usage, prev_handle->width, prev_handle->height,
  354. prev_handle->bpp);
  355. return compositionType;
  356. }
  357. static void reset_win_rect_info(hwc_win_info_t *win)
  358. {
  359. win->rect_info.x = 0;
  360. win->rect_info.y = 0;
  361. win->rect_info.w = 0;
  362. win->rect_info.h = 0;
  363. return;
  364. }
  365. static int assign_overlay_window(struct hwc_context_t *ctx, hwc_layer_t *cur,
  366. int win_idx, int layer_idx)
  367. {
  368. struct hwc_win_info_t *win;
  369. sec_rect rect;
  370. int ret = 0;
  371. if (NUM_OF_WIN <= win_idx)
  372. return -1;
  373. win = &ctx->win[win_idx];
  374. SEC_HWC_Log(HWC_LOG_DEBUG,
  375. "%s:: left(%d),top(%d),right(%d),bottom(%d),transform(%d)"
  376. "lcd_info.xres(%d),lcd_info.yres(%d)",
  377. "++assign_overlay_window()",
  378. cur->displayFrame.left, cur->displayFrame.top,
  379. cur->displayFrame.right, cur->displayFrame.bottom, cur->transform,
  380. win->lcd_info.xres, win->lcd_info.yres);
  381. calculate_rect(win, cur, &rect);
  382. if ((rect.x != win->rect_info.x) || (rect.y != win->rect_info.y) ||
  383. (rect.w != win->rect_info.w) || (rect.h != win->rect_info.h)){
  384. win->rect_info.x = rect.x;
  385. win->rect_info.y = rect.y;
  386. win->rect_info.w = rect.w;
  387. win->rect_info.h = rect.h;
  388. //turnoff the window and set the window position with new conf...
  389. if (window_set_pos(win) < 0) {
  390. SEC_HWC_Log(HWC_LOG_ERROR, "%s::window_set_pos is failed : %s",
  391. __func__, strerror(errno));
  392. ret = -1;
  393. }
  394. ctx->layer_prev_buf[win_idx] = 0;
  395. }
  396. win->layer_index = layer_idx;
  397. win->status = HWC_WIN_RESERVED;
  398. SEC_HWC_Log(HWC_LOG_DEBUG,
  399. "%s:: win_x %d win_y %d win_w %d win_h %d lay_idx %d win_idx %d\n",
  400. "--assign_overlay_window()",
  401. win->rect_info.x, win->rect_info.y, win->rect_info.w,
  402. win->rect_info.h, win->layer_index, win_idx );
  403. return 0;
  404. }
  405. static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
  406. {
  407. struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
  408. int overlay_win_cnt = 0;
  409. int compositionType = 0;
  410. int ret;
  411. //if geometry is not changed, there is no need to do any work here
  412. if (!list || (!(list->flags & HWC_GEOMETRY_CHANGED)))
  413. return 0;
  414. //all the windows are free here....
  415. for (int i = 0 ; i < NUM_OF_WIN; i++) {
  416. ctx->win[i].status = HWC_WIN_FREE;
  417. ctx->win[i].buf_index = 0;
  418. }
  419. ctx->num_of_hwc_layer = 0;
  420. ctx->num_of_fb_layer = 0;
  421. ctx->num_2d_blit_layer = 0;
  422. for (int i = 0; i < list->numHwLayers ; i++) {
  423. hwc_layer_t* cur = &list->hwLayers[i];
  424. if (overlay_win_cnt < NUM_OF_WIN) {
  425. compositionType = get_hwc_compos_decision(cur, 0, overlay_win_cnt);
  426. if (compositionType == HWC_FRAMEBUFFER) {
  427. cur->compositionType = HWC_FRAMEBUFFER;
  428. ctx->num_of_fb_layer++;
  429. } else {
  430. ret = assign_overlay_window(ctx, cur, overlay_win_cnt, i);
  431. if (ret != 0) {
  432. ALOGE("assign_overlay_window fail, change to frambuffer");
  433. cur->compositionType = HWC_FRAMEBUFFER;
  434. ctx->num_of_fb_layer++;
  435. continue;
  436. }
  437. cur->compositionType = HWC_OVERLAY;
  438. cur->hints = HWC_HINT_CLEAR_FB;
  439. overlay_win_cnt++;
  440. ctx->num_of_hwc_layer++;
  441. }
  442. } else {
  443. cur->compositionType = HWC_FRAMEBUFFER;
  444. ctx->num_of_fb_layer++;
  445. }
  446. }
  447. #ifdef SUB_TITLES_HWC
  448. for (int i = 0; i < list->numHwLayers ; i++) {
  449. if (overlay_win_cnt < NUM_OF_WIN) {
  450. hwc_layer_t* cur = &list->hwLayers[i];
  451. if (get_hwc_compos_decision(cur, 1, overlay_win_cnt) == HWC_OVERLAY) {
  452. ret = assign_overlay_window(ctx, cur, overlay_win_cnt, i);
  453. if (ret == 0) {
  454. cur->compositionType = HWC_OVERLAY;
  455. cur->hints = HWC_HINT_CLEAR_FB;
  456. overlay_win_cnt++;
  457. ctx->num_of_hwc_layer++;
  458. ctx->num_of_fb_layer--;
  459. ctx->num_2d_blit_layer = 1;
  460. }
  461. }
  462. }
  463. else
  464. break;
  465. }
  466. #endif
  467. #if defined(BOARD_USES_HDMI)
  468. android::SecHdmiClient *mHdmiClient = android::SecHdmiClient::getInstance();
  469. mHdmiClient->setHdmiHwcLayer(ctx->num_of_hwc_layer);
  470. #endif
  471. if (list->numHwLayers != (ctx->num_of_fb_layer + ctx->num_of_hwc_layer))
  472. SEC_HWC_Log(HWC_LOG_DEBUG,
  473. "%s:: numHwLayers %d num_of_fb_layer %d num_of_hwc_layer %d ",
  474. __func__, list->numHwLayers, ctx->num_of_fb_layer,
  475. ctx->num_of_hwc_layer);
  476. if (overlay_win_cnt < NUM_OF_WIN) {
  477. //turn off the free windows
  478. for (int i = overlay_win_cnt; i < NUM_OF_WIN; i++) {
  479. window_hide(&ctx->win[i]);
  480. reset_win_rect_info(&ctx->win[i]);
  481. }
  482. }
  483. return 0;
  484. }
  485. static int hwc_set(hwc_composer_device_t *dev,
  486. hwc_display_t dpy,
  487. hwc_surface_t sur,
  488. hwc_layer_list_t* list)
  489. {
  490. struct hwc_context_t *ctx = (struct hwc_context_t *)dev;
  491. int skipped_window_mask = 0;
  492. hwc_layer_t* cur;
  493. struct hwc_win_info_t *win;
  494. int ret;
  495. int pmem_phyaddr;
  496. static int egl_check;
  497. int egl_run = 0;
  498. struct sec_img src_img;
  499. struct sec_img dst_img;
  500. struct sec_rect src_work_rect;
  501. struct sec_rect dst_work_rect;
  502. memset(&src_img, 0, sizeof(src_img));
  503. memset(&dst_img, 0, sizeof(dst_img));
  504. memset(&src_work_rect, 0, sizeof(src_work_rect));
  505. memset(&dst_work_rect, 0, sizeof(dst_work_rect));
  506. #if defined(BOARD_USES_HDMI)
  507. int skip_hdmi_rendering = 0;
  508. int rotVal = 0;
  509. #endif
  510. if (!list) {
  511. //turn off the all windows
  512. for (int i = 0; i < NUM_OF_WIN; i++) {
  513. window_hide(&ctx->win[i]);
  514. reset_win_rect_info(&ctx->win[i]);
  515. ctx->win[i].status = HWC_WIN_FREE;
  516. }
  517. ctx->num_of_hwc_layer = 0;
  518. if (sur == NULL && dpy == NULL)
  519. return HWC_EGL_ERROR;
  520. }
  521. if(ctx->num_of_hwc_layer > NUM_OF_WIN)
  522. ctx->num_of_hwc_layer = NUM_OF_WIN;
  523. //compose hardware layers here
  524. for (int i = 0; i < ctx->num_of_hwc_layer - ctx->num_2d_blit_layer; i++) {
  525. win = &ctx->win[i];
  526. if (win->status == HWC_WIN_RESERVED) {
  527. cur = &list->hwLayers[win->layer_index];
  528. if (cur->compositionType == HWC_OVERLAY) {
  529. if (ctx->layer_prev_buf[i] == (uint32_t)cur->handle) {
  530. /*
  531. * In android platform, all the graphic buffer are at least
  532. * double buffered (2 or more) this buffer is already rendered.
  533. * It is the redundant src buffer for FIMC rendering.
  534. */
  535. ALOGD("SKIP FIMC rendering for Layer%d", win->layer_index);
  536. #if defined(BOARD_USES_HDMI)
  537. skip_hdmi_rendering = 1;
  538. #endif
  539. continue;
  540. }
  541. ctx->layer_prev_buf[i] = (uint32_t)cur->handle;
  542. // initialize the src & dist context for fimc
  543. set_src_dst_img_rect(cur, win, &src_img, &dst_img,
  544. &src_work_rect, &dst_work_rect, i);
  545. ret = runFimc(ctx,
  546. &src_img, &src_work_rect,
  547. &dst_img, &dst_work_rect,
  548. cur->transform);
  549. if (ret < 0) {
  550. SEC_HWC_Log(HWC_LOG_ERROR, "%s::runFimc fail : ret=%d\n",
  551. __func__, ret);
  552. skipped_window_mask |= (1 << i);
  553. continue;
  554. }
  555. window_pan_display(win);
  556. win->buf_index = (win->buf_index + 1) % NUM_OF_WIN_BUF;
  557. if (win->power_state == 0)
  558. window_show(win);
  559. } else {
  560. SEC_HWC_Log(HWC_LOG_ERROR,
  561. "%s:: error : layer %d compositionType should have been"
  562. " HWC_OVERLAY ", __func__, win->layer_index);
  563. skipped_window_mask |= (1 << i);
  564. continue;
  565. }
  566. } else {
  567. SEC_HWC_Log(HWC_LOG_ERROR, "%s:: error : window status should have "
  568. "been HWC_WIN_RESERVED by now... ", __func__);
  569. skipped_window_mask |= (1 << i);
  570. continue;
  571. }
  572. }
  573. #ifdef SUB_TITLES_HWC
  574. if (ctx->num_2d_blit_layer) {
  575. g2d_rect srcRect;
  576. g2d_rect dstRect;
  577. win = &ctx->win[ctx->num_of_hwc_layer - 1];
  578. cur = &list->hwLayers[win->layer_index];
  579. set_src_dst_g2d_rect(cur, win, &srcRect, &dstRect);
  580. ret = runG2d(ctx, &srcRect, &dstRect,
  581. cur->transform);
  582. if (ret < 0) {
  583. SEC_HWC_Log(HWC_LOG_ERROR, "%s::runG2d fail : ret=%d\n",
  584. __func__, ret);
  585. skipped_window_mask |= (1 << (ctx->num_of_hwc_layer - 1));
  586. goto g2d_error;
  587. }
  588. window_pan_display(win);
  589. win->buf_index = (win->buf_index + 1) % NUM_OF_WIN_BUF;
  590. if (win->power_state == 0)
  591. window_show(win);
  592. }
  593. g2d_error:
  594. #endif
  595. if (skipped_window_mask) {
  596. //turn off the free windows
  597. for (int i = 0; i < NUM_OF_WIN; i++) {
  598. if (skipped_window_mask & (1 << i)) {
  599. window_hide(&ctx->win[i]);
  600. reset_win_rect_info(&ctx->win[i]);
  601. }
  602. }
  603. }
  604. if (0 < ctx->num_of_fb_layer) {
  605. #ifdef CHECK_EGL_FPS
  606. check_fps();
  607. #endif
  608. #ifdef HWC_HWOVERLAY
  609. unsigned char pixels[4];
  610. glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
  611. #endif
  612. egl_check = 1;
  613. egl_run = 1;
  614. } else {
  615. if (egl_check == 1) {
  616. egl_check = 0;
  617. egl_run = 1;
  618. }
  619. }
  620. if (egl_run == 1) {
  621. EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur);
  622. if (!sucess)
  623. return HWC_EGL_ERROR;
  624. }
  625. #if defined(BOARD_USES_HDMI)
  626. android::SecHdmiClient *mHdmiClient = android::SecHdmiClient::getInstance();
  627. if (skip_hdmi_rendering == 1)
  628. return 0;
  629. if (list == NULL) {
  630. // Don't display unnecessary image
  631. mHdmiClient->setHdmiEnable(0);
  632. return 0;
  633. } else {
  634. mHdmiClient->setHdmiEnable(1);
  635. }
  636. #ifdef SUPPORT_AUTO_UI_ROTATE
  637. cur = &list->hwLayers[0];
  638. if (cur->transform == HAL_TRANSFORM_ROT_90 || cur->transform == HAL_TRANSFORM_ROT_270)
  639. mHdmiClient->setHdmiRotate(270, ctx->num_of_hwc_layer);
  640. else
  641. mHdmiClient->setHdmiRotate(0, ctx->num_of_hwc_layer);
  642. #endif
  643. // To support S3D video playback (automatic TV mode change to 3D mode)
  644. if (ctx->num_of_hwc_layer == 1) {
  645. if (src_img.usage != prev_usage)
  646. mHdmiClient->setHdmiResolution(DEFAULT_HDMI_RESOLUTION_VALUE); // V4L2_STD_1080P_60
  647. if ((src_img.usage & GRALLOC_USAGE_PRIVATE_SBS_LR) ||
  648. (src_img.usage & GRALLOC_USAGE_PRIVATE_SBS_RL))
  649. mHdmiClient->setHdmiResolution(7209601); // V4L2_STD_TVOUT_720P_60_SBS_HALF
  650. else if ((src_img.usage & GRALLOC_USAGE_PRIVATE_TB_LR) ||
  651. (src_img.usage & GRALLOC_USAGE_PRIVATE_TB_RL))
  652. mHdmiClient->setHdmiResolution(1080924); // V4L2_STD_TVOUT_1080P_24_TB
  653. prev_usage = src_img.usage;
  654. } else {
  655. if ((prev_usage & GRALLOC_USAGE_PRIVATE_SBS_LR) ||
  656. (prev_usage & GRALLOC_USAGE_PRIVATE_SBS_RL) ||
  657. (prev_usage & GRALLOC_USAGE_PRIVATE_TB_LR) ||
  658. (prev_usage & GRALLOC_USAGE_PRIVATE_TB_RL))
  659. mHdmiClient->setHdmiResolution(DEFAULT_HDMI_RESOLUTION_VALUE); // V4L2_STD_1080P_60
  660. prev_usage = 0;
  661. }
  662. if (ctx->num_of_hwc_layer == 1) {
  663. if ((src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED)||
  664. (src_img.format == HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP)) {
  665. ADDRS * addr = (ADDRS *)(src_img.base);
  666. mHdmiClient->blit2Hdmi(src_img.w, src_img.h,
  667. src_img.format,
  668. (unsigned int)addr->addr_y, (unsigned int)addr->addr_cbcr, (unsigned int)addr->addr_cbcr,
  669. 0, 0,
  670. android::SecHdmiClient::HDMI_MODE_VIDEO,
  671. ctx->num_of_hwc_layer);
  672. } else if ((src_img.format == HAL_PIXEL_FORMAT_YCbCr_420_SP) ||
  673. (src_img.format == HAL_PIXEL_FORMAT_YCrCb_420_SP) ||
  674. (src_img.format == HAL_PIXEL_FORMAT_YCbCr_420_P) ||
  675. (src_img.format == HAL_PIXEL_FORMAT_YV12)) {
  676. mHdmiClient->blit2Hdmi(src_img.w, src_img.h,
  677. src_img.format,
  678. (unsigned int)ctx->fimc.params.src.buf_addr_phy_rgb_y,
  679. (unsigned int)ctx->fimc.params.src.buf_addr_phy_cb,
  680. (unsigned int)ctx->fimc.params.src.buf_addr_phy_cr,
  681. 0, 0,
  682. android::SecHdmiClient::HDMI_MODE_VIDEO,
  683. ctx->num_of_hwc_layer);
  684. } else {
  685. ALOGE("%s: Unsupported format = %d", __func__, src_img.format);
  686. }
  687. }
  688. #endif
  689. return 0;
  690. }
  691. static int hwc_device_close(struct hw_device_t *dev)
  692. {
  693. struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
  694. int ret = 0;
  695. int i;
  696. if (ctx) {
  697. if (destroyFimc(&ctx->fimc) < 0) {
  698. SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyFimc fail", __func__);
  699. ret = -1;
  700. }
  701. #ifdef SUB_TITLES_HWC
  702. if (destroyG2d(&ctx->g2d) < 0) {
  703. SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyG2d() fail", __func__);
  704. ret = -1;
  705. }
  706. #endif
  707. if (destroyMem(&ctx->s3c_mem) < 0) {
  708. SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyMem fail", __func__);
  709. ret = -1;
  710. }
  711. #ifdef USE_HW_PMEM
  712. if (destroyPmem(&ctx->sec_pmem) < 0) {
  713. SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyPmem fail", __func__);
  714. ret = -1;
  715. }
  716. #endif
  717. for (i = 0; i < NUM_OF_WIN; i++) {
  718. if (window_close(&ctx->win[i]) < 0)
  719. SEC_HWC_Log(HWC_LOG_DEBUG, "%s::window_close() fail", __func__);
  720. }
  721. free(ctx);
  722. }
  723. return ret;
  724. }
  725. static int hwc_device_open(const struct hw_module_t* module, const char* name,
  726. struct hw_device_t** device)
  727. {
  728. int status = 0;
  729. struct hwc_win_info_t *win;
  730. if (strcmp(name, HWC_HARDWARE_COMPOSER))
  731. return -EINVAL;
  732. struct hwc_context_t *dev;
  733. dev = (hwc_context_t*)malloc(sizeof(*dev));
  734. /* initialize our state here */
  735. memset(dev, 0, sizeof(*dev));
  736. /* initialize the procs */
  737. dev->device.common.tag = HARDWARE_DEVICE_TAG;
  738. dev->device.common.version = 0;
  739. dev->device.common.module = const_cast<hw_module_t*>(module);
  740. dev->device.common.close = hwc_device_close;
  741. dev->device.prepare = hwc_prepare;
  742. dev->device.set = hwc_set;
  743. *device = &dev->device.common;
  744. //initializing
  745. memset(&(dev->fimc), 0, sizeof(s5p_fimc_t));
  746. memset(&(dev->s3c_mem), 0, sizeof(struct s3c_mem_t));
  747. #ifdef USE_HW_PMEM
  748. memset(&(dev->sec_pmem), 0, sizeof(sec_pmem_t));
  749. #endif
  750. /* open WIN0 & WIN1 here */
  751. for (int i = 0; i < NUM_OF_WIN; i++) {
  752. if (window_open(&(dev->win[i]), i) < 0) {
  753. SEC_HWC_Log(HWC_LOG_ERROR,
  754. "%s:: Failed to open window %d device ", __func__, i);
  755. status = -EINVAL;
  756. goto err;
  757. }
  758. }
  759. if (window_get_global_lcd_info(dev->win[0].fd, &dev->lcd_info) < 0) {
  760. SEC_HWC_Log(HWC_LOG_ERROR,
  761. "%s::window_get_global_lcd_info is failed : %s",
  762. __func__, strerror(errno));
  763. status = -EINVAL;
  764. goto err;
  765. }
  766. #if defined(BOARD_USES_HDMI)
  767. lcd_width = dev->lcd_info.xres;
  768. lcd_height = dev->lcd_info.yres;
  769. #endif
  770. /* initialize the window context */
  771. for (int i = 0; i < NUM_OF_WIN; i++) {
  772. win = &dev->win[i];
  773. memcpy(&win->lcd_info, &dev->lcd_info, sizeof(struct fb_var_screeninfo));
  774. memcpy(&win->var_info, &dev->lcd_info, sizeof(struct fb_var_screeninfo));
  775. win->rect_info.x = 0;
  776. win->rect_info.y = 0;
  777. win->rect_info.w = win->var_info.xres;
  778. win->rect_info.h = win->var_info.yres;
  779. if (window_set_pos(win) < 0) {
  780. SEC_HWC_Log(HWC_LOG_ERROR, "%s::window_set_pos is failed : %s",
  781. __func__, strerror(errno));
  782. status = -EINVAL;
  783. goto err;
  784. }
  785. if (window_get_info(win, i) < 0) {
  786. SEC_HWC_Log(HWC_LOG_ERROR, "%s::window_get_info is failed : %s",
  787. __func__, strerror(errno));
  788. status = -EINVAL;
  789. goto err;
  790. }
  791. }
  792. #ifdef USE_HW_PMEM
  793. if (createPmem(&dev->sec_pmem, PMEM_SIZE) < 0) {
  794. SEC_HWC_Log(HWC_LOG_ERROR, "%s::initPmem(%d) fail", __func__, PMEM_SIZE);
  795. }
  796. #endif
  797. if (createMem(&dev->s3c_mem, 0, 0) < 0) {
  798. SEC_HWC_Log(HWC_LOG_ERROR, "%s::createMem() fail (size=0)", __func__);
  799. status = -EINVAL;
  800. goto err;
  801. }
  802. //create PP
  803. if (createFimc(&dev->fimc) < 0) {
  804. SEC_HWC_Log(HWC_LOG_ERROR, "%s::creatFimc() fail", __func__);
  805. status = -EINVAL;
  806. goto err;
  807. }
  808. #ifdef SUB_TITLES_HWC
  809. if (createG2d(&dev->g2d) < 0) {
  810. SEC_HWC_Log(HWC_LOG_ERROR, "%s::createG2d() fail", __func__);
  811. status = -EINVAL;
  812. goto err;
  813. }
  814. #endif
  815. SEC_HWC_Log(HWC_LOG_DEBUG, "%s:: hwc_device_open: SUCCESS", __func__);
  816. return 0;
  817. err:
  818. if (destroyFimc(&dev->fimc) < 0)
  819. SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyFimc() fail", __func__);
  820. #ifdef SUB_TITLES_HWC
  821. if (destroyG2d(&dev->g2d) < 0)
  822. SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyG2d() fail", __func__);
  823. #endif
  824. if (destroyMem(&dev->s3c_mem) < 0)
  825. SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyMem() fail", __func__);
  826. #ifdef USE_HW_PMEM
  827. if (destroyPmem(&dev->sec_pmem) < 0)
  828. SEC_HWC_Log(HWC_LOG_ERROR, "%s::destroyPmem() fail", __func__);
  829. #endif
  830. for (int i = 0; i < NUM_OF_WIN; i++) {
  831. if (window_close(&dev->win[i]) < 0)
  832. SEC_HWC_Log(HWC_LOG_DEBUG, "%s::window_close() fail", __func__);
  833. }
  834. return status;
  835. }