PageRenderTime 28ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/exynos3/s5pc110/libhwcomposer/SecHWCUtils.cpp

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