libvideorender: CB1 abnormal video display on weston [1/1]
PD#SWPL-177568
Problem:
Abnormal video display after switching resolution multiple times
Solution:
release zwp buffers after resolution changed
Verify:
ap222
Change-Id: I16a53c35624a907c23c3273c761274f07d83036f
Signed-off-by: fei.deng <fei.deng@amlogic.com>
diff --git a/weston/wayland_buffer.cpp b/weston/wayland_buffer.cpp
index 01d1cee..60605a3 100644
--- a/weston/wayland_buffer.cpp
+++ b/weston/wayland_buffer.cpp
@@ -49,7 +49,7 @@
mBufferFormat = VIDEO_FORMAT_UNKNOWN;
mFrameWidth = 0;
mFrameHeight = 0;
- TRACE(mLogCategory,"new WaylandBuffer:%p",this);
+ //TRACE(mLogCategory,"new WaylandBuffer:%p",this);
}
WaylandBuffer::~WaylandBuffer()
@@ -64,13 +64,13 @@
delete mWaylandWlWrap;
mWaylandWlWrap = NULL;
}
- TRACE(mLogCategory,"delete WaylandBuffer:%p",this);
+ //TRACE(mLogCategory,"delete WaylandBuffer:%p",this);
}
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,renderBuffer:%p",wl_buffer,waylandBuffer->mRenderBuffer);
waylandBuffer->mUsedByCompositor = false;
//sometimes this callback be called twice
//this cause double free,so check mRenderBuffer
@@ -79,14 +79,16 @@
waylandBuffer->mRenderBuffer = NULL;
waylandBuffer->mRealTime = -1;
}
- //release after buffer release callback
+ //release dma buffer if resolution changed after buffer release callback
int fw = waylandBuffer->mDisplay->getFrameWidth();
int fh = waylandBuffer->mDisplay->getFrameHeight();
if ( (waylandBuffer->mFrameWidth != fw || waylandBuffer->mFrameHeight != fh) &&
waylandBuffer->mWaylandWlWrap) {
TRACE(waylandBuffer->mLogCategory,"resolution changed,delete WaylandBuffer:%p,WaylandDmaBuffer:%p",waylandBuffer,waylandBuffer->mWaylandWlWrap);
delete waylandBuffer->mWaylandWlWrap;
+ waylandBuffer->mLock.lock();
waylandBuffer->mWaylandWlWrap = NULL;
+ waylandBuffer->mLock.unlock();
}
}
@@ -122,7 +124,7 @@
waylandBuffer->mRedrawingPending = false;
waylandBuffer->mLock.unlock();
if (waylandBuffer->mRenderBuffer && redrawing) {
- TRACE(waylandBuffer->mLogCategory,"renderBuffer:%p, pts:%lld us",waylandBuffer->mRenderBuffer,waylandBuffer->mRenderBuffer->pts/1000);
+ //TRACE(waylandBuffer->mLogCategory,"renderBuffer:%p, pts:%lld us",waylandBuffer->mRenderBuffer,waylandBuffer->mRenderBuffer->pts/1000);
waylandBuffer->mDisplay->handleFrameDisplayedCallback(waylandBuffer);
}
wl_callback_destroy (callback);
@@ -153,7 +155,7 @@
mWaylandWlWrap = waylanddma;
mFrameWidth = buf->dma.width;
mFrameHeight = buf->dma.height;
- TRACE(mLogCategory,"WaylandBuffer:%p,WaylandDmaBuffer:%p",this,mWaylandWlWrap);
+ //TRACE(mLogCategory,"WaylandBuffer:%p,WaylandDmaBuffer:%p",this,mWaylandWlWrap);
}
/*register buffer release listen*/
@@ -198,10 +200,27 @@
mRedrawingPending = true;
}
+/**
+ * @brief check wayland buffer is free. if this is free
+ * ,it will be delete by waylandbuffer manager
+ *
+ * @return true if this buffer is free
+ * @return false if this buffer will be used
+ */
bool WaylandBuffer::isFree()
{
+ int fw = mDisplay->getFrameWidth();
+ int fh = mDisplay->getFrameHeight();
+ Tls::Mutex::Autolock _l(mLock);
if (!mWaylandWlWrap && !mRenderBuffer) {
return true;
}
+ /*if resolution changed,this buffer should be deleted after weston
+ release this buffer */
+ if ((mFrameWidth > 0 && mFrameHeight > 0 && fw > 0 && fh > 0) &&
+ (mFrameWidth != fw || mFrameHeight != fh) &&
+ !mRenderBuffer && !mUsedByCompositor) {
+ return true;
+ }
return false;
};
\ No newline at end of file
diff --git a/weston/wayland_display.cpp b/weston/wayland_display.cpp
index aa96bb9..69dac37 100644
--- a/weston/wayland_display.cpp
+++ b/weston/wayland_display.cpp
@@ -1290,6 +1290,7 @@
{
WaylandBuffer *waylandBuf = NULL;
int ret;
+ bool isNew = false;
if (!mDmabuf)
{
@@ -1300,15 +1301,17 @@
waylandBuf = findWaylandBuffer(buf);
if (waylandBuf == NULL) {
waylandBuf = new WaylandBuffer(this, mLogCategory);
- waylandBuf->setBufferFormat(mBufferFormat);
- ret = waylandBuf->constructWlBuffer(buf);
- if (ret != NO_ERROR) {
- WARNING(mLogCategory,"dmabufConstructWlBuffer fail,release waylandbuf");
- //delete waylanBuf,WaylandBuffer object destruct will call release callback
- goto waylandbuf_fail;
- } else {
- addWaylandBuffer(buf, waylandBuf);
- }
+ isNew = true;
+ }
+ waylandBuf->setBufferFormat(mBufferFormat);
+ ret = waylandBuf->constructWlBuffer(buf);
+ if (ret != NO_ERROR) {
+ WARNING(mLogCategory,"dmabufConstructWlBuffer fail,release waylandbuf");
+ //delete waylanBuf,WaylandBuffer object destruct will call release callback
+ goto waylandbuf_fail;
+ }
+ if (isNew) {
+ addWaylandBuffer(buf, waylandBuf);
}
return NO_ERROR;
waylandbuf_fail:
@@ -1336,6 +1339,9 @@
ensureFullscreen(mFullScreen);
}
resizeVideoSurface(true);
+ /*clean wayland buffers those allocated
+ before resolution changed and had release by weston */
+ cleanWaylandBufferBeforeResChanged();
}
WaylandBuffer *waylandBuf = NULL;
struct wl_buffer * wlbuffer = NULL;
@@ -1363,12 +1369,6 @@
waylandBuf = findWaylandBuffer(buf);
if (waylandBuf) {
waylandBuf->setRenderRealTime(realDisplayTime);
- ret = waylandBuf->constructWlBuffer(buf);
- if (ret != NO_ERROR) {
- WARNING(mLogCategory,"dmabufConstructWlBuffer fail,release waylandbuf");
- //delete waylanBuf,WaylandBuffer object destruct will call release callback
- goto waylandbuf_fail;
- }
} else {
ERROR(mLogCategory,"NOT found wayland buffer,please prepare buffer first");
goto waylandbuf_fail;
@@ -1423,9 +1423,6 @@
mWaylandPlugin->handleFrameDropped(buf);
//notify app release this buf
mWaylandPlugin->handleBufferRelease(buf);
- //delete waylandbuf
- delete waylandBuf;
- waylandBuf = NULL;
return;
}
@@ -1520,15 +1517,15 @@
void WaylandDisplay::videoCenterRect(Rectangle src, Rectangle dst, Rectangle *result, bool scaling)
{
//if dst is a small window, we scale video to map window size,don't doing center
- if (mRenderRect.w != dst.w && mRenderRect.h != dst.h) {
- result->x = dst.x;
- result->y = dst.y;
- result->w = dst.w;
- result->h = dst.h;
- TRACE(mLogCategory,"small window source is %dx%d dest is %dx%d, result is %d,%d,%d,%d",
- src.w, src.h, dst.w, dst.h, result->x, result->y, result->w, result->h);
- return;
- }
+ // if (mRenderRect.w != dst.w && mRenderRect.h != dst.h) {
+ // result->x = dst.x;
+ // result->y = dst.y;
+ // result->w = dst.w;
+ // result->h = dst.h;
+ // TRACE(mLogCategory,"small window source is %dx%d dest is %dx%d, result is %d,%d,%d,%d",
+ // src.w, src.h, dst.w, dst.h, result->x, result->y, result->w, result->h);
+ // return;
+ // }
if (!scaling) {
result->w = MIN (src.w, dst.w);
result->h = MIN (src.h, dst.h);
@@ -1593,7 +1590,7 @@
std::string hashString("");
for (int i = 0; i < dmabuf.planeCnt; i++) {
char hashtmp[1024];
- snprintf (hashtmp, 1024, "%d%d%d%d%d%d", dmabuf.width,dmabuf.height,dmabuf.planeCnt,
+ snprintf (hashtmp, 1024, "%d%d%d%d%d%d%d",i,dmabuf.width,dmabuf.height,dmabuf.planeCnt,
dmabuf.stride[i],dmabuf.offset[i],dmabuf.fd[i]);
std::string tmp(hashtmp);
hashString += tmp;
@@ -1612,17 +1609,6 @@
//TRACE(mLogCategory,"fd:%d,w:%d,h:%d,%p,hash:%zu",buf->dma.fd[0],buf->dma.width,buf->dma.height,waylandbuf,hashval);
mWaylandBuffersMap.insert(item);
}
-
- //clean invalid wayland buffer,if video resolution changed
- for (auto item = mWaylandBuffersMap.begin(); item != mWaylandBuffersMap.end(); ) {
- WaylandBuffer *wlbuf = (WaylandBuffer*)item->second;
- if (wlbuf->isFree()) {
- mWaylandBuffersMap.erase(item++);
- delete wlbuf;
- } else {
- item++;
- }
- }
TRACE(mLogCategory,"mWaylandBuffersMap size:%d",mWaylandBuffersMap.size());
}
@@ -1647,6 +1633,24 @@
}
}
+
+/**
+ * @brief clean wayland buffers those malloc before resolution changed
+ *
+ */
+void WaylandDisplay::cleanWaylandBufferBeforeResChanged()
+{
+ for (auto item = mWaylandBuffersMap.begin(); item != mWaylandBuffersMap.end(); ) {
+ WaylandBuffer *wlbuf = (WaylandBuffer*)item->second;
+ if (wlbuf->isFree()) {
+ mWaylandBuffersMap.erase(item++);
+ delete wlbuf;
+ } else {
+ item++;
+ }
+ }
+}
+
void WaylandDisplay::flushBuffers()
{
INFO(mLogCategory,"flushBuffers");
diff --git a/weston/wayland_display.h b/weston/wayland_display.h
index a8349ba..abf5ab9 100644
--- a/weston/wayland_display.h
+++ b/weston/wayland_display.h
@@ -289,6 +289,7 @@
void addWaylandBuffer(RenderBuffer * buf, WaylandBuffer *waylandbuf);
WaylandBuffer* findWaylandBuffer(RenderBuffer * buf);
void cleanAllWaylandBuffer();
+ void cleanWaylandBufferBeforeResChanged();
WaylandPlugin *mWaylandPlugin;
struct wl_display *mWlDisplay;
diff --git a/weston/wayland_plugin.cpp b/weston/wayland_plugin.cpp
index 95c7841..dc41c9f 100644
--- a/weston/wayland_plugin.cpp
+++ b/weston/wayland_plugin.cpp
@@ -393,7 +393,6 @@
close(fd);
fd = -1;
}
- Logger_set_level(4);
WaylandPlugin *pluginInstance = new WaylandPlugin(category);
return static_cast<void *>(pluginInstance);