modesetting: Use atomic modesetting to set DPMS mode
CRTCs and outputs needs to be enabled/disabled when the current DPMS mode is changed. We also try to do it in an atomic commit when possible. Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com> Tested-by: Daniel Stone <daniels@collabora.com> Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
parent
23c67987a3
commit
bc4d278132
|
@ -1658,7 +1658,10 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
|
||||||
if (!drmmode_setup_colormap(pScreen, pScrn))
|
if (!drmmode_setup_colormap(pScreen, pScrn))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
xf86DPMSInit(pScreen, xf86DPMSSet, 0);
|
if (ms->atomic_modeset)
|
||||||
|
xf86DPMSInit(pScreen, drmmode_set_dpms, 0);
|
||||||
|
else
|
||||||
|
xf86DPMSInit(pScreen, xf86DPMSSet, 0);
|
||||||
|
|
||||||
#ifdef GLAMOR_HAS_GBM
|
#ifdef GLAMOR_HAS_GBM
|
||||||
if (ms->drmmode.glamor) {
|
if (ms->drmmode.glamor) {
|
||||||
|
|
|
@ -106,6 +106,7 @@ typedef struct _modesettingRec {
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
Bool atomic_modeset;
|
Bool atomic_modeset;
|
||||||
|
Bool pending_modeset;
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
DamagePtr damage;
|
DamagePtr damage;
|
||||||
|
|
|
@ -407,6 +407,11 @@ drmmode_prop_info_free(drmmode_prop_info_ptr info, int num_props)
|
||||||
free(info[i].enum_values);
|
free(info[i].enum_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drmmode_ConvertToKMode(ScrnInfoPtr scrn,
|
||||||
|
drmModeModeInfo * kmode, DisplayModePtr mode);
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
plane_add_prop(drmModeAtomicReq *req, drmmode_crtc_private_ptr drmmode_crtc,
|
plane_add_prop(drmModeAtomicReq *req, drmmode_crtc_private_ptr drmmode_crtc,
|
||||||
enum drmmode_plane_property prop, uint64_t val)
|
enum drmmode_plane_property prop, uint64_t val)
|
||||||
|
@ -422,6 +427,33 @@ plane_add_prop(drmModeAtomicReq *req, drmmode_crtc_private_ptr drmmode_crtc,
|
||||||
return (ret <= 0) ? -1 : 0;
|
return (ret <= 0) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
plane_add_props(drmModeAtomicReq *req, xf86CrtcPtr crtc,
|
||||||
|
uint32_t fb_id, int x, int y)
|
||||||
|
{
|
||||||
|
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_FB_ID,
|
||||||
|
fb_id);
|
||||||
|
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_ID,
|
||||||
|
fb_id ? drmmode_crtc->mode_crtc->crtc_id : 0);
|
||||||
|
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_X, x << 16);
|
||||||
|
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_Y, y << 16);
|
||||||
|
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_W,
|
||||||
|
crtc->mode.HDisplay << 16);
|
||||||
|
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_H,
|
||||||
|
crtc->mode.VDisplay << 16);
|
||||||
|
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_X, 0);
|
||||||
|
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_Y, 0);
|
||||||
|
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_W,
|
||||||
|
crtc->mode.HDisplay);
|
||||||
|
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_H,
|
||||||
|
crtc->mode.VDisplay);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
crtc_add_prop(drmModeAtomicReq *req, drmmode_crtc_private_ptr drmmode_crtc,
|
crtc_add_prop(drmModeAtomicReq *req, drmmode_crtc_private_ptr drmmode_crtc,
|
||||||
enum drmmode_crtc_property prop, uint64_t val)
|
enum drmmode_crtc_property prop, uint64_t val)
|
||||||
|
@ -485,6 +517,60 @@ drm_mode_ensure_blob(xf86CrtcPtr crtc, drmModeModeInfo mode_info)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
crtc_add_dpms_props(drmModeAtomicReq *req, xf86CrtcPtr crtc,
|
||||||
|
int new_dpms, Bool *active)
|
||||||
|
{
|
||||||
|
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
|
||||||
|
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||||
|
Bool crtc_active = FALSE;
|
||||||
|
int i;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < xf86_config->num_output; i++) {
|
||||||
|
xf86OutputPtr output = xf86_config->output[i];
|
||||||
|
drmmode_output_private_ptr drmmode_output;
|
||||||
|
|
||||||
|
if (output->crtc != crtc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
drmmode_output = output->driver_private;
|
||||||
|
if (drmmode_output->output_id == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (new_dpms == DPMSModeOn)
|
||||||
|
crtc_active = TRUE;
|
||||||
|
|
||||||
|
ret |= connector_add_prop(req, drmmode_output,
|
||||||
|
DRMMODE_CONNECTOR_CRTC_ID,
|
||||||
|
crtc_active ?
|
||||||
|
drmmode_crtc->mode_crtc->crtc_id : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (crtc_active) {
|
||||||
|
drmModeModeInfo kmode;
|
||||||
|
|
||||||
|
drmmode_ConvertToKMode(crtc->scrn, &kmode, &crtc->mode);
|
||||||
|
ret |= drm_mode_ensure_blob(crtc, kmode);
|
||||||
|
|
||||||
|
ret |= crtc_add_prop(req, drmmode_crtc,
|
||||||
|
DRMMODE_CRTC_ACTIVE, 1);
|
||||||
|
ret |= crtc_add_prop(req, drmmode_crtc,
|
||||||
|
DRMMODE_CRTC_MODE_ID,
|
||||||
|
drmmode_crtc->current_mode->blob_id);
|
||||||
|
} else {
|
||||||
|
ret |= crtc_add_prop(req, drmmode_crtc,
|
||||||
|
DRMMODE_CRTC_ACTIVE, 0);
|
||||||
|
ret |= crtc_add_prop(req, drmmode_crtc,
|
||||||
|
DRMMODE_CRTC_MODE_ID, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active)
|
||||||
|
*active = crtc_active;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
drm_mode_destroy(xf86CrtcPtr crtc, drmmode_mode_ptr mode)
|
drm_mode_destroy(xf86CrtcPtr crtc, drmmode_mode_ptr mode)
|
||||||
{
|
{
|
||||||
|
@ -495,85 +581,179 @@ drm_mode_destroy(xf86CrtcPtr crtc, drmmode_mode_ptr mode)
|
||||||
free(mode);
|
free(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
drmmode_ConvertToKMode(ScrnInfoPtr scrn,
|
drmmode_crtc_can_test_mode(xf86CrtcPtr crtc)
|
||||||
drmModeModeInfo * kmode, DisplayModePtr mode);
|
{
|
||||||
|
modesettingPtr ms = modesettingPTR(crtc->scrn);
|
||||||
|
|
||||||
int
|
return ms->atomic_modeset;
|
||||||
drmmode_crtc_set_fb(xf86CrtcPtr crtc, DisplayModePtr mode, uint32_t fb_id,
|
}
|
||||||
int x, int y, uint32_t flags, void *data)
|
|
||||||
|
static Bool
|
||||||
|
drmmode_crtc_get_fb_id(xf86CrtcPtr crtc, uint32_t *fb_id, int *x, int *y)
|
||||||
|
{
|
||||||
|
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||||
|
drmmode_ptr drmmode = drmmode_crtc->drmmode;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (drmmode_crtc->prime_pixmap) {
|
||||||
|
if (!drmmode->reverse_prime_offload_mode) {
|
||||||
|
msPixmapPrivPtr ppriv =
|
||||||
|
msGetPixmapPriv(drmmode, drmmode_crtc->prime_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;
|
||||||
|
*x = *y = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*fb_id = drmmode->fb_id;
|
||||||
|
*x = crtc->x;
|
||||||
|
*y = crtc->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fb_id == 0) {
|
||||||
|
ret = drmmode_bo_import(drmmode, &drmmode->front_bo,
|
||||||
|
&drmmode->fb_id);
|
||||||
|
if (ret < 0) {
|
||||||
|
ErrorF("failed to add fb %d\n", ret);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
*fb_id = drmmode->fb_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drmmode_set_dpms(ScrnInfoPtr scrn, int dpms, int flags)
|
||||||
|
{
|
||||||
|
modesettingPtr ms = modesettingPTR(scrn);
|
||||||
|
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
|
||||||
|
drmModeAtomicReq *req = drmModeAtomicAlloc();
|
||||||
|
uint32_t mode_flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
|
||||||
|
int ret = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
assert(ms->atomic_modeset);
|
||||||
|
|
||||||
|
if (!req)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < xf86_config->num_crtc; i++) {
|
||||||
|
xf86CrtcPtr crtc = xf86_config->crtc[i];
|
||||||
|
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||||
|
Bool active = FALSE;
|
||||||
|
|
||||||
|
ret |= crtc_add_dpms_props(req, crtc, dpms, &active);
|
||||||
|
|
||||||
|
if (dpms == DPMSModeOn && active && drmmode_crtc->need_modeset) {
|
||||||
|
uint32_t fb_id;
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
if (!drmmode_crtc_get_fb_id(crtc, &fb_id, &x, &y))
|
||||||
|
continue;
|
||||||
|
ret |= plane_add_props(req, crtc, fb_id, x, y);
|
||||||
|
drmmode_crtc->need_modeset = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
drmModeAtomicCommit(ms->fd, req, mode_flags, NULL);
|
||||||
|
drmModeAtomicFree(req);
|
||||||
|
|
||||||
|
ms->pending_modeset = TRUE;
|
||||||
|
xf86DPMSSet(scrn, dpms, flags);
|
||||||
|
ms->pending_modeset = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
drmmode_output_disable(xf86OutputPtr output)
|
||||||
|
{
|
||||||
|
modesettingPtr ms = modesettingPTR(output->scrn);
|
||||||
|
drmmode_output_private_ptr drmmode_output = output->driver_private;
|
||||||
|
drmModeAtomicReq *req = drmModeAtomicAlloc();
|
||||||
|
uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
assert(ms->atomic_modeset);
|
||||||
|
|
||||||
|
if (!req)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* XXX Can we disable all outputs without disabling CRTC right away? */
|
||||||
|
ret = connector_add_prop(req, drmmode_output,
|
||||||
|
DRMMODE_CONNECTOR_CRTC_ID, 0);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = drmModeAtomicCommit(ms->fd, req, flags, NULL);
|
||||||
|
|
||||||
|
drmModeAtomicFree(req);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
drmmode_crtc_disable(xf86CrtcPtr crtc)
|
||||||
|
{
|
||||||
|
modesettingPtr ms = modesettingPTR(crtc->scrn);
|
||||||
|
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||||
|
drmModeAtomicReq *req = drmModeAtomicAlloc();
|
||||||
|
uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
assert(ms->atomic_modeset);
|
||||||
|
|
||||||
|
if (!req)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ret |= crtc_add_prop(req, drmmode_crtc,
|
||||||
|
DRMMODE_CRTC_ACTIVE, 0);
|
||||||
|
ret |= crtc_add_prop(req, drmmode_crtc,
|
||||||
|
DRMMODE_CRTC_MODE_ID, 0);
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
ret = drmModeAtomicCommit(ms->fd, req, flags, NULL);
|
||||||
|
|
||||||
|
drmModeAtomicFree(req);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
drmmode_crtc_set_mode(xf86CrtcPtr crtc, Bool test_only)
|
||||||
{
|
{
|
||||||
modesettingPtr ms = modesettingPTR(crtc->scrn);
|
modesettingPtr ms = modesettingPTR(crtc->scrn);
|
||||||
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
|
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
|
||||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||||
drmmode_ptr drmmode = drmmode_crtc->drmmode;
|
drmmode_ptr drmmode = drmmode_crtc->drmmode;
|
||||||
|
drmModeModeInfo kmode;
|
||||||
int output_count = 0;
|
int output_count = 0;
|
||||||
uint32_t *output_ids = NULL;
|
uint32_t *output_ids = NULL;
|
||||||
drmModeModeInfo kmode;
|
uint32_t fb_id;
|
||||||
|
int x, y;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
if (mode)
|
if (!drmmode_crtc_get_fb_id(crtc, &fb_id, &x, &y))
|
||||||
drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
|
return 1;
|
||||||
|
|
||||||
if (ms->atomic_modeset) {
|
if (ms->atomic_modeset) {
|
||||||
drmModeAtomicReq *req = drmModeAtomicAlloc();
|
drmModeAtomicReq *req = drmModeAtomicAlloc();
|
||||||
|
Bool active;
|
||||||
|
uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
|
||||||
|
|
||||||
if (!req)
|
if (!req)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (mode) {
|
ret |= crtc_add_dpms_props(req, crtc, DPMSModeOn, &active);
|
||||||
ret = drm_mode_ensure_blob(crtc, kmode);
|
ret |= plane_add_props(req, crtc, active ? fb_id : 0, x, y);
|
||||||
|
|
||||||
for (i = 0; i < xf86_config->num_output; i++) {
|
if (test_only)
|
||||||
xf86OutputPtr output = xf86_config->output[i];
|
flags |= DRM_MODE_ATOMIC_TEST_ONLY;
|
||||||
drmmode_output_private_ptr drmmode_output;
|
|
||||||
|
|
||||||
if (output->crtc != crtc)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
drmmode_output = output->driver_private;
|
|
||||||
if (drmmode_output->output_id == -1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (drmmode_output->dpms == DPMSModeOn) {
|
|
||||||
ret |= crtc_add_prop(req, drmmode_crtc,
|
|
||||||
DRMMODE_CRTC_ACTIVE, 1);
|
|
||||||
ret |= crtc_add_prop(req, drmmode_crtc,
|
|
||||||
DRMMODE_CRTC_MODE_ID,
|
|
||||||
drmmode_crtc->current_mode->blob_id);
|
|
||||||
ret |= connector_add_prop(req, drmmode_output,
|
|
||||||
DRMMODE_CONNECTOR_CRTC_ID,
|
|
||||||
drmmode_crtc->mode_crtc->crtc_id);
|
|
||||||
} else {
|
|
||||||
ret |= crtc_add_prop(req, drmmode_crtc,
|
|
||||||
DRMMODE_CRTC_ACTIVE, 0);
|
|
||||||
ret |= crtc_add_prop(req, drmmode_crtc,
|
|
||||||
DRMMODE_CRTC_MODE_ID, 0);
|
|
||||||
ret |= connector_add_prop(req, drmmode_output,
|
|
||||||
DRMMODE_CONNECTOR_CRTC_ID, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_FB_ID,
|
|
||||||
fb_id);
|
|
||||||
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_ID,
|
|
||||||
drmmode_crtc->mode_crtc->crtc_id);
|
|
||||||
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_X, x << 16);
|
|
||||||
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_Y, y << 16);
|
|
||||||
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_W,
|
|
||||||
crtc->mode.HDisplay << 16);
|
|
||||||
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_SRC_H,
|
|
||||||
crtc->mode.VDisplay << 16);
|
|
||||||
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_X, 0);
|
|
||||||
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_Y, 0);
|
|
||||||
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_W,
|
|
||||||
crtc->mode.HDisplay);
|
|
||||||
ret |= plane_add_prop(req, drmmode_crtc, DRMMODE_PLANE_CRTC_H,
|
|
||||||
crtc->mode.VDisplay);
|
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = drmModeAtomicCommit(ms->fd, req, flags, data);
|
ret = drmModeAtomicCommit(ms->fd, req, flags, NULL);
|
||||||
|
|
||||||
drmModeAtomicFree(req);
|
drmModeAtomicFree(req);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -597,6 +777,7 @@ drmmode_crtc_set_fb(xf86CrtcPtr crtc, DisplayModePtr mode, uint32_t fb_id,
|
||||||
output_count++;
|
output_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drmmode_ConvertToKMode(crtc->scrn, &kmode, &crtc->mode);
|
||||||
ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
|
ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
|
||||||
fb_id, x, y, output_ids, output_count, &kmode);
|
fb_id, x, y, output_ids, output_count, &kmode);
|
||||||
|
|
||||||
|
@ -604,6 +785,30 @@ drmmode_crtc_set_fb(xf86CrtcPtr crtc, DisplayModePtr mode, uint32_t fb_id,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
drmmode_crtc_flip(xf86CrtcPtr crtc, uint32_t fb_id, uint32_t flags, void *data)
|
||||||
|
{
|
||||||
|
modesettingPtr ms = modesettingPTR(crtc->scrn);
|
||||||
|
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (ms->atomic_modeset) {
|
||||||
|
drmModeAtomicReq *req = drmModeAtomicAlloc();
|
||||||
|
|
||||||
|
if (!req)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ret = plane_add_props(req, crtc, fb_id, crtc->x, crtc->y);
|
||||||
|
flags |= DRM_MODE_ATOMIC_NONBLOCK;
|
||||||
|
if (ret == 0)
|
||||||
|
ret = drmModeAtomicCommit(ms->fd, req, flags, data);
|
||||||
|
drmModeAtomicFree(req);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return drmModePageFlip(ms->fd, drmmode_crtc->mode_crtc->crtc_id,
|
||||||
|
fb_id, flags, data);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
|
drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
|
||||||
|
@ -1077,8 +1282,15 @@ drmmode_ConvertToKMode(ScrnInfoPtr scrn,
|
||||||
static void
|
static void
|
||||||
drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
|
drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
|
||||||
{
|
{
|
||||||
|
modesettingPtr ms = modesettingPTR(crtc->scrn);
|
||||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||||
|
|
||||||
|
/* XXX Check if DPMS mode is already the right one */
|
||||||
|
|
||||||
drmmode_crtc->dpms_mode = mode;
|
drmmode_crtc->dpms_mode = mode;
|
||||||
|
|
||||||
|
if (ms->atomic_modeset && mode != DPMSModeOn && !ms->pending_modeset)
|
||||||
|
drmmode_crtc_disable(crtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GLAMOR_HAS_GBM
|
#ifdef GLAMOR_HAS_GBM
|
||||||
|
@ -1178,6 +1390,7 @@ static Bool
|
||||||
drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||||
Rotation rotation, int x, int y)
|
Rotation rotation, int x, int y)
|
||||||
{
|
{
|
||||||
|
modesettingPtr ms = modesettingPTR(crtc->scrn);
|
||||||
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
|
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
|
||||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||||
drmmode_ptr drmmode = drmmode_crtc->drmmode;
|
drmmode_ptr drmmode = drmmode_crtc->drmmode;
|
||||||
|
@ -1185,9 +1398,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||||
Rotation saved_rotation;
|
Rotation saved_rotation;
|
||||||
DisplayModeRec saved_mode;
|
DisplayModeRec saved_mode;
|
||||||
Bool ret = TRUE;
|
Bool ret = TRUE;
|
||||||
|
Bool can_test;
|
||||||
int i;
|
int i;
|
||||||
uint32_t fb_id = 0;
|
|
||||||
uint32_t flags = 0;
|
|
||||||
|
|
||||||
saved_mode = crtc->mode;
|
saved_mode = crtc->mode;
|
||||||
saved_x = crtc->x;
|
saved_x = crtc->x;
|
||||||
|
@ -1207,35 +1419,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||||
crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
|
crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
|
||||||
crtc->gamma_blue, crtc->gamma_size);
|
crtc->gamma_blue, crtc->gamma_size);
|
||||||
|
|
||||||
fb_id = drmmode->fb_id;
|
can_test = drmmode_crtc_can_test_mode(crtc);
|
||||||
if (drmmode_crtc->prime_pixmap) {
|
if (drmmode_crtc_set_mode(crtc, can_test)) {
|
||||||
if (!drmmode->reverse_prime_offload_mode) {
|
|
||||||
msPixmapPrivPtr ppriv =
|
|
||||||
msGetPixmapPriv(drmmode, drmmode_crtc->prime_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;
|
|
||||||
x = y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fb_id == 0) {
|
|
||||||
ret = drmmode_bo_import(drmmode, &drmmode->front_bo,
|
|
||||||
&drmmode->fb_id);
|
|
||||||
if (ret < 0) {
|
|
||||||
ErrorF("failed to add fb %d\n", ret);
|
|
||||||
ret = FALSE;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
fb_id = drmmode->fb_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
|
|
||||||
if (drmmode_crtc_set_fb(crtc, mode, fb_id, x, y, flags, NULL)) {
|
|
||||||
xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
|
xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
|
||||||
"failed to set mode: %s\n", strerror(errno));
|
"failed to set mode: %s\n", strerror(errno));
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
|
@ -1246,6 +1431,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||||
if (crtc->scrn->pScreen)
|
if (crtc->scrn->pScreen)
|
||||||
xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen);
|
xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen);
|
||||||
|
|
||||||
|
ms->pending_modeset = TRUE;
|
||||||
drmmode_crtc->need_modeset = FALSE;
|
drmmode_crtc->need_modeset = FALSE;
|
||||||
crtc->funcs->dpms(crtc, DPMSModeOn);
|
crtc->funcs->dpms(crtc, DPMSModeOn);
|
||||||
|
|
||||||
|
@ -1265,6 +1451,11 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||||
continue;
|
continue;
|
||||||
output->funcs->dpms(output, DPMSModeOn);
|
output->funcs->dpms(output, DPMSModeOn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if we only tested the mode previously, really set it now */
|
||||||
|
if (can_test)
|
||||||
|
drmmode_crtc_set_mode(crtc, FALSE);
|
||||||
|
ms->pending_modeset = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -2261,20 +2452,22 @@ drmmode_output_destroy(xf86OutputPtr output)
|
||||||
static void
|
static void
|
||||||
drmmode_output_dpms(xf86OutputPtr output, int mode)
|
drmmode_output_dpms(xf86OutputPtr output, int mode)
|
||||||
{
|
{
|
||||||
|
modesettingPtr ms = modesettingPTR(output->scrn);
|
||||||
drmmode_output_private_ptr drmmode_output = output->driver_private;
|
drmmode_output_private_ptr drmmode_output = output->driver_private;
|
||||||
xf86CrtcPtr crtc = output->crtc;
|
|
||||||
modesettingPtr ms = NULL;
|
|
||||||
drmModeConnectorPtr koutput = drmmode_output->mode_output;
|
|
||||||
drmmode_ptr drmmode = drmmode_output->drmmode;
|
drmmode_ptr drmmode = drmmode_output->drmmode;
|
||||||
|
xf86CrtcPtr crtc = output->crtc;
|
||||||
|
drmModeConnectorPtr koutput = drmmode_output->mode_output;
|
||||||
|
|
||||||
if (!koutput)
|
if (!koutput)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (crtc)
|
/* XXX Check if DPMS mode is already the right one */
|
||||||
ms = modesettingPTR(crtc->scrn);
|
|
||||||
|
|
||||||
if (ms && ms->atomic_modeset) {
|
drmmode_output->dpms = mode;
|
||||||
drmmode_output->dpms = mode;
|
|
||||||
|
if (ms->atomic_modeset) {
|
||||||
|
if (mode != DPMSModeOn && !ms->pending_modeset)
|
||||||
|
drmmode_output_disable(output);
|
||||||
} else {
|
} else {
|
||||||
drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id,
|
drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id,
|
||||||
drmmode_output->dpms_enum_id, mode);
|
drmmode_output->dpms_enum_id, mode);
|
||||||
|
|
|
@ -283,7 +283,8 @@ void drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmmode,
|
||||||
|
|
||||||
void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
|
void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
|
||||||
|
|
||||||
int drmmode_crtc_set_fb(xf86CrtcPtr crtc, DisplayModePtr mode, uint32_t fb_id,
|
int drmmode_crtc_flip(xf86CrtcPtr crtc, uint32_t fb_id, uint32_t flags, void *data);
|
||||||
int x, int y, uint32_t flags, void *data);
|
|
||||||
|
void drmmode_set_dpms(ScrnInfoPtr scrn, int PowerManagementMode, int flags);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -163,17 +163,8 @@ static Bool
|
||||||
do_queue_flip_on_crtc(modesettingPtr ms, xf86CrtcPtr crtc,
|
do_queue_flip_on_crtc(modesettingPtr ms, xf86CrtcPtr crtc,
|
||||||
uint32_t flags, uint32_t seq)
|
uint32_t flags, uint32_t seq)
|
||||||
{
|
{
|
||||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
return drmmode_crtc_flip(crtc, ms->drmmode.fb_id, flags,
|
||||||
|
(void *) (uintptr_t) seq);
|
||||||
if (ms->atomic_modeset) {
|
|
||||||
flags |= DRM_MODE_ATOMIC_NONBLOCK;
|
|
||||||
return drmmode_crtc_set_fb(crtc, NULL, ms->drmmode.fb_id, crtc->x, crtc->y, flags,
|
|
||||||
(void *) (uintptr_t) seq);
|
|
||||||
}
|
|
||||||
|
|
||||||
return drmModePageFlip(ms->fd, drmmode_crtc->mode_crtc->crtc_id,
|
|
||||||
ms->drmmode.fb_id, flags,
|
|
||||||
(void *) (uintptr_t) seq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
|
|
Loading…
Reference in New Issue