This allow us to size and dynamically resize the dummy driver. Signed-off-by: Jeremy White <jwhite@xxxxxxxxxxxxxxx> --- spice-video-dummy/src/Makefile.am | 2 +- spice-video-dummy/src/display.c | 415 ++++++++++++++++++++++ spice-video-dummy/src/dri2.c | 5 +- spice-video-dummy/src/dummy.h | 33 ++ spice-video-dummy/src/dummy_cursor.c | 101 ------ spice-video-dummy/src/present.c | 125 ++++++- spice-video-dummy/src/spicedummy_driver.c | 53 +-- 7 files changed, 589 insertions(+), 145 deletions(-) create mode 100644 spice-video-dummy/src/display.c delete mode 100644 spice-video-dummy/src/dummy_cursor.c diff --git a/spice-video-dummy/src/Makefile.am b/spice-video-dummy/src/Makefile.am index 1dc4df8e..8c6e132b 100644 --- a/spice-video-dummy/src/Makefile.am +++ b/spice-video-dummy/src/Makefile.am @@ -35,7 +35,7 @@ spicedummy_drv_ladir = @moduledir@/drivers spicedummy_drv_la_SOURCES = \ compat-api.h \ dri2.c \ - dummy_cursor.c \ spicedummy_driver.c \ + display.c \ dummy.h \ present.c diff --git a/spice-video-dummy/src/display.c b/spice-video-dummy/src/display.c new file mode 100644 index 00000000..b83869bb --- /dev/null +++ b/spice-video-dummy/src/display.c @@ -0,0 +1,415 @@ +/* + * Copyright 2019 Jeremy White + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "dummy.h" + +#define DUMMY_DEFAULT_WIDTH 1024 +#define DUMMY_DEFAULT_HEIGHT 768 + +static Bool +crtc_resize(ScrnInfoRec * scrn, int width, int height) +{ + PixmapRec *pixmap; + ScreenRec *screen; + + screen = xf86ScrnToScreen(scrn); + pixmap = screen->GetScreenPixmap(screen); + + screen->ModifyPixmapHeader(pixmap, width, height, -1, -1, -1, NULL); + + scrn->virtualX = width; + scrn->virtualY = height; + + return TRUE; +} + +static const xf86CrtcConfigFuncsRec crtc_config_funcs = { + crtc_resize +}; + +static void +crtc_dpms(xf86CrtcPtr crtc, int mode) +{ + xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO, "%s: STUB dpms %d\n", __func__, mode); +} + +static Bool +crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, int x, int y) +{ + struct dummy_crtc_state *state; + uint64_t ust; + + xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO, "%s: mode %s, x %d, y %d\n", __func__, mode->name, x, + y); + + state = crtc->driver_private; + ust = dummy_gettime_us(); + if (state->interval) + state->msc_base += ((ust - state->ust_base) / state->interval); + state->ust_base = ust; + state->interval = + (((uint64_t) 1000 * mode->HTotal * mode->VTotal) + (mode->Clock / 2)) / mode->Clock; + + crtc->mode = *mode; + crtc->x = x; + crtc->y = y; + crtc->rotation = rotation; +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC (1, 5, 99, 0, 0) + crtc->transformPresent = FALSE; +#endif + + return TRUE; +} + +static void +crtc_destroy(xf86CrtcPtr crtc) +{ + xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO, "%s\n", __func__); + + if (crtc->driver_private) { + dummy_present_free_vblanks(crtc); + free(crtc->driver_private); + } + crtc->driver_private = NULL; +} + +static void +dummy_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) +{ +} + +static void +dummy_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) +{ +} + +static void +dummy_crtc_hide_cursor(xf86CrtcPtr crtc) +{ +} + +static Bool +dummy_crtc_show_cursor(xf86CrtcPtr crtc) +{ + return TRUE; +} + +static Bool +dummy_crtc_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 * image) +{ + return TRUE; +} + +static const xf86CrtcFuncsRec crtc_funcs = { + .dpms = crtc_dpms, + .save = NULL, + .restore = NULL, + .lock = NULL, + .unlock = NULL, + .mode_fixup = NULL, + .prepare = NULL, + .mode_set = NULL, + .commit = NULL, + .gamma_set = NULL, + .shadow_allocate = NULL, + .shadow_create = NULL, + .shadow_destroy = NULL, + .set_cursor_colors = dummy_crtc_set_cursor_colors, + .set_cursor_position = dummy_crtc_set_cursor_position, + .show_cursor = NULL, + .show_cursor_check = dummy_crtc_show_cursor, + .hide_cursor = dummy_crtc_hide_cursor, + .load_cursor_image = NULL, + .load_cursor_image_check = NULL, + .load_cursor_argb = NULL, + .load_cursor_argb_check = dummy_crtc_load_cursor_argb_check, + .destroy = crtc_destroy, + .set_mode_major = crtc_set_mode_major, + .set_origin = NULL, + .set_scanout_pixmap = NULL, +}; + +void +crtc_config_init(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigInit(pScrn, &crtc_config_funcs); +} + +void +crtc_create(ScrnInfoPtr pScrn) +{ + struct dummy_crtc_state *state; + xf86CrtcRec *crtc; + + crtc = xf86CrtcCreate(pScrn, &crtc_funcs); + + state = malloc(sizeof(*state)); + state->ust_base = 0; + state->msc_base = 0; + state->interval = 0; + xorg_list_init(&state->vblank_queue); + xorg_list_init(&state->vblank_free); + state->vblank_timer = NULL; + crtc->driver_private = state; + + /* + * Set the CRTC parameters for all of the modes based on the type + * of mode, and the chipset's interlace requirements. + * + * Calling this is required if the mode->Crtc* values are used by the + * driver and if the driver doesn't provide code to set them. They + * are not pre-initialised at all. + */ + xf86SetCrtcForModes(pScrn, 0); + + xf86CrtcSetSizeRange(pScrn, 320, 200, pScrn->display->virtualX, pScrn->display->virtualY); +} + +/** + * Turns the output on/off, or sets intermediate power levels if available. + * + * Unsupported intermediate modes drop to the lower power setting. If the + * mode is DPMSModeOff, the output must be disabled, as the DPLL may be + * disabled afterwards. + */ +static void +output_dpms(xf86OutputPtr output, int mode) +{ + xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "%s: STUB dpms %d\n", __func__, mode); +} + +/** + * Callback for testing a video mode for a given output. + * + * This function should only check for cases where a mode can't be supported + * on the output specifically, and not represent generic CRTC limitations. + * + * \return MODE_OK if the mode is valid, or another MODE_* otherwise. + */ +static int +output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) +{ + return MODE_OK; +} + +/* This is copied from xf86Crtc.c/GuessRangeFromModes. Essentially, we want + all of the default modes to be considered within sync range. The normal + xf86InitialConfiguration will use this, but then discard the sync ranges. +*/ +static void +output_guess_ranges_from_modes(MonPtr mon, DisplayModePtr mode) +{ + if (!mon || !mode) + return; + + mon->nHsync = 1; + mon->hsync[0].lo = 1024.0; + mon->hsync[0].hi = 0.0; + + mon->nVrefresh = 1; + mon->vrefresh[0].lo = 1024.0; + mon->vrefresh[0].hi = 0.0; + + while (mode) { + if (!mode->HSync) + mode->HSync = ((float) mode->Clock) / ((float) mode->HTotal); + + if (!mode->VRefresh) + mode->VRefresh = (1000.0 * ((float) mode->Clock)) / + ((float) (mode->HTotal * mode->VTotal)); + + if (mode->HSync < mon->hsync[0].lo) + mon->hsync[0].lo = mode->HSync; + + if (mode->HSync > mon->hsync[0].hi) + mon->hsync[0].hi = mode->HSync; + + if (mode->VRefresh < mon->vrefresh[0].lo) + mon->vrefresh[0].lo = mode->VRefresh; + + if (mode->VRefresh > mon->vrefresh[0].hi) + mon->vrefresh[0].hi = mode->VRefresh; + + mode = mode->next; + } + + /* stretch out the bottom to fit 640x480@60 */ + if (mon->hsync[0].lo > 31.0) + mon->hsync[0].lo = 31.0; + if (mon->vrefresh[0].lo > 58.0) + mon->vrefresh[0].lo = 58.0; +} + +/** + * Probe for a connected output, and return detect_status. + */ +static xf86OutputStatus +output_detect(xf86OutputPtr output) +{ + xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "%s: STUB detect\n", __func__); + return XF86OutputStatusConnected; +} + +static DisplayModePtr +output_create_mode(ScrnInfoPtr pScrn, int width, int height, int type) +{ + DisplayModePtr mode; + + mode = xnfcalloc(1, sizeof(DisplayModeRec)); + + mode->status = MODE_OK; + mode->type = type; + mode->HDisplay = width; + mode->HSyncStart = (width * 105 / 100 + 7) & ~7; + mode->HSyncEnd = (width * 115 / 100 + 7) & ~7; + mode->HTotal = (width * 130 / 100 + 7) & ~7; + mode->VDisplay = height; + mode->VSyncStart = height + 1; + mode->VSyncEnd = height + 4; + mode->VTotal = height * 1035 / 1000; + mode->Clock = mode->HTotal * mode->VTotal * 60 / 1000; + mode->Flags = V_NHSYNC | V_PVSYNC; + + xf86SetModeDefaultName(mode); + xf86SetModeCrtc(mode, pScrn->adjustFlags); /* needed? xf86-video-modesetting does this */ + + return mode; +} + +static void +output_check_modes(ScrnInfoPtr pScrn, DisplayModePtr modes) +{ + int preferred_found = 0; + int virtual_found = 0; + DisplayModePtr mode = modes; + + while (mode) { + if (mode->HDisplay == DUMMY_DEFAULT_WIDTH && mode->VDisplay == DUMMY_DEFAULT_HEIGHT) { + mode->type |= M_T_PREFERRED; + preferred_found++; + } + if (mode->HDisplay == pScrn->display->virtualX && + mode->VDisplay == pScrn->display->virtualY) { + virtual_found = 0; + } + + mode->type |= M_T_DRIVER; + mode = mode->next; + } + + if (preferred_found == 0) { + mode = output_create_mode(pScrn, DUMMY_DEFAULT_WIDTH, + DUMMY_DEFAULT_HEIGHT, M_T_DRIVER | M_T_PREFERRED); + xf86ModesAdd(modes, mode); + } + + if (DUMMY_DEFAULT_WIDTH == pScrn->display->virtualX && + DUMMY_DEFAULT_HEIGHT == pScrn->display->virtualY) { + virtual_found++; + } + + if (virtual_found == 0) { + mode = output_create_mode(pScrn, pScrn->display->virtualX, + pScrn->display->virtualY, M_T_DRIVER); + xf86ModesAdd(modes, mode); + } +} + +/** + * Query the device for the modes it provides. + * + * This function may also update MonInfo, mm_width, and mm_height. + * + * \return singly-linked list of modes or NULL if no modes found. + */ +static DisplayModePtr +output_get_modes(xf86OutputPtr output) +{ + DisplayModePtr modes = output->driver_private; + + xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "%s: STUB %p\n", __func__, modes); + + return xf86DuplicateModes(output->scrn, modes); +} + +/** + * Callback to get current CRTC for a given output + */ +static xf86CrtcPtr +output_get_crtc(xf86OutputPtr output) +{ + return output->crtc; +} + +/** + * Clean up driver-specific bits of the output + */ +static void +output_destroy(xf86OutputPtr output) +{ + DisplayModePtr modes = output->driver_private; + + output->driver_private = NULL; + while (modes) + xf86DeleteMode(&modes, modes); +} + +xf86OutputFuncsRec output_funcs = { + .create_resources = NULL, + .dpms = output_dpms, + .save = NULL, + .restore = NULL, + .mode_valid = output_mode_valid, + .mode_fixup = NULL, /* Not required if crtc provides set_major_mode */ + .prepare = NULL, + .commit = NULL, + .mode_set = NULL, + .detect = output_detect, + .get_modes = output_get_modes, + +#ifdef RANDR_12_INTERFACE + .set_property = NULL, +#endif +#ifdef RANDR_13_INTERFACE + .get_property = NULL, +#endif +#ifdef RANDR_GET_CRTC_INTERFACE + .get_crtc = output_get_crtc, +#endif + .destroy = output_destroy, +}; + +void +output_pre_init(ScrnInfoPtr pScrn) +{ + DisplayModePtr modes; + xf86OutputPtr output = xf86OutputCreate(pScrn, &output_funcs, "SPICE-0"); + output->possible_crtcs = (1 << 0); + modes = xf86GetDefaultModes(); + output_check_modes(pScrn, modes); + output_guess_ranges_from_modes(output->scrn->monitor, modes); + output->driver_private = modes; +} diff --git a/spice-video-dummy/src/dri2.c b/spice-video-dummy/src/dri2.c index 2d3f4c08..ea498da8 100644 --- a/spice-video-dummy/src/dri2.c +++ b/spice-video-dummy/src/dri2.c @@ -219,8 +219,9 @@ dummy_dri2_copy_region(DrawableRec * drawable, RegionRec * region, static int dummy_dri2_get_msc(DrawableRec * drawable, CARD64 * ust, CARD64 * msc) { - *ust = dummy_gettime_us(); - *msc = 0; + ScrnInfoRec *scrn = xf86ScreenToScrn(drawable->pScreen); + + dummy_get_ust_msc(xf86CompatRRCrtc(scrn), ust, msc); return TRUE; } diff --git a/spice-video-dummy/src/dummy.h b/spice-video-dummy/src/dummy.h index dc4ab92f..79d1a9ef 100644 --- a/spice-video-dummy/src/dummy.h +++ b/spice-video-dummy/src/dummy.h @@ -4,6 +4,7 @@ #include "xf86_OSproc.h" #include "xf86Cursor.h" +#include "xf86Crtc.h" #ifdef XvExtension #include "xf86xv.h" @@ -35,6 +36,14 @@ extern void DUMMYHideCursor(ScrnInfoPtr pScrn); void dummy_dri2_close_screen(ScreenRec * screen); Bool dummy_dri2_screen_init(ScreenRec * screen); Bool dummy_present_screen_init(ScreenRec * screen); +void dummy_present_free_vblanks(xf86CrtcPtr crtc); + +/* in crtc.c */ +void crtc_config_init(ScrnInfoPtr scrn); +void crtc_create(ScrnInfoPtr scrn); + +/* in output.c */ +void output_pre_init(ScrnInfoPtr scrn); /* globals */ typedef struct _color { @@ -63,6 +72,16 @@ typedef struct dummyRec { int fd; } DUMMYRec, *DUMMYPtr; +struct dummy_crtc_state { + uint64_t ust_base; + uint64_t msc_base; + uint64_t interval; + + struct xorg_list vblank_queue; + struct xorg_list vblank_free; + OsTimerPtr vblank_timer; +}; + /* The privates of the DUMMY driver */ #define DUMMYPTR(p) ((DUMMYPtr)((p)->driverPrivate)) @@ -77,3 +96,17 @@ dummy_gettime_us(void) return (uint64_t) tv.tv_sec * 1000000 + tv.tv_nsec / 1000; } + +static inline void +dummy_get_ust_msc(const RRCrtcRec * crtc, uint64_t * ust, uint64_t * msc) +{ + struct dummy_crtc_state *state; + xf86CrtcRec *xf86_crtc; + + xf86_crtc = crtc->devPrivate; + state = xf86_crtc->driver_private; + *ust = dummy_gettime_us(); + *msc = state->msc_base; + if (state->interval) + *msc += (*ust - state->ust_base) / state->interval; +} diff --git a/spice-video-dummy/src/dummy_cursor.c b/spice-video-dummy/src/dummy_cursor.c deleted file mode 100644 index 03de8eb6..00000000 --- a/spice-video-dummy/src/dummy_cursor.c +++ /dev/null @@ -1,101 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* All drivers should typically include these */ -#include "xf86.h" -#include "xf86_OSproc.h" - -#include "xf86Cursor.h" -#include "cursorstr.h" -/* Driver specific headers */ -#include "dummy.h" - -static void -dummyShowCursor(ScrnInfoPtr pScrn) -{ - DUMMYPtr dPtr = DUMMYPTR(pScrn); - - /* turn cursor on */ - dPtr->DummyHWCursorShown = TRUE; -} - -static void -dummyHideCursor(ScrnInfoPtr pScrn) -{ - DUMMYPtr dPtr = DUMMYPTR(pScrn); - - /* - * turn cursor off - * - */ - dPtr->DummyHWCursorShown = FALSE; -} - -#define MAX_CURS 64 - -static void -dummySetCursorPosition(ScrnInfoPtr pScrn, int x, int y) -{ - DUMMYPtr dPtr = DUMMYPTR(pScrn); - - dPtr->cursorX = x; - dPtr->cursorY = y; -} - -static void -dummySetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) -{ - DUMMYPtr dPtr = DUMMYPTR(pScrn); - - dPtr->cursorFG = fg; - dPtr->cursorBG = bg; -} - -static void -dummyLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) -{ -} - -static Bool -dummyUseHWCursor(ScreenPtr pScr, CursorPtr pCurs) -{ - DUMMYPtr dPtr = DUMMYPTR(xf86ScreenToScrn(pScr)); - return (!dPtr->swCursor); -} - -#if 0 -static unsigned char * -dummyRealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) -{ - return NULL; -} -#endif - -Bool -DUMMYCursorInit(ScreenPtr pScreen) -{ - DUMMYPtr dPtr = DUMMYPTR(xf86ScreenToScrn(pScreen)); - - xf86CursorInfoPtr infoPtr; - infoPtr = xf86CreateCursorInfoRec(); - if (!infoPtr) { - return FALSE; - } - - dPtr->CursorInfo = infoPtr; - - infoPtr->MaxHeight = 64; - infoPtr->MaxWidth = 64; - infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP; - - infoPtr->SetCursorColors = dummySetCursorColors; - infoPtr->SetCursorPosition = dummySetCursorPosition; - infoPtr->LoadCursorImage = dummyLoadCursorImage; - infoPtr->HideCursor = dummyHideCursor; - infoPtr->ShowCursor = dummyShowCursor; - infoPtr->UseHWCursor = dummyUseHWCursor; -/* infoPtr->RealizeCursor = dummyRealizeCursor; */ - - return (xf86InitCursor(pScreen, infoPtr)); -} diff --git a/spice-video-dummy/src/present.c b/spice-video-dummy/src/present.c index 81fcc5b6..ad29dc91 100644 --- a/spice-video-dummy/src/present.c +++ b/spice-video-dummy/src/present.c @@ -27,25 +27,109 @@ #include "dummy.h" #include "present.h" +#include <stdbool.h> + +struct dummy_vblank { + struct xorg_list list; + uint64_t event_id; + uint64_t target_msc; +}; + static RRCrtcRec * dummy_present_get_crtc(WindowRec * window) { - return NULL; + ScrnInfoRec *scrn; + + if (!(scrn = xf86ScreenToScrn(window->drawable.pScreen))) + return NULL; + return xf86CompatRRCrtc(scrn); } static int dummy_present_get_ust_msc(RRCrtcRec * crtc, CARD64 * ust, CARD64 * msc) { - *ust = dummy_gettime_us(); - *msc = 0; + dummy_get_ust_msc(crtc, ust, msc); return Success; } +static uint64_t +dummy_present_ust_for_msc(RRCrtcRec * crtc, uint64_t msc) +{ + struct dummy_crtc_state *state; + xf86CrtcRec *xf86_crtc; + + xf86_crtc = crtc->devPrivate; + state = xf86_crtc->driver_private; + + return state->ust_base + (state->interval * (msc - state->msc_base)); +} + +static uint32_t +dummy_do_timer(OsTimerPtr timer, uint32_t time, void *arg) +{ + struct dummy_vblank *vblank, *tmp; + struct dummy_crtc_state *state; + uint64_t ust, msc, next_ust; + xf86CrtcRec *xf86_crtc; + RRCrtcRec *crtc = arg; + + xf86_crtc = crtc->devPrivate; + state = xf86_crtc->driver_private; + + dummy_get_ust_msc(crtc, &ust, &msc); + xorg_list_for_each_entry_safe(vblank, tmp, &state->vblank_queue, list) { + if (msc < vblank->target_msc) + continue; + + present_event_notify(vblank->event_id, ust, msc); + xorg_list_del(&vblank->list); + xorg_list_add(&vblank->list, &state->vblank_free); + } + + if (!xorg_list_is_empty(&state->vblank_queue)) { + next_ust = dummy_present_ust_for_msc(crtc, msc + 1); + TimerSet(state->vblank_timer, TimerAbsolute, (next_ust / 1000) + 1, dummy_do_timer, arg); + } + + return 0; +} + static int -dummy_present_queue_vblank(RRCrtcRec * crtc, uint64_t event_id, uint64_t msc) +dummy_present_queue_vblank(RRCrtcRec * crtc, uint64_t event_id, uint64_t target_msc) { - present_event_notify(event_id, dummy_gettime_us(), msc); + struct dummy_crtc_state *state; + uint64_t ust, target_ust, msc; + struct dummy_vblank *vblank; + xf86CrtcRec *xf86_crtc; + bool start = false; + + xf86_crtc = crtc->devPrivate; + state = xf86_crtc->driver_private; + + dummy_get_ust_msc(crtc, &ust, &msc); + if ((target_ust = dummy_present_ust_for_msc(crtc, target_msc)) <= ust) + target_ust = dummy_present_ust_for_msc(crtc, msc + 1); + + if (!xorg_list_is_empty(&state->vblank_free)) { + vblank = xorg_list_first_entry(&state->vblank_free, struct dummy_vblank, list); + xorg_list_del(&vblank->list); + } else if (!(vblank = malloc(sizeof(*vblank)))) { + return BadAlloc; + } + + vblank->event_id = event_id; + vblank->target_msc = target_msc; + if (xorg_list_is_empty(&state->vblank_queue)) + start = true; + xorg_list_append(&vblank->list, &state->vblank_queue); + if (start + && !(state->vblank_timer = + TimerSet(NULL, TimerAbsolute, (target_ust / 1000) + 1, dummy_do_timer, crtc))) { + xorg_list_del(&vblank->list); + free(vblank); + return BadAlloc; + } return Success; } @@ -53,6 +137,20 @@ dummy_present_queue_vblank(RRCrtcRec * crtc, uint64_t event_id, uint64_t msc) static void dummy_present_abort_vblank(RRCrtcRec * crtc, uint64_t event_id, uint64_t msc) { + struct dummy_vblank *vblank, *tmp; + struct dummy_crtc_state *state; + xf86CrtcRec *xf86_crtc; + + xf86_crtc = crtc->devPrivate; + state = xf86_crtc->driver_private; + + xorg_list_for_each_entry_safe(vblank, tmp, &state->vblank_queue, list) { + if (vblank->event_id == event_id) { + xorg_list_del(&vblank->list); + free(vblank); + break; + } + } } static void @@ -100,3 +198,20 @@ dummy_present_screen_init(ScreenRec * screen) return present_screen_init(screen, &present_screen_info); } + +void +dummy_present_free_vblanks(xf86CrtcPtr crtc) +{ + struct dummy_crtc_state *state; + struct dummy_vblank *vblank, *tmp; + state = crtc->driver_private; + xorg_list_for_each_entry_safe(vblank, tmp, &state->vblank_queue, list) { + xorg_list_del(&vblank->list); + free(vblank); + } + + xorg_list_for_each_entry_safe(vblank, tmp, &state->vblank_free, list) { + xorg_list_del(&vblank->list); + free(vblank); + } +} diff --git a/spice-video-dummy/src/spicedummy_driver.c b/spice-video-dummy/src/spicedummy_driver.c index 1efae473..18e96cec 100644 --- a/spice-video-dummy/src/spicedummy_driver.c +++ b/spice-video-dummy/src/spicedummy_driver.c @@ -429,6 +429,16 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Max Clock: %d kHz\n", maxClock); } + /* Initialize an output and crtc */ + crtc_config_init(pScrn); + output_pre_init(pScrn); + crtc_create(pScrn); + + /* If monitor resolution is set on the command line, use it */ + xf86SetDpi(pScrn, 0, 0); + + xf86InitialConfiguration(pScrn, TRUE); + pScrn->progClock = TRUE; /* * Setup the ClockRanges, which describe what clock ranges are available, @@ -444,8 +454,6 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags) clockRanges->doubleScanAllowed = TRUE; /* Subtract memory for HW cursor */ - - { int apertureSize = (pScrn->videoRam * 1024); i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, @@ -468,35 +476,16 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags) RETURN; } - /* - * Set the CRTC parameters for all of the modes based on the type - * of mode, and the chipset's interlace requirements. - * - * Calling this is required if the mode->Crtc* values are used by the - * driver and if the driver doesn't provide code to set them. They - * are not pre-initialised at all. - */ - xf86SetCrtcForModes(pScrn, 0); - /* Set the current mode to the first in the list */ pScrn->currentMode = pScrn->modes; /* Print the list of modes being used */ xf86PrintModes(pScrn); - /* If monitor resolution is set on the command line, use it */ - xf86SetDpi(pScrn, 0, 0); - if (xf86LoadSubModule(pScrn, "fb") == NULL) { RETURN; } - if (!dPtr->swCursor) { - if (!xf86LoadSubModule(pScrn, "ramdac")) { - RETURN; - } - } - /* We have no contiguous physical fb in physical memory */ pScrn->memPhysBase = 0; pScrn->fbOffset = 0; @@ -631,6 +620,9 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL) /* must be after RGB ordering fixed */ fbPictureInit(pScreen, 0, 0); + if (!xf86CrtcScreenInit(pScreen)) + return FALSE; + if (dPtr->glamor && !glamor_init(pScreen, glamor_flags)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to initialise glamor at ScreenInit() time.\n"); @@ -639,13 +631,7 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL) xf86SetBlackWhitePixels(pScreen); - if (dPtr->swCursor) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using Software Cursor.\n"); - } - { - - BoxRec AvailFBArea; int lines = pScrn->videoRam * 1024 / (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); AvailFBArea.x1 = 0; @@ -663,15 +649,10 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL) /* Initialise cursor functions */ miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); - - - if (!dPtr->swCursor) { - /* HW cursor functions */ - if (!DUMMYCursorInit(pScreen)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Hardware cursor initialization failed\n"); - return FALSE; - } - } + if (!dPtr->swCursor) + xf86_cursors_init(pScreen, 64, 64, HARDWARE_CURSOR_UPDATE_UNHIDDEN | HARDWARE_CURSOR_ARGB); + else + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using Software Cursor.\n"); /* Initialise default colourmap */ if (!miCreateDefColormap(pScreen)) { -- 2.20.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel