Merge remote-tracking branch 'airlied/for-keithp'

This commit is contained in:
Keith Packard 2015-06-29 21:04:53 -07:00
commit 8a8d51358c
25 changed files with 821 additions and 127 deletions

View File

@ -2105,6 +2105,10 @@ if test "x$GLAMOR" = xyes; then
if test "x$GBM" = xyes; then
AC_DEFINE(GLAMOR_HAS_GBM, 1,
[Build glamor with GBM-based EGL support])
AC_CHECK_DECL(GBM_BO_USE_LINEAR,
[AC_DEFINE(GLAMOR_HAS_GBM_LINEAR, 1, [Have GBM_BO_USE_LINEAR])], [],
[#include <stdlib.h>
#include <gbm.h>])
fi
fi

View File

@ -80,9 +80,7 @@ FreeCursorBits(CursorBitsPtr bits)
return;
free(bits->source);
free(bits->mask);
#ifdef ARGB_CURSOR
free(bits->argb);
#endif
dixFiniPrivates(bits, PRIVATE_CURSOR_BITS);
if (bits->refcnt == 0) {
GlyphSharePtr *prev, this;
@ -165,7 +163,6 @@ CheckForEmptyMask(CursorBitsPtr bits)
while (n--)
if (*(msk++) != 0)
return;
#ifdef ARGB_CURSOR
if (bits->argb) {
CARD32 *argb = bits->argb;
@ -174,7 +171,6 @@ CheckForEmptyMask(CursorBitsPtr bits)
if (*argb++ & 0xff000000)
return;
}
#endif
bits->emptyMask = TRUE;
}
@ -259,9 +255,7 @@ AllocARGBCursor(unsigned char *psrcbits, unsigned char *pmaskbits,
dixInitPrivates(bits, bits + 1, PRIVATE_CURSOR_BITS)
bits->source = psrcbits;
bits->mask = pmaskbits;
#ifdef ARGB_CURSOR
bits->argb = argb;
#endif
bits->width = cm->width;
bits->height = cm->height;
bits->xhot = cm->xhot;
@ -400,9 +394,7 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar,
dixInitPrivates(bits, bits + 1, PRIVATE_CURSOR_BITS);
bits->source = srcbits;
bits->mask = mskbits;
#ifdef ARGB_CURSOR
bits->argb = 0;
#endif
bits->width = cm.width;
bits->height = cm.height;
bits->xhot = cm.xhot;

View File

@ -142,7 +142,8 @@ extern _X_EXPORT void glamor_enable_dri3(ScreenPtr screen);
extern _X_EXPORT unsigned int glamor_egl_create_argb8888_based_texture(ScreenPtr
screen,
int w,
int h);
int h,
Bool linear);
extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr,
unsigned int, Bool,
CARD16 *, CARD32 *);
@ -197,6 +198,21 @@ extern _X_EXPORT int glamor_fd_from_pixmap(ScreenPtr screen,
extern _X_EXPORT int glamor_name_from_pixmap(PixmapPtr pixmap,
CARD16 *stride, CARD32 *size);
/* @glamor_gbm_bo_from_pixmap: Get a GBM bo from a pixmap.
*
* @screen: Current screen pointer.
* @pixmap: The pixmap from which we want the fd.
* @stride, @size: Pointers to fill the stride and size of the
* buffer associated to the fd.
*
* the pixmap and the buffer represented by the gbm_bo will share the same
* content.
*
* Returns the gbm_bo on success, NULL on error.
* */
extern _X_EXPORT void *glamor_gbm_bo_from_pixmap(ScreenPtr screen,
PixmapPtr pixmap);
/* @glamor_pixmap_from_fd: Creates a pixmap to wrap a dma-buf fd.
*
* @screen: Current screen pointer.
@ -217,6 +233,25 @@ extern _X_EXPORT PixmapPtr glamor_pixmap_from_fd(ScreenPtr screen,
CARD8 depth,
CARD8 bpp);
/* @glamor_back_pixmap_from_fd: Backs an existing pixmap with a dma-buf fd.
*
* @pixmap: Pixmap to change backing for
* @fd: The dma-buf fd to import.
* @width: The width of the buffer.
* @height: The height of the buffer.
* @stride: The stride of the buffer.
* @depth: The depth of the buffer.
* @bpp: The number of bpp of the buffer.
*
* Returns TRUE if successful, FALSE on failure.
* */
extern _X_EXPORT Bool glamor_back_pixmap_from_fd(PixmapPtr pixmap,
int fd,
CARD16 width,
CARD16 height,
CARD16 stride,
CARD8 depth,
CARD8 bpp);
#ifdef GLAMOR_FOR_XORG
#define GLAMOR_EGL_MODULE_NAME "glamoregl"

View File

@ -187,7 +187,7 @@ glamor_egl_get_gbm_device(ScreenPtr screen)
}
unsigned int
glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h, Bool linear)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct glamor_egl_screen_private *glamor_egl;
@ -200,6 +200,9 @@ glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
glamor_egl = glamor_egl_get_screen_private(scrn);
bo = gbm_bo_create(glamor_egl->gbm, w, h, GBM_FORMAT_ARGB8888,
#ifdef GLAMOR_HAS_GBM_LINEAR
(linear ? GBM_BO_USE_LINEAR : 0) |
#endif
GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
if (!bo)
return 0;
@ -392,13 +395,10 @@ glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name)
}
#endif
int
glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
PixmapPtr pixmap,
unsigned int tex,
Bool want_name, CARD16 *stride, CARD32 *size)
{
#ifdef GLAMOR_HAS_GBM
static void *
_get_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, unsigned int tex)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
@ -407,7 +407,6 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
struct glamor_egl_screen_private *glamor_egl;
EGLImageKHR image;
struct gbm_bo *bo;
int fd = -1;
EGLint attribs[] = {
EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
@ -427,13 +426,64 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
(EGLClientBuffer) (uintptr_t)
tex, attribs);
if (image == EGL_NO_IMAGE_KHR)
goto failure;
return NULL;
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
glamor_egl_set_pixmap_image(pixmap, image);
}
bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
if (!bo)
return NULL;
pixmap->devKind = gbm_bo_get_stride(bo);
return bo;
}
#endif
void *
glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap)
{
#ifdef GLAMOR_HAS_GBM
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (pixmap_priv == NULL || !glamor_priv->dri3_enabled)
return NULL;
switch (pixmap_priv->type) {
case GLAMOR_TEXTURE_DRM:
case GLAMOR_TEXTURE_ONLY:
if (!glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0))
return NULL;
return _get_gbm_bo_from_pixmap(screen, pixmap,
pixmap_priv->fbo->tex);
default:
break;
}
return NULL;
#else
return NULL;
#endif
}
int
glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
PixmapPtr pixmap,
unsigned int tex,
Bool want_name, CARD16 *stride, CARD32 *size)
{
#ifdef GLAMOR_HAS_GBM
struct glamor_egl_screen_private *glamor_egl;
struct gbm_bo *bo;
int fd = -1;
glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
bo = _get_gbm_bo_from_pixmap(screen, pixmap, tex);
if (!bo)
goto failure;
@ -458,19 +508,19 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
#endif
}
_X_EXPORT PixmapPtr
glamor_pixmap_from_fd(ScreenPtr screen,
int fd,
CARD16 width,
CARD16 height,
CARD16 stride, CARD8 depth, CARD8 bpp)
_X_EXPORT Bool
glamor_back_pixmap_from_fd(PixmapPtr pixmap,
int fd,
CARD16 width,
CARD16 height,
CARD16 stride, CARD8 depth, CARD8 bpp)
{
#ifdef GLAMOR_HAS_GBM
ScreenPtr screen = pixmap->drawable.pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct glamor_egl_screen_private *glamor_egl;
struct gbm_bo *bo;
EGLImageKHR image;
PixmapPtr pixmap;
Bool ret = FALSE;
EGLint attribs[] = {
@ -486,10 +536,10 @@ glamor_pixmap_from_fd(ScreenPtr screen,
glamor_egl = glamor_egl_get_screen_private(scrn);
if (!glamor_egl->dri3_capable)
return NULL;
return FALSE;
if (bpp != 32 || !(depth == 24 || depth == 32) || width == 0 || height == 0)
return NULL;
return FALSE;
attribs[1] = width;
attribs[3] = height;
@ -501,29 +551,48 @@ glamor_pixmap_from_fd(ScreenPtr screen,
NULL, attribs);
if (image == EGL_NO_IMAGE_KHR)
return NULL;
return FALSE;
/* EGL_EXT_image_dma_buf_import can impose restrictions on the
* usage of the image. Use gbm_bo to bypass the limitations. */
bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
eglDestroyImageKHR(glamor_egl->display, image);
if (!bo)
return NULL;
return FALSE;
pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0);
screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL);
ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo);
gbm_bo_destroy(bo);
if (ret)
return pixmap;
else {
return TRUE;
return FALSE;
#else
return FALSE;
#endif
}
_X_EXPORT PixmapPtr
glamor_pixmap_from_fd(ScreenPtr screen,
int fd,
CARD16 width,
CARD16 height,
CARD16 stride, CARD8 depth, CARD8 bpp)
{
#ifdef GLAMOR_HAS_GBM
PixmapPtr pixmap;
Bool ret;
pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0);
ret = glamor_back_pixmap_from_fd(pixmap, fd, width, height,
stride, depth, bpp);
if (ret == FALSE) {
screen->DestroyPixmap(pixmap);
return NULL;
}
return pixmap;
#else
return NULL;
#endif

View File

@ -50,7 +50,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
}
unsigned int
glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h, Bool linear)
{
return 0;
}

View File

@ -228,6 +228,9 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
fbo->external = FALSE;
fbo->format = format;
if (flag == CREATE_PIXMAP_USAGE_SHARED)
fbo->external = TRUE;
if (flag != GLAMOR_CREATE_FBO_NO_FBO) {
if (glamor_pixmap_ensure_fb(glamor_priv, fbo) != 0) {
glamor_purge_fbo(glamor_priv, fbo);
@ -313,7 +316,7 @@ glamor_destroy_fbo(glamor_screen_private *glamor_priv,
static int
_glamor_create_tex(glamor_screen_private *glamor_priv,
int w, int h, GLenum format)
int w, int h, GLenum format, Bool linear)
{
unsigned int tex = 0;
@ -323,7 +326,7 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
* an ARGB8888 based texture for us. */
if (glamor_priv->dri3_enabled && format == GL_RGBA) {
tex = glamor_egl_create_argb8888_based_texture(glamor_priv->screen,
w, h);
w, h, linear);
}
if (!tex) {
glamor_make_current(glamor_priv);
@ -344,14 +347,14 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
glamor_pixmap_fbo *fbo;
GLint tex = 0;
if (flag == GLAMOR_CREATE_FBO_NO_FBO)
if (flag == GLAMOR_CREATE_FBO_NO_FBO || flag == CREATE_PIXMAP_USAGE_SHARED)
goto new_fbo;
fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h, format);
if (fbo)
return fbo;
new_fbo:
tex = _glamor_create_tex(glamor_priv, w, h, format);
tex = _glamor_create_tex(glamor_priv, w, h, format, flag == CREATE_PIXMAP_USAGE_SHARED);
fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag);
return fbo;
@ -531,7 +534,7 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
if (!pixmap_priv->fbo->tex)
pixmap_priv->fbo->tex =
_glamor_create_tex(glamor_priv, pixmap->drawable.width,
pixmap->drawable.height, format);
pixmap->drawable.height, format, FALSE);
if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->fbo->fb == 0)
if (glamor_pixmap_ensure_fb(glamor_priv, pixmap_priv->fbo) != 0)

View File

@ -100,7 +100,6 @@ ephyrRealizeCoreCursor(EphyrScrPriv *scr, CursorPtr cursor)
xcb_free_pixmap(conn, mask);
}
#ifdef ARGB_CURSOR
static xcb_render_pictformat_t
get_argb_format(void)
{
@ -170,7 +169,6 @@ can_argb_cursor(void)
return v->major_version == 0 && v->minor_version >= 5;
}
#endif
static Bool
ephyrRealizeCursor(DeviceIntPtr dev, ScreenPtr screen, CursorPtr cursor)
@ -179,11 +177,9 @@ ephyrRealizeCursor(DeviceIntPtr dev, ScreenPtr screen, CursorPtr cursor)
KdScreenInfo *kscr = pScreenPriv->screen;
EphyrScrPriv *scr = kscr->driver;
#ifdef ARGB_CURSOR
if (cursor->bits->argb && can_argb_cursor())
ephyrRealizeARGBCursor(scr, cursor);
else
#endif
{
ephyrRealizeCoreCursor(scr, cursor);
}

View File

@ -123,7 +123,7 @@ static ModuleDefault ModuleDefaults[] = {
/* Forward declarations */
static Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen,
int scrnum, MessageType from);
int scrnum, MessageType from, Bool auto_gpu_device);
static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor);
static Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device,
Bool active, Bool gpu);
@ -1524,7 +1524,7 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
else
scrnum = adjp->adj_scrnum;
if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum,
X_CONFIG)) {
X_CONFIG, (scrnum == 0 && !adjp->list.next))) {
do {
free(slp[count].screen);
} while (count--);
@ -1574,7 +1574,7 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
FIND_SUITABLE (XF86ConfScreenPtr, xf86configptr->conf_screen_lst, screen);
slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
if (!configScreen(slp[0].screen, screen,
0, X_CONFIG)) {
0, X_CONFIG, TRUE)) {
free(slp[0].screen);
free(slp);
return FALSE;
@ -1703,7 +1703,7 @@ configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
slp = xnfcalloc(1, 2 * sizeof(screenLayoutRec));
slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
slp[1].screen = NULL;
if (!configScreen(slp[0].screen, conf_screen, 0, from)) {
if (!configScreen(slp[0].screen, conf_screen, 0, from, TRUE)) {
free(slp);
return FALSE;
}
@ -1768,7 +1768,7 @@ configXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor)
static Bool
configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
MessageType from)
MessageType from, Bool auto_gpu_device)
{
int count = 0;
XF86ConfDisplayPtr dispptr;
@ -1825,7 +1825,8 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
screenp->device = NULL;
}
if (conf_screen->num_gpu_devices == 0 && xf86configptr->conf_device_lst) {
if (auto_gpu_device && conf_screen->num_gpu_devices == 0 &&
xf86configptr->conf_device_lst) {
XF86ConfDevicePtr sdevice = xf86configptr->conf_device_lst->list.next;
for (i = 0; i < MAX_GPUDEVICES; i++) {

View File

@ -123,6 +123,7 @@ typedef enum {
OPTION_DEVICE_PATH,
OPTION_SHADOW_FB,
OPTION_ACCEL_METHOD,
OPTION_PAGEFLIP,
} modesettingOpts;
static const OptionInfoRec Options[] = {
@ -130,6 +131,7 @@ static const OptionInfoRec Options[] = {
{OPTION_DEVICE_PATH, "kmsdev", OPTV_STRING, {0}, FALSE},
{OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE},
{OPTION_PAGEFLIP, "PageFlip", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
@ -531,6 +533,38 @@ dispatch_slave_dirty(ScreenPtr pScreen)
}
}
static void
redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
{
RegionRec pixregion;
PixmapRegionInit(&pixregion, dirty->slave_dst);
DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion);
PixmapSyncDirtyHelper(dirty, &pixregion);
DamageRegionProcessPending(&dirty->slave_dst->drawable);
RegionUninit(&pixregion);
}
static void
ms_dirty_update(ScreenPtr screen)
{
RegionPtr region;
PixmapDirtyUpdatePtr ent;
if (xorg_list_is_empty(&screen->pixmap_dirty_list))
return;
xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
region = DamageRegion(ent->damage);
if (RegionNotEmpty(region)) {
redisplay_dirty(screen, ent);
DamageEmpty(ent->damage);
}
}
}
static void
msBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask)
{
@ -540,10 +574,12 @@ msBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask)
pScreen->BlockHandler(pScreen, pTimeout, pReadmask);
ms->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = msBlockHandler;
if (pScreen->isGPU)
if (pScreen->isGPU && !ms->drmmode.reverse_prime_offload_mode)
dispatch_slave_dirty(pScreen);
else if (ms->dirty_enabled)
dispatch_dirty(pScreen);
ms_dirty_update(pScreen);
}
static void
@ -727,6 +763,10 @@ PreInit(ScrnInfoPtr pScrn, int flags)
if (ret == 0) {
if (value & DRM_PRIME_CAP_IMPORT)
pScrn->capabilities |= RR_Capability_SinkOutput;
#if GLAMOR_HAS_GBM_LINEAR
if (value & DRM_PRIME_CAP_EXPORT)
pScrn->capabilities |= RR_Capability_SourceOutput;
#endif
}
#endif
drmmode_get_default_bpp(pScrn, &ms->drmmode, &defaultdepth, &defaultbpp);
@ -782,7 +822,8 @@ PreInit(ScrnInfoPtr pScrn, int flags)
try_enable_glamor(pScrn);
if (ms->drmmode.glamor) {
xf86LoadSubModule(pScrn, "dri2");
ms->drmmode.pageflip =
xf86ReturnOptValBool(ms->Options, OPTION_PAGEFLIP, TRUE);
} else {
Bool prefer_shadow = TRUE;
@ -799,6 +840,8 @@ PreInit(ScrnInfoPtr pScrn, int flags)
"ShadowFB: preferred %s, enabled %s\n",
prefer_shadow ? "YES" : "NO",
ms->drmmode.shadow_enable ? "YES" : "NO");
ms->drmmode.pageflip = FALSE;
}
if (drmmode_pre_init(pScrn, &ms->drmmode, pScrn->bitsPerPixel / 8) == FALSE) {
@ -937,6 +980,23 @@ msShadowInit(ScreenPtr pScreen)
return TRUE;
}
static Bool
msSharePixmapBacking(PixmapPtr ppix, ScreenPtr screen, void **handle)
{
#ifdef GLAMOR_HAS_GBM
int ret;
CARD16 stride;
CARD32 size;
ret = glamor_fd_from_pixmap(ppix->drawable.pScreen, ppix, &stride, &size);
if (ret == -1)
return FALSE;
*handle = (void *)(long)(ret);
return TRUE;
#endif
return FALSE;
}
static Bool
msSetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle)
{
@ -944,10 +1004,18 @@ msSetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle)
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
Bool ret;
int size = ppix->devKind * ppix->drawable.height;
int ihandle = (int) (long) fd_handle;
ret = drmmode_SetSlaveBO(ppix, &ms->drmmode, ihandle, ppix->devKind, size);
if (ms->drmmode.reverse_prime_offload_mode) {
ret = glamor_back_pixmap_from_fd(ppix, ihandle,
ppix->drawable.width,
ppix->drawable.height,
ppix->devKind, ppix->drawable.depth,
ppix->drawable.bitsPerPixel);
} else {
int size = ppix->devKind * ppix->drawable.height;
ret = drmmode_SetSlaveBO(ppix, &ms->drmmode, ihandle, ppix->devKind, size);
}
if (ret == FALSE)
return ret;
@ -1089,7 +1157,10 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
ms->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = msBlockHandler;
pScreen->SharePixmapBacking = msSharePixmapBacking;
pScreen->SetSharedPixmapBacking = msSetSharedPixmapBacking;
pScreen->StartPixmapTracking = PixmapStartDirtyTracking;
pScreen->StopPixmapTracking = PixmapStopDirtyTracking;
if (!xf86CrtcScreenInit(pScreen))
return FALSE;
@ -1132,6 +1203,9 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to initialize the Present extension.\n");
}
/* enable reverse prime if we are a GPU screen, and accelerated */
if (pScreen->isGPU)
ms->drmmode.reverse_prime_offload_mode = TRUE;
}
#endif

View File

@ -101,6 +101,12 @@ typedef struct _modesettingRec {
drmEventContext event_context;
/**
* Page flipping stuff.
* @{
*/
/** @} */
DamagePtr damage;
Bool dirty_enabled;
@ -117,6 +123,9 @@ uint32_t ms_drm_queue_alloc(xf86CrtcPtr crtc,
void ms_drm_abort(ScrnInfoPtr scrn,
Bool (*match)(void *data, void *match_data),
void *match_data);
void ms_drm_abort_seq(ScrnInfoPtr scrn, uint32_t seq);
Bool ms_crtc_on(xf86CrtcPtr crtc);
xf86CrtcPtr ms_dri2_crtc_covering_drawable(DrawablePtr pDraw);
xf86CrtcPtr ms_covering_crtc(ScrnInfoPtr scrn, BoxPtr box,

View File

@ -50,7 +50,9 @@
#include "driver.h"
static int
static Bool drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height);
int
drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
{
int ret;
@ -71,7 +73,7 @@ drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
return 0;
}
static uint32_t
uint32_t
drmmode_bo_get_pitch(drmmode_bo *bo)
{
#ifdef GLAMOR_HAS_GBM
@ -141,6 +143,35 @@ drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
return bo->dumb != NULL;
}
Bool
drmmode_bo_for_pixmap(drmmode_ptr drmmode, drmmode_bo *bo, PixmapPtr pixmap)
{
ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn);
uint16_t pitch;
uint32_t size;
int fd;
#ifdef GLAMOR_HAS_GBM
if (drmmode->glamor) {
bo->gbm = glamor_gbm_bo_from_pixmap(screen, pixmap);
bo->dumb = NULL;
return bo->gbm != NULL;
}
#endif
fd = glamor_fd_from_pixmap(screen, pixmap, &pitch, &size);
if (fd < 0) {
xf86DrvMsg(drmmode->scrn->scrnIndex, X_ERROR,
"Failed to get fd for flip to new front.\n");
return FALSE;
}
bo->dumb = dumb_get_bo_from_fd(drmmode->fd, fd, pitch, size);
close(fd);
return bo->dumb != NULL;
}
Bool
drmmode_SetSlaveBO(PixmapPtr ppix,
drmmode_ptr drmmode, int fd_handle, int pitch, int size)
@ -343,10 +374,14 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
fb_id = drmmode->fb_id;
if (crtc->randr_crtc->scanout_pixmap) {
msPixmapPrivPtr ppriv =
msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap);
fb_id = ppriv->fb_id;
x = y = 0;
if (!drmmode->reverse_prime_offload_mode) {
msPixmapPrivPtr ppriv =
msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap);
fb_id = ppriv->fb_id;
x = 0;
} else
x = drmmode_crtc->prime_pixmap_x;
y = 0;
}
else if (drmmode_crtc->rotate_fb_id) {
fb_id = drmmode_crtc->rotate_fb_id;
@ -363,6 +398,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
if (crtc->scrn->pScreen)
xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen);
drmmode_crtc->need_modeset = FALSE;
crtc->funcs->dpms(crtc, DPMSModeOn);
/* go through all the outputs and force DPMS them back on? */
@ -502,7 +538,54 @@ drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t * red, uint16_t * green,
}
static Bool
drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
drmmode_set_scanout_pixmap_gpu(xf86CrtcPtr crtc, PixmapPtr ppix)
{
ScreenPtr screen = xf86ScrnToScreen(crtc->scrn);
PixmapPtr screenpix = screen->GetScreenPixmap(screen);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
int c, total_width = 0, max_height = 0, this_x = 0;
if (!ppix) {
if (crtc->randr_crtc->scanout_pixmap)
PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap, screenpix);
drmmode_crtc->prime_pixmap_x = 0;
return TRUE;
}
/* iterate over all the attached crtcs to work out the bounding box */
for (c = 0; c < xf86_config->num_crtc; c++) {
xf86CrtcPtr iter = xf86_config->crtc[c];
if (!iter->enabled && iter != crtc)
continue;
if (iter == crtc) {
this_x = total_width;
total_width += ppix->drawable.width;
if (max_height < ppix->drawable.height)
max_height = ppix->drawable.height;
} else {
total_width += iter->mode.HDisplay;
if (max_height < iter->mode.VDisplay)
max_height = iter->mode.VDisplay;
}
}
if (total_width != screenpix->drawable.width ||
max_height != screenpix->drawable.height) {
if (!drmmode_xf86crtc_resize(crtc->scrn, total_width, max_height))
return FALSE;
screenpix = screen->GetScreenPixmap(screen);
screen->width = screenpix->drawable.width = total_width;
screen->height = screenpix->drawable.height = max_height;
}
drmmode_crtc->prime_pixmap_x = this_x;
PixmapStartDirtyTracking2(ppix, screenpix, 0, 0, this_x, 0);
return TRUE;
}
static Bool
drmmode_set_scanout_pixmap_cpu(xf86CrtcPtr crtc, PixmapPtr ppix)
{
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
drmmode_ptr drmmode = drmmode_crtc->drmmode;
@ -543,6 +626,18 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
return TRUE;
}
static Bool
drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
{
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
drmmode_ptr drmmode = drmmode_crtc->drmmode;
if (drmmode->reverse_prime_offload_mode)
return drmmode_set_scanout_pixmap_gpu(crtc, ppix);
else
return drmmode_set_scanout_pixmap_cpu(crtc, ppix);
}
static void *
drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
{
@ -939,6 +1034,7 @@ static void
drmmode_output_dpms(xf86OutputPtr output, int mode)
{
drmmode_output_private_ptr drmmode_output = output->driver_private;
xf86CrtcPtr crtc = output->crtc;
drmModeConnectorPtr koutput = drmmode_output->mode_output;
drmmode_ptr drmmode = drmmode_output->drmmode;
@ -947,6 +1043,13 @@ drmmode_output_dpms(xf86OutputPtr output, int mode)
drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id,
drmmode_output->dpms_enum_id, mode);
if (mode == DPMSModeOn && crtc) {
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
if (drmmode_crtc->need_modeset)
drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation,
crtc->x, crtc->y);
}
return;
}

View File

@ -46,7 +46,6 @@ typedef struct {
typedef struct {
int fd;
unsigned fb_id;
unsigned old_fb_id;
drmModeFBPtr mode_fb;
int cpp;
ScrnInfoPtr scrn;
@ -63,6 +62,8 @@ typedef struct {
Bool glamor;
Bool shadow_enable;
/** Is Option "PageFlip" enabled? */
Bool pageflip;
void *shadow_fb;
/**
@ -79,6 +80,8 @@ typedef struct {
uint32_t triple_buffer_name;
DevPrivateKeyRec pixmapPrivateKeyRec;
Bool reverse_prime_offload_mode;
} drmmode_rec, *drmmode_ptr;
typedef struct {
@ -93,7 +96,7 @@ typedef struct {
drmmode_bo rotate_bo;
unsigned rotate_fb_id;
unsigned prime_pixmap_x;
/**
* @{ MSC (vblank count) handling for the PRESENT extension.
*
@ -105,6 +108,8 @@ typedef struct {
uint32_t msc_prev;
uint64_t msc_high;
/** @} */
Bool need_modeset;
} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
typedef struct {
@ -139,6 +144,9 @@ extern DevPrivateKeyRec msPixmapPrivateKeyRec;
#define msGetPixmapPriv(drmmode, p) ((msPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &(drmmode)->pixmapPrivateKeyRec))
Bool drmmode_bo_for_pixmap(drmmode_ptr drmmode, drmmode_bo *bo, PixmapPtr pixmap);
int drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo);
uint32_t drmmode_bo_get_pitch(drmmode_bo *bo);
uint32_t drmmode_bo_get_handle(drmmode_bo *bo);
Bool drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode);
void *drmmode_map_slave_bo(drmmode_ptr drmmode, msPixmapPrivPtr ppriv);

View File

@ -44,6 +44,7 @@
#include <present.h>
#include "driver.h"
#include "drmmode_display.h"
#if 0
#define DebugPresent(x) ErrorF x
@ -72,8 +73,11 @@ ms_present_get_ust_msc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc)
/*
* Flush the DRM event queue when full; makes space for new events.
*
* Returns a negative value on error, 0 if there was nothing to process,
* or 1 if we handled any events.
*/
static Bool
static int
ms_flush_drm_events(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
@ -86,10 +90,19 @@ ms_flush_drm_events(ScreenPtr screen)
r = poll(&p, 1, 0);
} while (r == -1 && (errno == EINTR || errno == EAGAIN));
/* If there was an error, r will be < 0. Return that. If there was
* nothing to process, r == 0. Return that.
*/
if (r <= 0)
return TRUE;
return r;
return drmHandleEvent(ms->fd, &ms->event_context) >= 0;
/* Try to handle the event. If there was an error, return it. */
r = drmHandleEvent(ms->fd, &ms->event_context);
if (r < 0)
return r;
/* Otherwise return 1 to indicate that we handled an event. */
return 1;
}
/*
@ -159,8 +172,13 @@ ms_present_queue_vblank(RRCrtcPtr crtc,
ret = drmWaitVBlank(ms->fd, &vbl);
if (!ret)
break;
if (errno != EBUSY || !ms_flush_drm_events(screen))
/* If we hit EBUSY, then try to flush events. If we can't, then
* this is an error.
*/
if (errno != EBUSY || ms_flush_drm_events(screen) < 0) {
ms_drm_abort_seq(scrn, seq);
return BadAlloc;
}
}
DebugPresent(("\t\tmq %lld seq %u msc %llu (hw msc %u)\n",
(long long) event_id, seq, (long long) msc,
@ -206,6 +224,413 @@ ms_present_flush(WindowPtr window)
#endif
}
#ifdef GLAMOR
/*
* Event data for an in progress flip.
* This contains a pointer to the vblank event,
* and information about the flip in progress.
* a reference to this is stored in the per-crtc
* flips.
*/
struct ms_flipdata {
ScreenPtr screen;
struct ms_present_vblank_event *event;
/* number of CRTC events referencing this */
int flip_count;
uint64_t fe_msc;
uint64_t fe_usec;
uint32_t old_fb_id;
};
/*
* Per crtc pageflipping infomation,
* These are submitted to the queuing code
* one of them per crtc per flip.
*/
struct ms_crtc_pageflip {
Bool on_reference_crtc;
/* reference to the ms_flipdata */
struct ms_flipdata *flipdata;
};
/**
* Free an ms_crtc_pageflip.
*
* Drops the reference count on the flipdata.
*/
static void
ms_present_flip_free(struct ms_crtc_pageflip *flip)
{
struct ms_flipdata *flipdata = flip->flipdata;
free(flip);
if (--flipdata->flip_count > 0)
return;
free(flipdata);
}
/**
* Callback for the DRM event queue when a single flip has completed
*
* Once the flip has been completed on all pipes, notify the
* extension code telling it when that happened
*/
static void
ms_flip_handler(uint64_t msc, uint64_t ust, void *data)
{
struct ms_crtc_pageflip *flip = data;
ScreenPtr screen = flip->flipdata->screen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
struct ms_flipdata *flipdata = flip->flipdata;
DebugPresent(("\t\tms:fh %lld c %d msc %llu ust %llu\n",
(long long) flipdata->event->event_id,
flipdata->flip_count,
(long long) msc, (long long) ust));
if (flip->on_reference_crtc) {
flipdata->fe_msc = msc;
flipdata->fe_usec = ust;
}
if (flipdata->flip_count == 1) {
DebugPresent(("\t\tms:fc %lld c %d msc %llu ust %llu\n",
(long long) flipdata->event->event_id,
flipdata->flip_count,
(long long) flipdata->fe_msc, (long long) flipdata->fe_usec));
ms_present_vblank_handler(flipdata->fe_msc,
flipdata->fe_usec,
flipdata->event);
drmModeRmFB(ms->fd, flipdata->old_fb_id);
}
ms_present_flip_free(flip);
}
/*
* Callback for the DRM queue abort code. A flip has been aborted.
*/
static void
ms_present_flip_abort(void *data)
{
struct ms_crtc_pageflip *flip = data;
struct ms_flipdata *flipdata = flip->flipdata;
DebugPresent(("\t\tms:fa %lld c %d\n", (long long) flipdata->event->event_id, flipdata->flip_count));
if (flipdata->flip_count == 1)
free(flipdata->event);
ms_present_flip_free(flip);
}
static Bool
queue_flip_on_crtc(ScreenPtr screen, xf86CrtcPtr crtc,
struct ms_flipdata *flipdata,
int ref_crtc_vblank_pipe, uint32_t flags)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
struct ms_crtc_pageflip *flip;
uint32_t seq;
int err;
flip = calloc(1, sizeof(struct ms_crtc_pageflip));
if (flip == NULL) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"flip queue: carrier alloc failed.\n");
return FALSE;
}
/* Only the reference crtc will finally deliver its page flip
* completion event. All other crtc's events will be discarded.
*/
flip->on_reference_crtc = (drmmode_crtc->vblank_pipe == ref_crtc_vblank_pipe);
flip->flipdata = flipdata;
seq = ms_drm_queue_alloc(crtc, flip, ms_flip_handler, ms_present_flip_abort);
if (!seq) {
free(flip);
return FALSE;
}
DebugPresent(("\t\tms:fq %lld c %d -> %d seq %llu\n",
(long long) flipdata->event->event_id,
flipdata->flip_count, flipdata->flip_count + 1,
(long long) seq));
/* take a reference on flipdata for use in flip */
flipdata->flip_count++;
while (drmModePageFlip(ms->fd, drmmode_crtc->mode_crtc->crtc_id,
ms->drmmode.fb_id, flags, (void *) (uintptr_t) seq)) {
err = errno;
/* We may have failed because the event queue was full. Flush it
* and retry. If there was nothing to flush, then we failed for
* some other reason and should just return an error.
*/
if (ms_flush_drm_events(screen) <= 0) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"flip queue failed: %s\n", strerror(err));
/* Aborting will also decrement flip_count and free(flip). */
ms_drm_abort_seq(scrn, seq);
return FALSE;
}
/* We flushed some events, so try again. */
xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue retry\n");
}
/* The page flip succeded. */
return TRUE;
}
static Bool
ms_do_pageflip(ScreenPtr screen,
PixmapPtr new_front,
struct ms_present_vblank_event *event,
int ref_crtc_vblank_pipe,
Bool async)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
drmmode_bo new_front_bo;
uint32_t flags;
int i;
struct ms_flipdata *flipdata;
glamor_block_handler(screen);
new_front_bo.gbm = glamor_gbm_bo_from_pixmap(screen, new_front);
new_front_bo.dumb = NULL;
if (!new_front_bo.gbm) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to get GBM bo for flip to new front.\n");
return FALSE;
}
flipdata = calloc(1, sizeof(struct ms_flipdata));
if (!flipdata) {
drmmode_bo_destroy(&ms->drmmode, &new_front_bo);
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to allocate flipdata.\n");
return FALSE;
}
flipdata->event = event;
flipdata->screen = screen;
/*
* Take a local reference on flipdata.
* if the first flip fails, the sequence abort
* code will free the crtc flip data, and drop
* it's reference which would cause this to be
* freed when we still required it.
*/
flipdata->flip_count++;
/* Create a new handle for the back buffer */
flipdata->old_fb_id = ms->drmmode.fb_id;
if (drmModeAddFB(ms->fd, scrn->virtualX, scrn->virtualY,
scrn->depth, scrn->bitsPerPixel,
drmmode_bo_get_pitch(&new_front_bo),
drmmode_bo_get_handle(&new_front_bo), &ms->drmmode.fb_id)) {
goto error_out;
}
drmmode_bo_destroy(&ms->drmmode, &new_front_bo);
flags = DRM_MODE_PAGE_FLIP_EVENT;
if (async)
flags |= DRM_MODE_PAGE_FLIP_ASYNC;
/* Queue flips on all enabled CRTCs.
*
* Note that if/when we get per-CRTC buffers, we'll have to update this.
* Right now it assumes a single shared fb across all CRTCs, with the
* kernel fixing up the offset of each CRTC as necessary.
*
* Also, flips queued on disabled or incorrectly configured displays
* may never complete; this is a configuration error.
*/
for (i = 0; i < config->num_crtc; i++) {
xf86CrtcPtr crtc = config->crtc[i];
if (!ms_crtc_on(crtc))
continue;
if (!queue_flip_on_crtc(screen, crtc, flipdata,
ref_crtc_vblank_pipe,
flags)) {
goto error_undo;
}
}
/*
* Do we have more than our local reference,
* if so and no errors, then drop our local
* reference and return now.
*/
if (flipdata->flip_count > 1) {
flipdata->flip_count--;
return TRUE;
}
error_undo:
/*
* Have we just got the local reference?
* free the framebuffer if so since nobody successfully
* submitted anything
*/
if (flipdata->flip_count == 1) {
drmModeRmFB(ms->fd, ms->drmmode.fb_id);
ms->drmmode.fb_id = flipdata->old_fb_id;
}
error_out:
xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n",
strerror(errno));
/* if only the local reference - free the structure,
* else drop the local reference and return */
if (flipdata->flip_count == 1)
free(flipdata);
else
flipdata->flip_count--;
return FALSE;
}
/*
* Test to see if page flipping is possible on the target crtc
*/
static Bool
ms_present_check_flip(RRCrtcPtr crtc,
WindowPtr window,
PixmapPtr pixmap,
Bool sync_flip)
{
ScreenPtr screen = window->drawable.pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int num_crtcs_on = 0;
int i;
if (!ms->drmmode.pageflip)
return FALSE;
if (!scrn->vtSema)
return FALSE;
for (i = 0; i < config->num_crtc; i++) {
drmmode_crtc_private_ptr drmmode_crtc = config->crtc[i]->driver_private;
/* Don't do pageflipping if CRTCs are rotated. */
if (drmmode_crtc->rotate_bo.gbm)
return FALSE;
if (ms_crtc_on(config->crtc[i]))
num_crtcs_on++;
}
/* We can't do pageflipping if all the CRTCs are off. */
if (num_crtcs_on == 0)
return FALSE;
/* Check stride, can't change that on flip */
if (pixmap->devKind != drmmode_bo_get_pitch(&ms->drmmode.front_bo))
return FALSE;
/* Make sure there's a bo we can get to */
/* XXX: actually do this. also...is it sufficient?
* if (!glamor_get_pixmap_private(pixmap))
* return FALSE;
*/
return TRUE;
}
/*
* Queue a flip on 'crtc' to 'pixmap' at 'target_msc'. If 'sync_flip' is true,
* then wait for vblank. Otherwise, flip immediately
*/
static Bool
ms_present_flip(RRCrtcPtr crtc,
uint64_t event_id,
uint64_t target_msc,
PixmapPtr pixmap,
Bool sync_flip)
{
ScreenPtr screen = crtc->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
xf86CrtcPtr xf86_crtc = crtc->devPrivate;
drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
Bool ret;
struct ms_present_vblank_event *event;
if (!ms_present_check_flip(crtc, screen->root, pixmap, sync_flip))
return FALSE;
event = calloc(1, sizeof(struct ms_present_vblank_event));
if (!event)
return FALSE;
event->event_id = event_id;
ret = ms_do_pageflip(screen, pixmap, event, drmmode_crtc->vblank_pipe, !sync_flip);
if (!ret)
xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present flip failed\n");
return ret;
}
/*
* Queue a flip back to the normal frame buffer
*/
static void
ms_present_unflip(ScreenPtr screen, uint64_t event_id)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
PixmapPtr pixmap = screen->GetScreenPixmap(screen);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int i;
struct ms_present_vblank_event *event;
event = calloc(1, sizeof(struct ms_present_vblank_event));
if (!event)
return;
event->event_id = event_id;
if (ms_present_check_flip(NULL, screen->root, pixmap, TRUE) &&
ms_do_pageflip(screen, pixmap, event, -1, FALSE)) {
return;
}
for (i = 0; i < config->num_crtc; i++) {
xf86CrtcPtr crtc = config->crtc[i];
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
if (!crtc->enabled)
continue;
if (drmmode_crtc->dpms_mode == DPMSModeOn)
crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation,
crtc->x, crtc->y);
else
drmmode_crtc->need_modeset = TRUE;
}
present_event_notify(event_id, 0, 0);
}
#endif
static present_screen_info_rec ms_present_screen_info = {
.version = PRESENT_SCREEN_INFO_VERSION,
@ -216,13 +641,24 @@ static present_screen_info_rec ms_present_screen_info = {
.flush = ms_present_flush,
.capabilities = PresentCapabilityNone,
.check_flip = 0,
.flip = 0,
.unflip = 0,
.check_flip = ms_present_check_flip,
#ifdef GLAMOR
.flip = ms_present_flip,
.unflip = ms_present_unflip,
#endif
};
Bool
ms_present_screen_init(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
uint64_t value;
int ret;
ret = drmGetCap(ms->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value);
if (ret == 0 && value == 1)
ms_present_screen_info.capabilities |= PresentCapabilityAsync;
return present_screen_init(screen, &ms_present_screen_info);
}

View File

@ -50,11 +50,6 @@
static struct xorg_list ms_drm_queue;
static uint32_t ms_drm_seq;
struct ms_pageflip {
ScreenPtr screen;
Bool crtc_for_msc_ust;
};
static void ms_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
{
dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
@ -88,7 +83,7 @@ static int ms_box_area(BoxPtr box)
return (int)(box->x2 - box->x1) * (int)(box->y2 - box->y1);
}
static Bool
Bool
ms_crtc_on(xf86CrtcPtr crtc)
{
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
@ -323,6 +318,22 @@ ms_drm_abort_scrn(ScrnInfoPtr scrn)
}
}
/**
* Abort by drm queue sequence number.
*/
void
ms_drm_abort_seq(ScrnInfoPtr scrn, uint32_t seq)
{
struct ms_drm_queue *q, *tmp;
xorg_list_for_each_entry_safe(q, tmp, &ms_drm_queue, list) {
if (q->seq == seq) {
ms_drm_abort_one(q);
break;
}
}
}
/*
* Externally usable abort function that uses a callback to match a single
* queued entry to abort

View File

@ -258,9 +258,7 @@ xf86_crtc_convert_cursor_to_argb(xf86CrtcPtr crtc, unsigned char *src)
CARD32 bits;
const Rotation rotation = xf86_crtc_cursor_rotation(crtc);
#ifdef ARGB_CURSOR
crtc->cursor_argb = FALSE;
#endif
for (y = 0; y < cursor_info->MaxHeight; y++)
for (x = 0; x < cursor_info->MaxWidth; x++) {
@ -458,9 +456,7 @@ xf86_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *src)
CARD8 *cursor_image;
const Rotation rotation = xf86_crtc_cursor_rotation(crtc);
#ifdef ARGB_CURSOR
crtc->cursor_argb = FALSE;
#endif
if (rotation == RR_Rotate_0)
cursor_image = src;
@ -632,12 +628,10 @@ xf86_cursors_init(ScreenPtr screen, int max_width, int max_height, int flags)
cursor_info->HideCursor = xf86_hide_cursors;
cursor_info->ShowCursor = xf86_show_cursors;
cursor_info->UseHWCursor = xf86_use_hw_cursor;
#ifdef ARGB_CURSOR
if (flags & HARDWARE_CURSOR_ARGB) {
cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb;
cursor_info->LoadCursorARGBCheck = xf86_load_cursor_argb;
}
#endif
xf86_config->cursor = NULL;
xf86_hide_cursors(scrn);
@ -691,11 +685,9 @@ xf86_reload_cursors(ScreenPtr screen)
void *src =
dixLookupScreenPrivate(&cursor->devPrivates, CursorScreenKey,
screen);
#ifdef ARGB_CURSOR
if (cursor->bits->argb && xf86DriverHasLoadCursorARGB(cursor_info))
xf86DriverLoadCursorARGB(cursor_info, cursor);
else if (src)
#endif
xf86DriverLoadCursorImage(cursor_info, src);
x += scrn->frameX0 + cursor_screen_priv->HotX;

View File

@ -43,12 +43,6 @@
#include "X11/extensions/dpmsconst.h"
#include "X11/Xatom.h"
/* borrowed from composite extension, move to Render and publish? */
#define F(x) IntToxFixed(x)
#define toF(x) ((float) (x) / 65536.0f)
static void
xf86RotateCrtcRedisplay(xf86CrtcPtr crtc, RegionPtr region)
{

View File

@ -340,12 +340,10 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
if (infoPtr->pScrn->vtSema && xorg_list_is_empty(&pScreen->pixmap_dirty_list) &&
(ScreenPriv->ForceHWCursorCount ||
((
#ifdef ARGB_CURSOR
cursor->bits->argb &&
infoPtr->UseHWCursorARGB &&
(*infoPtr->UseHWCursorARGB)(pScreen, cursor)) ||
(cursor->bits->argb == 0 &&
#endif
(cursor->bits->height <= infoPtr->MaxHeight) &&
(cursor->bits->width <= infoPtr->MaxWidth) &&
(!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor) (pScreen, cursor)))))) {

View File

@ -19,11 +19,9 @@ typedef struct _xf86CursorInfoRec {
unsigned char *(*RealizeCursor) (struct _xf86CursorInfoRec *, CursorPtr);
Bool (*UseHWCursor) (ScreenPtr, CursorPtr);
#ifdef ARGB_CURSOR
Bool (*UseHWCursorARGB) (ScreenPtr, CursorPtr);
void (*LoadCursorARGB) (ScrnInfoPtr, CursorPtr);
Bool (*LoadCursorARGBCheck) (ScrnInfoPtr, CursorPtr);
#endif
} xf86CursorInfoRec, *xf86CursorInfoPtr;
@ -77,8 +75,6 @@ extern _X_EXPORT void xf86ForceHWCursor(ScreenPtr pScreen, Bool on);
#define HARDWARE_CURSOR_NIBBLE_SWAPPED 0x00000800
#define HARDWARE_CURSOR_SHOW_TRANSPARENT 0x00001000
#define HARDWARE_CURSOR_UPDATE_UNHIDDEN 0x00002000
#ifdef ARGB_CURSOR
#define HARDWARE_CURSOR_ARGB 0x00004000
#endif
#endif /* _XF86CURSOR_H */

View File

@ -139,9 +139,7 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
#ifdef ARGB_CURSOR
if (!pCurs->bits->argb || !xf86DriverHasLoadCursorARGB(infoPtr))
#endif
if (!bits) {
bits = (*infoPtr->RealizeCursor) (infoPtr, pCurs);
dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
@ -151,12 +149,10 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
(*infoPtr->HideCursor) (infoPtr->pScrn);
#ifdef ARGB_CURSOR
if (pCurs->bits->argb && xf86DriverHasLoadCursorARGB(infoPtr)) {
if (!xf86DriverLoadCursorARGB (infoPtr, pCurs))
return FALSE;
} else
#endif
if (bits)
if (!xf86DriverLoadCursorImage (infoPtr, bits))
return FALSE;
@ -213,12 +209,10 @@ xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
xf86CursorScreenKey);
xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
#ifdef ARGB_CURSOR
/* recoloring isn't applicable to ARGB cursors and drivers
shouldn't have to ignore SetCursorColors requests */
if (pCurs->bits->argb)
return;
#endif
if (ScreenPriv->PalettedCursor) {
xColorItem sourceColor, maskColor;

View File

@ -85,7 +85,6 @@ load_cursor(CursorPtr src, int screen)
hot_x = src->bits->xhot;
hot_y = src->bits->yhot;
#ifdef ARGB_CURSOR
if (src->bits->argb != NULL) {
#if BITMAP_BIT_ORDER == MSBFirst
rowbytes = src->bits->width * sizeof(CARD32);
@ -104,7 +103,6 @@ load_cursor(CursorPtr src, int screen)
#endif
}
else
#endif
{
fg_color = 0xFF00 | (src->foreRed >> 8);
fg_color <<= 16;

View File

@ -415,7 +415,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
}
unsigned int
glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h, Bool linear)
{
return 0;
}

View File

@ -64,9 +64,7 @@ typedef struct _CursorBits {
unsigned short width, height, xhot, yhot; /* metrics */
int refcnt; /* can be shared */
PrivateRec *devPrivates; /* set by pScr->RealizeCursor */
#ifdef ARGB_CURSOR
CARD32 *argb; /* full-color alpha blended */
#endif
} CursorBits, *CursorBitsPtr;
#define CURSOR_BITS_SIZE (sizeof(CursorBits) + dixPrivatesSize(PRIVATE_CURSOR_BITS))

View File

@ -503,6 +503,9 @@
/* Build glamor's GBM-based EGL support */
#undef GLAMOR_HAS_GBM
/* Build glamor/gbm has linear support */
#undef GLAMOR_HAS_GBM_LINEAR
/* byte order */
#undef X_BYTE_ORDER

View File

@ -46,9 +46,7 @@ in this Software without prior written authorization from The Open Group.
#include "misprite.h"
#include "gcstruct.h"
#ifdef ARGB_CURSOR
#include "picturestr.h"
#endif
#include "inputstr.h"
@ -68,9 +66,7 @@ typedef struct {
GCPtr pSourceGC, pMaskGC;
GCPtr pSaveGC, pRestoreGC;
PixmapPtr pSave;
#ifdef ARGB_CURSOR
PicturePtr pRootPicture;
#endif
} miDCBufferRec, *miDCBufferPtr;
#define miGetDCDevice(dev, screen) \
@ -86,9 +82,7 @@ typedef struct {
CloseScreenProcPtr CloseScreen;
PixmapPtr sourceBits; /* source bits */
PixmapPtr maskBits; /* mask bits */
#ifdef ARGB_CURSOR
PicturePtr pPicture;
#endif
CursorPtr pCursor;
} miDCScreenRec, *miDCScreenPtr;
@ -133,11 +127,9 @@ miDCSwitchScreenCursor(ScreenPtr pScreen, CursorPtr pCursor, PixmapPtr sourceBit
(*pScreen->DestroyPixmap)(pScreenPriv->maskBits);
pScreenPriv->maskBits = maskBits;
#ifdef ARGB_CURSOR
if (pScreenPriv->pPicture)
FreePicture(pScreenPriv->pPicture, 0);
pScreenPriv->pPicture = pPicture;
#endif
pScreenPriv->pCursor = pCursor;
}
@ -162,7 +154,6 @@ miDCRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
return TRUE;
}
#ifdef ARGB_CURSOR
#define EnsurePicture(picture,draw,win) (picture || miDCMakePicture(&picture,draw,win))
static PicturePtr
@ -182,7 +173,6 @@ miDCMakePicture(PicturePtr * ppPicture, DrawablePtr pDraw, WindowPtr pWin)
*ppPicture = pPicture;
return pPicture;
}
#endif
static Bool
miDCRealize(ScreenPtr pScreen, CursorPtr pCursor)
@ -195,8 +185,6 @@ miDCRealize(ScreenPtr pScreen, CursorPtr pCursor)
if (pScreenPriv->pCursor == pCursor)
return TRUE;
#ifdef ARGB_CURSOR
if (pCursor->bits->argb) {
PixmapPtr pPixmap;
PictFormatPtr pFormat;
@ -233,7 +221,7 @@ miDCRealize(ScreenPtr pScreen, CursorPtr pCursor)
miDCSwitchScreenCursor(pScreen, pCursor, NULL, NULL, pPicture);
return TRUE;
}
#endif
sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width,
pCursor->bits->height, 1, 0);
if (!sourceBits)
@ -373,7 +361,6 @@ miDCPutUpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
pWin = pScreen->root;
pBuffer = miGetDCDevice(pDev, pScreen);
#ifdef ARGB_CURSOR
if (pScreenPriv->pPicture) {
if (!EnsurePicture(pBuffer->pRootPicture, &pWin->drawable, pWin))
return FALSE;
@ -385,7 +372,6 @@ miDCPutUpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
x, y, pCursor->bits->width, pCursor->bits->height);
}
else
#endif
{
miDCPutBits((DrawablePtr) pWin,
pBuffer->pSourceGC, pBuffer->pMaskGC,
@ -486,9 +472,7 @@ miDCDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
if (!pBuffer->pRestoreGC)
goto failure;
#ifdef ARGB_CURSOR
pBuffer->pRootPicture = NULL;
#endif
/* (re)allocated lazily depending on the cursor size */
pBuffer->pSave = NULL;
@ -525,11 +509,9 @@ miDCDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
if (pBuffer->pRestoreGC)
FreeGC(pBuffer->pRestoreGC, (GContext) 0);
#ifdef ARGB_CURSOR
/* If a pRootPicture was allocated for a root window, it
* is freed when that root window is destroyed, so don't
* free it again here. */
#endif
if (pBuffer->pSave)
(*pScreen->DestroyPixmap) (pBuffer->pSave);

View File

@ -306,11 +306,9 @@ CopyCursorToImage(CursorPtr pCursor, CARD32 *image)
int height = pCursor->bits->height;
int npixels = width * height;
#ifdef ARGB_CURSOR
if (pCursor->bits->argb)
memcpy(image, pCursor->bits->argb, npixels * sizeof(CARD32));
else
#endif
{
unsigned char *srcLine = pCursor->bits->source;
unsigned char *mskLine = pCursor->bits->mask;