libvideorender: CB1 fix crash on weston [1/1]

PD#SWPL-198922

Problem:
crash happened on handleFrameTime.
renderBuffer of WaylandBuffer is null.if bufferRelease
takes long time,but prepare buffer at this time. after
bufferRelease set renderBuffer to null

Solution:
1.using mutex to protect renderBuffer
2.constructWlBuffer renderBuffer again if detected
renderBuffer is null

Verify:
ap222

Change-Id: If92f16e13f190b58977a80e56151658b324ff90a
Signed-off-by: fei.deng <fei.deng@amlogic.com>
diff --git a/weston/wayland_buffer.cpp b/weston/wayland_buffer.cpp
index 14c6a61..4679702 100644
--- a/weston/wayland_buffer.cpp
+++ b/weston/wayland_buffer.cpp
@@ -79,14 +79,17 @@
 void WaylandBuffer::bufferRelease (void *data, struct wl_buffer *wl_buffer)
 {
     WaylandBuffer* waylandBuffer = static_cast<WaylandBuffer*>(data);
-    TRACE(waylandBuffer->mLogCategory,"--wl_buffer:%p,renderBuffer:%p",wl_buffer,waylandBuffer->mRenderBuffer);
+    TRACE(waylandBuffer->mLogCategory,"--wl_buffer:%p(%p),renderBuffer:%p",wl_buffer,waylandBuffer,waylandBuffer->mRenderBuffer);
     waylandBuffer->mUsedByCompositor = false;
     waylandBuffer->mState = BUFFER_IDLE;
     //sometimes this callback be called twice
     //this cause double free,so check mRenderBuffer
     if (waylandBuffer->mRenderBuffer) {
         waylandBuffer->mDisplay->handleBufferReleaseCallback(waylandBuffer);
+        waylandBuffer->mLock.lock();
         waylandBuffer->mRenderBuffer = NULL;
+        waylandBuffer->mRealTime = -1;
+        waylandBuffer->mLock.unlock();
     }
     //resolution changed,release buffers before resolution changed
     if ((waylandBuffer->mCookieId < waylandBuffer->mDisplay->getWaylandBufferCookieId()) &&
@@ -102,7 +105,7 @@
 void WaylandBuffer::bufferdroped (void *data, struct wl_buffer *wl_buffer)
 {
     WaylandBuffer* waylandBuffer = static_cast<WaylandBuffer*>(data);
-    WARNING(waylandBuffer->mLogCategory,"--droped wl_buffer:%p,renderBuffer:%p",wl_buffer,waylandBuffer->mRenderBuffer);
+    WARNING(waylandBuffer->mLogCategory,"--dropped wl_buffer:%p(%p),renderBuffer:%p",wl_buffer,waylandBuffer,waylandBuffer->mRenderBuffer);
     waylandBuffer->mUsedByCompositor = false;
     waylandBuffer->mState = BUFFER_IDLE;
 
@@ -116,7 +119,12 @@
 void WaylandBuffer::bufferDisplayTime (void *data, struct wl_buffer *wl_buffer, uint32_t sec, uint32_t usec)
 {
     WaylandBuffer* waylandBuffer = static_cast<WaylandBuffer*>(data);
-    waylandBuffer->mDisplay->handleFrameTime(waylandBuffer, sec, usec);
+    if (ENABLE_MORE_LOG) {
+        TRACE(waylandBuffer->mLogCategory,"wl_buffer:%p(%p)",wl_buffer,waylandBuffer);
+    }
+    if (waylandBuffer->mRenderBuffer) {
+        waylandBuffer->mDisplay->handleFrameTime(waylandBuffer, sec, usec);
+    }
 }
 
 static const struct wl_buffer_listener buffer_with_drop_listener = {
@@ -147,8 +155,8 @@
     bool redrawing = waylandBuffer->mRedrawingPending;
     waylandBuffer->mRedrawingPending = false;
     waylandBuffer->mLock.unlock();
+    TRACE(waylandBuffer->mLogCategory,"--WaylandBuffer:%p,renderBuffer:%p,elapsed:%lld ms",waylandBuffer,waylandBuffer->mRenderBuffer,elapsed);
     if (waylandBuffer->mRenderBuffer && redrawing) {
-        TRACE(waylandBuffer->mLogCategory,"--renderBuffer:%p, pts:%lld us,elapsed:%lld ms",waylandBuffer->mRenderBuffer,waylandBuffer->mRenderBuffer->pts/1000,elapsed);
         waylandBuffer->mDisplay->handleFrameDisplayedCallback(waylandBuffer);
     }
     wl_callback_destroy (callback);
@@ -168,7 +176,7 @@
     mState = BUFFER_PREPARED;
     if (mWaylandWlWrap) {
         mLock.unlock();
-        //TRACE(mLogCategory,"WaylandBuffer:%p,WaylandDmaBuffer:%p,pts:%lld us,cookie:%d",this,mWaylandWlWrap,buf->pts/1000,mCookieId);
+        //TRACE(mLogCategory,"WaylandBuffer:%p,WaylandDmaBuffer:%p,renderBuffer:%p,pts:%lld us,cookie:%d",this,mWaylandWlWrap,mRenderBuffer,buf->pts/1000,mCookieId);
         return NO_ERROR;
     }
     mLock.unlock();
diff --git a/weston/wayland_display.cpp b/weston/wayland_display.cpp
index 27cdd2a..9edb32a 100644
--- a/weston/wayland_display.cpp
+++ b/weston/wayland_display.cpp
@@ -1378,7 +1378,7 @@
         mWaylandBufferCookieId += 1;
         DEBUG(mLogCategory,"drs,pts:%lld us,w:%d,h:%d,update cookie:%d",buf->pts/1000,buf->dma.width,buf->dma.height,mWaylandBufferCookieId);
     }
-    //TRACE(mLogCategory,"pts:%lld us,w:%d,h:%d,cookie:%d",buf->pts/1000,buf->dma.width,buf->dma.height,mWaylandBufferCookieId);
+    //TRACE(mLogCategory,"renderbuf:%p,pts:%lld us,w:%d,h:%d,cookie:%d",buf,buf->pts/1000,buf->dma.width,buf->dma.height,mWaylandBufferCookieId);
 
     waylandBuf = findWaylandBuffer(buf);
     if (waylandBuf == NULL || waylandBuf->getCookieId() != mWaylandBufferCookieId) {
@@ -1498,13 +1498,21 @@
             TRACE(mLogCategory,"Error.release same display time buffer,pts:%lld us",buf->pts/1000);
             goto waylandbuf_fail;
         }
+        //if renderbuffer in WaylandBuffer is null, construct it
+        if (!waylandBuf->getRenderBuffer()) {
+            ret = waylandBuf->constructWlBuffer(buf);
+            if (ret != NO_ERROR) {
+                WARNING(mLogCategory,"waylandBuf construct failed");
+                goto waylandbuf_fail;
+            }
+        }
         Tls::Mutex::Autolock _l(mRenderMutex);
         ++mCommitCnt;
         uint32_t hiPts = realDisplayTime >> 32;
         uint32_t lowPts = realDisplayTime & 0xFFFFFFFF;
         //attach this wl_buffer to weston
-        TRACE(mLogCategory,"++attach,renderbuf:%p,wl_buffer:%p(%d,%d,%d,%d),pts:%lld us,commitCnt:%d",
-            buf,wlbuffer,mVideoRect.x,mVideoRect.y,mVideoRect.w,mVideoRect.h,buf->pts/1000,mCommitCnt);
+        TRACE(mLogCategory,"++attach,renderbuf:%p(%p),wl_buffer:%p(%d,%d,%d,%d),pts:%lld us,commitCnt:%d",
+            buf,waylandBuf->getRenderBuffer(),wlbuffer,mVideoRect.x,mVideoRect.y,mVideoRect.w,mVideoRect.h,buf->pts/1000,mCommitCnt);
         waylandBuf->attach(mVideoSurfaceWrapper);
 
         if (mAmlConfigAPIList.enableSetPts) {