Add restriction of Direct drawing on external output. 77/26377/2
authorAndrii Sokolenko <a.sokolenko@samsung.com>
Thu, 21 Aug 2014 10:23:31 +0000 (13:23 +0300)
committerAndrii Sokolenko <a.sokolenko@samsung.com>
Wed, 3 Sep 2014 08:09:29 +0000 (11:09 +0300)
Change-Id: Id73cb298d93f9305ad3380fb5961b7d670a8588f

src/crtcconfig/sec_plane.c
src/xv/sec_video.c
src/xv/sec_video_tvout.c
src/xv/sec_video_tvout.h

index 7d654b9..23ceb56 100644 (file)
@@ -61,7 +61,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 /* HW restriction */
 #define MIN_WIDTH   32
-#define MIN_HEIGHT   32
+#define MIN_HEIGHT   4
 
 enum
 {
@@ -390,7 +390,7 @@ _check_hw_restriction (ScrnInfoPtr pScrn, int crtc_id, int buf_w, int buf_h,
     }
 
     aligned_dst->width = (aligned_dst->width - aligned_dst->x) & (~0x1);
-    aligned_dst->height = (aligned_dst->height - aligned_dst->y) & (~0x1);
+    aligned_dst->height = (aligned_dst->height - aligned_dst->y);
 
     aligned_src->x = (src->x < 0) ? 0 : src->x;
     aligned_src->y = (src->y < 0) ? 0 : src->y;
@@ -413,7 +413,7 @@ _check_hw_restriction (ScrnInfoPtr pScrn, int crtc_id, int buf_w, int buf_h,
     }
 
     aligned_src->width = (aligned_src->width - aligned_src->x) & (~0x1);
-    aligned_src->height = (aligned_src->height - aligned_src->y) & (~0x1);
+    aligned_src->height = (aligned_src->height - aligned_src->y);
 #if 0
     if (!virtual_screen)
     {
@@ -441,17 +441,20 @@ _check_hw_restriction (ScrnInfoPtr pScrn, int crtc_id, int buf_w, int buf_h,
         XDBG_TRACE (MPLN, " => buf_w(%d) src(%d,%d) dst(%d,%d), virt(%d) start(%d) end(%d)\n",
                     buf_w, *new_src_x, *new_src_w, *new_dst_x, *new_dst_w, virtual_screen, start_dst, end_dst);
 #endif
-    XDBG_TRACE (MPLN, "src(x%d,y%d w%d-h%d) dst(x%d,y%d w%d-h%d)\n",
+    XDBG_TRACE (MPLN, "src(x%d,y%d w%d-h%d) dst(x%d,y%d w%d-h%d) ratio_x %f ratio_y %f\n",
                 src->x, src->y, src->width, src->height,
-                dst->x, dst->y, dst->width, dst->height);
+                dst->x, dst->y, dst->width, dst->height,
+                (double) src->width/dst->width, (double) src->height/dst->height);
     if (!memcmp(aligned_src, src, sizeof(xRectangle))
         || !memcmp(aligned_dst, dst, sizeof(xRectangle)))
     {
-        XDBG_TRACE(MPLN, "===> src(x%d,y%d w%d-h%d) dst(x%d,y%d w%d-h%d)\n",
+        XDBG_TRACE(MPLN, "===> src(x%d,y%d w%d-h%d) dst(x%d,y%d w%d-h%d) ratio_x %f ratio_y %f\n",
                    aligned_src->x, aligned_src->y,
                    aligned_src->width, aligned_src->height,
                    aligned_dst->x, aligned_dst->y,
-                   aligned_dst->width, aligned_dst->height);
+                   aligned_dst->width, aligned_dst->height,
+                   (double) aligned_src->width / aligned_dst->width,
+                   (double) aligned_src->height / aligned_dst->height);
     }
     return TRUE;
 }
index 0c82900..e58d31b 100644 (file)
@@ -1520,7 +1520,6 @@ _secVideoCalculateSize (SECPortPrivPtr pPort)
     pPort->out_width = dst_prop.width;
     pPort->out_height = dst_prop.height;
     pPort->out_crop = dst_prop.crop;
-
     return TRUE;
 }
 
@@ -1801,6 +1800,16 @@ _secVideoPutImageTvout (SECPortPrivPtr pPort, int output, SECVideoBuf *inbuf)
         }
 
         tv_cvt = secVideoTvGetConverter (pPort->tv);
+
+        if (tv_cvt == NULL)
+        {
+            if (!secVideoCanDirectDrawing (NULL, pPort->d.src.width, pPort->d.src.height,
+                                           pPort->d.dst.width, pPort->d.dst.height))
+            {
+                XDBG_GOTO_IF_FAIL (secVideoTvReCreateConverter (pPort->tv),
+                                   fail_to_put_tvout);
+            }
+        }
         if (tv_cvt)
         {
             /* HDMI    : SN12
@@ -1836,7 +1845,11 @@ _secVideoPutImageTvout (SECPortPrivPtr pPort, int output, SECVideoBuf *inbuf)
                     secVideoTvSetConvertFormat (pPort->tv, FOURCC_RGB32);
             }
             else
+            {
+#if 0
                 secVideoTvSetConvertFormat (pPort->tv, FOURCC_SN12);
+#endif
+            }
 
             secCvtAddCallback (tv_cvt, _secVideoTvoutCvtCallback, pPort);
         }
@@ -2502,12 +2515,7 @@ SECVideoPutImage (ScrnInfoPtr pScrn,
     XDBG_TRACE (MVDO, "======================================= \n");
     XDBG_DEBUG(MVDO, "src:(x%d,y%d w%d-h%d), dst:(x%d,y%d w%d-h%d)\n",
                src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h);
-    XDBG_DEBUG(MVDO, "image size:(w%d-h%d)\n", width, height);
-    if (pDraw)
-    {
-        XDBG_DEBUG(MVDO, "pixmap:(x%d,y%d w%d-h%d)\n",
-                   pDraw->x, pDraw->y, pDraw->width, pDraw->height);
-    }
+    XDBG_DEBUG(MVDO, "image size:(w%d-h%d) fourcc(%c%c%c%c)\n", width, height, FOURCC_STR(id));
     pPort->pScrn = pScrn;
     pPort->d.id = id;
     pPort->d.buf = buf;
@@ -2570,6 +2578,11 @@ SECVideoPutImage (ScrnInfoPtr pScrn,
 
     old_drawing = pPort->drawing;
     pPort->drawing = _secVideodrawingOn (pPort);
+    if (pDraw)
+    {
+        XDBG_DEBUG(MVDO, "pixmap:(x%d,y%d w%d-h%d) on:%d\n",
+                   pDraw->x, pDraw->y, pDraw->width, pDraw->height, pPort->drawing);
+    }
     if (old_drawing != pPort->drawing)
     {
         _secVideoCloseConverter (pPort);
@@ -2663,14 +2676,14 @@ SECVideoPutImage (ScrnInfoPtr pScrn,
         pPort->inbuf_is_fb = FALSE;
         if (pPort->tv)
         {
-            if (secVideoTvResizeOutput (pPort->tv) == TRUE)
+            if (secVideoTvResizeOutput (pPort->tv, &pPort->d.src, &pPort->d.dst) == TRUE)
             {
-                if (secVideoTvGetConverter(pPort->tv) != NULL)
+                pPort->wait_vbuf = NULL;
+                SECCvt *tv_cvt = secVideoTvGetConverter (pPort->tv);
+                if (tv_cvt != NULL)
                 {
-                    secCvtAddCallback (secVideoTvGetConverter(pPort->tv),
-                                       _secVideoTvoutCvtCallback, pPort);
+                    secCvtAddCallback (tv_cvt, _secVideoTvoutCvtCallback, pPort);
                 }
-                pPort->wait_vbuf = NULL;
             }
             else
             {
index 04044d7..9bb11f4 100644 (file)
@@ -76,10 +76,13 @@ struct _SECVideoTv
     xRectangle   tv_rect;
     int          is_resized;
     unsigned int convert_id;
-};
+    unsigned int src_id;
+    SECLayerOutput output;
 
+};
+#if 0
 static Bool
-_secVieoTvCalSize (SECVideoTv* tv, int src_w, int src_h, int dst_w, int dst_h)
+_secVideoTvCalSize (SECVideoTv* tv, int src_w, int src_h, int dst_w, int dst_h)
 {
     float r;
 
@@ -105,7 +108,7 @@ _secVieoTvCalSize (SECVideoTv* tv, int src_w, int src_h, int dst_w, int dst_h)
 
     return TRUE;
 }
-
+#endif
 static SECVideoBuf*
 _secVideoTvGetOutBuffer (SECVideoTv* tv, int width, int height, Bool secure)
 {
@@ -211,14 +214,14 @@ _secVideoTvPutImageInternal (SECVideoTv *tv, SECVideoBuf *vbuf, xRectangle *rect
         secLayerFreezeUpdate (tv->layer, FALSE);
         tv->is_resized = 0;
     }
-
+#if 0
     if (tv->lpos == LAYER_LOWER1)
-        if (!_secVieoTvCalSize (tv, vbuf->width, vbuf->height,
+        if (!_secVideoTvCalSize (tv, vbuf->width, vbuf->height,
                                 rect->width, rect->height))
         {
             return 0;
         }
-
+#endif
     secLayerSetRect (tv->layer, &vbuf->crop, rect);
 
     ret = secLayerSetBuffer (tv->layer, vbuf);
@@ -284,9 +287,9 @@ secVideoTvConnect (ScrnInfoPtr pScrn, unsigned int id, SECLayerPos lpos)
         if (!secLayerSupport (pScrn, LAYER_OUTPUT_EXT, lpos, id))
         {
             /* used if id is not supported in case of lpos == LAYER_LOWER1. */
+            convert_id = FOURCC_SN12;
             tv->cvt = secCvtCreate (pScrn, CVT_OP_M2M);
             XDBG_GOTO_IF_FAIL (tv->cvt != NULL, fail_connect);
-
             secCvtAddCallback (tv->cvt, _secVideoTvCvtCallback, tv);
         }
         else
@@ -297,12 +300,13 @@ secVideoTvConnect (ScrnInfoPtr pScrn, unsigned int id, SECLayerPos lpos)
     }
 
     XDBG_DEBUG (MTVO, "id(%c%c%c%c), lpos(%d)!\n", FOURCC_STR (id), lpos);
-
+    tv->output = LAYER_OUTPUT_EXT;
     tv->pScrn = pScrn;
     tv->lpos = lpos;
     tv->outbuf_index = -1;
     tv->convert_id = convert_id;
     tv->outbuf_num = TVBUF_NUM;
+    tv->src_id = id;
 
     return tv;
 
@@ -317,7 +321,7 @@ fail_connect:
 }
 
 Bool
-secVideoTvResizeOutput (SECVideoTv* tv)
+secVideoTvResizeOutput (SECVideoTv* tv, xRectanglePtr src, xRectanglePtr dst)
 {
     if (tv == NULL)
         return FALSE;
@@ -336,11 +340,15 @@ secVideoTvResizeOutput (SECVideoTv* tv)
     if (tv->cvt)
     {
         secCvtDestroy (tv->cvt);
-        tv->cvt = secCvtCreate (tv->pScrn, CVT_OP_M2M);
-        XDBG_RETURN_VAL_IF_FAIL (tv->cvt != NULL, FALSE);
-        secCvtAddCallback (tv->cvt, _secVideoTvCvtCallback, tv);
+        tv->cvt = NULL;
+    }
+
+    if (!secVideoCanDirectDrawing (tv, src->width, src->height,
+                                   dst->width, dst->height))
+    {
+        secVideoTvReCreateConverter(tv);
     }
-//    secLayerHide(tv->layer);
+
     secLayerFreezeUpdate (tv->layer, TRUE);
     tv->is_resized = 1;
     return TRUE;
@@ -459,7 +467,10 @@ secVideoTvPutImage (SECVideoTv *tv, SECVideoBuf *vbuf, xRectangle *rect, int csc
 
     XDBG_RETURN_VAL_IF_FAIL (vbuf->handles[0] > 0, 0);
     XDBG_RETURN_VAL_IF_FAIL (vbuf->pitches[0] > 0, 0);
-
+    XDBG_RETURN_VAL_IF_FAIL (rect->width > 0, 0);
+    XDBG_RETURN_VAL_IF_FAIL (rect->height > 0, 0);
+    XDBG_RETURN_VAL_IF_FAIL (vbuf->width > 0, 0);
+    XDBG_RETURN_VAL_IF_FAIL (vbuf->height > 0, 0);
     _secVideoTvLayerEnsure (tv);
     XDBG_RETURN_VAL_IF_FAIL (tv->layer != NULL, 0);
 
@@ -566,3 +577,90 @@ secVideoTvSetConvertFormat (SECVideoTv *tv, unsigned int convert_id)
 
     XDBG_TRACE (MTVO, "convert_id(%c%c%c%c) \n", FOURCC_STR (convert_id));
 }
+
+Bool
+secVideoCanDirectDrawing (SECVideoTv *tv, int src_w, int src_h, int dst_w, int dst_h)
+{
+    XDBG_RETURN_VAL_IF_FAIL(src_w != 0, FALSE);
+    XDBG_RETURN_VAL_IF_FAIL(src_h != 0, FALSE);
+    XDBG_RETURN_VAL_IF_FAIL(dst_w != 0, FALSE);
+    XDBG_RETURN_VAL_IF_FAIL(dst_h != 0, FALSE);
+    int ratio_w = 0;
+    int ratio_h = 0;
+    XDBG_DEBUG(MTVO, "tv(%p) src_w %d, src_h %d, dst_w %d, dst_h %d\n",
+               tv, src_w, src_h, dst_w, dst_h);
+    if (src_w >= dst_w)
+    {
+        ratio_w = src_w / dst_w;
+        if (ratio_w > 4)
+        {
+            XDBG_DEBUG(MTVO, "Can't direct draw ratio_w (1/%d) < 1/4\n", ratio_w);
+            return FALSE;
+        }
+        XDBG_DEBUG(MTVO, "ratio_w = 1/%d\n", ratio_w);
+    }
+    else if (src_w < dst_w)
+    {
+        ratio_w = dst_w / src_w;
+        if (ratio_w > 16)
+        {
+            XDBG_DEBUG(MTVO, "Can't direct draw ratio_w (%d) > 16\n", ratio_w);
+            return FALSE;
+        }
+        XDBG_DEBUG(MTVO, "ratio_w = %d\n", ratio_w);
+    }
+
+    if (src_h >= dst_h)
+    {
+        ratio_h = src_h / dst_h;
+        if (ratio_h > 4)
+        {
+            XDBG_DEBUG(MTVO, "Can't direct draw ratio_h (1/%d) < 1/4\n", ratio_w);
+            return FALSE;
+        }
+        XDBG_DEBUG(MTVO, "ratio_h = 1/%d\n", ratio_h);
+    }
+    else if (src_h < dst_h)
+    {
+        ratio_h = dst_h / src_h;
+        if (ratio_h > 16)
+        {
+            XDBG_DEBUG(MTVO, "Can't direct draw ratio_w (%d) > 16\n", ratio_w);
+            return FALSE;
+        }
+        XDBG_DEBUG(MTVO, "ratio_h = %d\n", ratio_h);
+    }
+
+    if (ratio_w != ratio_h)
+    {
+        XDBG_DEBUG(MTVO, "Can't direct draw ratio_w (%d) != ratio_h (%d)\n", ratio_w, ratio_h);
+        return FALSE;
+    }
+
+    if (tv != NULL)
+    {
+        if (!secLayerSupport (tv->pScrn, tv->output, tv->lpos, tv->src_id))
+        {
+            XDBG_DEBUG(MTVO, "Can't direct draw. Layer not support. lpos(%d), src_id (%c%c%c%c)\n",
+            tv->lpos, FOURCC_STR(tv->src_id));
+            return FALSE;
+        }
+    }
+    XDBG_DEBUG(MTVO, "Support direct drawing\n");
+    return TRUE;
+}
+
+Bool
+secVideoTvReCreateConverter(SECVideoTv* tv)
+{
+    if (tv == NULL)
+        return FALSE;
+    if (tv->cvt)
+    {
+         secCvtDestroy (tv->cvt);
+    }
+    tv->cvt = secCvtCreate (tv->pScrn, CVT_OP_M2M);
+    XDBG_RETURN_VAL_IF_FAIL (tv->cvt != NULL, FALSE);
+    secCvtAddCallback (tv->cvt, _secVideoTvCvtCallback, tv);
+    return TRUE;
+}
index 9c2765e..a6f3567 100644 (file)
@@ -52,6 +52,8 @@ int         secVideoTvPutImage    (SECVideoTv *tv, SECVideoBuf *vbuf, xRectangle
 
 SECCvt*     secVideoTvGetConverter (SECVideoTv *tv);
 void        secVideoTvSetConvertFormat (SECVideoTv *tv, unsigned int convert_id);
-Bool        secVideoTvResizeOutput (SECVideoTv* tv);
+Bool        secVideoTvResizeOutput (SECVideoTv* tv, xRectanglePtr src, xRectanglePtr dst);
+Bool        secVideoCanDirectDrawing (SECVideoTv* tv, int src_w, int src_h, int dst_w, int dst_h);
+Bool        secVideoTvReCreateConverter (SECVideoTv* tv);
 
 #endif /* __SEC_VIDEO_TVOUT_H__ */