We are currently experiencing downtime impacting viewing & cloning the Mesa repo, and some GitLab pages returning 503. Please see #freedesktop on IRC for more updates.

Commit bbb82b80 authored by Dave Barnish's avatar Dave Barnish

Reviewed and revised bo reference counting.

Change-Id: I9d827678692207101565e235b44b62ffee756dc7
parent f99604d3
......@@ -25,3 +25,26 @@ You can also copy src/drmmode_template into src/drmmode_<yourdrivername> and bui
$ ./configure --with-drmmode=<yourdrivername>
Summary of bo reference counting
--------------------------------
The Screen takes a ref on the scanout bo in InitScreen and drops it in ScreenClose. When the scanout bo changes
(due to a flip or a modeset) the ref is moved from the old bo to the new one by set_scanout_bo.
Pixmaps take a ref on their bo(s) when created in ARMSOCCreatePixmap2 and drop it in ARMSOCDestroyPixmap.
If ARMSOCModifyPixmapHeader points a pixmap at anything other than the scanout bo then the ref to
the existing bo (if any) is dropped.
If ARMSOCModifyPixmapHeader points a pixmap at the scanout bo the ref is moved from the old bo to the new
If ARMSOCModifyPixmapHeader changes the size of the pixmap's bo the ref is dropped, a new bo created and a
ref taken on that.
resize_scanout_bo creates and takes a ref on the new bo and drops its ref when the new bo becomes the scanout bo and
the Screen has taken a ref.
The swap chain takes a ref on the src and dst bos when a swap is scheduled in ARMSOCDRI2ScheduleSwap and drops them
in ARMSOCDRI2SwapComplete after the src becomes pARMSOC->scanout and the screen takes a ref.
The cursor takes a ref on its bo in drmmode_cursor_init and drops it in drmmode_cursor_fini
......@@ -286,7 +286,7 @@ ARMSOCDRI2DestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
if (--buf->refcnt > 0)
return;
DEBUG_MSG("pDraw=%p, buffer=%p", pDraw, buffer);
DEBUG_MSG("pDraw=%p, DRIbuffer=%p", pDraw, buffer);
if (buffer->attachment == DRI2BufferBackLeft) {
assert(pARMSOC->driNumBufs > 1);
......@@ -307,6 +307,7 @@ static void
ARMSOCDRI2ReferenceBuffer(DRI2BufferPtr buffer)
{
struct ARMSOCDRI2BufferRec *buf = ARMSOCBUF(buffer);
buf->refcnt++;
}
......@@ -387,9 +388,9 @@ ARMSOCDRI2GetMSC(DrawablePtr pDraw, CARD64 *ust, CARD64 *msc)
#if DRI2INFOREC_VERSION >= 6
/**
* Validates that the swap limit range is within the range of supported
* asynchronous buffer flips. This is bounded by the DRI2MaxBuffers option plus
* one additional flip in case of early display usage.
* Called by DRI2 to validate that any new swap limit being set by
* DRI2 is in range. In our case the range is 1 to the DRI2MaxBuffers
* option, plus one in the case of early display usage.
*/
static Bool
ARMSOCDRI2SwapLimitValidate(DrawablePtr pDraw, int swap_limit) {
......@@ -423,12 +424,12 @@ struct ARMSOCDRISwapCmd {
DRI2BufferPtr pDstBuffer;
DRI2BufferPtr pSrcBuffer;
DRI2SwapEventPtr func;
int swapCount;
int swapCount; /* number of crtcs with flips in flight for this swap */
int flags;
void *data;
struct armsoc_bo *old_src_bo;
struct armsoc_bo *old_dst_bo;
struct armsoc_bo *new_scanout;
struct armsoc_bo *old_src_bo; /* Swap chain holds ref on src bo */
struct armsoc_bo *old_dst_bo; /* Swap chain holds ref on dst bo */
struct armsoc_bo *new_scanout; /* scanout to be used after swap */
unsigned int swap_id;
};
......@@ -562,33 +563,40 @@ void updateResizedBuffer(ScrnInfoPtr pScrn, void *buffer,
for (i = 0; i < buf->numPixmaps; i++) {
if (buf->pPixmaps[i] != NULL) {
struct ARMSOCPixmapPrivRec *priv = exaGetPixmapDriverPrivate(buf->pPixmaps[i]);
if (old_bo == priv->bo) {
int ret;
ret = armsoc_bo_get_name(resized_bo, &dri2buf->name);
assert(!ret);
/* Update the buffer name if this pixmap is current */
if (i == buf->currentPixmap) {
ret = armsoc_bo_get_name(resized_bo, &dri2buf->name);
assert(!ret);
}
/* pixmap takes ref on resized bo */
armsoc_bo_reference(resized_bo);
/* replace the old_bo with the resized_bo */
priv->bo = resized_bo;
/* pixmap drops ref on old bo */
armsoc_bo_unreference(old_bo);
}
}
}
}
void
ARMSOCDRI2ResizeSwapChain(ScrnInfoPtr pScrn, struct armsoc_bo *old_bo,
struct armsoc_bo *resized_bo) {
PixmapPtr rootPixmap;
struct ARMSOCPixmapPrivRec *rootPriv;
struct armsoc_bo *resized_bo)
{
struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
struct ARMSOCDRISwapCmd *cmd = NULL;
int i;
int back = pARMSOC->swap_chain_count - 1;
rootPixmap = pScrn->pScreen->GetScreenPixmap(pScrn->pScreen);
rootPriv = exaGetPixmapDriverPrivate(rootPixmap);
/* We need to access the front to back (count-1) % size. */
int back = pARMSOC->swap_chain_count - 1; /* The last swap scheduled */
/* Update the bos for each scheduled swap in the swap chain */
for (i = 0; i < pARMSOC->swap_chain_size && back >= 0; i++) {
unsigned int idx = back % pARMSOC->swap_chain_size;
cmd = pARMSOC->swap_chain[idx];
back--;
if (!cmd)
......@@ -596,12 +604,6 @@ ARMSOCDRI2ResizeSwapChain(ScrnInfoPtr pScrn, struct armsoc_bo *old_bo,
updateResizedBuffer(pScrn, cmd->pSrcBuffer, old_bo, resized_bo);
updateResizedBuffer(pScrn, cmd->pDstBuffer, old_bo, resized_bo);
}
/* The current front buffer might be several frames ahead of scanout. So we
* need to check if the current front buffer owned the previous scanout,
* i.e. the one we are deleting. If so we will transfer the ownership. */
if (0 == armsoc_bo_unreference(old_bo) && rootPriv->bo == old_bo)
rootPriv->bo = resized_bo;
}
......@@ -615,11 +617,12 @@ ARMSOCDRI2SwapComplete(struct ARMSOCDRISwapCmd *cmd)
unsigned int idx;
int status;
if (--cmd->swapCount > 0)
if (--cmd->swapCount > 0) /* wait for all crtcs to flip */
return;
if ((cmd->flags & ARMSOC_SWAP_FAIL) == 0) {
DEBUG_MSG("%s complete: %d -> %d", swap_names[cmd->type],
DEBUG_MSG("swap %d %s complete: %d -> %d",
cmd->swap_id, swap_names[cmd->type],
cmd->pSrcBuffer->attachment,
cmd->pDstBuffer->attachment);
status = dixLookupDrawable(&pDraw, cmd->draw_id, serverClient,
......@@ -635,7 +638,11 @@ ARMSOCDRI2SwapComplete(struct ARMSOCDRISwapCmd *cmd)
assert(cmd->type == DRI2_FLIP_COMPLETE);
set_scanout_bo(pScrn, cmd->new_scanout);
}
} else {
ERROR_MSG("dixLookupDrawable fail on swap complete");
}
} else {
ERROR_MSG("swap %d ARMSOC_SWAP_FAIL on swap complete", cmd->swap_id);
}
/* drop extra refcnt we obtained prior to swap:
......@@ -643,14 +650,15 @@ ARMSOCDRI2SwapComplete(struct ARMSOCDRISwapCmd *cmd)
ARMSOCDRI2DestroyBuffer(pDraw, cmd->pSrcBuffer);
ARMSOCDRI2DestroyBuffer(pDraw, cmd->pDstBuffer);
/* drop extra reference of the actual buffer objects used */
/* swap chain drops ref on original src bo */
armsoc_bo_unreference(cmd->old_src_bo);
/* swap chain drops ref on original dst bo */
armsoc_bo_unreference(cmd->old_dst_bo);
if (cmd->type == DRI2_FLIP_COMPLETE)
pARMSOC->pending_flips--;
/* Free the swap operation and progress the swap chain. */
/* Free the swap cmd and remove it from the swap chain. */
idx = cmd->swap_id % pARMSOC->swap_chain_size;
assert(pARMSOC->swap_chain[idx] == cmd);
free(cmd);
......@@ -709,10 +717,8 @@ ARMSOCDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw,
DamageRegionAppend(&pDstPixmap->drawable, &region);
DamageRegionProcessPending(&pDstPixmap->drawable);
DEBUG_MSG("%d -> %d", pSrcBuffer->attachment, pDstBuffer->attachment);
/* obtain extra ref on buffers to avoid them going away while we await
* the page flip event:
/* obtain extra ref on DRI buffers to avoid them going
* away while we await the page flip event.
*/
ARMSOCDRI2ReferenceBuffer(pSrcBuffer);
ARMSOCDRI2ReferenceBuffer(pDstBuffer);
......@@ -723,13 +729,16 @@ ARMSOCDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw,
src_fb_id = armsoc_bo_get_fb(src_bo);
dst_fb_id = armsoc_bo_get_fb(dst_bo);
/* Store and reference actual buffer-objects used as they could
* be exchanged under-the-hood if doing a page flip. */
/* Store and reference actual buffer-objects used in case
* the pixmaps disappear.
*/
cmd->old_src_bo = src_bo;
cmd->old_dst_bo = dst_bo;
armsoc_bo_reference(src_bo);
armsoc_bo_reference(dst_bo);
/* Swap chain takes a ref on original src bo */
armsoc_bo_reference(cmd->old_src_bo);
/* Swap chain takes a ref on original dst bo */
armsoc_bo_reference(cmd->old_dst_bo);
/* Add swap operation to the swap chain */
cmd->swap_id = pARMSOC->swap_chain_count++;
......@@ -737,6 +746,9 @@ ARMSOCDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw,
assert(NULL == pARMSOC->swap_chain[idx]);
pARMSOC->swap_chain[idx] = cmd;
DEBUG_MSG("SWAP %d SCHEDULED : %d -> %d ", cmd->swap_id,
pSrcBuffer->attachment, pDstBuffer->attachment);
new_canflip = canflip(pDraw);
if ((src->previous_canflip != new_canflip) ||
(dst->previous_canflip != new_canflip)) {
......@@ -775,7 +787,7 @@ ARMSOCDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw,
(armsoc_bo_height(src_bo) == armsoc_bo_height(dst_bo));
if (do_flip) {
DEBUG_MSG("can flip: %d -> %d", src_fb_id, dst_fb_id);
DEBUG_MSG("FLIPPING: FB%d -> FB%d", src_fb_id, dst_fb_id);
cmd->type = DRI2_FLIP_COMPLETE;
/* TODO: MIDEGL-1461: Handle rollback if multiple CRTC flip is
* only partially successful
......@@ -800,7 +812,6 @@ ARMSOCDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw,
cmd->swapCount = 0;
cmd->new_scanout = boFromBuffer(pDstBuffer);
if (cmd->swapCount == 0)
ARMSOCDRI2SwapComplete(cmd);
......@@ -814,9 +825,9 @@ ARMSOCDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw,
else
cmd->swapCount = 0;
/* Here we have successfully scheduled a flip. We now
* need to exchange buffers between src and dst pixmaps
* and obtain the next buffer.
/* Flip successfully scheduled.
* Now exchange bos between src and dst pixmaps
* and select the next bo for the back buffer.
*/
if (ret) {
assert(cmd->type == DRI2_FLIP_COMPLETE);
......@@ -826,10 +837,11 @@ ARMSOCDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw,
nextBuffer(pDraw, ARMSOCBUF(pSrcBuffer));
}
/* We need to store the new scanout now as the
* destination buffer might be switched before the cb. */
/* Store the new scanout bo now as the destination
* buffer bo might be exchanged if another swap is
* scheduled before this swap completes
*/
cmd->new_scanout = boFromBuffer(pDstBuffer);
if (cmd->swapCount == 0)
ARMSOCDRI2SwapComplete(cmd);
}
......@@ -842,6 +854,8 @@ ARMSOCDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw,
.y2 = pDraw->height,
};
RegionRec region;
DEBUG_MSG("BLITTING");
RegionInit(&region, &box, 0);
ARMSOCDRI2CopyRegion(pDraw, &region, pDstBuffer, pSrcBuffer);
cmd->type = DRI2_BLIT_COMPLETE;
......@@ -934,7 +948,7 @@ ARMSOCDRI2ScreenInit(ScreenPtr pScreen)
#endif
}
pARMSOC->swap_chain = calloc(pARMSOC->swap_chain_size,
sizeof *pARMSOC->swap_chain);
sizeof(*pARMSOC->swap_chain));
INFO_MSG("Setting swap chain size: %d ", pARMSOC->swap_chain_size);
......
......@@ -663,7 +663,7 @@ ARMSOCProbe(DriverPtr drv, int flags)
* driverPrivate field.
*/
pScrn->driverPrivate =
calloc(1, sizeof *pARMSOC);
calloc(1, sizeof(*pARMSOC));
if (!pScrn->driverPrivate)
return FALSE;
......@@ -973,6 +973,7 @@ ARMSOCScreenInit(SCREEN_INIT_ARGS_DECL)
pScrn->virtualX, pScrn->virtualY,
depth, pScrn->bitsPerPixel);
assert(!pARMSOC->scanout);
/* Screen creates and takes a ref on the scanout bo */
pARMSOC->scanout = armsoc_bo_new_with_dim(pARMSOC->dev, pScrn->virtualX,
pScrn->virtualY, depth, pScrn->bitsPerPixel,
ARMSOC_BO_SCANOUT);
......@@ -1163,7 +1164,7 @@ fail3:
miClearVisualTypes();
fail2:
/* release the scanout buffer */
/* Screen drops its ref on scanout bo on failure exit */
armsoc_bo_unreference(pARMSOC->scanout);
pARMSOC->scanout = NULL;
pScrn->displayWidth = 0;
......@@ -1228,7 +1229,9 @@ ARMSOCCloseScreen(CLOSE_SCREEN_ARGS_DECL)
if (pARMSOC->pARMSOCEXA->CloseScreen)
pARMSOC->pARMSOCEXA->CloseScreen(CLOSE_SCREEN_ARGS);
/* scanout buffer is released when root pixmap is destroyed */
assert(pARMSOC->scanout);
/* Screen drops its ref on the scanout buffer */
armsoc_bo_unreference(pARMSOC->scanout);
pARMSOC->scanout = NULL;
pScrn->displayWidth = 0;
......@@ -1243,8 +1246,6 @@ ARMSOCCloseScreen(CLOSE_SCREEN_ARGS_DECL)
return ret;
}
/**
* Adjust the screen pixmap for the current location of the front buffer.
* This is done at EnterVT when buffers are bound as long as the resources
......
......@@ -154,12 +154,13 @@ struct ARMSOCRec {
/* The Swap Chain stores the pending swap operations */
struct ARMSOCDRISwapCmd **swap_chain;
/* This is the swap chain's count used to track last swap cmd. */
/* Count of swaps scheduled since startup.
* Used as swap_id of the next swap cmd */
unsigned int swap_chain_count;
/* Defines swap chain size. */
/* Size of the swap chain. Set to 1 if DRI2SwapLimit unsupported,
* driNumBufs if early display enabled, otherwise driNumBufs-1 */
unsigned int swap_chain_size;
};
/*
......
......@@ -70,7 +70,7 @@ struct armsoc_device *armsoc_device_new(int fd,
int (*create_custom_gem)(int fd,
struct armsoc_create_gem *create_gem))
{
struct armsoc_device *new_dev = calloc(1, sizeof *new_dev);
struct armsoc_device *new_dev = calloc(1, sizeof(*new_dev));
if (!new_dev)
return NULL;
......@@ -201,18 +201,14 @@ static void armsoc_bo_del(struct armsoc_bo *bo)
free(bo);
}
int armsoc_bo_unreference(struct armsoc_bo *bo)
void armsoc_bo_unreference(struct armsoc_bo *bo)
{
int refcnt;
if (!bo)
return 0;
return;
assert(bo->refcnt > 0);
refcnt = bo->refcnt;
if (--bo->refcnt == 0)
armsoc_bo_del(bo);
return --refcnt;
}
void armsoc_bo_reference(struct armsoc_bo *bo)
......@@ -361,9 +357,10 @@ int armsoc_bo_add_fb(struct armsoc_bo *bo)
bo->bpp, bo->pitch, bo->handle, &bo->fb_id);
if (ret < 0 && bo->bpp == 32 && bo->depth == 32 && bo->dev->alpha_supported) {
/* The DRM driver may not support an alpha channel but it is possible
* to continue by ignoring the alpha, so if an attempt to create
* a depth 32, bpp 32 framebuffer fails we retry with depth 24, bpp 32
/* The DRM driver may not support an alpha channel but
* it is possible to continue by ignoring the alpha, so
* if an attempt to create a depth 32, bpp 32 framebuffer
* fails we retry with depth 24, bpp 32
*/
xf86DrvMsg(-1, X_WARNING,
"depth 32 FB unsupported : falling back to depth 24\n");
......
......@@ -81,7 +81,7 @@ uint32_t armsoc_bo_bpp(struct armsoc_bo *bo);
uint32_t armsoc_bo_pitch(struct armsoc_bo *bo);
void armsoc_bo_reference(struct armsoc_bo *bo);
int armsoc_bo_unreference(struct armsoc_bo *bo);
void armsoc_bo_unreference(struct armsoc_bo *bo);
/* When dmabuf is set on a bo, armsoc_bo_cpu_prep()
* waits for KDS shared access
......
/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
/*
* Copyright © 2011 Texas Instruments, Inc
......@@ -78,7 +77,7 @@ ARMSOCCreatePixmap2(ScreenPtr pScreen, int width, int height,
int depth, int usage_hint, int bitsPerPixel,
int *new_fb_pitch)
{
struct ARMSOCPixmapPrivRec *priv = calloc(1, sizeof *priv);
struct ARMSOCPixmapPrivRec *priv = calloc(1, sizeof(*priv));
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
enum armsoc_buf_type buf_type = ARMSOC_BO_NON_SCANOUT;
......@@ -90,6 +89,7 @@ ARMSOCCreatePixmap2(ScreenPtr pScreen, int width, int height,
buf_type = ARMSOC_BO_SCANOUT;
if (width > 0 && height > 0 && depth > 0 && bitsPerPixel > 0) {
/* Pixmap creates and takes a ref on its bo */
priv->bo = armsoc_bo_new_with_dim(pARMSOC->dev,
width,
height,
......@@ -103,6 +103,7 @@ ARMSOCCreatePixmap2(ScreenPtr pScreen, int width, int height,
WARNING_MSG(
"Scanout buffer allocation failed, falling back to non-scanout");
buf_type = ARMSOC_BO_NON_SCANOUT;
/* Pixmap creates and takes a ref on its bo */
priv->bo = armsoc_bo_new_with_dim(pARMSOC->dev,
width,
height,
......@@ -141,6 +142,7 @@ ARMSOCDestroyPixmap(ScreenPtr pScreen, void *driverPriv)
* backing this pixmap. */
if (priv->bo) {
assert(!armsoc_bo_has_dmabuf(priv->bo));
/* pixmap drops ref on its bo */
armsoc_bo_unreference(priv->bo);
}
......@@ -172,6 +174,10 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
/* scratch-pixmap (see GetScratchPixmapHeader()) gets recycled,
* so could have a previous bo!
*/
/* scratch pixmap should not have a dmabuf */
assert(!armsoc_bo_has_dmabuf(priv->bo));
/* Pixmap drops ref on its old bo */
armsoc_bo_unreference(priv->bo);
priv->bo = NULL;
......@@ -179,15 +185,19 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
return FALSE;
}
if (pPixData == armsoc_bo_map(pARMSOC->scanout)) {
/* Replacing the pixmap's current bo with the scanout bo */
if (pPixData == armsoc_bo_map(pARMSOC->scanout) && priv->bo != pARMSOC->scanout) {
struct armsoc_bo *old_bo = priv->bo;
priv->bo = pARMSOC->scanout;
/* pixmap takes a ref on its new bo */
armsoc_bo_reference(priv->bo);
if (old_bo) {
/* We are detaching the old_bo so clear it now. */
if (armsoc_bo_has_dmabuf(old_bo))
armsoc_bo_clear_dmabuf(old_bo);
/* pixmap drops ref on previous bo */
armsoc_bo_unreference(old_bo);
}
}
......@@ -220,8 +230,9 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
if (armsoc_bo_width(priv->bo) != pPixmap->drawable.width ||
armsoc_bo_height(priv->bo) != pPixmap->drawable.height ||
armsoc_bo_bpp(priv->bo) != pPixmap->drawable.bitsPerPixel) {
/* re-allocate buffer! */
/* pixmap drops ref on its old bo */
armsoc_bo_unreference(priv->bo);
/* pixmap creates new bo and takes ref on it */
priv->bo = armsoc_bo_new_with_dim(pARMSOC->dev,
pPixmap->drawable.width,
pPixmap->drawable.height,
......@@ -235,6 +246,7 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
WARNING_MSG(
"Scanout buffer allocation failed, falling back to non-scanout");
buf_type = ARMSOC_BO_NON_SCANOUT;
/* pixmap creates new bo and takes ref on it */
priv->bo = armsoc_bo_new_with_dim(pARMSOC->dev,
pPixmap->drawable.width,
pPixmap->drawable.height,
......
......@@ -1458,10 +1458,10 @@ void set_scanout_bo(ScrnInfoPtr pScrn, struct armsoc_bo *bo)
/* It had better have a framebuffer if we're scanning it out */
assert(armsoc_bo_get_fb(bo));
armsoc_bo_reference(bo);
armsoc_bo_reference(bo); /* Screen takes ref on new scanout bo */
pARMSOC->scanout = bo;
if (old_scanout)
armsoc_bo_unreference(old_scanout);
armsoc_bo_unreference(old_scanout); /* Screen drops ref on old scanout bo */
}
static Bool resize_scanout_bo(ScrnInfoPtr pScrn, int width, int height)
......@@ -1475,12 +1475,12 @@ static Bool resize_scanout_bo(ScrnInfoPtr pScrn, int width, int height)
depth = armsoc_bo_depth(pARMSOC->scanout);
bpp = armsoc_bo_bpp(pARMSOC->scanout);
DEBUG_MSG("Resize: %dx%d %d,%d", width, height, depth, bpp );
DEBUG_MSG("Resize: %dx%d %d,%d", width, height, depth, bpp);
/* We don't expect the depth and bpp to change for the screen
* assert this here as a check */
assert( depth == pScrn->bitsPerPixel );
assert( bpp == pScrn->bitsPerPixel );
assert(depth == pScrn->bitsPerPixel);
assert(bpp == pScrn->bitsPerPixel);
pScrn->virtualX = width;
pScrn->virtualY = height;
......@@ -1489,7 +1489,7 @@ static Bool resize_scanout_bo(ScrnInfoPtr pScrn, int width, int height)
(height != armsoc_bo_height(pARMSOC->scanout))) {
struct armsoc_bo *new_scanout;
/* allocate new scanout buffer */
/* resize_scanout_bo creates and takes ref on new scanout bo */
new_scanout = armsoc_bo_new_with_dim(pARMSOC->dev,
width, height,
depth, bpp,
......@@ -1526,10 +1526,12 @@ static Bool resize_scanout_bo(ScrnInfoPtr pScrn, int width, int height)
pitch = armsoc_bo_pitch(pARMSOC->scanout);
} else {
struct armsoc_bo *old_scanout = pARMSOC->scanout;
DEBUG_MSG("allocated new scanout buffer okay");
pitch = armsoc_bo_pitch(new_scanout);
/* clear new BO and add FB */
if (armsoc_bo_clear(new_scanout)) {
/* resize_scanout_bo drops ref on new scanout on failure exit */
armsoc_bo_unreference(new_scanout);
return FALSE;
}
......@@ -1537,6 +1539,7 @@ static Bool resize_scanout_bo(ScrnInfoPtr pScrn, int width, int height)
if (armsoc_bo_add_fb(new_scanout)) {
ERROR_MSG(
"Failed to add framebuffer to the new scanout buffer");
/* resize_scanout_bo drops ref on new scanout on failure exit */
armsoc_bo_unreference(new_scanout);
return FALSE;
}
......@@ -1551,14 +1554,14 @@ static Bool resize_scanout_bo(ScrnInfoPtr pScrn, int width, int height)
ERROR_MSG(
"Unable to attach dma_buf fd to new scanout buffer - %d (%s)\n",
res, strerror(res));
armsoc_bo_unreference(new_scanout);
armsoc_bo_unreference(new_scanout); /* resize_scanout_bo drops ref on new scanout on failure exit */
return FALSE;
}
}
/* use new scanout buffer */
set_scanout_bo(pScrn, new_scanout);
armsoc_bo_unreference(new_scanout); /* Screen has now taken ref on new_scanout so resize_scanout_bo drops it */
/* Resize swap chain will delete old_scanout */
ARMSOCDRI2ResizeSwapChain(pScrn, old_scanout, new_scanout);
}
pScrn->displayWidth = pitch / ((pScrn->bitsPerPixel + 7) / 8);
......@@ -1568,10 +1571,20 @@ static Bool resize_scanout_bo(ScrnInfoPtr pScrn, int width, int height)
if (pScreen && pScreen->ModifyPixmapHeader) {
PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
/* Wrap the screen pixmap around the new scanout bo.
* If we are n-buffering and the scanout bo is behind the
* screen pixmap by a few flips, the bo which is being resized
* may not belong to the screen pixmap. However we need to
* resize the screen pixmap in order to continue flipping.
* For now we let this happen and the swap chain reference
* on the screen pixmap's existing bo will prevent it being
* deleted here. Things may look odd until the swap chain
* works through. This needs improvement.
*/
pScreen->ModifyPixmapHeader(rootPixmap,
pScrn->virtualX, pScrn->virtualY,
depth, bpp, pitch,
armsoc_bo_map(pARMSOC->scanout));
pScrn->virtualX, pScrn->virtualY,
depth, bpp, pitch,
armsoc_bo_map(pARMSOC->scanout));
/* Bump the serial number to ensure that all existing DRI2
* buffers are invalidated.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment