summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drmmode_display.c66
1 files changed, 58 insertions, 8 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 5e0c413..5b24314 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -756,6 +756,17 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode,
}
}
+static void
+drmmode_crtc_gamma_do_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green,
+ uint16_t *blue, int size)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(crtc->scrn);
+
+ drmModeCrtcSetGamma(pAMDGPUEnt->fd, drmmode_crtc->mode_crtc->crtc_id,
+ size, red, green, blue);
+}
+
static Bool
drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
Rotation rotation, int x, int y)
@@ -820,8 +831,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
if (drmmode_crtc->tear_free)
scanout_id = drmmode_crtc->scanout_id;
- crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
- crtc->gamma_blue, crtc->gamma_size);
+ drmmode_crtc_gamma_do_set(crtc, crtc->gamma_red, crtc->gamma_green,
+ crtc->gamma_blue, crtc->gamma_size);
drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
@@ -991,6 +1002,31 @@ drmmode_cursor_src_offset(Rotation rotation, int width, int height,
#endif
+static uint32_t
+drmmode_cursor_gamma(xf86CrtcPtr crtc, uint32_t argb)
+{
+ uint32_t alpha = argb >> 24;
+ uint32_t rgb[3];
+ int i;
+
+ if (!alpha)
+ return 0;
+
+ if (crtc->scrn->depth != 24 && crtc->scrn->depth != 32)
+ return argb;
+
+ /* Un-premultiply alpha */
+ for (i = 0; i < 3; i++)
+ rgb[i] = ((argb >> (i * 8)) & 0xff) * 0xff / alpha;
+
+ /* Apply gamma correction and pre-multiply alpha */
+ rgb[0] = (crtc->gamma_blue[rgb[0]] >> 8) * alpha / 0xff;
+ rgb[1] = (crtc->gamma_green[rgb[1]] >> 8) * alpha / 0xff;
+ rgb[2] = (crtc->gamma_red[rgb[2]] >> 8) * alpha / 0xff;
+
+ return alpha << 24 | rgb[2] << 16 | rgb[1] << 8 | rgb[0];
+}
+
static void drmmode_do_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image, uint32_t *ptr)
{
ScrnInfoPtr pScrn = crtc->scrn;
@@ -1010,7 +1046,8 @@ static void drmmode_do_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image, uint32_
dstx, dsty);
ptr[dsty * info->cursor_w + dstx] =
- cpu_to_le32(image[srcoffset]);
+ cpu_to_le32(drmmode_cursor_gamma(crtc,
+ image[srcoffset]));
}
}
} else
@@ -1020,7 +1057,7 @@ static void drmmode_do_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image, uint32_
int i;
for (i = 0; i < cursor_size; i++)
- ptr[i] = cpu_to_le32(image[i]);
+ ptr[i] = cpu_to_le32(drmmode_cursor_gamma(crtc, image[i]));
}
}
@@ -1176,11 +1213,24 @@ static void
drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t * red, uint16_t * green,
uint16_t * blue, int size)
{
- drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
- AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(crtc->scrn);
+ ScrnInfoPtr scrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+ int i;
- drmModeCrtcSetGamma(pAMDGPUEnt->fd, drmmode_crtc->mode_crtc->crtc_id,
- size, red, green, blue);
+ drmmode_crtc_gamma_do_set(crtc, red, green, blue, size);
+
+ /* Compute index of this CRTC into xf86_config->crtc */
+ for (i = 0; xf86_config->crtc[i] != crtc; i++) {}
+
+ if (info->hwcursor_disabled & (1 << i))
+ return;
+
+#ifdef HAVE_XF86_CURSOR_RESET_CURSOR
+ xf86CursorResetCursor(scrn->pScreen);
+#else
+ xf86_reload_cursors(scrn->pScreen);
+#endif
}
#ifdef AMDGPU_PIXMAP_SHARING