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 static Bool can_pause = TRUE;
51 typedef struct _SECCvtFuncData
55 struct xorg_list link;
58 typedef struct _SECCvtBuf
62 unsigned int handles[EXYNOS_DRM_PLANAR_MAX];
67 struct xorg_list link;
78 SECCvtProp props[CVT_TYPE_MAX];
80 struct xorg_list func_datas;
81 struct xorg_list src_bufs;
82 struct xorg_list dst_bufs;
93 struct xorg_list link;
96 static unsigned int formats[] =
117 static struct xorg_list cvt_list;
122 static Bool inited = FALSE;
127 xorg_list_init (&cvt_list);
133 _findCvt (CARD32 stamp)
135 SECCvt *cur = NULL, *next = NULL;
139 if (cvt_list.next != NULL)
141 xorg_list_for_each_entry_safe (cur, next, &cvt_list, link)
143 if (cur->stamp == stamp)
151 static enum drm_exynos_ipp_cmd
152 _drmCommand (SECCvtOp op)
157 return IPP_CMD_OUTPUT;
163 static enum drm_exynos_degree
164 _drmDegree (int degree)
166 switch (degree % 360)
169 return EXYNOS_DRM_DEGREE_90;
171 return EXYNOS_DRM_DEGREE_180;
173 return EXYNOS_DRM_DEGREE_270;
175 return EXYNOS_DRM_DEGREE_0;
180 _FillConfig (SECCvtType type, SECCvtProp *prop, struct drm_exynos_ipp_config *config)
182 config->ops_id = (type == CVT_TYPE_SRC) ? EXYNOS_DRM_OPS_SRC : EXYNOS_DRM_OPS_DST;
185 config->flip |= EXYNOS_DRM_FLIP_HORIZONTAL;
187 config->flip |= EXYNOS_DRM_FLIP_VERTICAL;
189 config->degree = _drmDegree (prop->degree);
190 config->fmt = secUtilGetDrmFormat (prop->id);
191 config->sz.hsize = (__u32)prop->width;
192 config->sz.vsize = (__u32)prop->height;
193 config->pos.x = (__u32)prop->crop.x;
194 config->pos.y = (__u32)prop->crop.y;
195 config->pos.w = (__u32)prop->crop.width;
196 config->pos.h = (__u32)prop->crop.height;
200 _fillProperty (SECCvt *cvt, SECCvtType type, SECVideoBuf *vbuf, SECCvtProp *prop)
203 prop->width = vbuf->width;
204 prop->height = vbuf->height;
205 prop->crop = vbuf->crop;
207 prop->degree = cvt->props[type].degree;
208 prop->vflip = cvt->props[type].vflip;
209 prop->hflip = cvt->props[type].hflip;
210 prop->secure = cvt->props[type].secure;
211 prop->csc_range = cvt->props[type].csc_range;
215 _SetVbufConverting (SECVideoBuf *vbuf, SECCvt *cvt, Bool converting)
219 ConvertInfo *cur = NULL, *next = NULL;
221 xorg_list_for_each_entry_safe (cur, next, &vbuf->convert_info, link)
223 if (cur->cvt == (void*)cvt)
225 xorg_list_del (&cur->link);
231 XDBG_ERROR (MCVT, "failed: %ld not found in %ld.\n", cvt->stamp, vbuf->stamp);
236 ConvertInfo *info = NULL, *next = NULL;
238 xorg_list_for_each_entry_safe (info, next, &vbuf->convert_info, link)
240 if (info->cvt == (void*)cvt)
242 XDBG_ERROR (MCVT, "failed: %ld already converting %ld.\n", cvt->stamp, vbuf->stamp);
247 info = calloc (1, sizeof (ConvertInfo));
248 XDBG_RETURN_VAL_IF_FAIL (info != NULL, FALSE);
250 info->cvt = (void*)cvt;
252 xorg_list_add (&info->link, &vbuf->convert_info);
260 _printBufIndices (SECCvt *cvt, SECCvtType type, char *str)
262 struct xorg_list *bufs;
263 SECCvtBuf *cur, *next;
266 bufs = (type == CVT_TYPE_SRC) ? &cvt->src_bufs : &cvt->dst_bufs;
268 snprintf (nums, 128, "bufs:");
270 list_rev_for_each_entry_safe (cur, next, bufs, link)
272 snprintf (nums, 128, "%s %d", nums, cur->index);
275 ErrorF ("%s: cvt(%p) %s(%s). \n", str, cvt,
276 (type == CVT_TYPE_SRC)?"SRC":"DST", nums);
281 _secCvtGetEmptyIndex (SECCvt *cvt, SECCvtType type)
286 if(type == CVT_TYPE_SRC)
288 ret = cvt->src_index++;
289 if (cvt->src_index >= CVT_BUF_MAX)
294 ret = cvt->dst_index++;
295 if (cvt->dst_index >= CVT_BUF_MAX)
301 struct xorg_list *bufs;
302 SECCvtBuf *cur = NULL, *next = NULL;
305 bufs = (type == CVT_TYPE_SRC) ? &cvt->src_bufs : &cvt->dst_bufs;
311 xorg_list_for_each_entry_safe (cur, next, bufs, link)
313 if (ret == cur->index)
331 _secCvtFindBuf (SECCvt *cvt, SECCvtType type, int index)
333 struct xorg_list *bufs;
334 SECCvtBuf *cur = NULL, *next = NULL;
336 bufs = (type == CVT_TYPE_SRC) ? &cvt->src_bufs : &cvt->dst_bufs;
338 xorg_list_for_each_entry_safe (cur, next, bufs, link)
340 if (index == cur->index)
344 XDBG_ERROR (MCVT, "cvt(%p), type(%d), index(%d) not found.\n", cvt, type, index);
350 _secCvtQueue (SECCvt *cvt, SECCvtBuf *cbuf)
352 struct drm_exynos_ipp_queue_buf buf = {0,};
353 struct xorg_list *bufs;
355 int index = _secCvtGetEmptyIndex (cvt, cbuf->type);
357 buf.prop_id = cvt->prop_id;
358 buf.ops_id = (cbuf->type == CVT_TYPE_SRC) ? EXYNOS_DRM_OPS_SRC : EXYNOS_DRM_OPS_DST;
359 buf.buf_type = IPP_BUF_ENQUEUE;
360 buf.buf_id = cbuf->index = index;
361 buf.user_data = (__u64)cvt->stamp;
363 for (i = 0; i < EXYNOS_DRM_PLANAR_MAX; i++)
364 buf.handle[i] = (__u32)cbuf->handles[i];
366 if (!secDrmIppQueueBuf (cvt->pScrn, &buf))
369 bufs = (cbuf->type == CVT_TYPE_SRC) ? &cvt->src_bufs : &cvt->dst_bufs;
370 xorg_list_add (&cbuf->link, bufs);
372 _SetVbufConverting (cbuf->vbuf, cvt, TRUE);
375 if (cbuf->type == CVT_TYPE_SRC)
376 _printBufIndices (cvt, CVT_TYPE_SRC, "in");
379 XDBG_DEBUG (MCVT, "cvt(%p), cbuf(%p), type(%d), index(%d) vbuf(%p) converting(%d)\n",
380 cvt, cbuf, cbuf->type, index, cbuf->vbuf, VBUF_IS_CONVERTING (cbuf->vbuf));
386 _secCvtDequeue (SECCvt *cvt, SECCvtBuf *cbuf)
388 struct drm_exynos_ipp_queue_buf buf = {0,};
391 if (!_secCvtFindBuf (cvt, cbuf->type, cbuf->index))
393 XDBG_WARNING (MCVT, "cvt(%p) type(%d), index(%d) already dequeued!\n",
394 cvt, cbuf->type, cbuf->index);
398 XDBG_RETURN_IF_FAIL (VBUF_IS_VALID (cbuf->vbuf));
400 buf.prop_id = cvt->prop_id;
401 buf.ops_id = (cbuf->type == CVT_TYPE_SRC) ? EXYNOS_DRM_OPS_SRC : EXYNOS_DRM_OPS_DST;
402 buf.buf_type = IPP_BUF_DEQUEUE;
403 buf.buf_id = cbuf->index;
404 buf.user_data = (__u64)cvt->stamp;
406 for (i = 0; i < EXYNOS_DRM_PLANAR_MAX; i++)
407 buf.handle[i] = (__u32)cbuf->handles[i];
409 if (!secDrmIppQueueBuf (cvt->pScrn, &buf))
414 _secCvtDequeued (SECCvt *cvt, SECCvtType type, int index)
416 SECCvtBuf *cbuf = _secCvtFindBuf (cvt, type, index);
420 XDBG_WARNING (MCVT, "cvt(%p) type(%d), index(%d) already dequeued!\n",
425 XDBG_RETURN_IF_FAIL (VBUF_IS_VALID (cbuf->vbuf));
427 _SetVbufConverting (cbuf->vbuf, cvt, FALSE);
429 XDBG_DEBUG (MCVT, "cvt(%p) type(%d) index(%d) vbuf(%p) converting(%d)\n",
430 cvt, type, index, cbuf->vbuf, VBUF_IS_CONVERTING (cbuf->vbuf));
432 xorg_list_del (&cbuf->link);
435 if (cbuf->type == CVT_TYPE_SRC)
436 _printBufIndices (cvt, CVT_TYPE_SRC, "out");
439 secUtilVideoBufferUnref (cbuf->vbuf);
444 _secCvtDequeueAll (SECCvt *cvt)
446 SECCvtBuf *cur = NULL, *next = NULL;
448 xorg_list_for_each_entry_safe (cur, next, &cvt->src_bufs, link)
450 _secCvtDequeue (cvt, cur);
453 xorg_list_for_each_entry_safe (cur, next, &cvt->dst_bufs, link)
455 _secCvtDequeue (cvt, cur);
460 _secCvtDequeuedAll (SECCvt *cvt)
462 SECCvtBuf *cur = NULL, *next = NULL;
464 xorg_list_for_each_entry_safe (cur, next, &cvt->src_bufs, link)
466 _secCvtDequeued (cvt, EXYNOS_DRM_OPS_SRC, cur->index);
469 xorg_list_for_each_entry_safe (cur, next, &cvt->dst_bufs, link)
471 _secCvtDequeued (cvt, EXYNOS_DRM_OPS_DST, cur->index);
476 _secCvtStop (SECCvt *cvt)
478 struct drm_exynos_ipp_cmd_ctrl ctrl = {0,};
480 XDBG_RETURN_IF_FAIL (cvt != NULL);
485 _secCvtDequeueAll (cvt);
487 ctrl.prop_id = cvt->prop_id;
488 ctrl.ctrl = IPP_CTRL_STOP;
490 secDrmIppCmdCtrl (cvt->pScrn, &ctrl);
492 _secCvtDequeuedAll (cvt);
494 XDBG_TRACE (MCVT, "cvt(%p)\n", cvt);
498 memset (cvt->props, 0, sizeof (SECCvtProp) * CVT_TYPE_MAX);
504 cvt->started = FALSE;
510 secCvtSupportFormat (SECCvtOp op, int id)
512 unsigned int *drmfmts;
513 int i, size, num = 0;
514 unsigned int drmfmt = secUtilGetDrmFormat (id);
516 XDBG_RETURN_VAL_IF_FAIL (op >= 0 && op < CVT_OP_MAX, FALSE);
517 XDBG_RETURN_VAL_IF_FAIL (id > 0, FALSE);
519 size = sizeof (formats) / sizeof (unsigned int);
521 for (i = 0; i < size; i++)
522 if (formats[i] == id)
527 XDBG_ERROR (MCVT, "converter(op:%d) not support : '%c%c%c%c'.\n",
528 op, FOURCC_STR (id));
532 drmfmts = secDrmIppGetFormatList (&num);
535 XDBG_ERROR (MCVT, "no drm format list.\n");
539 for (i = 0; i < num; i++)
540 if (drmfmts[i] == drmfmt)
546 XDBG_ERROR (MCVT, "drm ipp not support : '%c%c%c%c'.\n", FOURCC_STR (id));
554 secCvtEnsureSize (SECCvtProp *src, SECCvtProp *dst)
558 int type = secUtilGetColorType (src->id);
560 XDBG_RETURN_VAL_IF_FAIL (src->width >= 16, FALSE);
561 XDBG_RETURN_VAL_IF_FAIL (src->height >= 8, FALSE);
562 XDBG_RETURN_VAL_IF_FAIL (src->crop.width >= 16, FALSE);
563 XDBG_RETURN_VAL_IF_FAIL (src->crop.height >= 8, FALSE);
567 if (!IS_ZEROCOPY (src->id))
569 int new_width = (src->width + 16) & (~0xF);
570 XDBG_DEBUG (MCVT, "src's width : %d to %d.\n", src->width, new_width);
571 src->width = new_width;
575 if (type == TYPE_YUV420 && src->height % 2)
576 XDBG_WARNING (MCVT, "src's height(%d) is not multiple of 2!!!\n", src->height);
578 if (type == TYPE_YUV420 || type == TYPE_YUV422)
580 src->crop.x = src->crop.x & (~0x1);
581 src->crop.width = src->crop.width & (~0x1);
584 if (type == TYPE_YUV420)
585 src->crop.height = src->crop.height & (~0x1);
587 if (src->crop.x + src->crop.width > src->width)
588 src->crop.width = src->width - src->crop.x;
589 if (src->crop.y + src->crop.height > src->height)
590 src->crop.height = src->height - src->crop.y;
595 int type = secUtilGetColorType (dst->id);
597 XDBG_RETURN_VAL_IF_FAIL (dst->width >= 16, FALSE);
598 XDBG_RETURN_VAL_IF_FAIL (dst->height >= 8, FALSE);
599 XDBG_RETURN_VAL_IF_FAIL (dst->crop.width >= 16, FALSE);
600 XDBG_RETURN_VAL_IF_FAIL (dst->crop.height >= 4, FALSE);
604 int new_width = (dst->width + 16) & (~0xF);
605 XDBG_DEBUG (MCVT, "dst's width : %d to %d.\n", dst->width, new_width);
606 dst->width = new_width;
609 dst->height = dst->height & (~0x1);
611 if (type == TYPE_YUV420 && dst->height % 2)
612 XDBG_WARNING (MCVT, "dst's height(%d) is not multiple of 2!!!\n", dst->height);
614 if (type == TYPE_YUV420 || type == TYPE_YUV422)
616 dst->crop.x = dst->crop.x & (~0x1);
617 dst->crop.width = dst->crop.width & (~0x1);
620 if (type == TYPE_YUV420)
621 dst->crop.height = dst->crop.height & (~0x1);
623 if (dst->crop.x + dst->crop.width > dst->width)
624 dst->crop.width = dst->width - dst->crop.x;
625 if (dst->crop.y + dst->crop.height > dst->height)
626 dst->crop.height = dst->height - dst->crop.y;
633 secCvtCreate (ScrnInfoPtr pScrn, SECCvtOp op)
636 CARD32 stamp = GetTimeInMillis ();
640 XDBG_RETURN_VAL_IF_FAIL (pScrn != NULL, NULL);
641 XDBG_RETURN_VAL_IF_FAIL (op >= 0 && op < CVT_OP_MAX, NULL);
643 while (_findCvt (stamp))
646 cvt = calloc (1, sizeof (SECCvt));
647 XDBG_RETURN_VAL_IF_FAIL (cvt != NULL, NULL);
655 xorg_list_init (&cvt->func_datas);
656 xorg_list_init (&cvt->src_bufs);
657 xorg_list_init (&cvt->dst_bufs);
659 XDBG_TRACE (MCVT, "op(%d), cvt(%p) stamp(%ld)\n", op, cvt, stamp);
661 xorg_list_add (&cvt->link, &cvt_list);
667 secCvtDestroy (SECCvt *cvt)
669 SECCvtFuncData *cur = NULL, *next = NULL;
676 xorg_list_del (&cvt->link);
678 xorg_list_for_each_entry_safe (cur, next, &cvt->func_datas, link)
680 xorg_list_del (&cur->link);
684 XDBG_TRACE (MCVT, "cvt(%p)\n", cvt);
690 secCvtGetOp (SECCvt *cvt)
692 XDBG_RETURN_VAL_IF_FAIL (cvt != NULL, CVT_OP_M2M);
698 secCvtSetProperpty (SECCvt *cvt, SECCvtProp *src, SECCvtProp *dst)
700 if (cvt->started && !cvt->paused)
703 struct drm_exynos_ipp_property property;
705 XDBG_RETURN_VAL_IF_FAIL (cvt != NULL, FALSE);
706 XDBG_RETURN_VAL_IF_FAIL (src != NULL, FALSE);
707 XDBG_RETURN_VAL_IF_FAIL (dst != NULL, FALSE);
709 if (!secCvtEnsureSize (src, dst))
712 if (dst->crop.x + dst->crop.width > dst->width)
714 XDBG_ERROR (MCVT, "dst(%d+%d > %d). !\n", dst->crop.x, dst->crop.width, dst->width);
717 if (!secCvtSupportFormat (cvt->op, src->id))
719 XDBG_ERROR (MCVT, "cvt(%p) src '%c%c%c%c' not supported.\n",
720 cvt, FOURCC_STR (src->id));
724 if (!secCvtSupportFormat (cvt->op, dst->id))
726 XDBG_ERROR (MCVT, "cvt(%p) dst '%c%c%c%c' not supported.\n",
727 cvt, FOURCC_STR (dst->id));
731 memcpy (&cvt->props[CVT_TYPE_SRC], src, sizeof (SECCvtProp));
732 memcpy (&cvt->props[CVT_TYPE_DST], dst, sizeof (SECCvtProp));
735 _FillConfig (CVT_TYPE_SRC, &cvt->props[CVT_TYPE_SRC], &property.config[0]);
736 _FillConfig (CVT_TYPE_DST, &cvt->props[CVT_TYPE_DST], &property.config[1]);
737 property.cmd = _drmCommand (cvt->op);
738 #ifdef _F_WEARABLE_FEATURE_
739 property.type = IPP_EVENT_DRIVEN;
741 property.prop_id = cvt->prop_id;
742 property.protect = dst->secure;
743 property.range = dst->csc_range;
745 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",
746 cvt, FOURCC_STR(src->id), FOURCC_STR(secUtilGetDrmFormat(src->id)),
747 src->width, src->height,
748 src->crop.x, src->crop.y, src->crop.width, src->crop.height,
749 src->degree, src->hflip, src->vflip,
750 src->secure, src->csc_range);
752 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",
753 cvt, FOURCC_STR(dst->id), FOURCC_STR(secUtilGetDrmFormat(dst->id)),
754 dst->width, dst->height,
755 dst->crop.x, dst->crop.y, dst->crop.width, dst->crop.height,
756 dst->degree, dst->hflip, dst->vflip,
757 dst->secure, dst->csc_range);
759 cvt->prop_id = secDrmIppSetProperty (cvt->pScrn, &property);
760 XDBG_RETURN_VAL_IF_FAIL (cvt->prop_id >= 0, FALSE);
766 secCvtGetProperpty (SECCvt *cvt, SECCvtProp *src, SECCvtProp *dst)
768 XDBG_RETURN_IF_FAIL (cvt != NULL);
771 *src = cvt->props[CVT_TYPE_SRC];
774 *dst = cvt->props[CVT_TYPE_DST];
778 secCvtConvert (SECCvt *cvt, SECVideoBuf *src, SECVideoBuf *dst)
780 SECCvtBuf *src_cbuf = NULL, *dst_cbuf = NULL;
781 SECCvtProp src_prop, dst_prop;
783 XDBG_RETURN_VAL_IF_FAIL (cvt != NULL, FALSE);
784 XDBG_RETURN_VAL_IF_FAIL (cvt->op == CVT_OP_M2M, FALSE);
785 XDBG_RETURN_VAL_IF_FAIL (src != NULL, FALSE);
786 XDBG_RETURN_VAL_IF_FAIL (dst != NULL, FALSE);
787 XDBG_RETURN_VAL_IF_FAIL (VBUF_IS_VALID (src), FALSE);
788 XDBG_RETURN_VAL_IF_FAIL (VBUF_IS_VALID (dst), FALSE);
790 _fillProperty (cvt, CVT_TYPE_SRC, src, &src_prop);
791 _fillProperty (cvt, CVT_TYPE_DST, dst, &dst_prop);
793 if (memcmp (&cvt->props[CVT_TYPE_SRC], &src_prop, sizeof (SECCvtProp)) ||
794 memcmp (&cvt->props[CVT_TYPE_DST], &dst_prop, sizeof (SECCvtProp)))
796 XDBG_ERROR (MCVT, "cvt(%p) prop changed!\n", cvt);
797 XDBG_TRACE (MCVT, "cvt(%p) src_old('%c%c%c%c', %dx%d, %d,%d %dx%d, %d, %d&%d, %d, %d)\n",
798 cvt, FOURCC_STR(cvt->props[CVT_TYPE_SRC].id),
799 cvt->props[CVT_TYPE_SRC].width, cvt->props[CVT_TYPE_SRC].height,
800 cvt->props[CVT_TYPE_SRC].crop.x, cvt->props[CVT_TYPE_SRC].crop.y,
801 cvt->props[CVT_TYPE_SRC].crop.width, cvt->props[CVT_TYPE_SRC].crop.height,
802 cvt->props[CVT_TYPE_SRC].degree,
803 cvt->props[CVT_TYPE_SRC].hflip, cvt->props[CVT_TYPE_SRC].vflip,
804 cvt->props[CVT_TYPE_SRC].secure, cvt->props[CVT_TYPE_SRC].csc_range);
805 XDBG_TRACE (MCVT, "cvt(%p) src_new('%c%c%c%c', %dx%d, %d,%d %dx%d, %d, %d&%d, %d, %d)\n",
806 cvt, FOURCC_STR(src_prop.id), src_prop.width, src_prop.height,
807 src_prop.crop.x, src_prop.crop.y, src_prop.crop.width, src_prop.crop.height,
808 src_prop.degree, src_prop.hflip, src_prop.vflip,
809 src_prop.secure, src_prop.csc_range);
810 XDBG_TRACE (MCVT, "cvt(%p) dst_old('%c%c%c%c', %dx%d, %d,%d %dx%d, %d, %d&%d, %d, %d)\n",
811 cvt, FOURCC_STR(cvt->props[CVT_TYPE_DST].id),
812 cvt->props[CVT_TYPE_DST].width, cvt->props[CVT_TYPE_DST].height,
813 cvt->props[CVT_TYPE_DST].crop.x, cvt->props[CVT_TYPE_DST].crop.y,
814 cvt->props[CVT_TYPE_DST].crop.width, cvt->props[CVT_TYPE_DST].crop.height,
815 cvt->props[CVT_TYPE_DST].degree,
816 cvt->props[CVT_TYPE_DST].hflip, cvt->props[CVT_TYPE_DST].vflip,
817 cvt->props[CVT_TYPE_DST].secure, cvt->props[CVT_TYPE_DST].csc_range);
818 XDBG_TRACE (MCVT, "cvt(%p) dst_new('%c%c%c%c', %dx%d, %d,%d %dx%d, %d, %d&%d, %d, %d)\n",
819 cvt, FOURCC_STR(dst_prop.id), dst_prop.width, dst_prop.height,
820 dst_prop.crop.x, dst_prop.crop.y, dst_prop.crop.width, dst_prop.crop.height,
821 dst_prop.degree, dst_prop.hflip, dst_prop.vflip,
822 dst_prop.secure, dst_prop.csc_range);
826 XDBG_GOTO_IF_FAIL (cvt->prop_id >= 0, fail_to_convert);
827 XDBG_GOTO_IF_FAIL (src->handles[0] > 0, fail_to_convert);
828 XDBG_GOTO_IF_FAIL (dst->handles[0] > 0, fail_to_convert);
830 src_cbuf = calloc (1, sizeof (SECCvtBuf));
831 XDBG_GOTO_IF_FAIL (src_cbuf != NULL, fail_to_convert);
832 dst_cbuf = calloc (1, sizeof (SECCvtBuf));
833 XDBG_GOTO_IF_FAIL (dst_cbuf != NULL, fail_to_convert);
835 src_cbuf->type = CVT_TYPE_SRC;
836 src_cbuf->vbuf = secUtilVideoBufferRef (src);
837 memcpy (src_cbuf->handles, src->handles, sizeof (unsigned int) * EXYNOS_DRM_PLANAR_MAX);
839 if (!_secCvtQueue (cvt, src_cbuf))
841 secUtilVideoBufferUnref (src_cbuf->vbuf);
842 goto fail_to_convert;
845 XDBG_DEBUG (MCVT, "cvt(%p) srcbuf(%p) converting(%d)\n",
846 cvt, src, VBUF_IS_CONVERTING (src));
848 dst_cbuf->type = CVT_TYPE_DST;
849 dst_cbuf->vbuf = secUtilVideoBufferRef (dst);
850 memcpy (dst_cbuf->handles, dst->handles, sizeof (unsigned int) * EXYNOS_DRM_PLANAR_MAX);
852 if (!_secCvtQueue (cvt, dst_cbuf))
854 secUtilVideoBufferUnref (dst_cbuf->vbuf);
855 goto fail_to_convert;
858 XDBG_DEBUG (MCVT, "cvt(%p) dstbuf(%p) converting(%d)\n",
859 cvt, dst, VBUF_IS_CONVERTING (dst));
861 XDBG_DEBUG (MVBUF, "==> ipp (%ld,%d,%d : %ld,%d,%d) \n",
862 src->stamp, VBUF_IS_CONVERTING (src), src->showing,
863 dst->stamp, VBUF_IS_CONVERTING (dst), dst->showing);
867 struct drm_exynos_ipp_cmd_ctrl ctrl = {0,};
869 ctrl.prop_id = cvt->prop_id;
870 ctrl.ctrl = IPP_CTRL_PLAY;
872 if (!secDrmIppCmdCtrl (cvt->pScrn, &ctrl))
873 goto fail_to_convert;
875 XDBG_TRACE (MCVT, "cvt(%p) start.\n", cvt);
879 else if (cvt->paused)
881 struct drm_exynos_ipp_cmd_ctrl ctrl = {0,};
883 ctrl.prop_id = cvt->prop_id;
884 ctrl.ctrl = IPP_CTRL_RESUME;
886 if (!secDrmIppCmdCtrl (cvt->pScrn, &ctrl))
887 goto fail_to_convert;
889 XDBG_TRACE (MCVT, "cvt(%p) resume.\n", cvt);
896 SECPtr pSec = SECPTR (cvt->pScrn);
897 if (pSec->xvperf_mode & XBERC_XVPERF_MODE_CVT)
898 src_cbuf->begin = GetTimeInMillis ();
915 secCvtAddCallback (SECCvt *cvt, CvtFunc func, void *data)
917 SECCvtFuncData *func_data;
919 XDBG_RETURN_VAL_IF_FAIL (cvt != NULL, FALSE);
920 XDBG_RETURN_VAL_IF_FAIL (func != NULL, FALSE);
922 func_data = calloc (1, sizeof (SECCvtFuncData));
923 XDBG_RETURN_VAL_IF_FAIL (func_data != NULL, FALSE);
925 xorg_list_add (&func_data->link, &cvt->func_datas);
927 func_data->func = func;
928 func_data->data = data;
934 secCvtRemoveCallback (SECCvt *cvt, CvtFunc func, void *data)
936 SECCvtFuncData *cur = NULL, *next = NULL;
938 XDBG_RETURN_IF_FAIL (cvt != NULL);
939 XDBG_RETURN_IF_FAIL (func != NULL);
941 xorg_list_for_each_entry_safe (cur, next, &cvt->func_datas, link)
943 if (cur->func == func && cur->data == data)
945 xorg_list_del (&cur->link);
952 secCvtHandleIppEvent (int fd, unsigned int *buf_idx, void *data, Bool error)
954 CARD32 stamp = (CARD32)data;
956 SECCvtBuf *src_cbuf, *dst_cbuf;
957 SECVideoBuf *src_vbuf, *dst_vbuf;
958 SECCvtFuncData *curr = NULL, *next = NULL;
960 XDBG_RETURN_IF_FAIL (buf_idx != NULL);
962 cvt = _findCvt (stamp);
965 XDBG_DEBUG (MCVT, "invalid cvt's stamp (%ld).\n", stamp);
969 XDBG_DEBUG (MCVT, "cvt(%p) index(%d, %d)\n",
970 cvt, buf_idx[EXYNOS_DRM_OPS_SRC], buf_idx[EXYNOS_DRM_OPS_DST]);
974 snprintf (temp, 64, "%d,%d", buf_idx[EXYNOS_DRM_OPS_SRC], buf_idx[EXYNOS_DRM_OPS_DST]);
975 _printBufIndices (cvt, CVT_TYPE_SRC, temp);
979 SECCvtBuf *cur = NULL, *prev = NULL;
981 list_rev_for_each_entry_safe (cur, prev, &cvt->src_bufs, link)
983 if (buf_idx[EXYNOS_DRM_OPS_SRC] != cur->index)
985 unsigned int indice[EXYNOS_DRM_OPS_MAX] = {cur->index, cur->index};
987 XDBG_WARNING (MCVT, "cvt(%p) event(%d,%d) has been skipped!! \n",
988 cvt, cur->index, cur->index);
990 /* To make sure all events are received, _secCvtDequeued should be called
991 * for every event. If a event has been skipped, to call _secCvtDequeued
992 * forcely, we call secCvtHandleIppEvent recursivly.
994 secCvtHandleIppEvent (0, indice, (void*)cvt->stamp, TRUE);
1001 src_cbuf = _secCvtFindBuf (cvt, EXYNOS_DRM_OPS_SRC, buf_idx[EXYNOS_DRM_OPS_SRC]);
1002 XDBG_RETURN_IF_FAIL (src_cbuf != NULL);
1004 dst_cbuf = _secCvtFindBuf (cvt, EXYNOS_DRM_OPS_DST, buf_idx[EXYNOS_DRM_OPS_DST]);
1005 XDBG_RETURN_IF_FAIL (dst_cbuf != NULL);
1007 SECPtr pSec = SECPTR (cvt->pScrn);
1008 if (pSec->xvperf_mode & XBERC_XVPERF_MODE_CVT)
1011 cur = GetTimeInMillis ();
1012 sub = cur - src_cbuf->begin;
1013 ErrorF ("cvt(%p) ipp interval : %6ld ms\n", cvt, sub);
1016 src_vbuf = src_cbuf->vbuf;
1017 dst_vbuf = dst_cbuf->vbuf;
1019 XDBG_DEBUG (MVBUF, "<== ipp (%ld,%d,%d : %ld,%d,%d) \n",
1020 src_vbuf->stamp, VBUF_IS_CONVERTING (src_vbuf), src_vbuf->showing,
1021 dst_vbuf->stamp, VBUF_IS_CONVERTING (dst_vbuf), dst_vbuf->showing);
1023 if (!cvt->first_event)
1025 XDBG_DEBUG (MCVT, "cvt(%p) got a IPP event. \n", cvt);
1026 cvt->first_event = TRUE;
1029 xorg_list_for_each_entry_safe (curr, next, &cvt->func_datas, link)
1032 curr->func (cvt, src_vbuf, dst_vbuf, curr->data, error);
1035 _secCvtDequeued (cvt, EXYNOS_DRM_OPS_SRC, buf_idx[EXYNOS_DRM_OPS_SRC]);
1036 _secCvtDequeued (cvt, EXYNOS_DRM_OPS_DST, buf_idx[EXYNOS_DRM_OPS_DST]);
1040 secCvtPause (SECCvt *cvt)
1044 XDBG_DEBUG (MCVT, "IPP not support pause-resume mode\n");
1047 XDBG_RETURN_VAL_IF_FAIL (cvt != NULL, FALSE);
1048 struct drm_exynos_ipp_cmd_ctrl ctrl = {0,};
1050 ctrl.prop_id = cvt->prop_id;
1051 ctrl.ctrl = IPP_CTRL_PAUSE;
1053 if (!secDrmIppCmdCtrl (cvt->pScrn, &ctrl))
1056 XDBG_TRACE (MCVT, "cvt(%p) pause.\n", cvt);
1064 XDBG_ERROR (MCVT, "cvt(%p) pause error.\n", cvt);
1067 // _secCvtStop (cvt);