Fix flickering resized video frame. 81/27081/4
authorAndrii Sokolenko <a.sokolenko@samsung.com>
Thu, 4 Sep 2014 08:02:40 +0000 (11:02 +0300)
committerAndrii Sokolenko <a.sokolenko@samsung.com>
Thu, 11 Sep 2014 08:14:29 +0000 (11:14 +0300)
Change-Id: I5d16ac11de9c665381ad2f9bd7ca9d3566ebe594

src/crtcconfig/sec_layer.c
src/crtcconfig/sec_plane.c
src/ipp/sec_converter.c
src/ipp/sec_converter.h
src/xv/sec_video.c
src/xv/sec_video_tvout.c

index c0414a5..db3270c 100644 (file)
@@ -308,7 +308,10 @@ _secLayerWatchVblank (SECLayer *layer)
     else
 #endif //NO_CRTC_MODE
     if (pSec->isLcdOff)
+    {
+        XDBG_DEBUG(MLYR, "pSec->isLcdOff (%d)\n", pSec->isLcdOff);
         return;
+    }
 
     pipe = secDisplayCrtcPipe (layer->pScrn, _GetCrtcID (layer));
 
@@ -492,7 +495,6 @@ secLayerCreate (ScrnInfoPtr pScrn, SECLayerOutput output, SECLayerPos lpos)
     }
 
     layer->ref_cnt = 1;
-
     xorg_list_init (&layer->noti_data);
 
     _secLayerInitList ();
@@ -623,7 +625,7 @@ secLayerHide (SECLayer *layer)
     XDBG_RETURN_IF_FAIL (layer != NULL);
 
     pSecMode = (SECModePtr) SECPTR (layer->pScrn)->pSecMode;
-
+#if 1
     if (!layer->visible || layer->ref_cnt > 1)
         return;
 
@@ -633,7 +635,7 @@ secLayerHide (SECLayer *layer)
         XDBG_TRACE (MLYR, "layer(%p) hidden. \n", layer);
         return;
     }
-
+#endif
     if (!secPlaneHide (layer->plane_id))
         return;
 
index 23ceb56..bd25ee2 100644 (file)
@@ -356,9 +356,9 @@ _check_hw_restriction (ScrnInfoPtr pScrn, int crtc_id, int buf_w, int buf_h,
         return FALSE;
     }
 
-    if (buf_h < MIN_HEIGHT || buf_h % 2)
+    if (buf_h < MIN_HEIGHT)
     {
-        XDBG_TRACE (MPLN, "hide: buf_h(%d) not 2's multiple or less than %d\n",
+        XDBG_TRACE (MPLN, "hide: buf_h(%d) less than %d\n",
                     buf_h, MIN_HEIGHT);
         return FALSE;
     }
index f4aa92a..49705e8 100644 (file)
@@ -46,6 +46,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define CVT_BUF_MAX    6
 #endif
 
+static Bool can_pause = TRUE;
+
 typedef struct _SECCvtFuncData
 {
     CvtFunc  func;
@@ -85,6 +87,7 @@ struct _SECCvt
 #endif
 
     Bool          started;
+    Bool          paused;
     Bool          first_event;
 
     struct xorg_list   link;
@@ -694,7 +697,7 @@ secCvtGetOp (SECCvt *cvt)
 Bool
 secCvtSetProperpty (SECCvt *cvt, SECCvtProp *src, SECCvtProp *dst)
 {
-    if (cvt->started)
+    if (cvt->started && !cvt->paused)
         return TRUE;
 
     struct drm_exynos_ipp_property property;
@@ -873,6 +876,20 @@ secCvtConvert (SECCvt *cvt, SECVideoBuf *src, SECVideoBuf *dst)
 
         cvt->started = TRUE;
     }
+    else if (cvt->paused)
+    {
+        struct drm_exynos_ipp_cmd_ctrl ctrl = {0,};
+
+        ctrl.prop_id = cvt->prop_id;
+        ctrl.ctrl = IPP_CTRL_RESUME;
+
+        if (!secDrmIppCmdCtrl (cvt->pScrn, &ctrl))
+            goto fail_to_convert;
+
+        XDBG_TRACE (MCVT, "cvt(%p) resume.\n", cvt);
+
+        cvt->paused = FALSE;
+    }
 
     dst->dirty = TRUE;
 
@@ -1018,3 +1035,36 @@ secCvtHandleIppEvent (int fd, unsigned int *buf_idx, void *data, Bool error)
     _secCvtDequeued (cvt, EXYNOS_DRM_OPS_SRC, buf_idx[EXYNOS_DRM_OPS_SRC]);
     _secCvtDequeued (cvt, EXYNOS_DRM_OPS_DST, buf_idx[EXYNOS_DRM_OPS_DST]);
 }
+
+Bool
+secCvtPause (SECCvt *cvt)
+{
+    if (!can_pause)
+    {
+        XDBG_DEBUG (MCVT, "IPP not support pause-resume mode\n");
+        return FALSE;
+    }
+    XDBG_RETURN_VAL_IF_FAIL (cvt != NULL, FALSE);
+    struct drm_exynos_ipp_cmd_ctrl ctrl = {0,};
+
+    ctrl.prop_id = cvt->prop_id;
+    ctrl.ctrl = IPP_CTRL_PAUSE;
+
+    if (!secDrmIppCmdCtrl (cvt->pScrn, &ctrl))
+        goto fail_to_pause;
+
+    XDBG_TRACE (MCVT, "cvt(%p) pause.\n", cvt);
+
+    cvt->paused = TRUE;
+
+    return TRUE;
+
+fail_to_pause:
+
+    XDBG_ERROR (MCVT, "cvt(%p) pause error.\n", cvt);
+    can_pause = FALSE;
+
+//    _secCvtStop (cvt);
+
+    return FALSE;
+}
index dfd1f47..e565a15 100644 (file)
@@ -86,5 +86,6 @@ Bool     secCvtAddCallback    (SECCvt *cvt, CvtFunc func, void *data);
 void     secCvtRemoveCallback (SECCvt *cvt, CvtFunc func, void *data);
 
 void     secCvtHandleIppEvent (int fd, unsigned int *buf_idx, void *data, Bool error);
+Bool     secCvtPause (SECCvt *cvt);
 
 #endif  /* __SEC_CONVERTER_H__ */
index e58d31b..9d8e074 100644 (file)
@@ -1353,11 +1353,11 @@ _secVideoTvoutCvtCallback (SECCvt *cvt,
 
     XDBG_DEBUG (MVDO, "######################## \n");
     XDBG_DEBUG (MVDO, "cvt(%p) src(%p) dst(%p)\n", cvt, src, dst);
-
+#if 0
     if (pPort->wait_vbuf != src)
         XDBG_WARNING (MVDO, "wait_vbuf(%p) != src(%p). \n",
                       pPort->wait_vbuf, src);
-
+#endif
     pPort->wait_vbuf = NULL;
 
     XDBG_DEBUG (MVDO, "########################.. \n");
@@ -1374,11 +1374,11 @@ _secVideoLayerNotifyFunc (SECLayer *layer, int type, void *type_data, void *data
 
     XDBG_RETURN_IF_FAIL (pPort != NULL);
     XDBG_RETURN_IF_FAIL (VBUF_IS_VALID (vbuf));
-
+#if 0
     if (pPort->wait_vbuf != vbuf)
         XDBG_WARNING (MVDO, "wait_vbuf(%p) != vbuf(%p). \n",
                       pPort->wait_vbuf, vbuf);
-
+#endif
     XDBG_DEBUG (MVBUF, "now_showing(%p). \n", vbuf);
 
     pPort->wait_vbuf = NULL;
@@ -1529,21 +1529,29 @@ _secVideoPunchDrawable (SECPortPrivPtr pPort)
     PixmapPtr pPixmap = _getPixmap (pPort->d.pDraw);
     SECPtr pSec = SECPTR (pPort->pScrn);
 
-    if (pPort->drawing != ON_FB || !pSec->pVideoPriv->video_punch)
+    if (pPort->drawing != ON_FB)
+    {
+        XDBG_DEBUG (MVDO, "pPort->drawing (%d), pSec->pVideoPriv->video_punch (%d)\n",
+                    pPort->drawing, pSec->pVideoPriv->video_punch);
         return;
+    }
 
     if (!pPort->punched)
     {
+        DamageRegionAppend(pPort->d.pDraw, pPort->d.clip_boxes);
         secExaPrepareAccess (pPixmap, EXA_PREPARE_DEST);
         if (pPixmap->devPrivate.ptr)
             memset (pPixmap->devPrivate.ptr, 0,
                     pPixmap->drawable.width * pPixmap->drawable.height * 4);
         secExaFinishAccess (pPixmap, EXA_PREPARE_DEST);
+        DamageRegionProcessPending(pPort->d.pDraw);
         XDBG_TRACE (MVDO, "Punched (%dx%d) %p. \n",
                     pPixmap->drawable.width, pPixmap->drawable.height,
                     pPixmap->devPrivate.ptr);
         pPort->punched = TRUE;
+#if 0
         DamageDamageRegion (pPort->d.pDraw, pPort->d.clip_boxes);
+#endif
     }
 }
 
@@ -1759,10 +1767,16 @@ _secVideoPutImageTvout (SECPortPrivPtr pPort, int output, SECVideoBuf *inbuf)
     Bool first_put = FALSE;
 
     if (!(output & OUTPUT_EXT))
+    {
+        XDBG_DEBUG(MTVO, "!(output (%d) & OUTPUT_EXT)\n", output);
         return FALSE;
+    }
 
     if (pPort->skip_tvout)
+    {
+        XDBG_DEBUG(MTVO, "pPort->skip_tvout (%d)\n", pPort->skip_tvout);
         return FALSE;
+    }
 
     if (!_secVideoGrabTvout(pPort))
         goto fail_to_put_tvout;
@@ -1879,7 +1893,7 @@ _secVideoPutImageTvout (SECPortPrivPtr pPort, int output, SECVideoBuf *inbuf)
                         sub, inbuf->stamp,
                         inbuf->keys[0], inbuf->keys[1], inbuf->keys[2]);
         }
-
+        XDBG_DEBUG (MVDO, "pPort->wait_vbuf (%d) skip_frame\n", pPort->wait_vbuf);
         return FALSE;
     }
     else if (pSec->pVideoPriv->video_fps)
@@ -2674,11 +2688,39 @@ SECVideoPutImage (ScrnInfoPtr pScrn,
         _secVideoCloseConverter (pPort);
         _secVideoCloseOutBuffer (pPort, FALSE);
         pPort->inbuf_is_fb = FALSE;
-        if (pPort->tv)
+    }
+
+    if (pPort->tv)
+    {
+        SECCvt *tv_cvt = secVideoTvGetConverter (pPort->tv);
+        if (pPort->d.id != pPort->old_d.id ||
+            pPort->d.width != pPort->old_d.width ||
+            pPort->d.height != pPort->old_d.height ||
+            memcmp (&pPort->d.src, &pPort->old_d.src, sizeof (xRectangle)))
+        {
+            _secVideoCloseInBuffer (pPort);
+            pPort->inbuf_is_fb = FALSE;
+        }
+        else if (tv_cvt != NULL)
+        {
+            SECCvtProp dst_prop;
+            secCvtGetProperpty (tv_cvt, NULL, &dst_prop);
+
+            if (dst_prop.degree != pPort->hw_rotate ||
+                dst_prop.hflip != pPort->hflip ||
+                dst_prop.vflip != pPort->vflip ||
+                dst_prop.secure != pPort->secure ||
+                dst_prop.csc_range != pPort->csc_range)
+            {
+                _secVideoCloseInBuffer (pPort);
+                pPort->inbuf_is_fb = FALSE;
+            }
+        }
+
+        if (pPort->tv && memcmp (&pPort->d.dst, &pPort->old_d.dst, sizeof (xRectangle)))
         {
             if (secVideoTvResizeOutput (pPort->tv, &pPort->d.src, &pPort->d.dst) == TRUE)
             {
-                pPort->wait_vbuf = NULL;
                 SECCvt *tv_cvt = secVideoTvGetConverter (pPort->tv);
                 if (tv_cvt != NULL)
                 {
@@ -2691,6 +2733,7 @@ SECVideoPutImage (ScrnInfoPtr pScrn,
                 pPort->tv = NULL;
             }
             pPort->punched = FALSE;
+            pPort->wait_vbuf = NULL;
         }
     }
 
index 9bb11f4..807fdf9 100644 (file)
@@ -133,8 +133,26 @@ _secVideoTvGetOutBuffer (SECVideoTv* tv, int width, int height, Bool secure)
 
             if (tv->outbuf[i] && !VBUF_IS_CONVERTING (tv->outbuf[i]) && !tv->outbuf[i]->showing)
             {
-                tv->outbuf_index = i;
-                return tv->outbuf[i];
+                if (tv->outbuf[i]->width == width &&
+                    tv->outbuf[i]->id == tv->convert_id &&
+                    tv->outbuf[i]->height == height)
+                {
+                    tv->outbuf_index = i;
+                    return tv->outbuf[i];
+                }
+                else
+                {
+                    secUtilVideoBufferUnref (tv->outbuf[i]);
+                    SECPtr pSec = SECPTR (tv->pScrn);
+                    tv->outbuf[i] = secUtilAllocVideoBuffer (tv->pScrn, tv->convert_id, width, height,
+                                                             (pSec->scanout)?TRUE:FALSE, TRUE, secure);
+                    XDBG_RETURN_VAL_IF_FAIL (tv->outbuf[i] != NULL, NULL);
+
+                    XDBG_DEBUG (MTVO, "outbuf(%p, %c%c%c%c)\n", tv->outbuf[i], FOURCC_STR (tv->convert_id));
+
+                    tv->outbuf_index = i;
+                    return tv->outbuf[i];
+                }
             }
         }
         else
@@ -209,11 +227,6 @@ _secVideoTvPutImageInternal (SECVideoTv *tv, SECVideoBuf *vbuf, xRectangle *rect
     XDBG_DEBUG (MTVO, "rect (%d,%d %dx%d) \n",
                 rect->x, rect->y, rect->width, rect->height);
 
-    if (tv->is_resized == 1)
-    {
-        secLayerFreezeUpdate (tv->layer, FALSE);
-        tv->is_resized = 0;
-    }
 #if 0
     if (tv->lpos == LAYER_LOWER1)
         if (!_secVideoTvCalSize (tv, vbuf->width, vbuf->height,
@@ -222,15 +235,36 @@ _secVideoTvPutImageInternal (SECVideoTv *tv, SECVideoBuf *vbuf, xRectangle *rect
             return 0;
         }
 #endif
-    secLayerSetRect (tv->layer, &vbuf->crop, rect);
+    xRectangle src_rect, dst_rect;
+    secLayerGetRect (tv->layer, &src_rect, &dst_rect);
+
+    if (tv->is_resized == 1)
+    {
+        secLayerFreezeUpdate (tv->layer, FALSE);
+//        secLayerHide (tv->layer);
+        tv->is_resized = 0;
+    }
+
+    if (memcmp (&vbuf->crop, &src_rect, sizeof (xRectangle)) ||
+        memcmp (rect, &dst_rect, sizeof (xRectangle)))
+    {
+        secLayerFreezeUpdate (tv->layer, TRUE);
+        secLayerSetRect (tv->layer, &vbuf->crop, rect);
+        secLayerFreezeUpdate (tv->layer, FALSE);
+    }
 
     ret = secLayerSetBuffer (tv->layer, vbuf);
 
     if (ret == 0)
         return 0;
-
-    secLayerShow (tv->layer);
-
+    if (!secLayerIsVisible (tv->layer))
+    {
+        secLayerShow (tv->layer);
+    }
+    else
+    {
+        XDBG_DEBUG(MTVO,"tv->layer(%p) is not visible\n", tv->layer);
+    }
     return ret;
 }
 
@@ -326,27 +360,29 @@ secVideoTvResizeOutput (SECVideoTv* tv, xRectanglePtr src, xRectanglePtr dst)
     if (tv == NULL)
         return FALSE;
 
-    if (tv->outbuf)
+    if (!secVideoCanDirectDrawing (tv, src->width, src->height,
+                                   dst->width, dst->height))
     {
-        int i;
-        for (i = 0; i < tv->outbuf_num; i++)
-            if (tv->outbuf[i])
-                secUtilVideoBufferUnref (tv->outbuf[i]);
-
-        free (tv->outbuf);
-        tv->outbuf = NULL;
+        secVideoTvReCreateConverter(tv);
     }
-
-    if (tv->cvt)
+    else
     {
-        secCvtDestroy (tv->cvt);
-        tv->cvt = NULL;
+        if (tv->cvt)
+        {
+           secCvtDestroy (tv->cvt);
+        }
     }
 
-    if (!secVideoCanDirectDrawing (tv, src->width, src->height,
-                                   dst->width, dst->height))
+    if (tv->outbuf)
     {
-        secVideoTvReCreateConverter(tv);
+        int i;
+        for (i = 0; i < tv->outbuf_num; i++)
+            if (tv->outbuf[i] && !VBUF_IS_CONVERTING(tv->outbuf[i]) && !tv->outbuf[i]->showing)
+            {
+                secUtilVideoBufferUnref (tv->outbuf[i]);
+                tv->outbuf[i] = NULL;
+            }
+        tv->outbuf_index = -1;
     }
 
     secLayerFreezeUpdate (tv->layer, TRUE);
@@ -522,18 +558,30 @@ secVideoTvPutImage (SECVideoTv *tv, SECVideoBuf *vbuf, xRectangle *rect, int csc
         dst_prop.csc_range = csc_range;
 
         if (!secCvtEnsureSize (&src_prop, &dst_prop))
+        {
+            XDBG_DEBUG(MTVO, "Can't ensure size\n");
             return 0;
+        }
 
         outbuf = _secVideoTvGetOutBuffer (tv, dst_prop.width, dst_prop.height, vbuf->secure);
         if (!outbuf)
+        {
+            XDBG_DEBUG(MTVO, "Can't get outbuf\n");
             return 0;
+        }
         outbuf->crop = dst_prop.crop;
 
         if (!secCvtSetProperpty (tv->cvt, &src_prop, &dst_prop))
+        {
+            XDBG_DEBUG(MTVO, "Can't set cvt property\n");
             return 0;
+        }
 
         if (!secCvtConvert (tv->cvt, vbuf, outbuf))
+        {
+            XDBG_DEBUG(MTVO, "Can't start cvt\n");
             return 0;
+        }
 
         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",
                     FOURCC_STR (vbuf->id), vbuf->width, vbuf->height,
@@ -585,6 +633,10 @@ secVideoCanDirectDrawing (SECVideoTv *tv, int src_w, int src_h, int dst_w, int d
     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);
+#if 1
+    /* :TODO. Need Fix flickering in direct draw case */
+    return FALSE;
+#endif
     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",
@@ -646,6 +698,14 @@ secVideoCanDirectDrawing (SECVideoTv *tv, int src_w, int src_h, int dst_w, int d
             return FALSE;
         }
     }
+#if 0
+    /* FIXME: Using IPP converter if we haven't native frame size */
+    if (ratio_w > 1 || ratio_h > 1)
+    {
+        XDBG_DEBUG(MTVO, "Can't direct draw ratio_w (%d) && ratio_h (%d) != 1\n", ratio_w, ratio_h);
+        return FALSE;
+    }
+#endif
     XDBG_DEBUG(MTVO, "Support direct drawing\n");
     return TRUE;
 }