Skip to content
Commits on Source (6)
......@@ -262,6 +262,10 @@
#define MAX_H (_MAX_H(c) + _MAX_H_OFFSET(c))
#define _MAX_CLOCK(x) x[9]
#define MAX_CLOCK _MAX_CLOCK(c)
#define _DEFAULT_GTF(x) (x[10] == 0x00)
#define DEFAULT_GTF _DEFAULT_GTF(c)
#define _RANGE_LIMITS_ONLY(x) (x[10] == 0x01)
#define RANGE_LIMITS_ONLY _RANGE_LIMITS_ONLY(c)
#define _HAVE_2ND_GTF(x) (x[10] == 0x02)
#define HAVE_2ND_GTF _HAVE_2ND_GTF(c)
#define _F_2ND_GTF(x) (x[12] * 2)
......@@ -477,6 +481,16 @@ struct detailed_timings {
#define DS_VENDOR 0x101
#define DS_VENDOR_MAX 0x110
/*
* Display range limit Descriptor of EDID version1, reversion 4
*/
typedef enum {
DR_DEFAULT_GTF,
DR_LIMITS_ONLY,
DR_SECONDARY_GTF,
DR_CVT_SUPPORTED = 4,
} DR_timing_flags;
struct monitor_ranges {
int min_v;
int max_v;
......@@ -495,6 +509,7 @@ struct monitor_ranges {
char supported_blanking;
char supported_scaling;
int preferred_refresh; /* in hz */
DR_timing_flags display_range_timing_flags;
};
struct whitePoints {
......@@ -524,7 +539,7 @@ struct detailed_monitor_section {
Uchar serial[13];
Uchar ascii_data[13];
Uchar name[13];
struct monitor_ranges ranges; /* 56 */
struct monitor_ranges ranges; /* 60 */
struct std_timings std_t[5]; /* 80 */
struct whitePoints wp[2]; /* 32 */
/* color management data */
......
......@@ -672,6 +672,9 @@ get_monitor_ranges(Uchar * c, struct monitor_ranges *r)
r->max_clock = 0;
if (MAX_CLOCK != 0xff) /* is specified? */
r->max_clock = MAX_CLOCK * 10 + 5;
r->display_range_timing_flags = c[10];
if (HAVE_2ND_GTF) {
r->gtf_2nd_f = F_2ND_GTF;
r->gtf_2nd_c = C_2ND_GTF;
......@@ -751,6 +754,30 @@ validate_version(int scrnIndex, struct edid_version *r)
return TRUE;
}
Bool
gtf_supported(xf86MonPtr mon)
{
int i;
if (!mon)
return FALSE;
if ((mon->ver.version == 1) && (mon->ver.revision < 4)) {
if (mon->features.msc & 0x1)
return TRUE;
} else {
for (i = 0; i < DET_TIMINGS; i++) {
struct detailed_monitor_section *det_timing_des = &(mon->det_mon[i]);
if (det_timing_des && (det_timing_des->type == DS_RANGES) &&
(det_timing_des->section.ranges.display_range_timing_flags == DR_DEFAULT_GTF
|| det_timing_des->section.ranges.display_range_timing_flags == DR_SECONDARY_GTF))
return TRUE;
}
}
return FALSE;
}
/*
* Returns true if HDMI, false if definitely not or unknown.
*/
......
......@@ -48,6 +48,9 @@ extern _X_EXPORT Bool xf86SetDDCproperties(ScrnInfoPtr pScreen, xf86MonPtr DDC);
extern _X_EXPORT Bool
xf86MonitorIsHDMI(xf86MonPtr mon);
extern _X_EXPORT Bool
gtf_supported(xf86MonPtr mon);
extern _X_EXPORT DisplayModePtr
FindDMTMode(int hsize, int vsize, int refresh, Bool rb);
......
......@@ -2459,7 +2459,7 @@ drmmode_output_add_gtf_modes(xf86OutputPtr output, DisplayModePtr Modes)
int max_x = 0, max_y = 0;
float max_vrefresh = 0.0;
if (mon && GTF_SUPPORTED(mon->features.msc))
if (mon && gtf_supported(mon))
return Modes;
if (!has_panel_fitter(output))
......
......@@ -1731,11 +1731,10 @@ xf86ProbeOutputModes(ScrnInfoPtr scrn, int maxX, int maxY)
if (edid_monitor) {
struct det_monrec_parameter p;
struct disp_features *features = &edid_monitor->features;
struct cea_data_block *hdmi_db;
/* if display is not continuous-frequency, don't add default modes */
if (!GTF_SUPPORTED(features->msc))
if (!gtf_supported(edid_monitor))
add_default_modes = FALSE;
p.mon_rec = &mon_rec;
......
......@@ -212,7 +212,7 @@ xf86CursorEnableDisableFBAccess(ScrnInfoPtr pScrn, Bool enable)
xf86CursorScreenKey);
if (!enable && ScreenPriv->CurrentCursor != NullCursor) {
CursorPtr currentCursor = ScreenPriv->CurrentCursor;
CursorPtr currentCursor = RefCursor(ScreenPriv->CurrentCursor);
xf86CursorSetCursor(pDev, pScreen, NullCursor, ScreenPriv->x,
ScreenPriv->y);
......@@ -231,6 +231,7 @@ xf86CursorEnableDisableFBAccess(ScrnInfoPtr pScrn, Bool enable)
*/
xf86CursorSetCursor(pDev, pScreen, ScreenPriv->SavedCursor,
ScreenPriv->x, ScreenPriv->y);
UnrefCursor(ScreenPriv->SavedCursor);
ScreenPriv->SavedCursor = NULL;
}
}
......
......@@ -117,6 +117,23 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
}
}
static void
xwl_present_free_event(struct xwl_present_event *event)
{
if (!event)
return;
if (event->pixmap) {
if (!event->buffer_released)
xwl_pixmap_del_buffer_release_cb(event->pixmap);
dixDestroyPixmap(event->pixmap, event->pixmap->drawable.id);
}
xorg_list_del(&event->list);
free(event);
}
void
xwl_present_cleanup(WindowPtr window)
{
......@@ -134,26 +151,13 @@ xwl_present_cleanup(WindowPtr window)
}
/* Clear remaining events */
xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->event_list, list) {
xorg_list_del(&event->list);
free(event);
}
xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->event_list, list)
xwl_present_free_event(event);
/* Clear remaining buffer releases and inform Present about free ressources */
event = xwl_present_window->sync_flip;
xwl_present_window->sync_flip = NULL;
if (event) {
if (event->buffer_released) {
free(event);
} else {
event->pending = FALSE;
event->abort = TRUE;
}
}
xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->release_queue, list) {
xorg_list_del(&event->list);
event->abort = TRUE;
}
xwl_present_free_event(xwl_present_window->sync_flip);
xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->release_queue, list)
xwl_present_free_event(event);
/* Clear timer */
xwl_present_free_timer(xwl_present_window);
......@@ -166,13 +170,6 @@ xwl_present_cleanup(WindowPtr window)
free(xwl_present_window);
}
static void
xwl_present_free_event(struct xwl_present_event *event)
{
xorg_list_del(&event->list);
free(event);
}
static void
xwl_present_buffer_release(PixmapPtr pixmap, void *data)
{
......@@ -219,7 +216,7 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
/* If the buffer was already released, clean up now */
present_wnmd_event_notify(xwl_present_window->window, event->event_id,
xwl_present_window->ust, msc);
free(event);
xwl_present_free_event(event);
} else {
xorg_list_add(&event->list, &xwl_present_window->release_queue);
}
......@@ -358,6 +355,7 @@ xwl_present_queue_vblank(WindowPtr present_window,
return BadAlloc;
event->event_id = event_id;
event->pixmap = NULL;
event->xwl_present_window = xwl_present_window;
event->target_msc = msc;
......@@ -395,8 +393,7 @@ xwl_present_abort_vblank(WindowPtr present_window,
xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->event_list, list) {
if (event->event_id == event_id) {
xorg_list_del(&event->list);
free(event);
xwl_present_free_event(event);
return;
}
}
......@@ -462,11 +459,12 @@ xwl_present_flip(WindowPtr present_window,
if (!event)
return FALSE;
pixmap->refcnt++;
buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap, NULL);
event->event_id = event_id;
event->xwl_present_window = xwl_present_window;
event->buffer = buffer;
event->pixmap = pixmap;
event->target_msc = target_msc;
event->pending = TRUE;
event->abort = FALSE;
......
......@@ -59,7 +59,7 @@ struct xwl_present_event {
Bool buffer_released;
struct xwl_present_window *xwl_present_window;
struct wl_buffer *buffer;
PixmapPtr pixmap;
struct xorg_list list;
};
......
......@@ -115,15 +115,13 @@ present_wnmd_clear_window_flip(WindowPtr window)
present_window_priv_ptr window_priv = present_window_priv(window);
present_vblank_ptr vblank, tmp;
if (window_priv->flip_pending) {
present_wnmd_set_abort_flip(window);
window_priv->flip_pending->window = NULL;
xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->flip_queue, event_queue) {
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
present_vblank_destroy(vblank);
}
xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->idle_queue, event_queue) {
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
/* The pixmap will be destroyed by freeing the window resources. */
vblank->pixmap = NULL;
present_vblank_destroy(vblank);
}
......