Commit 1d13da04 authored by Eskil Sund's avatar Eskil Sund

Enabling n-buffering support when using page flip events.

DRI2INFOREC_VERSION 6 introduces DRI2SwapLimit which enables us to schedule
swaps and retrieve next buffer n-times as given by the swap-limit. This
further enables us to do asynchronous swaps which enables asynchronous
rendering to n-buffers.

The swap limit is given by the xorg.conf option DRI2MaxBuffers. If
DRI2MaxBuffers is not specified no swap limit will be set and behavior will
default to synchronous swaps.

Notably, this commit bumps up the required DRI2INFOREC_VERSION to 5 as required
by drmAuth. DRI2INFOREC_VERSION 6, with DRI2SwapLimit, is optional.

Change-Id: Ia39dcd91628172f884eac914938d8ddd4b41aa71
parent 16d0102d
This diff is collapsed.
......@@ -151,6 +151,15 @@ struct ARMSOCRec {
/* Identify which CRTC to use. -1 uses all CRTCs */
int crtcNum;
/* 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. */
int swap_chain_count;
/* Defines swap chain size. */
int swap_chain_size;
};
/*
......@@ -209,6 +218,7 @@ struct ARMSOCDRISwapCmd;
Bool ARMSOCDRI2ScreenInit(ScreenPtr pScreen);
void ARMSOCDRI2CloseScreen(ScreenPtr pScreen);
void ARMSOCDRI2SwapComplete(struct ARMSOCDRISwapCmd *cmd);
void ARMSOCDRI2ResizeSwapChain(ScrnInfoPtr pScrn, struct armsoc_bo *old_bo, struct armsoc_bo *resized_bo);
/**
* DRI2 util functions..
......
......@@ -201,14 +201,18 @@ static void armsoc_bo_del(struct armsoc_bo *bo)
free(bo);
}
void armsoc_bo_unreference(struct armsoc_bo *bo)
int armsoc_bo_unreference(struct armsoc_bo *bo)
{
int refcnt;
if (!bo)
return;
return 0;
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)
......
......@@ -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);
void armsoc_bo_unreference(struct armsoc_bo *bo);
int armsoc_bo_unreference(struct armsoc_bo *bo);
/* When dmabuf is set on a bo, armsoc_bo_cpu_prep()
* waits for KDS shared access
......
......@@ -136,9 +136,9 @@ ARMSOCDestroyPixmap(ScreenPtr pScreen, void *driverPriv)
struct ARMSOCPixmapPrivRec *priv = driverPriv;
assert(!priv->ext_access_cnt);
/* If ModifyPixmapHeader failed, it's possible we don't have a bo
* backing this pixmap. */
if (priv->bo) {
assert(!armsoc_bo_has_dmabuf(priv->bo));
armsoc_bo_unreference(priv->bo);
......@@ -179,8 +179,18 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
return FALSE;
}
if (pPixData == armsoc_bo_map(pARMSOC->scanout))
if (pPixData == armsoc_bo_map(pARMSOC->scanout)) {
struct armsoc_bo *old_bo = priv->bo;
priv->bo = pARMSOC->scanout;
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);
armsoc_bo_unreference(old_bo);
}
}
if (priv->usage_hint & ARMSOC_CREATE_PIXMAP_SCANOUT)
buf_type = ARMSOC_BO_SCANOUT;
......@@ -211,7 +221,8 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
armsoc_bo_height(priv->bo) != pPixmap->drawable.height ||
armsoc_bo_bpp(priv->bo) != pPixmap->drawable.bitsPerPixel) {
/* re-allocate buffer! */
armsoc_bo_unreference(priv->bo);
if (priv->bo)
armsoc_bo_unreference(priv->bo);
priv->bo = armsoc_bo_new_with_dim(pARMSOC->dev,
pPixmap->drawable.width,
pPixmap->drawable.height,
......
......@@ -1418,11 +1418,16 @@ drmmode_clones_init(ScrnInfoPtr pScrn, struct drmmode_rec *drmmode)
void set_scanout_bo(ScrnInfoPtr pScrn, struct armsoc_bo *bo)
{
struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
struct armsoc_bo *old_scanout;
old_scanout = pARMSOC->scanout;
/* It had better have a framebuffer if we're scanning it out */
assert(armsoc_bo_get_fb(bo));
armsoc_bo_reference(bo);
pARMSOC->scanout = bo;
if (old_scanout)
armsoc_bo_unreference(old_scanout);
}
static Bool resize_scanout_bo(ScrnInfoPtr pScrn, int width, int height)
......@@ -1486,6 +1491,7 @@ 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 */
......@@ -1502,10 +1508,10 @@ static Bool resize_scanout_bo(ScrnInfoPtr pScrn, int width, int height)
}
/* Handle dma_buf fd that may be attached to old bo */
if (armsoc_bo_has_dmabuf(pARMSOC->scanout)) {
if (armsoc_bo_has_dmabuf(old_scanout)) {
int res;
armsoc_bo_clear_dmabuf(pARMSOC->scanout);
armsoc_bo_clear_dmabuf(old_scanout);
res = armsoc_bo_set_dmabuf(new_scanout);
if (res) {
ERROR_MSG(
......@@ -1515,10 +1521,11 @@ static Bool resize_scanout_bo(ScrnInfoPtr pScrn, int width, int height)
return FALSE;
}
}
/* delete old scanout buffer */
armsoc_bo_unreference(pARMSOC->scanout);
/* use new scanout buffer */
set_scanout_bo(pScrn, new_scanout);
/* Resize swap chain will delete old_scanout */
ARMSOCDRI2ResizeSwapChain(pScrn, old_scanout, new_scanout);
}
pScrn->displayWidth = pitch / ((pScrn->bitsPerPixel + 7) / 8);
} else
......@@ -1556,7 +1563,7 @@ drmmode_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height)
TRACE_ENTER();
if (!resize_scanout_bo(pScrn, width, height))
return FALSE;
goto fail;
/* Framebuffer needs to be reset on all CRTCs, not just
* those that have repositioned */
......@@ -1573,6 +1580,10 @@ drmmode_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height)
TRACE_EXIT();
return TRUE;
fail:
TRACE_EXIT();
return FALSE;
}
static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
......
......@@ -43,6 +43,12 @@ struct drmmode_interface {
*/
int use_page_flip_events;
/* Boolean value indicating whether to support early display
* feature. This allows the next back buffer to be obtained while
* the previous is being flipped.
*/
int use_early_display;
/* The cursor width */
int cursor_width;
......
......@@ -146,6 +146,7 @@ static int create_custom_gem(int fd, struct armsoc_create_gem *create_gem)
struct drmmode_interface exynos_interface = {
1 /* use_page_flip_events */,
1 /* use_early_display */,
CURSORW /* cursor width */,
CURSORH /* cursor_height */,
CURSORPAD /* cursor padding */,
......
......@@ -106,7 +106,8 @@ static int create_custom_gem(int fd, struct armsoc_create_gem *create_gem)
}
struct drmmode_interface pl111_interface = {
0 /* use_page_flip_events */,
1 /* use_page_flip_events */,
1 /* use_early_display */,
CURSORW /* cursor width */,
CURSORH /* cursor_height */,
CURSORPAD /* cursor padding */,
......
......@@ -54,6 +54,7 @@ static int create_custom_gem(int fd, struct armsoc_create_gem *create_gem)
struct drmmode_interface template_interface = {
1 /* use_page_flip_events */,
1 /* use_early_display */,
CURSORW /* cursor width */,
CURSORH /* cursor_height */,
CURSORPAD /* cursor padding */,
......
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