PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/libhwcomposer/SecHWCUtils.cpp

https://bitbucket.org/bigxie/android_device_samsung_crespo
C++ | 890 lines | 658 code | 150 blank | 82 comment | 90 complexity | 515765e624b7f7c0c90caa7cad80b40e MD5 | raw file
Possible License(s): LGPL-2.0
  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-07-28
  22. *
  23. */
  24. #include "SecHWCUtils.h"
  25. int window_open(struct hwc_win_info_t *win, int id)
  26. {
  27. char name[64];
  28. char const * const device_template = "/dev/graphics/fb%u";
  29. /* window & FB maping
  30. fb0 -> win-id : 2
  31. fb1 -> win-id : 3
  32. fb2 -> win-id : 4
  33. fb3 -> win-id : 0
  34. fb4 -> win_id : 1
  35. it is pre assumed that ...win0 or win1 is used here..
  36. */
  37. switch (id) {
  38. case 0:
  39. case 1:
  40. case 2:
  41. break;
  42. default:
  43. LOGE("%s::id(%d) is weird", __func__, id);
  44. goto error;
  45. }
  46. snprintf(name, 64, device_template, (id + 3)%5);
  47. win->fd = open(name, O_RDWR);
  48. if (win->fd < 0) {
  49. LOGE("%s::Failed to open window device (%s) : %s",
  50. __func__, strerror(errno), device_template);
  51. goto error;
  52. }
  53. return 0;
  54. error:
  55. if (0 <= win->fd)
  56. close(win->fd);
  57. win->fd = -1;
  58. return -1;
  59. }
  60. int window_close(struct hwc_win_info_t *win)
  61. {
  62. int ret = 0;
  63. if (0 <= win->fd)
  64. ret = close(win->fd);
  65. win->fd = -1;
  66. return ret;
  67. }
  68. int window_set_pos(struct hwc_win_info_t *win)
  69. {
  70. struct secfb_user_window window;
  71. /* before changing the screen configuration...powerdown the window */
  72. if(window_hide(win) != 0)
  73. return -1;
  74. win->var_info.xres = win->rect_info.w;
  75. win->var_info.yres = win->rect_info.h;
  76. win->var_info.activate &= ~FB_ACTIVATE_MASK;
  77. win->var_info.activate |= FB_ACTIVATE_FORCE;
  78. if (ioctl(win->fd, FBIOPUT_VSCREENINFO, &(win->var_info)) < 0) {
  79. LOGE("%s::FBIOPUT_VSCREENINFO(%d, %d) fail",
  80. __func__, win->rect_info.w, win->rect_info.h);
  81. return -1;
  82. }
  83. window.x = win->rect_info.x;
  84. window.y = win->rect_info.y;
  85. if (ioctl(win->fd, SECFB_WIN_POSITION, &window) < 0) {
  86. LOGE("%s::S3CFB_WIN_POSITION(%d, %d) fail",
  87. __func__, window.x, window.y);
  88. return -1;
  89. }
  90. return 0;
  91. }
  92. int window_get_info(struct hwc_win_info_t *win)
  93. {
  94. if (ioctl(win->fd, FBIOGET_FSCREENINFO, &win->fix_info) < 0) {
  95. LOGE("FBIOGET_FSCREENINFO failed : %s", strerror(errno));
  96. goto error;
  97. }
  98. return 0;
  99. error:
  100. win->fix_info.smem_start = 0;
  101. return -1;
  102. }
  103. int window_pan_display(struct hwc_win_info_t *win)
  104. {
  105. struct fb_var_screeninfo *lcd_info = &(win->lcd_info);
  106. lcd_info->yoffset = lcd_info->yres * win->buf_index;
  107. if (ioctl(win->fd, FBIOPAN_DISPLAY, lcd_info) < 0) {
  108. LOGE("%s::FBIOPAN_DISPLAY(%d / %d / %d) fail(%s)",
  109. __func__, lcd_info->yres, win->buf_index, lcd_info->yres_virtual,
  110. strerror(errno));
  111. return -1;
  112. }
  113. return 0;
  114. }
  115. int window_show(struct hwc_win_info_t *win)
  116. {
  117. if(win->power_state == 0) {
  118. if (ioctl(win->fd, FBIOBLANK, FB_BLANK_UNBLANK) < 0) {
  119. LOGE("%s: FBIOBLANK failed : (%d:%s)", __func__, win->fd,
  120. strerror(errno));
  121. return -1;
  122. }
  123. win->power_state = 1;
  124. }
  125. return 0;
  126. }
  127. int window_hide(struct hwc_win_info_t *win)
  128. {
  129. if (win->power_state == 1) {
  130. if (ioctl(win->fd, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) {
  131. LOGE("%s::FBIOBLANK failed : (%d:%s)",
  132. __func__, win->fd, strerror(errno));
  133. return -1;
  134. }
  135. win->power_state = 0;
  136. }
  137. return 0;
  138. }
  139. int window_get_global_lcd_info(struct fb_var_screeninfo *lcd_info)
  140. {
  141. struct hwc_win_info_t win;
  142. int ret = 0;
  143. if (window_open(&win, 2) < 0) {
  144. LOGE("%s:: Failed to open window 2 device ", __func__);
  145. return -1;
  146. }
  147. if (ioctl(win.fd, FBIOGET_VSCREENINFO, lcd_info) < 0) {
  148. LOGE("FBIOGET_VSCREENINFO failed : %s", strerror(errno));
  149. ret = -1;
  150. goto fun_err;
  151. }
  152. if (lcd_info->xres == 0) {
  153. lcd_info->xres = DEFAULT_LCD_WIDTH;
  154. lcd_info->xres_virtual = DEFAULT_LCD_WIDTH;
  155. }
  156. if (lcd_info->yres == 0) {
  157. lcd_info->yres = DEFAULT_LCD_HEIGHT;
  158. lcd_info->yres_virtual = DEFAULT_LCD_HEIGHT * NUM_OF_WIN_BUF;
  159. }
  160. if (lcd_info->bits_per_pixel == 0)
  161. lcd_info->bits_per_pixel = DEFAULT_LCD_BPP;
  162. fun_err:
  163. if (window_close(&win) < 0)
  164. LOGE("%s::window2 close fail", __func__);
  165. return ret;
  166. }
  167. int fimc_v4l2_set_src(int fd, unsigned int hw_ver, s5p_fimc_img_info *src)
  168. {
  169. struct v4l2_format fmt;
  170. struct v4l2_cropcap cropcap;
  171. struct v4l2_crop crop;
  172. struct v4l2_requestbuffers req;
  173. /*
  174. * To set size & format for source image (DMA-INPUT)
  175. */
  176. fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
  177. fmt.fmt.pix.width = src->full_width;
  178. fmt.fmt.pix.height = src->full_height;
  179. fmt.fmt.pix.pixelformat = src->color_space;
  180. fmt.fmt.pix.field = V4L2_FIELD_NONE;
  181. if (ioctl (fd, VIDIOC_S_FMT, &fmt) < 0) {
  182. LOGE("VIDIOC_S_FMT failed : errno=%d (%s) : fd=%d", errno,
  183. strerror(errno), fd);
  184. return -1;
  185. }
  186. /*
  187. * crop input size
  188. */
  189. crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
  190. if (0x50 == hw_ver) {
  191. crop.c.left = src->start_x;
  192. crop.c.top = src->start_y;
  193. } else {
  194. crop.c.left = 0;
  195. crop.c.top = 0;
  196. }
  197. crop.c.width = src->width;
  198. crop.c.height = src->height;
  199. if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) {
  200. LOGE("Error in video VIDIOC_S_CROP (%d, %d, %d, %d)",
  201. crop.c.left, crop.c.top, crop.c.width, crop.c.height);
  202. return -1;
  203. }
  204. /*
  205. * input buffer type
  206. */
  207. req.count = 1;
  208. req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
  209. req.memory = V4L2_MEMORY_USERPTR;
  210. if (ioctl (fd, VIDIOC_REQBUFS, &req) < 0) {
  211. LOGE("Error in VIDIOC_REQBUFS");
  212. return -1;
  213. }
  214. return 0;
  215. }
  216. int fimc_v4l2_set_dst(int fd,
  217. s5p_fimc_img_info *dst,
  218. int rotation,
  219. int flag_h_flip,
  220. int flag_v_flip,
  221. unsigned int addr)
  222. {
  223. struct v4l2_format sFormat;
  224. struct v4l2_control vc;
  225. struct v4l2_framebuffer fbuf;
  226. /*
  227. * set rotation configuration
  228. */
  229. vc.id = V4L2_CID_HFLIP;
  230. vc.value = flag_h_flip;
  231. if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
  232. LOGE("Error in video VIDIOC_S_CTRL - flag_h_flip (%d)", flag_h_flip);
  233. return -1;
  234. }
  235. vc.id = V4L2_CID_VFLIP;
  236. vc.value = flag_v_flip;
  237. if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
  238. LOGE("Error in video VIDIOC_S_CTRL - flag_v_flip (%d)", flag_v_flip);
  239. return -1;
  240. }
  241. vc.id = V4L2_CID_ROTATION;
  242. vc.value = rotation;
  243. if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
  244. LOGE("Error in video VIDIOC_S_CTRL - rotation (%d)", rotation);
  245. return -1;
  246. }
  247. /*
  248. * set size, format & address for destination image (DMA-OUTPUT)
  249. */
  250. if (ioctl (fd, VIDIOC_G_FBUF, &fbuf) < 0) {
  251. LOGE("Error in video VIDIOC_G_FBUF");
  252. return -1;
  253. }
  254. fbuf.base = (void *)addr;
  255. fbuf.fmt.width = dst->full_width;
  256. fbuf.fmt.height = dst->full_height;
  257. fbuf.fmt.pixelformat = dst->color_space;
  258. if (ioctl (fd, VIDIOC_S_FBUF, &fbuf) < 0) {
  259. LOGE("Error in video VIDIOC_S_FBUF 0x%x %d %d %d",
  260. (void *)addr, dst->full_width, dst->full_height,
  261. dst->color_space);
  262. return -1;
  263. }
  264. /*
  265. * set destination window
  266. */
  267. sFormat.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
  268. sFormat.fmt.win.w.left = dst->start_x;
  269. sFormat.fmt.win.w.top = dst->start_y;
  270. sFormat.fmt.win.w.width = dst->width;
  271. sFormat.fmt.win.w.height = dst->height;
  272. if (ioctl(fd, VIDIOC_S_FMT, &sFormat) < 0) {
  273. LOGE("Error in video VIDIOC_S_FMT %d %d %d %d",
  274. dst->start_x, dst->start_y, dst->width, dst->height);
  275. return -1;
  276. }
  277. return 0;
  278. }
  279. int fimc_v4l2_stream_on(int fd, enum v4l2_buf_type type)
  280. {
  281. if (ioctl (fd, VIDIOC_STREAMON, &type) < 0) {
  282. LOGE("Error in VIDIOC_STREAMON");
  283. return -1;
  284. }
  285. return 0;
  286. }
  287. int fimc_v4l2_queue(int fd, struct fimc_buf *fimc_buf)
  288. {
  289. struct v4l2_buffer buf;
  290. buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
  291. buf.memory = V4L2_MEMORY_USERPTR;
  292. buf.m.userptr = (unsigned long)fimc_buf;
  293. buf.length = 0;
  294. buf.index = 0;
  295. if (ioctl (fd, VIDIOC_QBUF, &buf) < 0) {
  296. LOGE("Error in VIDIOC_QBUF");
  297. return -1;
  298. }
  299. return 0;
  300. }
  301. int fimc_v4l2_dequeue(int fd)
  302. {
  303. struct v4l2_buffer buf;
  304. buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
  305. buf.memory = V4L2_MEMORY_USERPTR;
  306. if (ioctl (fd, VIDIOC_DQBUF, &buf) < 0) {
  307. LOGE("Error in VIDIOC_DQBUF");
  308. return -1;
  309. }
  310. return buf.index;
  311. }
  312. int fimc_v4l2_stream_off(int fd)
  313. {
  314. enum v4l2_buf_type type;
  315. type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
  316. if (ioctl (fd, VIDIOC_STREAMOFF, &type) < 0) {
  317. LOGE("Error in VIDIOC_STREAMOFF");
  318. return -1;
  319. }
  320. return 0;
  321. }
  322. int fimc_v4l2_clr_buf(int fd)
  323. {
  324. struct v4l2_requestbuffers req;
  325. req.count = 0;
  326. req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
  327. req.memory = V4L2_MEMORY_USERPTR;
  328. if (ioctl (fd, VIDIOC_REQBUFS, &req) < 0) {
  329. LOGE("Error in VIDIOC_REQBUFS");
  330. }
  331. return 0;
  332. }
  333. int fimc_handle_oneshot(int fd, struct fimc_buf *fimc_buf)
  334. {
  335. int ret =0;
  336. if (fimc_v4l2_stream_on(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT) < 0) {
  337. LOGE("Fail : v4l2_stream_on()");
  338. return -1;
  339. }
  340. if (fimc_v4l2_queue(fd, fimc_buf) < 0) {
  341. LOGE("Fail : v4l2_queue()");
  342. ret = -1;
  343. goto stream_off;
  344. }
  345. if (fimc_v4l2_dequeue(fd) < 0) {
  346. LOGE("Fail : v4l2_dequeue()");
  347. ret = -1;
  348. goto stream_off;
  349. }
  350. stream_off:
  351. if (fimc_v4l2_stream_off(fd) < 0) {
  352. LOGE("Fail : v4l2_stream_off()");
  353. return -1;
  354. }
  355. if (fimc_v4l2_clr_buf(fd) < 0) {
  356. LOGE("Fail : v4l2_clr_buf()");
  357. return -1;
  358. }
  359. return ret;
  360. }
  361. static int get_src_phys_addr(struct hwc_context_t *ctx,
  362. sec_img *src_img,
  363. unsigned int *phyAddr)
  364. {
  365. s5p_fimc_t *fimc = &ctx->fimc;
  366. if(src_img->mem_type == HWC_PHYS_MEM_TYPE) {
  367. switch(src_img->format) {
  368. case HAL_PIXEL_FORMAT_YCbCr_420_SP:
  369. fimc->params.src.buf_addr_phy_rgb_y = phyAddr[0];
  370. fimc->params.src.buf_addr_phy_cb = phyAddr[1];
  371. break;
  372. default:
  373. LOGE("%s format error (format=0x%x)", __func__,
  374. src_img->format);
  375. return -1;
  376. }
  377. } else {
  378. LOGE("%s mem_type error (mem_type=%d)", __func__, src_img->mem_type);
  379. return -1;
  380. }
  381. return 0;
  382. }
  383. static int get_dst_phys_addr(struct hwc_context_t *ctx,
  384. sec_img *dst_img)
  385. {
  386. unsigned int dst_phys_addr = 0;
  387. if (HWC_PHYS_MEM_TYPE == dst_img->mem_type && 0 != dst_img->base)
  388. dst_phys_addr = dst_img->base;
  389. else {
  390. LOGE("%s::get_dst_phys_addr fail ", __func__);
  391. dst_phys_addr = 0;
  392. }
  393. return dst_phys_addr;
  394. }
  395. static inline int rotateValueHAL2PP(unsigned char transform,
  396. int *flag_h_flip,
  397. int *flag_v_flip)
  398. {
  399. int rotate_result = 0;
  400. int rotate_flag = transform & 0x7;
  401. switch (rotate_flag) {
  402. case HAL_TRANSFORM_ROT_90:
  403. rotate_result = 90;
  404. break;
  405. case HAL_TRANSFORM_ROT_180:
  406. rotate_result = 180;
  407. break;
  408. case HAL_TRANSFORM_ROT_270:
  409. rotate_result = 270;
  410. break;
  411. }
  412. switch (rotate_flag) {
  413. case HAL_TRANSFORM_FLIP_H:
  414. *flag_h_flip = 1;
  415. *flag_v_flip = 0;
  416. break;
  417. case HAL_TRANSFORM_FLIP_V:
  418. *flag_h_flip = 0;
  419. *flag_v_flip = 1;
  420. break;
  421. default:
  422. *flag_h_flip = 0;
  423. *flag_v_flip = 0;
  424. break;
  425. }
  426. return rotate_result;
  427. }
  428. static inline int multipleOfN(int number, int N)
  429. {
  430. int result = number;
  431. switch (N) {
  432. case 1:
  433. case 2:
  434. case 4:
  435. case 8:
  436. case 16:
  437. case 32:
  438. case 64:
  439. case 128:
  440. case 256:
  441. result = (number - (number & (N-1)));
  442. break;
  443. default:
  444. result = number - (number % N);
  445. break;
  446. }
  447. return result;
  448. }
  449. static inline int widthOfPP(unsigned int ver,
  450. int pp_color_format,
  451. int number)
  452. {
  453. if (0x50 == ver) {
  454. switch(pp_color_format) {
  455. /* 422 1/2/3 plane */
  456. case V4L2_PIX_FMT_YUYV:
  457. case V4L2_PIX_FMT_UYVY:
  458. case V4L2_PIX_FMT_NV61:
  459. case V4L2_PIX_FMT_NV16:
  460. case V4L2_PIX_FMT_YUV422P:
  461. /* 420 2/3 plane */
  462. case V4L2_PIX_FMT_NV21:
  463. case V4L2_PIX_FMT_NV12:
  464. case V4L2_PIX_FMT_NV12T:
  465. case V4L2_PIX_FMT_YUV420:
  466. return multipleOfN(number, 2);
  467. default :
  468. return number;
  469. }
  470. } else {
  471. switch(pp_color_format) {
  472. case V4L2_PIX_FMT_RGB565:
  473. return multipleOfN(number, 8);
  474. case V4L2_PIX_FMT_RGB32:
  475. return multipleOfN(number, 4);
  476. case V4L2_PIX_FMT_YUYV:
  477. case V4L2_PIX_FMT_UYVY:
  478. return multipleOfN(number, 4);
  479. case V4L2_PIX_FMT_NV61:
  480. case V4L2_PIX_FMT_NV16:
  481. return multipleOfN(number, 8);
  482. case V4L2_PIX_FMT_YUV422P:
  483. return multipleOfN(number, 16);
  484. case V4L2_PIX_FMT_NV21:
  485. case V4L2_PIX_FMT_NV12:
  486. case V4L2_PIX_FMT_NV12T:
  487. return multipleOfN(number, 8);
  488. case V4L2_PIX_FMT_YUV420:
  489. return multipleOfN(number, 16);
  490. default :
  491. return number;
  492. }
  493. }
  494. return number;
  495. }
  496. static inline int heightOfPP(int pp_color_format,
  497. int number)
  498. {
  499. switch(pp_color_format) {
  500. case V4L2_PIX_FMT_NV21:
  501. case V4L2_PIX_FMT_NV12:
  502. case V4L2_PIX_FMT_NV12T:
  503. case V4L2_PIX_FMT_YUV420:
  504. return multipleOfN(number, 2);
  505. default :
  506. return number;
  507. }
  508. return number;
  509. }
  510. static int runcFimcCore(struct hwc_context_t *ctx,
  511. sec_img *src_img,
  512. sec_rect *src_rect,
  513. uint32_t src_color_space,
  514. unsigned int dst_phys_addr,
  515. sec_img *dst_img,
  516. sec_rect *dst_rect,
  517. uint32_t dst_color_space,
  518. int transform)
  519. {
  520. s5p_fimc_t * fimc = &ctx->fimc;
  521. s5p_fimc_params_t * params = &(fimc->params);
  522. unsigned int frame_size = 0;
  523. struct fimc_buf fimc_src_buf;
  524. int src_bpp, src_planes;
  525. int flag_h_flip = 0;
  526. int flag_v_flip = 0;
  527. int rotate_value = rotateValueHAL2PP(transform, &flag_h_flip, &flag_v_flip);
  528. /* set post processor configuration */
  529. params->src.full_width = src_img->w;
  530. params->src.full_height = src_img->h;
  531. params->src.start_x = src_rect->x;
  532. params->src.start_y = src_rect->y;
  533. params->src.width = widthOfPP(fimc->hw_ver, src_color_space, src_rect->w);
  534. params->src.height = heightOfPP(src_color_space, src_rect->h);
  535. params->src.color_space = src_color_space;
  536. /* check minimum */
  537. if (src_rect->w < 16 || src_rect->h < 8) {
  538. LOGE("%s src size is not supported by fimc : f_w=%d f_h=%d x=%d y=%d \
  539. w=%d h=%d (ow=%d oh=%d) format=0x%x", __func__,
  540. params->src.full_width, params->src.full_height,
  541. params->src.start_x, params->src.start_y, params->src.width,
  542. params->src.height, src_rect->w, src_rect->h,
  543. params->src.color_space);
  544. return -1;
  545. }
  546. switch (rotate_value) {
  547. case 0:
  548. params->dst.full_width = dst_img->w;
  549. params->dst.full_height = dst_img->h;
  550. params->dst.start_x = dst_rect->x;
  551. params->dst.start_y = dst_rect->y;
  552. params->dst.width =
  553. widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
  554. params->dst.height = heightOfPP(dst_color_space, dst_rect->h);
  555. break;
  556. case 90:
  557. params->dst.full_width = dst_img->h;
  558. params->dst.full_height = dst_img->w;
  559. params->dst.start_x = dst_rect->y;
  560. params->dst.start_y = dst_img->w - (dst_rect->x + dst_rect->w);
  561. params->dst.width =
  562. widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->h);
  563. params->dst.height =
  564. widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
  565. if (0x50 > fimc->hw_ver)
  566. params->dst.start_y += (dst_rect->w - params->dst.height);
  567. break;
  568. case 180:
  569. params->dst.full_width = dst_img->w;
  570. params->dst.full_height = dst_img->h;
  571. params->dst.start_x = dst_img->w - (dst_rect->x + dst_rect->w);
  572. params->dst.start_y = dst_img->h - (dst_rect->y + dst_rect->h);
  573. params->dst.width =
  574. widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
  575. params->dst.height = heightOfPP(dst_color_space, dst_rect->h);
  576. break;
  577. case 270:
  578. params->dst.full_width = dst_img->h;
  579. params->dst.full_height = dst_img->w;
  580. params->dst.start_x = dst_img->h - (dst_rect->y + dst_rect->h);
  581. params->dst.start_y = dst_rect->x;
  582. params->dst.width =
  583. widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->h);
  584. params->dst.height =
  585. widthOfPP(fimc->hw_ver, dst_color_space, dst_rect->w);
  586. if (0x50 > fimc->hw_ver)
  587. params->dst.start_y += (dst_rect->w - params->dst.height);
  588. break;
  589. }
  590. params->dst.color_space = dst_color_space;
  591. /* check minimum */
  592. if (dst_rect->w < 8 || dst_rect->h < 4) {
  593. LOGE("%s dst size is not supported by fimc : \
  594. f_w=%d f_h=%d x=%d y=%d w=%d h=%d (ow=%d oh=%d) format=0x%x",
  595. __func__, params->dst.full_width, params->dst.full_height,
  596. params->dst.start_x, params->dst.start_y, params->dst.width,
  597. params->dst.height, dst_rect->w, dst_rect->h,
  598. params->dst.color_space);
  599. return -1;
  600. }
  601. /* check scaling limit
  602. * the scaling limie must not be more than MAX_RESIZING_RATIO_LIMIT
  603. */
  604. if (((src_rect->w > dst_rect->w) &&
  605. ((src_rect->w / dst_rect->w) > MAX_RESIZING_RATIO_LIMIT)) ||
  606. ((dst_rect->w > src_rect->w) &&
  607. ((dst_rect->w / src_rect->w) > MAX_RESIZING_RATIO_LIMIT))) {
  608. LOGE("%s over scaling limit : src.w=%d dst.w=%d (limit=%d)",
  609. __func__, src_rect->w, dst_rect->w, MAX_RESIZING_RATIO_LIMIT);
  610. return -1;
  611. }
  612. /* set configuration related to destination (DMA-OUT)
  613. * - set input format & size
  614. * - crop input size
  615. * - set input buffer
  616. * - set buffer type (V4L2_MEMORY_USERPTR)
  617. */
  618. if (fimc_v4l2_set_dst(fimc->dev_fd,
  619. &params->dst,
  620. rotate_value,
  621. flag_h_flip,
  622. flag_v_flip,
  623. dst_phys_addr) < 0) {
  624. return -1;
  625. }
  626. /* set configuration related to source (DMA-INPUT)
  627. * - set input format & size
  628. * - crop input size
  629. * - set input buffer
  630. * - set buffer type (V4L2_MEMORY_USERPTR)
  631. */
  632. if (fimc_v4l2_set_src(fimc->dev_fd, fimc->hw_ver, &params->src) < 0)
  633. return -1;
  634. /* set input dma address (Y/RGB, Cb, Cr) */
  635. switch (src_img->format) {
  636. case HAL_PIXEL_FORMAT_YCbCr_420_SP:
  637. /* for video display zero copy case */
  638. fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y;
  639. fimc_src_buf.base[1] = params->src.buf_addr_phy_cb;
  640. break;
  641. default:
  642. /* set source image */
  643. fimc_src_buf.base[0] = params->src.buf_addr_phy_rgb_y;
  644. break;
  645. }
  646. if (fimc_handle_oneshot(fimc->dev_fd, &fimc_src_buf) < 0) {
  647. fimc_v4l2_clr_buf(fimc->dev_fd);
  648. return -1;
  649. }
  650. return 0;
  651. }
  652. int createFimc(s5p_fimc_t *fimc)
  653. {
  654. struct v4l2_capability cap;
  655. struct v4l2_format fmt;
  656. struct v4l2_control vc;
  657. #define PP_DEVICE_DEV_NAME "/dev/video1"
  658. /* open device file */
  659. if(fimc->dev_fd < 0) {
  660. fimc->dev_fd = open(PP_DEVICE_DEV_NAME, O_RDWR);
  661. if (fimc->dev_fd < 0) {
  662. LOGE("%s::Post processor open error (%d)", __func__, errno);
  663. goto err;
  664. }
  665. }
  666. /* check capability */
  667. if (ioctl(fimc->dev_fd, VIDIOC_QUERYCAP, &cap) < 0) {
  668. LOGE("VIDIOC_QUERYCAP failed");
  669. goto err;
  670. }
  671. if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
  672. LOGE("%d has no streaming support", fimc->dev_fd);
  673. goto err;
  674. }
  675. if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) {
  676. LOGE("%d is no video output", fimc->dev_fd);
  677. goto err;
  678. }
  679. /*
  680. * malloc fimc_outinfo structure
  681. */
  682. fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
  683. if (ioctl(fimc->dev_fd, VIDIOC_G_FMT, &fmt) < 0) {
  684. LOGE("%s::Error in video VIDIOC_G_FMT", __func__);
  685. goto err;
  686. }
  687. vc.id = V4L2_CID_FIMC_VERSION;
  688. vc.value = 0;
  689. if (ioctl(fimc->dev_fd, VIDIOC_G_CTRL, &vc) < 0) {
  690. LOGE("%s::Error in video VIDIOC_G_CTRL", __func__);
  691. goto err;
  692. }
  693. fimc->hw_ver = vc.value;
  694. return 0;
  695. err:
  696. if (0 <= fimc->dev_fd)
  697. close(fimc->dev_fd);
  698. fimc->dev_fd = -1;
  699. return -1;
  700. }
  701. int destroyFimc(s5p_fimc_t *fimc)
  702. {
  703. if (fimc->out_buf.virt_addr != NULL) {
  704. fimc->out_buf.virt_addr = NULL;
  705. fimc->out_buf.length = 0;
  706. }
  707. /* close */
  708. if (0 <= fimc->dev_fd)
  709. close(fimc->dev_fd);
  710. fimc->dev_fd = -1;
  711. return 0;
  712. }
  713. int runFimc(struct hwc_context_t *ctx,
  714. struct sec_img *src_img,
  715. struct sec_rect *src_rect,
  716. struct sec_img *dst_img,
  717. struct sec_rect *dst_rect,
  718. unsigned int *phyAddr,
  719. uint32_t transform)
  720. {
  721. s5p_fimc_t *fimc = &ctx->fimc;
  722. unsigned int dst_phys_addr = 0;
  723. int32_t src_color_space;
  724. int32_t dst_color_space;
  725. /* 1 : source address and size */
  726. if(0 > get_src_phys_addr(ctx, src_img, phyAddr))
  727. return -1;
  728. /* 2 : destination address and size */
  729. if(0 == (dst_phys_addr = get_dst_phys_addr(ctx, dst_img)))
  730. return -2;
  731. /* check whether fimc supports the src format */
  732. if (0 > (src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format)))
  733. return -3;
  734. if (0 > (dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format)))
  735. return -4;
  736. if(runcFimcCore(ctx, src_img, src_rect, (uint32_t)src_color_space,
  737. dst_phys_addr, dst_img, dst_rect, (uint32_t)dst_color_space, transform) < 0)
  738. return -5;
  739. return 0;
  740. }