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 **************************************************************************/
32 #include "sec_display.h"
34 #include "sec_output.h"
35 #include "sec_accel.h"
37 #include "sec_converter.h"
38 #include "sec_video_tvout.h"
39 #include "sec_video_virtual.h"
40 #include "sec_video_fourcc.h"
41 #include "sec_drm_ipp.h"
42 #include "sec_layer.h"
45 #include <sys/ioctl.h>
47 #include <drm_fourcc.h>
51 /* HW restriction (VP) */
54 #define MAX_WIDTH 1920
55 #define MAX_HEIGHT 1080
56 #define MIN_SCALE 0.25
57 #define MAX_SCALE 16.0
59 /* private structure */
67 /* used if id is not supported in case of lpos == LAYER_LOWER1. */
78 unsigned int convert_id;
80 SECLayerOutput output;
85 _secVideoTvCalSize (SECVideoTv* tv, int src_w, int src_h, int dst_w, int dst_h)
89 if (src_w < MIN_WIDTH || src_h < MIN_HEIGHT)
91 XDBG_WARNING (MTVO, "size(%dx%d) must be more than (%dx%d).\n",
92 src_w, src_h, MIN_WIDTH, MAX_WIDTH);
95 r = (float)dst_w / src_w;
96 if (r < MIN_SCALE || r > MAX_SCALE)
98 XDBG_WARNING (MTVO, "ratio_w(%f) is out of range(%f~%f).\n",
99 r, MIN_SCALE, MAX_SCALE);
102 r = (float)dst_h / src_h;
103 if (r < MIN_SCALE || r > MAX_SCALE)
105 XDBG_WARNING (MTVO, "ratio_h(%d) is out of range(%f~%f).\n",
106 r, MIN_SCALE, MAX_SCALE);
113 _secVideoTvGetOutBuffer (SECVideoTv* tv, int width, int height, Bool secure)
115 int i = tv->outbuf_index, j;
119 tv->outbuf = (SECVideoBuf**)calloc (tv->outbuf_num, sizeof (SECVideoBuf*));
120 XDBG_RETURN_VAL_IF_FAIL (tv->outbuf != NULL, NULL);
124 if (i >= tv->outbuf_num)
127 for (j = 0; j < tv->outbuf_num; j++)
131 XDBG_DEBUG (MTVO, "outbuf(%p) converting(%d) showing(%d)\n",
132 tv->outbuf[i], VBUF_IS_CONVERTING (tv->outbuf[i]), tv->outbuf[i]->showing);
134 if (tv->outbuf[i] && !VBUF_IS_CONVERTING (tv->outbuf[i]) && !tv->outbuf[i]->showing)
136 tv->outbuf_index = i;
137 return tv->outbuf[i];
142 SECPtr pSec = SECPTR (tv->pScrn);
143 tv->outbuf[i] = secUtilAllocVideoBuffer (tv->pScrn, tv->convert_id, width, height,
144 (pSec->scanout)?TRUE:FALSE, TRUE, secure);
145 XDBG_RETURN_VAL_IF_FAIL (tv->outbuf[i] != NULL, NULL);
147 XDBG_DEBUG (MTVO, "outbuf(%p, %c%c%c%c)\n", tv->outbuf[i], FOURCC_STR (tv->convert_id));
149 tv->outbuf_index = i;
150 return tv->outbuf[i];
154 if (i >= tv->outbuf_num)
161 for (j = 0; j < tv->outbuf_num; j++)
164 snprintf (buffers, 1024, "%s %d(%d,%d) ", buffers, tv->outbuf[j]->keys[0],
165 VBUF_IS_CONVERTING (tv->outbuf[j]), tv->outbuf[j]->showing);
168 XDBG_ERROR (MTVO, "now all outbufs in use! %s\n", buffers);
170 XDBG_ERROR (MTVO, "now all outbufs in use!\n");
177 _secVideoTvLayerEnsure (SECVideoTv* tv)
184 XDBG_RETURN_VAL_IF_FAIL (tv->lpos != LAYER_NONE, FALSE);
186 layer = secLayerCreate (tv->pScrn, LAYER_OUTPUT_EXT, tv->lpos);
187 XDBG_RETURN_VAL_IF_FAIL (layer != NULL, FALSE);
195 _secVideoTvLayerDestroy (SECVideoTv* tv)
199 secLayerUnref (tv->layer);
205 _secVideoTvPutImageInternal (SECVideoTv *tv, SECVideoBuf *vbuf, xRectangle *rect)
209 XDBG_DEBUG (MTVO, "rect (%d,%d %dx%d) \n",
210 rect->x, rect->y, rect->width, rect->height);
212 if (tv->is_resized == 1)
214 secLayerFreezeUpdate (tv->layer, FALSE);
218 if (tv->lpos == LAYER_LOWER1)
219 if (!_secVideoTvCalSize (tv, vbuf->width, vbuf->height,
220 rect->width, rect->height))
225 secLayerSetRect (tv->layer, &vbuf->crop, rect);
227 ret = secLayerSetBuffer (tv->layer, vbuf);
232 secLayerShow (tv->layer);
238 _secVideoTvCvtCallback (SECCvt *cvt,
244 SECVideoTv *tv = (SECVideoTv*)cvt_data;
247 XDBG_RETURN_IF_FAIL (tv != NULL);
248 XDBG_RETURN_IF_FAIL (cvt != NULL);
249 XDBG_RETURN_IF_FAIL (VBUF_IS_VALID (dst));
251 XDBG_DEBUG (MTVO, "++++++++++++++++++++++++ \n");
253 for (i = 0; i < tv->outbuf_num; i++)
254 if (tv->outbuf[i] == dst)
256 XDBG_RETURN_IF_FAIL (i < tv->outbuf_num);
257 _secVideoTvPutImageInternal (tv, dst, &tv->tv_rect);
259 XDBG_DEBUG (MTVO, "++++++++++++++++++++++++.. \n");
263 secVideoTvConnect (ScrnInfoPtr pScrn, unsigned int id, SECLayerPos lpos)
265 SECVideoTv* tv = NULL;
267 unsigned int convert_id = FOURCC_RGB32;
268 XDBG_RETURN_VAL_IF_FAIL (pScrn != NULL, NULL);
269 XDBG_RETURN_VAL_IF_FAIL (lpos >= LAYER_LOWER1 && lpos <= LAYER_UPPER, NULL);
270 XDBG_RETURN_VAL_IF_FAIL (id > 0, NULL);
272 tv = calloc (sizeof (SECVideoTv), 1);
273 XDBG_RETURN_VAL_IF_FAIL (tv != NULL, NULL);
275 pSecMode = (SECModePtr) SECPTR (pScrn)->pSecMode;
277 if (lpos == LAYER_LOWER1 && pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
279 /* In case of video-only(virtual), we always use converter. */
280 tv->cvt = secCvtCreate (pScrn, CVT_OP_M2M);
281 XDBG_GOTO_IF_FAIL (tv->cvt != NULL, fail_connect);
283 secCvtAddCallback (tv->cvt, _secVideoTvCvtCallback, tv);
285 else if (lpos == LAYER_LOWER1 && pSecMode->conn_mode == DISPLAY_CONN_MODE_HDMI)
287 if (!secLayerSupport (pScrn, LAYER_OUTPUT_EXT, lpos, id))
289 /* used if id is not supported in case of lpos == LAYER_LOWER1. */
290 convert_id = FOURCC_SN12;
291 tv->cvt = secCvtCreate (pScrn, CVT_OP_M2M);
292 XDBG_GOTO_IF_FAIL (tv->cvt != NULL, fail_connect);
293 secCvtAddCallback (tv->cvt, _secVideoTvCvtCallback, tv);
297 XDBG_DEBUG(MTVO, "Not need converting id(%c%c%c%c)\n", FOURCC_STR (id));
302 XDBG_DEBUG (MTVO, "id(%c%c%c%c), lpos(%d)!\n", FOURCC_STR (id), lpos);
303 tv->output = LAYER_OUTPUT_EXT;
306 tv->outbuf_index = -1;
307 tv->convert_id = convert_id;
308 tv->outbuf_num = TVBUF_NUM;
317 secCvtDestroy (tv->cvt);
324 secVideoTvResizeOutput (SECVideoTv* tv, xRectanglePtr src, xRectanglePtr dst)
332 for (i = 0; i < tv->outbuf_num; i++)
334 secUtilVideoBufferUnref (tv->outbuf[i]);
342 secCvtDestroy (tv->cvt);
346 if (!secVideoCanDirectDrawing (tv, src->width, src->height,
347 dst->width, dst->height))
349 secVideoTvReCreateConverter(tv);
352 secLayerFreezeUpdate (tv->layer, TRUE);
358 secVideoTvDisconnect (SECVideoTv* tv)
362 XDBG_RETURN_IF_FAIL (tv != NULL);
364 XDBG_DEBUG (MTVO, "!\n");
367 secCvtDestroy (tv->cvt);
369 _secVideoTvLayerDestroy (tv);
373 for (i = 0; i < tv->outbuf_num; i++)
375 secUtilVideoBufferUnref (tv->outbuf[i]);
384 secVideoTvSetBuffer (SECVideoTv* tv, SECVideoBuf **vbufs, int bufnum)
388 XDBG_RETURN_VAL_IF_FAIL (tv != NULL, FALSE);
389 XDBG_RETURN_VAL_IF_FAIL (vbufs != NULL, FALSE);
390 XDBG_RETURN_VAL_IF_FAIL (bufnum >= TVBUF_NUM, FALSE);
394 XDBG_ERROR (MTVO, "already has buffers.\n");
398 tv->outbuf_num = bufnum;
399 tv->outbuf = (SECVideoBuf**)calloc (bufnum, sizeof (SECVideoBuf*));
400 XDBG_RETURN_VAL_IF_FAIL (tv->outbuf != NULL, FALSE);
402 for (i = 0; i < tv->outbuf_num; i++)
404 XDBG_GOTO_IF_FAIL (tv->convert_id == vbufs[i]->id, fail_set_buffer);
405 XDBG_GOTO_IF_FAIL (tv->tv_width == vbufs[i]->width, fail_set_buffer);
406 XDBG_GOTO_IF_FAIL (tv->tv_height == vbufs[i]->height, fail_set_buffer);
408 tv->outbuf[i] = secUtilVideoBufferRef (vbufs[i]);
409 XDBG_GOTO_IF_FAIL (tv->outbuf[i] != NULL, fail_set_buffer);
411 if (!tv->outbuf[i]->showing && tv->outbuf[i]->need_reset)
412 secUtilClearVideoBuffer (tv->outbuf[i]);
414 tv->outbuf[i]->need_reset = TRUE;
422 for (i = 0; i < tv->outbuf_num; i++)
426 secUtilVideoBufferUnref (tv->outbuf[i]);
427 tv->outbuf[i] = NULL;
438 secVideoTvGetPos (SECVideoTv *tv)
440 XDBG_RETURN_VAL_IF_FAIL (tv != NULL, LAYER_NONE);
446 secVideoTvGetLayer (SECVideoTv *tv)
448 XDBG_RETURN_VAL_IF_FAIL (tv != NULL, NULL);
450 _secVideoTvLayerEnsure (tv);
455 /* HDMI : 'handles' is "gem handle"
456 * VIRTUAL : 'handles' is "physical address"
457 * 'data' is "raw data"
458 * only one of 'handles' and 'data' has value.
461 secVideoTvPutImage (SECVideoTv *tv, SECVideoBuf *vbuf, xRectangle *rect, int csc_range)
463 XDBG_RETURN_VAL_IF_FAIL (tv != NULL, 0);
464 XDBG_RETURN_VAL_IF_FAIL (VBUF_IS_VALID (vbuf), 0);
465 XDBG_RETURN_VAL_IF_FAIL (vbuf->id > 0, 0);
466 XDBG_RETURN_VAL_IF_FAIL (rect != NULL, 0);
468 XDBG_RETURN_VAL_IF_FAIL (vbuf->handles[0] > 0, 0);
469 XDBG_RETURN_VAL_IF_FAIL (vbuf->pitches[0] > 0, 0);
470 XDBG_RETURN_VAL_IF_FAIL (rect->width > 0, 0);
471 XDBG_RETURN_VAL_IF_FAIL (rect->height > 0, 0);
472 XDBG_RETURN_VAL_IF_FAIL (vbuf->width > 0, 0);
473 XDBG_RETURN_VAL_IF_FAIL (vbuf->height > 0, 0);
474 _secVideoTvLayerEnsure (tv);
475 XDBG_RETURN_VAL_IF_FAIL (tv->layer != NULL, 0);
479 /* can't show buffer to HDMI at now. */
480 SECModePtr pSecMode = (SECModePtr) SECPTR (tv->pScrn)->pSecMode;
481 SECCvtProp src_prop = {0,}, dst_prop = {0,};
483 int dst_width, dst_height;
488 if (pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
490 XDBG_RETURN_VAL_IF_FAIL (tv->tv_width > 0, 0);
491 XDBG_RETURN_VAL_IF_FAIL (tv->tv_height > 0, 0);
492 dst_width = tv->tv_width;
493 dst_height = tv->tv_height;
498 tv->tv_rect.width = tv->tv_width;
499 tv->tv_rect.height = tv->tv_height;
503 dst_width = rect->width;
504 dst_height = rect->height;
512 src_prop.id = vbuf->id;
513 src_prop.width = vbuf->width;
514 src_prop.height = vbuf->height;
515 src_prop.crop = vbuf->crop;
517 dst_prop.id = tv->convert_id;
518 dst_prop.width = dst_width;
519 dst_prop.height = dst_height;
520 dst_prop.crop = dst_crop;
521 dst_prop.secure = vbuf->secure;
522 dst_prop.csc_range = csc_range;
524 if (!secCvtEnsureSize (&src_prop, &dst_prop))
527 outbuf = _secVideoTvGetOutBuffer (tv, dst_prop.width, dst_prop.height, vbuf->secure);
530 outbuf->crop = dst_prop.crop;
532 if (!secCvtSetProperpty (tv->cvt, &src_prop, &dst_prop))
535 if (!secCvtConvert (tv->cvt, vbuf, outbuf))
538 XDBG_TRACE (MTVO, "'%c%c%c%c' %dx%d (%d,%d %dx%d) => '%c%c%c%c' %dx%d (%d,%d %dx%d) convert. rect(%d,%d %dx%d)\n",
539 FOURCC_STR (vbuf->id), vbuf->width, vbuf->height,
540 vbuf->crop.x, vbuf->crop.y, vbuf->crop.width, vbuf->crop.height,
541 FOURCC_STR (outbuf->id), outbuf->width, outbuf->height,
542 outbuf->crop.x, outbuf->crop.y, outbuf->crop.width, outbuf->crop.height,
543 rect->x, rect->y, rect->width, rect->height);
547 /* can show buffer to HDMI at now. */
548 return _secVideoTvPutImageInternal (tv, vbuf, rect);
552 secVideoTvSetSize (SECVideoTv *tv, int width, int height)
554 XDBG_RETURN_IF_FAIL (tv != NULL);
556 tv->tv_width = width;
557 tv->tv_height = height;
559 XDBG_TRACE (MTVO, "size(%dx%d) \n", width, height);
563 secVideoTvGetConverter (SECVideoTv *tv)
565 XDBG_RETURN_VAL_IF_FAIL (tv != NULL, NULL);
571 secVideoTvSetConvertFormat (SECVideoTv *tv, unsigned int convert_id)
573 XDBG_RETURN_IF_FAIL (tv != NULL);
574 XDBG_RETURN_IF_FAIL (convert_id > 0);
576 tv->convert_id = convert_id;
578 XDBG_TRACE (MTVO, "convert_id(%c%c%c%c) \n", FOURCC_STR (convert_id));
582 secVideoCanDirectDrawing (SECVideoTv *tv, int src_w, int src_h, int dst_w, int dst_h)
584 XDBG_RETURN_VAL_IF_FAIL(src_w != 0, FALSE);
585 XDBG_RETURN_VAL_IF_FAIL(src_h != 0, FALSE);
586 XDBG_RETURN_VAL_IF_FAIL(dst_w != 0, FALSE);
587 XDBG_RETURN_VAL_IF_FAIL(dst_h != 0, FALSE);
590 XDBG_DEBUG(MTVO, "tv(%p) src_w %d, src_h %d, dst_w %d, dst_h %d\n",
591 tv, src_w, src_h, dst_w, dst_h);
594 ratio_w = src_w / dst_w;
597 XDBG_DEBUG(MTVO, "Can't direct draw ratio_w (1/%d) < 1/4\n", ratio_w);
600 XDBG_DEBUG(MTVO, "ratio_w = 1/%d\n", ratio_w);
602 else if (src_w < dst_w)
604 ratio_w = dst_w / src_w;
607 XDBG_DEBUG(MTVO, "Can't direct draw ratio_w (%d) > 16\n", ratio_w);
610 XDBG_DEBUG(MTVO, "ratio_w = %d\n", ratio_w);
615 ratio_h = src_h / dst_h;
618 XDBG_DEBUG(MTVO, "Can't direct draw ratio_h (1/%d) < 1/4\n", ratio_w);
621 XDBG_DEBUG(MTVO, "ratio_h = 1/%d\n", ratio_h);
623 else if (src_h < dst_h)
625 ratio_h = dst_h / src_h;
628 XDBG_DEBUG(MTVO, "Can't direct draw ratio_w (%d) > 16\n", ratio_w);
631 XDBG_DEBUG(MTVO, "ratio_h = %d\n", ratio_h);
634 if (ratio_w != ratio_h)
636 XDBG_DEBUG(MTVO, "Can't direct draw ratio_w (%d) != ratio_h (%d)\n", ratio_w, ratio_h);
642 if (!secLayerSupport (tv->pScrn, tv->output, tv->lpos, tv->src_id))
644 XDBG_DEBUG(MTVO, "Can't direct draw. Layer not support. lpos(%d), src_id (%c%c%c%c)\n",
645 tv->lpos, FOURCC_STR(tv->src_id));
649 XDBG_DEBUG(MTVO, "Support direct drawing\n");
654 secVideoTvReCreateConverter(SECVideoTv* tv)
660 secCvtDestroy (tv->cvt);
662 tv->cvt = secCvtCreate (tv->pScrn, CVT_OP_M2M);
663 XDBG_RETURN_VAL_IF_FAIL (tv->cvt != NULL, FALSE);
664 secCvtAddCallback (tv->cvt, _secVideoTvCvtCallback, tv);