Add reference counting to omap_bo
Add reference counting to omap_bo to avoid freeing a buffer object
during page flip.
BUG=chrome-os-partner:12889
TEST=Tested on snow, could hotplug & resize while flipping
Change-Id: I7b65e9553427ce1668d2838712e1e18e47a80f79
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/31771
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 956c3ac..da1f2f1 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1054,7 +1054,7 @@
|| (pScrn->bitsPerPixel != omap_bo_bpp(pOMAP->scanout)) ) {
/* delete old scanout buffer */
- omap_bo_del(pOMAP->scanout);
+ omap_bo_unreference(pOMAP->scanout);
pOMAP->has_resized = TRUE;
DEBUG_MSG("allocating new scanout buffer: %dx%d",
width, height);
diff --git a/src/omap_dri2.c b/src/omap_dri2.c
index 2645aef..8e0f39f 100644
--- a/src/omap_dri2.c
+++ b/src/omap_dri2.c
@@ -362,11 +362,18 @@
OMAPPtr pOMAP = OMAPPTR(pScrn);
DrawablePtr pDraw = NULL;
int status;
- OMAPPixmapPrivPtr dst_priv;
+ OMAPPixmapPrivPtr src_priv, dst_priv;
+ struct omap_bo *old_src_bo, *old_dst_bo;
if (--cmd->swapCount > 0)
return;
+ /* Save the old source bo for unreference below */
+ src_priv = exaGetPixmapDriverPrivate(OMAPBUF(cmd->pSrcBuffer)->pPixmap);
+ dst_priv = exaGetPixmapDriverPrivate(OMAPBUF(cmd->pDstBuffer)->pPixmap);
+ old_src_bo = src_priv->bo;
+ old_dst_bo = dst_priv->bo;
+
if ((cmd->flags & OMAP_SWAP_FAIL) == 0) {
DEBUG_MSG("%s complete: %d -> %d", swap_names[cmd->type],
cmd->pSrcBuffer->attachment, cmd->pDstBuffer->attachment);
@@ -395,6 +402,8 @@
*/
OMAPDRI2DestroyBuffer(pDraw, cmd->pSrcBuffer);
OMAPDRI2DestroyBuffer(pDraw, cmd->pDstBuffer);
+ omap_bo_unreference(old_src_bo);
+ omap_bo_unreference(old_dst_bo);
pOMAP->pending_flips--;
free(cmd);
@@ -476,6 +485,8 @@
src->previous_canflip = new_canflip;
dst->previous_canflip = new_canflip;
+ omap_bo_reference(src_priv->bo);
+ omap_bo_reference(dst_priv->bo);
if (src_fb_id && dst_fb_id && canflip(pDraw) && !(pOMAP->has_resized)) {
/* has_resized: On hotplug the fb size and crtc sizes arent updated
* hence on this event we do a copyb but flip from the next frame
diff --git a/src/omap_drmif_fb.h b/src/omap_drmif_fb.h
index b1be641..26aa8a2 100644
--- a/src/omap_drmif_fb.h
+++ b/src/omap_drmif_fb.h
@@ -47,6 +47,8 @@
uint32_t omap_bo_pitch(struct omap_bo *bo);
void *omap_bo_addr(struct omap_bo *bo);
int omap_bo_clear(struct omap_bo *bo);
+void omap_bo_reference(struct omap_bo *bo);
+void omap_bo_unreference(struct omap_bo *bo);
#endif /* OMAP_DRMIF_FB_H_ */
diff --git a/src/omap_dumb.c b/src/omap_dumb.c
index 070d463..9afe87a 100644
--- a/src/omap_dumb.c
+++ b/src/omap_dumb.c
@@ -47,6 +47,7 @@
uint8_t depth;
uint8_t bpp;
uint32_t pitch;
+ int refcnt;
};
/* device related functions:
@@ -108,6 +109,7 @@
new_buf->height = create_dumb.height;
new_buf->depth = depth;
new_buf->bpp = create_dumb.bpp;
+ new_buf->refcnt = 1;
return new_buf;
}
@@ -138,6 +140,22 @@
free(bo);
}
+void omap_bo_unreference(struct omap_bo *bo)
+{
+ if (!bo)
+ return;
+
+ assert(bo->refcnt > 0);
+ if (--bo->refcnt == 0)
+ omap_bo_del(bo);
+}
+
+void omap_bo_reference(struct omap_bo *bo)
+{
+ assert(bo->refcnt > 0);
+ bo->refcnt++;
+}
+
int omap_bo_get_name(struct omap_bo *bo, uint32_t *name)
{
int ret;
diff --git a/src/omap_exa.c b/src/omap_exa.c
index 2552835..cf2e294 100644
--- a/src/omap_exa.c
+++ b/src/omap_exa.c
@@ -76,7 +76,7 @@
{
OMAPPixmapPrivPtr priv = driverPriv;
- omap_bo_del(priv->bo);
+ omap_bo_unreference(priv->bo);
free(priv);
}
@@ -105,7 +105,7 @@
/* scratch-pixmap (see GetScratchPixmapHeader()) gets recycled,
* so could have a previous bo!
*/
- omap_bo_del(priv->bo);
+ omap_bo_unreference(priv->bo);
priv->bo = NULL;
/* Returning FALSE calls miModifyPixmapHeader */
@@ -144,7 +144,7 @@
omap_bo_height(priv->bo) != pPixmap->drawable.height ||
omap_bo_bpp(priv->bo) != pPixmap->drawable.bitsPerPixel) {
/* re-allocate buffer! */
- omap_bo_del(priv->bo);
+ omap_bo_unreference(priv->bo);
priv->bo = omap_bo_new_with_dim(pOMAP->dev,
pPixmap->drawable.width,
pPixmap->drawable.height,