aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xfree86/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xfree86/drivers')
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/driver.c2
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c196
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h4
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/vblank.c9
4 files changed, 177 insertions, 34 deletions
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/driver.c b/xorg-server/hw/xfree86/drivers/modesetting/driver.c
index 1ebf807e5..d52517d1a 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/driver.c
+++ b/xorg-server/hw/xfree86/drivers/modesetting/driver.c
@@ -538,6 +538,7 @@ msBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask)
pScreen->BlockHandler = ms->BlockHandler;
pScreen->BlockHandler(pScreen, pTimeout, pReadmask);
+ ms->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = msBlockHandler;
if (pScreen->isGPU)
dispatch_slave_dirty(pScreen);
@@ -1077,6 +1078,7 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
if (!ms->drmmode.sw_cursor)
xf86_cursors_init(pScreen, ms->cursor_width, ms->cursor_height,
HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
+ HARDWARE_CURSOR_UPDATE_UNHIDDEN |
HARDWARE_CURSOR_ARGB);
/* Must force it before EnterVT, so we are in control of VT and
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c
index 824500bae..1ea799b3a 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -82,6 +82,17 @@ drmmode_bo_get_pitch(drmmode_bo *bo)
return bo->dumb->pitch;
}
+static Bool
+drmmode_bo_has_bo(drmmode_bo *bo)
+{
+#ifdef GLAMOR_HAS_GBM
+ if (bo->gbm)
+ return TRUE;
+#endif
+
+ return bo->dumb != NULL;
+}
+
uint32_t
drmmode_bo_get_handle(drmmode_bo *bo)
{
@@ -93,6 +104,26 @@ drmmode_bo_get_handle(drmmode_bo *bo)
return bo->dumb->handle;
}
+static void *
+drmmode_bo_map(drmmode_ptr drmmode, drmmode_bo *bo)
+{
+ int ret;
+
+#ifdef GLAMOR_HAS_GBM
+ if (bo->gbm)
+ return NULL;
+#endif
+
+ if (bo->dumb->ptr)
+ return bo->dumb->ptr;
+
+ ret = dumb_bo_map(drmmode->fd, bo->dumb);
+ if (ret)
+ return NULL;
+
+ return bo->dumb->ptr;
+}
+
static Bool
drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
unsigned width, unsigned height, unsigned bpp)
@@ -509,13 +540,122 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
static void *
drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
{
- return NULL;
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ int ret;
+
+ if (!drmmode_create_bo(drmmode, &drmmode_crtc->rotate_bo,
+ width, height, crtc->scrn->bitsPerPixel)) {
+ xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow memory for rotated CRTC\n");
+ return NULL;
+ }
+
+ ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth,
+ crtc->scrn->bitsPerPixel,
+ drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo),
+ drmmode_bo_get_handle(&drmmode_crtc->rotate_bo),
+ &drmmode_crtc->rotate_fb_id);
+
+ if (ret) {
+ ErrorF("failed to add rotate fb\n");
+ drmmode_bo_destroy(drmmode, &drmmode_crtc->rotate_bo);
+ return NULL;
+ }
+
+#ifdef GLAMOR_HAS_GBM
+ if (drmmode->gbm)
+ return drmmode_crtc->rotate_bo.gbm;
+#endif
+ return drmmode_crtc->rotate_bo.dumb;
+}
+
+static PixmapPtr
+drmmode_create_pixmap_header(ScreenPtr pScreen, int width, int height,
+ int depth, int bitsPerPixel, int devKind,
+ void *pPixData)
+{
+ PixmapPtr pixmap;
+
+ /* width and height of 0 means don't allocate any pixmap data */
+ pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0);
+
+ if (pixmap) {
+ if ((*pScreen->ModifyPixmapHeader)(pixmap, width, height, depth,
+ bitsPerPixel, devKind, pPixData))
+ return pixmap;
+ (*pScreen->DestroyPixmap)(pixmap);
+ }
+ return NullPixmap;
}
+static Bool
+drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo);
+
static PixmapPtr
drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
{
- return NULL;
+ ScrnInfoPtr scrn = crtc->scrn;
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ uint32_t rotate_pitch;
+ PixmapPtr rotate_pixmap;
+ void *pPixData = NULL;
+
+ if (!data) {
+ data = drmmode_shadow_allocate(crtc, width, height);
+ if (!data) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow pixmap for rotated CRTC\n");
+ return NULL;
+ }
+ }
+
+ if (!drmmode_bo_has_bo(&drmmode_crtc->rotate_bo)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow pixmap for rotated CRTC\n");
+ return NULL;
+ }
+
+ pPixData = drmmode_bo_map(drmmode, &drmmode_crtc->rotate_bo);
+ rotate_pitch = drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo),
+
+ rotate_pixmap = drmmode_create_pixmap_header(scrn->pScreen,
+ width, height,
+ scrn->depth,
+ scrn->bitsPerPixel,
+ rotate_pitch,
+ pPixData);
+
+ if (rotate_pixmap == NULL) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow pixmap for rotated CRTC\n");
+ return NULL;
+ }
+
+ drmmode_set_pixmap_bo(drmmode, rotate_pixmap, &drmmode_crtc->rotate_bo);
+
+ return rotate_pixmap;
+}
+
+static void
+drmmode_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+ if (rotate_pixmap) {
+ drmmode_set_pixmap_bo(drmmode, rotate_pixmap, NULL);
+ rotate_pixmap->drawable.pScreen->DestroyPixmap(rotate_pixmap);
+ }
+
+ if (data) {
+ drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id);
+ drmmode_crtc->rotate_fb_id = 0;
+
+ drmmode_bo_destroy(drmmode, &drmmode_crtc->rotate_bo);
+ memset(&drmmode_crtc->rotate_bo, 0, sizeof drmmode_crtc->rotate_bo);
+ }
}
static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
@@ -532,6 +672,7 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
.set_scanout_pixmap = drmmode_set_scanout_pixmap,
.shadow_allocate = drmmode_shadow_allocate,
.shadow_create = drmmode_shadow_create,
+ .shadow_destroy = drmmode_shadow_destroy,
};
static uint32_t
@@ -1123,34 +1264,32 @@ drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
}
}
-Bool
-drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode)
+static Bool
+drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo)
{
#ifdef GLAMOR
ScrnInfoPtr scrn = drmmode->scrn;
- ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn);
- PixmapPtr screen_pixmap;
- void *gbm_bo;
if (!drmmode->glamor)
return TRUE;
-#ifdef GLAMOR_HAS_GBM
- gbm_bo = drmmode->front_bo.gbm;
- screen_pixmap = screen->GetScreenPixmap(screen);
+ if (bo == NULL) {
+ glamor_egl_destroy_textured_pixmap(pixmap);
+ return TRUE;
+ }
- if (!glamor_egl_create_textured_pixmap_from_gbm_bo(screen_pixmap, gbm_bo)) {
+#ifdef GLAMOR_HAS_GBM
+ if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed");
return FALSE;
}
- glamor_set_screen_pixmap(screen_pixmap, NULL);
#else
- if (!glamor_egl_create_textured_screen(screen,
+ if (!glamor_egl_create_textured_pixmap(pixmap,
drmmode_bo_get_handle(&drmmode->front_bo),
scrn->displayWidth *
scrn->bitsPerPixel / 8)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
- "glamor_egl_create_textured_screen() failed\n");
+ "glamor_egl_create_textured_pixmap() failed\n");
return FALSE;
}
#endif
@@ -1159,6 +1298,23 @@ drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode)
return TRUE;
}
+Bool
+drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode)
+{
+ ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn);
+ PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+
+ if (!drmmode_set_pixmap_bo(drmmode, screen_pixmap, &drmmode->front_bo))
+ return FALSE;
+
+#ifdef GLAMOR
+ if (drmmode->glamor)
+ glamor_set_screen_pixmap(screen_pixmap, NULL);
+#endif
+
+ return TRUE;
+}
+
static Bool
drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
{
@@ -1555,17 +1711,7 @@ drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
void *
drmmode_map_front_bo(drmmode_ptr drmmode)
{
- int ret;
-
- if (drmmode->front_bo.dumb->ptr)
- return drmmode->front_bo.dumb->ptr;
-
- ret = dumb_bo_map(drmmode->fd, drmmode->front_bo.dumb);
- if (ret)
- return NULL;
-
- return drmmode->front_bo.dumb->ptr;
-
+ return drmmode_bo_map(drmmode, &drmmode->front_bo);
}
void *
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h
index 66d0ca260..3a8959ac3 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -89,10 +89,12 @@ typedef struct {
int dpms_mode;
struct dumb_bo *cursor_bo;
Bool cursor_up;
- unsigned rotate_fb_id;
uint16_t lut_r[256], lut_g[256], lut_b[256];
DamagePtr slave_damage;
+ drmmode_bo rotate_bo;
+ unsigned rotate_fb_id;
+
/**
* @{ MSC (vblank count) handling for the PRESENT extension.
*
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/vblank.c b/xorg-server/hw/xfree86/drivers/modesetting/vblank.c
index 711f6edb3..a342662a7 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/vblank.c
+++ b/xorg-server/hw/xfree86/drivers/modesetting/vblank.c
@@ -147,20 +147,13 @@ ms_dri2_crtc_covering_drawable(DrawablePtr pDraw)
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
BoxRec box, crtcbox;
- xf86CrtcPtr crtc;
box.x1 = pDraw->x;
box.y1 = pDraw->y;
box.x2 = box.x1 + pDraw->width;
box.y2 = box.y1 + pDraw->height;
- crtc = ms_covering_crtc(pScrn, &box, NULL, &crtcbox);
-
- /* Make sure the CRTC is valid and this is the real front buffer */
- if (crtc != NULL && !crtc->rotatedData)
- return crtc;
-
- return NULL;
+ return ms_covering_crtc(pScrn, &box, NULL, &crtcbox);
}
static Bool