PageRenderTime 71ms CodeModel.GetById 37ms RepoModel.GetById 0ms app.codeStats 0ms

/exynos5/hal/libhwcomposer/SecHWC.cpp

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