1 /**************************************************************************
3 xserver-xorg-video-exynos
5 Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: Boram Park <boram1288.park@samsung.com>
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
31 #include <sys/ioctl.h>
35 #include "sec_video_types.h"
36 #include "sec_video_fourcc.h"
37 #include "sec_drm_ipp.h"
38 #include "sec_converter.h"
40 #include <drm_fourcc.h>
42 //#define INCREASE_NUM 1
43 #define DEQUEUE_FORCE 1
49 typedef struct _SECCvtFuncData
53 struct xorg_list link;
56 typedef struct _SECCvtBuf
60 unsigned int handles[EXYNOS_DRM_PLANAR_MAX];
65 struct xorg_list link;
76 SECCvtProp props[CVT_TYPE_MAX];
78 struct xorg_list func_datas;
79 struct xorg_list src_bufs;
80 struct xorg_list dst_bufs;
90 struct xorg_list link;
93 static unsigned int formats[] =
114 static struct xorg_list cvt_list;
119 static Bool inited = FALSE;
124 xorg_list_init (&cvt_list);
130 _findCvt (CARD32 stamp)
132 SECCvt *cur = NULL, *next = NULL;
136 if (cvt_list.next != NULL)
138 xorg_list_for_each_entry_safe (cur, next, &cvt_list, link)
140 if (cur->stamp == stamp)
148 static enum drm_exynos_ipp_cmd
149 _drmCommand (SECCvtOp op)
154 return IPP_CMD_OUTPUT;
160 static enum drm_exynos_degree
161 _drmDegree (int degree)
163 switch (degree % 360)
166 return EXYNOS_DRM_DEGREE_90;
168 return EXYNOS_DRM_DEGREE_180;
170 return EXYNOS_DRM_DEGREE_270;
172 return EXYNOS_DRM_DEGREE_0;
177 _FillConfig (SECCvtType type, SECCvtProp *prop, struct drm_exynos_ipp_config *config)
179 config->ops_id = (type == CVT_TYPE_SRC) ? EXYNOS_DRM_OPS_SRC : EXYNOS_DRM_OPS_DST;
182 config->flip |= EXYNOS_DRM_FLIP_HORIZONTAL;
184 config->flip |= EXYNOS_DRM_FLIP_VERTICAL;
186 config->degree = _drmDegree (prop->degree);
187 config->fmt = secUtilGetDrmFormat (prop->id);
188 config->sz.hsize = (__u32)prop->width;
189 config->sz.vsize = (__u32)prop->height;
190 config->pos.x = (__u32)prop->crop.x;
191 config->pos.y = (__u32)prop->crop.y;
192 config->pos.w = (__u32)prop->crop.width;
193 config->pos.h = (__u32)prop->crop.height;
197 _fillProperty (SECCvt *cvt, SECCvtType type, SECVideoBuf *vbuf, SECCvtProp *prop)
200 prop->width = vbuf->width;
201 prop->height = vbuf->height;
202 prop->crop = vbuf->crop;
204 prop->degree = cvt->props[type].degree;
205 prop->vflip = cvt->props[type].vflip;
206 prop->hflip = cvt->props[type].hflip;
207 prop->secure = cvt->props[type].secure;
208 prop->csc_range = cvt->props[type].csc_range;
212 _SetVbufConverting (SECVideoBuf *vbuf, SECCvt *cvt, Bool converting)
216 ConvertInfo *cur = NULL, *next = NULL;
218 xorg_list_for_each_entry_safe (cur, next, &vbuf->convert_info, link)
220 if (cur->cvt == (void*)cvt)
222 xorg_list_del (&cur->link);
228 XDBG_ERROR (MCVT, "failed: %ld not found in %ld.\n", cvt->stamp, vbuf->stamp);
233 ConvertInfo *info = NULL, *next = NULL;
235 xorg_list_for_each_entry_safe (info, next, &vbuf->convert_info, link)
237 if (info->cvt == (void*)cvt)
239 XDBG_ERROR (MCVT, "failed: %ld already converting %ld.\n", cvt->stamp, vbuf->stamp);
244 info = calloc (1, sizeof (ConvertInfo));
245 XDBG_RETURN_VAL_IF_FAIL (info != NULL, FALSE);
247 info->cvt = (void*)cvt;
249 xorg_list_add (&info->link, &vbuf->convert_info);
257 _printBufIndices (SECCvt *cvt, SECCvtType type, char *str)
259 struct xorg_list *bufs;
260 SECCvtBuf *cur, *next;
263 bufs = (type == CVT_TYPE_SRC) ? &cvt->src_bufs : &cvt->dst_bufs;
265 snprintf (nums, 128, "bufs:");
267 list_rev_for_each_entry_safe (cur, next, bufs, link)
269 snprintf (nums, 128, "%s %d", nums, cur->index);
272 ErrorF ("%s: cvt(%p) %s(%s). \n", str, cvt,
273 (type == CVT_TYPE_SRC)?"SRC":"DST", nums);
278 _secCvtGetEmptyIndex (SECCvt *cvt, SECCvtType type)
283 if(type == CVT_TYPE_SRC)
285 ret = cvt->src_index++;
286 if (cvt->src_index >= CVT_BUF_MAX)
291 ret = cvt->dst_index++;
292 if (cvt->dst_index >= CVT_BUF_MAX)
298 struct xorg_list *bufs;
299 SECCvtBuf *cur = NULL, *next = NULL;
302 bufs = (type == CVT_TYPE_SRC) ? &cvt->src_bufs : &cvt->dst_bufs;
308 xorg_list_for_each_entry_safe (cur, next, bufs, link)
310 if (ret == cur->index)
328 _secCvtFindBuf (SECCvt *cvt, SECCvtType type, int index)
330 struct xorg_list *bufs;
331 SECCvtBuf *cur = NULL, *next = NULL;
333 bufs = (type == CVT_TYPE_SRC) ? &cvt->src_bufs : &cvt->dst_bufs;
335 xorg_list_for_each_entry_safe (cur, next, bufs, link)
337 if (index == cur->index)
341 XDBG_ERROR (MCVT, "cvt(%p), type(%d), index(%d) not found.\n", cvt, type, index);
347 _secCvtQueue (SECCvt *cvt, SECCvtBuf *cbuf)
349 struct drm_exynos_ipp_queue_buf buf = {0,};
350 struct xorg_list *bufs;
352 int index = _secCvtGetEmptyIndex (cvt, cbuf->type);
354 buf.prop_id = cvt->prop_id;
355 buf.ops_id = (cbuf->type == CVT_TYPE_SRC) ? EXYNOS_DRM_OPS_SRC : EXYNOS_DRM_OPS_DST;
356 buf.buf_type = IPP_BUF_ENQUEUE;
357 buf.buf_id = cbuf->index = index;
358 buf.user_data = (__u64)cvt->stamp;
360 for (i = 0; i < EXYNOS_DRM_PLANAR_MAX; i++)
361 buf.handle[i] = (__u32)cbuf->handles[i];
363 if (!secDrmIppQueueBuf (cvt->pScrn, &buf))
366 bufs = (cbuf->type == CVT_TYPE_SRC) ? &cvt->src_bufs : &cvt->dst_bufs;
367 xorg_list_add (&cbuf->link, bufs);
369 _SetVbufConverting (cbuf->vbuf, cvt, TRUE);
372 if (cbuf->type == CVT_TYPE_SRC)
373 _printBufIndices (cvt, CVT_TYPE_SRC, "in");
376 XDBG_DEBUG (MCVT, "cvt(%p), cbuf(%p), type(%d), index(%d) vbuf(%p) converting(%d)\n",
377 cvt, cbuf, cbuf->type, index, cbuf->vbuf, VBUF_IS_CONVERTING (cbuf->vbuf));
383 _secCvtDequeue (SECCvt *cvt, SECCvtBuf *cbuf)
385 struct drm_exynos_ipp_queue_buf buf = {0,};
388 if (!_secCvtFindBuf (cvt, cbuf->type, cbuf->index))
390 XDBG_WARNING (MCVT, "cvt(%p) type(%d), index(%d) already dequeued!\n",
391 cvt, cbuf->type, cbuf->index);
395 XDBG_RETURN_IF_FAIL (VBUF_IS_VALID (cbuf->vbuf));
397 buf.prop_id = cvt->prop_id;
398 buf.ops_id = (cbuf->type == CVT_TYPE_SRC) ? EXYNOS_DRM_OPS_SRC : EXYNOS_DRM_OPS_DST;
399 buf.buf_type = IPP_BUF_DEQUEUE;
400 buf.buf_id = cbuf->index;
401 buf.user_data = (__u64)cvt->stamp;
403 for (i = 0; i < EXYNOS_DRM_PLANAR_MAX; i++)
404 buf.handle[i] = (__u32)cbuf->handles[i];
406 if (!secDrmIppQueueBuf (cvt->pScrn, &buf))
411 _secCvtDequeued (SECCvt *cvt, SECCvtType type, int index)
413 SECCvtBuf *cbuf = _secCvtFindBuf (cvt, type, index);
417 XDBG_WARNING (MCVT, "cvt(%p) type(%d), index(%d) already dequeued!\n",
422 XDBG_RETURN_IF_FAIL (VBUF_IS_VALID (cbuf->vbuf));
424 _SetVbufConverting (cbuf->vbuf, cvt, FALSE);
426 XDBG_DEBUG (MCVT, "cvt(%p) type(%d) index(%d) vbuf(%p) converting(%d)\n",
427 cvt, type, index, cbuf->vbuf, VBUF_IS_CONVERTING (cbuf->vbuf));
429 xorg_list_del (&cbuf->link);
432 if (cbuf->type == CVT_TYPE_SRC)
433 _printBufIndices (cvt, CVT_TYPE_SRC, "out");
436 secUtilVideoBufferUnref (cbuf->vbuf);
441 _secCvtDequeueAll (SECCvt *cvt)
443 SECCvtBuf *cur = NULL, *next = NULL;
445 xorg_list_for_each_entry_safe (cur, next, &cvt->src_bufs, link)
447 _secCvtDequeue (cvt, cur);
450 xorg_list_for_each_entry_safe (cur, next, &cvt->dst_bufs, link)
452 _secCvtDequeue (cvt, cur);
457 _secCvtDequeuedAll (SECCvt *cvt)
459 SECCvtBuf *cur = NULL, *next = NULL;
461 xorg_list_for_each_entry_safe (cur, next, &cvt->src_bufs, link)
463 _secCvtDequeued (cvt, EXYNOS_DRM_OPS_SRC, cur->index);
466 xorg_list_for_each_entry_safe (cur, next, &cvt->dst_bufs, link)
468 _secCvtDequeued (cvt, EXYNOS_DRM_OPS_DST, cur->index);
473 _secCvtStop (SECCvt *cvt)
475 struct drm_exynos_ipp_cmd_ctrl ctrl = {0,};
477 XDBG_RETURN_IF_FAIL (cvt != NULL);
482 _secCvtDequeueAll (cvt);
484 ctrl.prop_id = cvt->prop_id;
485 ctrl.ctrl = IPP_CTRL_STOP;
487 secDrmIppCmdCtrl (cvt->pScrn, &ctrl);
489 _secCvtDequeuedAll (cvt);
491 XDBG_TRACE (MCVT, "cvt(%p)\n", cvt);
495 memset (cvt->props, 0, sizeof (SECCvtProp) * CVT_TYPE_MAX);
501 cvt->started = FALSE;
507 secCvtSupportFormat (SECCvtOp op, int id)
509 unsigned int *drmfmts;
510 int i, size, num = 0;
511 unsigned int drmfmt = secUtilGetDrmFormat (id);
513 XDBG_RETURN_VAL_IF_FAIL (op >= 0 && op < CVT_OP_MAX, FALSE);
514 XDBG_RETURN_VAL_IF_FAIL (id > 0, FALSE);
516 size = sizeof (formats) / sizeof (unsigned int);
518 for (i = 0; i < size; i++)
519 if (formats[i] == id)
524 XDBG_ERROR (MCVT, "converter(op:%d) not support : '%c%c%c%c'.\n",
525 op, FOURCC_STR (id));
529 drmfmts = secDrmIppGetFormatList (&num);
532 XDBG_ERROR (MCVT, "no drm format list.\n");
536 for (i = 0; i < num; i++)
537 if (drmfmts[i] == drmfmt)
543 XDBG_ERROR (MCVT, "drm ipp not support : '%c%c%c%c'.\n", FOURCC_STR (id));
551 secCvtEnsureSize (SECCvtProp *src, SECCvtProp *dst)
555 int type = secUtilGetColorType (src->id);
557 XDBG_RETURN_VAL_IF_FAIL (src->width >= 16, FALSE);
558 XDBG_RETURN_VAL_IF_FAIL (src->height >= 8, FALSE);
559 XDBG_RETURN_VAL_IF_FAIL (src->crop.width >= 16, FALSE);
560 XDBG_RETURN_VAL_IF_FAIL (src->crop.height >= 8, FALSE);
564 if (!IS_ZEROCOPY (src->id))
566 int new_width = (src->width + 16) & (~0xF);
567 XDBG_DEBUG (MCVT, "src's width : %d to %d.\n", src->width, new_width);
568 src->width = new_width;
572 if (type == TYPE_YUV420 && src->height % 2)
573 XDBG_WARNING (MCVT, "src's height(%d) is not multiple of 2!!!\n", src->height);
575 if (type == TYPE_YUV420 || type == TYPE_YUV422)
577 src->crop.x = src->crop.x & (~0x1);
578 src->crop.width = src->crop.width & (~0x1);
581 if (type == TYPE_YUV420)
582 src->crop.height = src->crop.height & (~0x1);
584 if (src->crop.x + src->crop.width > src->width)
585 src->crop.width = src->width - src->crop.x;
586 if (src->crop.y + src->crop.height > src->height)
587 src->crop.height = src->height - src->crop.y;
592 int type = secUtilGetColorType (dst->id);
594 XDBG_RETURN_VAL_IF_FAIL (dst->width >= 16, FALSE);
595 XDBG_RETURN_VAL_IF_FAIL (dst->height >= 8, FALSE);
596 XDBG_RETURN_VAL_IF_FAIL (dst->crop.width >= 16, FALSE);
597 XDBG_RETURN_VAL_IF_FAIL (dst->crop.height >= 4, FALSE);
601 int new_width = (dst->width + 16) & (~0xF);
602 XDBG_DEBUG (MCVT, "dst's width : %d to %d.\n", dst->width, new_width);
603 dst->width = new_width;
606 dst->height = dst->height & (~0x1);
608 if (type == TYPE_YUV420 && dst->height % 2)
609 XDBG_WARNING (MCVT, "dst's height(%d) is not multiple of 2!!!\n", dst->height);
611 if (type == TYPE_YUV420 || type == TYPE_YUV422)
613 dst->crop.x = dst->crop.x & (~0x1);
614 dst->crop.width = dst->crop.width & (~0x1);
617 if (type == TYPE_YUV420)
618 dst->crop.height = dst->crop.height & (~0x1);
620 if (dst->crop.x + dst->crop.width > dst->width)
621 dst->crop.width = dst->width - dst->crop.x;
622 if (dst->crop.y + dst->crop.height > dst->height)
623 dst->crop.height = dst->height - dst->crop.y;
630 secCvtCreate (ScrnInfoPtr pScrn, SECCvtOp op)
633 CARD32 stamp = GetTimeInMillis ();
637 XDBG_RETURN_VAL_IF_FAIL (pScrn != NULL, NULL);
638 XDBG_RETURN_VAL_IF_FAIL (op >= 0 && op < CVT_OP_MAX, NULL);
640 while (_findCvt (stamp))
643 cvt = calloc (1, sizeof (SECCvt));
644 XDBG_RETURN_VAL_IF_FAIL (cvt != NULL, NULL);
652 xorg_list_init (&cvt->func_datas);
653 xorg_list_init (&cvt->src_bufs);
654 xorg_list_init (&cvt->dst_bufs);
656 XDBG_TRACE (MCVT, "op(%d), cvt(%p) stamp(%ld)\n", op, cvt, stamp);
658 xorg_list_add (&cvt->link, &cvt_list);
664 secCvtDestroy (SECCvt *cvt)
666 SECCvtFuncData *cur = NULL, *next = NULL;
673 xorg_list_del (&cvt->link);
675 xorg_list_for_each_entry_safe (cur, next, &cvt->func_datas, link)
677 xorg_list_del (&cur->link);
681 XDBG_TRACE (MCVT, "cvt(%p)\n", cvt);
687 secCvtGetOp (SECCvt *cvt)
689 XDBG_RETURN_VAL_IF_FAIL (cvt != NULL, CVT_OP_M2M);
695 secCvtSetProperpty (SECCvt *cvt, SECCvtProp *src, SECCvtProp *dst)
700 struct drm_exynos_ipp_property property;
702 XDBG_RETURN_VAL_IF_FAIL (cvt != NULL, FALSE);
703 XDBG_RETURN_VAL_IF_FAIL (src != NULL, FALSE);
704 XDBG_RETURN_VAL_IF_FAIL (dst != NULL, FALSE);
706 if (!secCvtEnsureSize (src, dst))
709 if (dst->crop.x + dst->crop.width > dst->width)
711 XDBG_ERROR (MCVT, "dst(%d+%d > %d). !\n", dst->crop.x, dst->crop.width, dst->width);
714 if (!secCvtSupportFormat (cvt->op, src->id))
716 XDBG_ERROR (MCVT, "cvt(%p) src '%c%c%c%c' not supported.\n",
717 cvt, FOURCC_STR (src->id));
721 if (!secCvtSupportFormat (cvt->op, dst->id))
723 XDBG_ERROR (MCVT, "cvt(%p) dst '%c%c%c%c' not supported.\n",
724 cvt, FOURCC_STR (dst->id));
728 memcpy (&cvt->props[CVT_TYPE_SRC], src, sizeof (SECCvtProp));
729 memcpy (&cvt->props[CVT_TYPE_DST], dst, sizeof (SECCvtProp));
732 _FillConfig (CVT_TYPE_SRC, &cvt->props[CVT_TYPE_SRC], &property.config[0]);
733 _FillConfig (CVT_TYPE_DST, &cvt->props[CVT_TYPE_DST], &property.config[1]);
734 property.cmd = _drmCommand (cvt->op);
735 #ifdef _F_WEARABLE_FEATURE_
736 property.type = IPP_EVENT_DRIVEN;
738 property.prop_id = cvt->prop_id;
739 property.protect = dst->secure;
740 property.range = dst->csc_range;
742 XDBG_TRACE (MCVT, "cvt(%p) src('%c%c%c%c', '%c%c%c%c', %dx%d, %d,%d %dx%d, %d, %d&%d, %d, %d)\n",
743 cvt, FOURCC_STR(src->id), FOURCC_STR(secUtilGetDrmFormat(src->id)),
744 src->width, src->height,
745 src->crop.x, src->crop.y, src->crop.width, src->crop.height,
746 src->degree, src->hflip, src->vflip,
747 src->secure, src->csc_range);
749 XDBG_TRACE (MCVT, "cvt(%p) dst('%c%c%c%c', '%c%c%c%c',%dx%d, %d,%d %dx%d, %d, %d&%d, %d, %d)\n",
750 cvt, FOURCC_STR(dst->id), FOURCC_STR(secUtilGetDrmFormat(dst->id)),
751 dst->width, dst->height,
752 dst->crop.x, dst->crop.y, dst->crop.width, dst->crop.height,
753 dst->degree, dst->hflip, dst->vflip,
754 dst->secure, dst->csc_range);
756 cvt->prop_id = secDrmIppSetProperty (cvt->pScrn, &property);
757 XDBG_RETURN_VAL_IF_FAIL (cvt->prop_id >= 0, FALSE);
763 secCvtGetProperpty (SECCvt *cvt, SECCvtProp *src, SECCvtProp *dst)
765 XDBG_RETURN_IF_FAIL (cvt != NULL);
768 *src = cvt->props[CVT_TYPE_SRC];
771 *dst = cvt->props[CVT_TYPE_DST];
775 secCvtConvert (SECCvt *cvt, SECVideoBuf *src, SECVideoBuf *dst)
777 SECCvtBuf *src_cbuf = NULL, *dst_cbuf = NULL;
778 SECCvtProp src_prop, dst_prop;
780 XDBG_RETURN_VAL_IF_FAIL (cvt != NULL, FALSE);
781 XDBG_RETURN_VAL_IF_FAIL (cvt->op == CVT_OP_M2M, FALSE);
782 XDBG_RETURN_VAL_IF_FAIL (src != NULL, FALSE);
783 XDBG_RETURN_VAL_IF_FAIL (dst != NULL, FALSE);
784 XDBG_RETURN_VAL_IF_FAIL (VBUF_IS_VALID (src), FALSE);
785 XDBG_RETURN_VAL_IF_FAIL (VBUF_IS_VALID (dst), FALSE);
787 _fillProperty (cvt, CVT_TYPE_SRC, src, &src_prop);
788 _fillProperty (cvt, CVT_TYPE_DST, dst, &dst_prop);
790 if (memcmp (&cvt->props[CVT_TYPE_SRC], &src_prop, sizeof (SECCvtProp)) ||
791 memcmp (&cvt->props[CVT_TYPE_DST], &dst_prop, sizeof (SECCvtProp)))
793 XDBG_ERROR (MCVT, "cvt(%p) prop changed!\n", cvt);
794 XDBG_TRACE (MCVT, "cvt(%p) src_old('%c%c%c%c', %dx%d, %d,%d %dx%d, %d, %d&%d, %d, %d)\n",
795 cvt, FOURCC_STR(cvt->props[CVT_TYPE_SRC].id),
796 cvt->props[CVT_TYPE_SRC].width, cvt->props[CVT_TYPE_SRC].height,
797 cvt->props[CVT_TYPE_SRC].crop.x, cvt->props[CVT_TYPE_SRC].crop.y,
798 cvt->props[CVT_TYPE_SRC].crop.width, cvt->props[CVT_TYPE_SRC].crop.height,
799 cvt->props[CVT_TYPE_SRC].degree,
800 cvt->props[CVT_TYPE_SRC].hflip, cvt->props[CVT_TYPE_SRC].vflip,
801 cvt->props[CVT_TYPE_SRC].secure, cvt->props[CVT_TYPE_SRC].csc_range);
802 XDBG_TRACE (MCVT, "cvt(%p) src_new('%c%c%c%c', %dx%d, %d,%d %dx%d, %d, %d&%d, %d, %d)\n",
803 cvt, FOURCC_STR(src_prop.id), src_prop.width, src_prop.height,
804 src_prop.crop.x, src_prop.crop.y, src_prop.crop.width, src_prop.crop.height,
805 src_prop.degree, src_prop.hflip, src_prop.vflip,
806 src_prop.secure, src_prop.csc_range);
807 XDBG_TRACE (MCVT, "cvt(%p) dst_old('%c%c%c%c', %dx%d, %d,%d %dx%d, %d, %d&%d, %d, %d)\n",
808 cvt, FOURCC_STR(cvt->props[CVT_TYPE_DST].id),
809 cvt->props[CVT_TYPE_DST].width, cvt->props[CVT_TYPE_DST].height,
810 cvt->props[CVT_TYPE_DST].crop.x, cvt->props[CVT_TYPE_DST].crop.y,
811 cvt->props[CVT_TYPE_DST].crop.width, cvt->props[CVT_TYPE_DST].crop.height,
812 cvt->props[CVT_TYPE_DST].degree,
813 cvt->props[CVT_TYPE_DST].hflip, cvt->props[CVT_TYPE_DST].vflip,
814 cvt->props[CVT_TYPE_DST].secure, cvt->props[CVT_TYPE_DST].csc_range);
815 XDBG_TRACE (MCVT, "cvt(%p) dst_new('%c%c%c%c', %dx%d, %d,%d %dx%d, %d, %d&%d, %d, %d)\n",
816 cvt, FOURCC_STR(dst_prop.id), dst_prop.width, dst_prop.height,
817 dst_prop.crop.x, dst_prop.crop.y, dst_prop.crop.width, dst_prop.crop.height,
818 dst_prop.degree, dst_prop.hflip, dst_prop.vflip,
819 dst_prop.secure, dst_prop.csc_range);
823 XDBG_GOTO_IF_FAIL (cvt->prop_id >= 0, fail_to_convert);
824 XDBG_GOTO_IF_FAIL (src->handles[0] > 0, fail_to_convert);
825 XDBG_GOTO_IF_FAIL (dst->handles[0] > 0, fail_to_convert);
827 src_cbuf = calloc (1, sizeof (SECCvtBuf));
828 XDBG_GOTO_IF_FAIL (src_cbuf != NULL, fail_to_convert);
829 dst_cbuf = calloc (1, sizeof (SECCvtBuf));
830 XDBG_GOTO_IF_FAIL (dst_cbuf != NULL, fail_to_convert);
832 src_cbuf->type = CVT_TYPE_SRC;
833 src_cbuf->vbuf = secUtilVideoBufferRef (src);
834 memcpy (src_cbuf->handles, src->handles, sizeof (unsigned int) * EXYNOS_DRM_PLANAR_MAX);
836 if (!_secCvtQueue (cvt, src_cbuf))
838 secUtilVideoBufferUnref (src_cbuf->vbuf);
839 goto fail_to_convert;
842 XDBG_DEBUG (MCVT, "cvt(%p) srcbuf(%p) converting(%d)\n",
843 cvt, src, VBUF_IS_CONVERTING (src));
845 dst_cbuf->type = CVT_TYPE_DST;
846 dst_cbuf->vbuf = secUtilVideoBufferRef (dst);
847 memcpy (dst_cbuf->handles, dst->handles, sizeof (unsigned int) * EXYNOS_DRM_PLANAR_MAX);
849 if (!_secCvtQueue (cvt, dst_cbuf))
851 secUtilVideoBufferUnref (dst_cbuf->vbuf);
852 goto fail_to_convert;
855 XDBG_DEBUG (MCVT, "cvt(%p) dstbuf(%p) converting(%d)\n",
856 cvt, dst, VBUF_IS_CONVERTING (dst));
858 XDBG_DEBUG (MVBUF, "==> ipp (%ld,%d,%d : %ld,%d,%d) \n",
859 src->stamp, VBUF_IS_CONVERTING (src), src->showing,
860 dst->stamp, VBUF_IS_CONVERTING (dst), dst->showing);
864 struct drm_exynos_ipp_cmd_ctrl ctrl = {0,};
866 ctrl.prop_id = cvt->prop_id;
867 ctrl.ctrl = IPP_CTRL_PLAY;
869 if (!secDrmIppCmdCtrl (cvt->pScrn, &ctrl))
870 goto fail_to_convert;
872 XDBG_TRACE (MCVT, "cvt(%p) start.\n", cvt);
879 SECPtr pSec = SECPTR (cvt->pScrn);
880 if (pSec->xvperf_mode & XBERC_XVPERF_MODE_CVT)
881 src_cbuf->begin = GetTimeInMillis ();
898 secCvtAddCallback (SECCvt *cvt, CvtFunc func, void *data)
900 SECCvtFuncData *func_data;
902 XDBG_RETURN_VAL_IF_FAIL (cvt != NULL, FALSE);
903 XDBG_RETURN_VAL_IF_FAIL (func != NULL, FALSE);
905 func_data = calloc (1, sizeof (SECCvtFuncData));
906 XDBG_RETURN_VAL_IF_FAIL (func_data != NULL, FALSE);
908 xorg_list_add (&func_data->link, &cvt->func_datas);
910 func_data->func = func;
911 func_data->data = data;
917 secCvtRemoveCallback (SECCvt *cvt, CvtFunc func, void *data)
919 SECCvtFuncData *cur = NULL, *next = NULL;
921 XDBG_RETURN_IF_FAIL (cvt != NULL);
922 XDBG_RETURN_IF_FAIL (func != NULL);
924 xorg_list_for_each_entry_safe (cur, next, &cvt->func_datas, link)
926 if (cur->func == func && cur->data == data)
928 xorg_list_del (&cur->link);
935 secCvtHandleIppEvent (int fd, unsigned int *buf_idx, void *data, Bool error)
937 CARD32 stamp = (CARD32)data;
939 SECCvtBuf *src_cbuf, *dst_cbuf;
940 SECVideoBuf *src_vbuf, *dst_vbuf;
941 SECCvtFuncData *curr = NULL, *next = NULL;
943 XDBG_RETURN_IF_FAIL (buf_idx != NULL);
945 cvt = _findCvt (stamp);
948 XDBG_DEBUG (MCVT, "invalid cvt's stamp (%ld).\n", stamp);
952 XDBG_DEBUG (MCVT, "cvt(%p) index(%d, %d)\n",
953 cvt, buf_idx[EXYNOS_DRM_OPS_SRC], buf_idx[EXYNOS_DRM_OPS_DST]);
957 snprintf (temp, 64, "%d,%d", buf_idx[EXYNOS_DRM_OPS_SRC], buf_idx[EXYNOS_DRM_OPS_DST]);
958 _printBufIndices (cvt, CVT_TYPE_SRC, temp);
962 SECCvtBuf *cur = NULL, *prev = NULL;
964 list_rev_for_each_entry_safe (cur, prev, &cvt->src_bufs, link)
966 if (buf_idx[EXYNOS_DRM_OPS_SRC] != cur->index)
968 unsigned int indice[EXYNOS_DRM_OPS_MAX] = {cur->index, cur->index};
970 XDBG_WARNING (MCVT, "cvt(%p) event(%d,%d) has been skipped!! \n",
971 cvt, cur->index, cur->index);
973 /* To make sure all events are received, _secCvtDequeued should be called
974 * for every event. If a event has been skipped, to call _secCvtDequeued
975 * forcely, we call secCvtHandleIppEvent recursivly.
977 secCvtHandleIppEvent (0, indice, (void*)cvt->stamp, TRUE);
984 src_cbuf = _secCvtFindBuf (cvt, EXYNOS_DRM_OPS_SRC, buf_idx[EXYNOS_DRM_OPS_SRC]);
985 XDBG_RETURN_IF_FAIL (src_cbuf != NULL);
987 dst_cbuf = _secCvtFindBuf (cvt, EXYNOS_DRM_OPS_DST, buf_idx[EXYNOS_DRM_OPS_DST]);
988 XDBG_RETURN_IF_FAIL (dst_cbuf != NULL);
990 SECPtr pSec = SECPTR (cvt->pScrn);
991 if (pSec->xvperf_mode & XBERC_XVPERF_MODE_CVT)
994 cur = GetTimeInMillis ();
995 sub = cur - src_cbuf->begin;
996 ErrorF ("cvt(%p) ipp interval : %6ld ms\n", cvt, sub);
999 src_vbuf = src_cbuf->vbuf;
1000 dst_vbuf = dst_cbuf->vbuf;
1002 XDBG_DEBUG (MVBUF, "<== ipp (%ld,%d,%d : %ld,%d,%d) \n",
1003 src_vbuf->stamp, VBUF_IS_CONVERTING (src_vbuf), src_vbuf->showing,
1004 dst_vbuf->stamp, VBUF_IS_CONVERTING (dst_vbuf), dst_vbuf->showing);
1006 if (!cvt->first_event)
1008 XDBG_DEBUG (MCVT, "cvt(%p) got a IPP event. \n", cvt);
1009 cvt->first_event = TRUE;
1012 xorg_list_for_each_entry_safe (curr, next, &cvt->func_datas, link)
1015 curr->func (cvt, src_vbuf, dst_vbuf, curr->data, error);
1018 _secCvtDequeued (cvt, EXYNOS_DRM_OPS_SRC, buf_idx[EXYNOS_DRM_OPS_SRC]);
1019 _secCvtDequeued (cvt, EXYNOS_DRM_OPS_DST, buf_idx[EXYNOS_DRM_OPS_DST]);