summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-05-11 16:35:05 +0100
committerDave Airlie <airlied@redhat.com>2012-05-11 16:35:05 +0100
commitc8ff63337a8b1f552c801050283f62d92d997ae6 (patch)
treecd88e6fd6196565309207f55c087b8609ba614cb
parent883285df3a6cf82dbdd3549211fce296bf0bb181 (diff)
dirty pixmap trackingdrvmodelv3
-rw-r--r--src/driver.c91
-rw-r--r--src/drmmode_display.c75
-rw-r--r--src/drmmode_display.h5
3 files changed, 151 insertions, 20 deletions
diff --git a/src/driver.c b/src/driver.c
index ff86c07..e26b19e 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -287,7 +287,8 @@ ms_udev_probe(DriverPtr driver,
scrn->LeaveVT = LeaveVT;
scrn->FreeScreen = FreeScreen;
scrn->ValidMode = ValidMode;
- scrn->roles = ROLE_SLAVE_OUTPUT;
+ scrn->roles = RR_Role_Slave_Output;
+ scrn->abilities = 0;
xf86DrvMsg(scrn->scrnIndex, X_INFO,
"using drv %s\n", dev ? dev->path : "default device");
}
@@ -361,11 +362,13 @@ GetRec(ScrnInfoPtr pScrn)
return TRUE;
}
-static void dispatch_dirty(ScreenPtr pScreen)
+static int dispatch_dirty_region(ScrnInfoPtr scrn,
+ PixmapPtr pixmap,
+ DamagePtr damage,
+ int fb_id)
{
- ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
modesettingPtr ms = modesettingPTR(scrn);
- RegionPtr dirty = DamageRegion(ms->damage);
+ RegionPtr dirty = DamageRegion(damage);
unsigned num_cliprects = REGION_NUM_RECTS(dirty);
if (num_cliprects) {
@@ -382,21 +385,68 @@ static void dispatch_dirty(ScreenPtr pScreen)
}
/* TODO query connector property to see if this is needed */
- ret = drmModeDirtyFB(ms->fd, ms->drmmode.fb_id, clip, num_cliprects);
+ ret = drmModeDirtyFB(ms->fd, fb_id, clip, num_cliprects);
+ DamageEmpty(damage);
if (ret) {
- if (ret == -EINVAL || ret == -ENOSYS) {
- ms->dirty_enabled = FALSE;
- DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage);
- DamageDestroy(ms->damage);
- ms->damage = NULL;
- xf86DrvMsg(scrn->scrnIndex, X_INFO, "Disabling kernel dirty updates, not required.\n");
- return;
- } else
- ErrorF("%s: failed to send dirty (%i, %s)\n",
- __func__, ret, strerror(-ret));
+ if (ret == -EINVAL)
+ return ret;
}
-
- DamageEmpty(ms->damage);
+ }
+ return 0;
+}
+
+static void dispatch_dirty(ScreenPtr pScreen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
+ modesettingPtr ms = modesettingPTR(scrn);
+ PixmapPtr pixmap = pScreen->GetScreenPixmap(pScreen);
+ int fb_id = ms->drmmode.fb_id;
+ int ret;
+
+ ret = dispatch_dirty_region(scrn, pixmap, ms->damage, fb_id);
+ if (ret == -EINVAL || ret == -ENOSYS) {
+ ms->dirty_enabled = FALSE;
+ DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage);
+ DamageDestroy(ms->damage);
+ ms->damage = NULL;
+ xf86DrvMsg(scrn->scrnIndex, X_INFO, "Disabling kernel dirty updates, not required.\n");
+ return;
+ }
+}
+
+static void dispatch_dirty_crtc(ScrnInfoPtr scrn, xf86CrtcPtr crtc)
+{
+ modesettingPtr ms = modesettingPTR(scrn);
+ ScreenPtr pScreen = scrn->pScreen;
+ PixmapPtr pixmap = crtc->randr_crtc->slave_pixmap;
+ msPixmapPrivPtr ppriv = msGetPixmapPriv(pixmap);
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ DamagePtr damage = drmmode_crtc->slave_damage;
+ int fb_id = ppriv->fb_id;
+ int ret;
+
+ ret = dispatch_dirty_region(scrn, pixmap, damage, fb_id);
+ if (ret) {
+
+ }
+}
+
+static void dispatch_slave_dirty(ScreenPtr pScreen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
+ modesettingPtr ms = modesettingPTR(scrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (!crtc->randr_crtc)
+ continue;
+ if (!crtc->randr_crtc->slave_pixmap)
+ continue;
+
+ dispatch_dirty_crtc(scrn, crtc);
}
}
@@ -408,8 +458,13 @@ static void msBlockHandler(ScreenPtr pScreen, pointer blockData, pointer pTimeou
pScreen->BlockHandler = ms->BlockHandler;
pScreen->BlockHandler(pScreen, blockData, pTimeout, pReadmask);
pScreen->BlockHandler = msBlockHandler;
- if (ms->dirty_enabled)
+
+ if (pScreen->isGPU) {
+ dispatch_slave_dirty(pScreen);
+ } else if (ms->dirty_enabled)
dispatch_dirty(pScreen);
+
+
}
static void
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index c140bfc..78e3168 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -31,6 +31,7 @@
#include <errno.h>
#include <sys/ioctl.h>
+#include <unistd.h>
#include <sys/mman.h>
#include "xf86str.h"
#include "X11/Xatom.h"
@@ -50,6 +51,8 @@
#include <X11/extensions/dpms.h>
#endif
+#include <X11/extensions/randr.h>
+
static struct dumb_bo *dumb_bo_create(int fd,
const unsigned width, const unsigned height,
const unsigned bpp)
@@ -371,7 +374,11 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
fb_id = drmmode->fb_id;
- if (drmmode_crtc->rotate_fb_id) {
+ if (crtc->randr_crtc->slave_pixmap) {
+ msPixmapPrivPtr ppriv = msGetPixmapPriv(crtc->randr_crtc->slave_pixmap);
+ fb_id = ppriv->fb_id;
+ x = y = 0;
+ } else if (drmmode_crtc->rotate_fb_id) {
fb_id = drmmode_crtc->rotate_fb_id;
x = y = 0;
}
@@ -488,6 +495,52 @@ drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green,
size, red, green, blue);
}
+static Bool
+drmmode_set_slave_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ msPixmapPrivPtr ppriv;
+ void *ptr;
+
+ if (!ppix) {
+ if (crtc->randr_crtc->slave_pixmap) {
+ ppriv = msGetPixmapPriv(crtc->randr_crtc->slave_pixmap);
+ drmModeRmFB(drmmode->fd, ppriv->fb_id);
+ }
+ if (drmmode_crtc->slave_damage) {
+ DamageUnregister(&crtc->randr_crtc->slave_pixmap->drawable,
+ drmmode_crtc->slave_damage);
+ drmmode_crtc->slave_damage = NULL;
+ }
+ return TRUE;
+ }
+
+ ppriv = msGetPixmapPriv(ppix);
+ if (!drmmode_crtc->slave_damage) {
+ drmmode_crtc->slave_damage = DamageCreate(NULL, NULL,
+ DamageReportNone,
+ TRUE,
+ crtc->randr_crtc->pScreen,
+ NULL);
+ }
+ ptr = drmmode_map_slave_bo(drmmode, ppriv);
+ ppix->devPrivate.ptr = ptr;
+ DamageRegister(&ppix->drawable, drmmode_crtc->slave_damage);
+
+ if (ppriv->fb_id == 0) {
+ int r;
+ r = drmModeAddFB(drmmode->fd, ppix->drawable.width,
+ ppix->drawable.height,
+ ppix->drawable.depth,
+ ppix->drawable.bitsPerPixel,
+ ppix->devKind,
+ ppriv->backing_bo->handle,
+ &ppriv->fb_id);
+ }
+ return TRUE;
+}
+
static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
.dpms = drmmode_crtc_dpms,
.set_mode_major = drmmode_set_mode_major,
@@ -499,6 +552,7 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
.gamma_set = drmmode_crtc_gamma_set,
.destroy = NULL, /* XXX */
+ .set_slave_pixmap = drmmode_set_slave_pixmap,
};
static void
@@ -1071,6 +1125,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
int i, num_dvi = 0, num_hdmi = 0;
int ret;
uint64_t value = 0;
+ xf86ProviderPtr provider;
/* check for dumb capability */
ret = drmGetCap(drmmode->fd, DRM_CAP_DUMB_BUFFER, &value);
@@ -1095,9 +1150,13 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
for (i = 0; i < drmmode->mode_res->count_connectors; i++)
drmmode_output_init(pScrn, drmmode, i, &num_dvi, &num_hdmi);
+
/* workout clones */
drmmode_clones_init(pScrn, drmmode);
+ provider = xf86ProviderCreate(pScrn);
+ if (provider == NULL)
+ return FALSE;
xf86InitialConfiguration(pScrn, TRUE);
return TRUE;
@@ -1357,6 +1416,20 @@ void *drmmode_map_front_bo(drmmode_ptr drmmode)
}
+void *drmmode_map_slave_bo(drmmode_ptr drmmode, msPixmapPrivPtr ppriv)
+{
+ int ret;
+
+ if (ppriv->backing_bo->ptr)
+ return ppriv->backing_bo->ptr;
+
+ ret = dumb_bo_map(drmmode->fd, ppriv->backing_bo);
+ if (ret)
+ return NULL;
+
+ return ppriv->backing_bo->ptr;
+}
+
Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 259f01e..fac6c28 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -67,6 +67,9 @@ typedef struct {
struct dumb_bo *cursor_bo;
unsigned rotate_fb_id;
uint16_t lut_r[256], lut_g[256], lut_b[256];
+ DamagePtr slave_damage;
+ PixmapPtr slave_pixmap;
+ int slave_fb_id;
} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
typedef struct {
@@ -112,7 +115,7 @@ Bool drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
void *drmmode_map_front_bo(drmmode_ptr drmmode);
Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
void drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
-
+void *drmmode_map_slave_bo(drmmode_ptr drmmode, msPixmapPrivPtr ppriv);
Bool drmmode_SetSlaveBO(PixmapPtr ppix,
drmmode_ptr drmmode,
int fd_handle, int pitch, int size);