From c8e1c498431b1f8758f62c94131c302cf3d07b39 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 16 Dec 2013 06:05:35 -0800 Subject: [PATCH] vmwgfx: Add an infrastructure to be able to run hosted under a compositor v2 Figure out what's needed both for XMir and XWayland and make a common driver structure out of it. v2: Added a lot of comments. No code change. Signed-off-by: Thomas Hellstrom Reviewed-by: Brian Paul Reviewed-by: Jakob Bornecrantz --- src/vmware_bootstrap.c | 19 ++- src/vmware_bootstrap.h | 2 + vmwgfx/Makefile.am | 3 + vmwgfx/vmwgfx_dri2.c | 37 ++++++ vmwgfx/vmwgfx_driver.c | 307 +++++++++++++++++++++++++++----------------- vmwgfx/vmwgfx_driver.h | 4 + vmwgfx/vmwgfx_hosted.c | 64 +++++++++ vmwgfx/vmwgfx_hosted.h | 257 ++++++++++++++++++++++++++++++++++++ vmwgfx/vmwgfx_hosted_priv.h | 34 +++++ vmwgfx/vmwgfx_overlay.c | 4 + 10 files changed, 610 insertions(+), 121 deletions(-) create mode 100644 vmwgfx/vmwgfx_hosted.c create mode 100644 vmwgfx/vmwgfx_hosted.h create mode 100644 vmwgfx/vmwgfx_hosted_priv.h diff --git a/src/vmware_bootstrap.c b/src/vmware_bootstrap.c index bb58325..57f8ae9 100644 --- a/src/vmware_bootstrap.c +++ b/src/vmware_bootstrap.c @@ -199,6 +199,12 @@ OptionInfoPtr VMWARECopyOptions(void) return options; } +/* + * Also in vmwgfx_hosted.h, which we don't include. + */ +void * +vmwgfx_hosted_detect(void); + static Bool VMwarePreinitStub(ScrnInfoPtr pScrn, int flags) { @@ -220,6 +226,11 @@ VMwarePreinitStub(ScrnInfoPtr pScrn, int flags) if ((*pScrn->PreInit)(pScrn, flags)) return TRUE; + /* + * Can't run legacy hosted + */ + if (vmwgfx_hosted_detect()) + return FALSE; #else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Driver was compiled without KMS- and 3D support.\n"); @@ -413,15 +424,19 @@ VMWareDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer data) { - CARD32 *flag; + uint32_t *flag; xorgRRModeMM *modemm; switch (op) { case GET_REQUIRED_HW_INTERFACES: - flag = (CARD32 *)data; + flag = (uint32_t *)data; if (flag) { +#ifdef BUILD_VMWGFX + vmwgfx_modify_flags(flag); +#else *flag = HW_IO | HW_MMIO; +#endif } return TRUE; case RR_GET_MODE_MM: diff --git a/src/vmware_bootstrap.h b/src/vmware_bootstrap.h index f72d298..b71d3cd 100644 --- a/src/vmware_bootstrap.h +++ b/src/vmware_bootstrap.h @@ -52,6 +52,8 @@ vmwlegacy_hookup(ScrnInfoPtr pScrn); #ifdef BUILD_VMWGFX void vmwgfx_hookup(ScrnInfoPtr pScrn); +void +vmwgfx_modify_flags(uint32_t *flags); #endif /* defined(BUILD_VMWGFX) */ #ifdef XFree86LOADER diff --git a/vmwgfx/Makefile.am b/vmwgfx/Makefile.am index 269d870..2b0380b 100644 --- a/vmwgfx/Makefile.am +++ b/vmwgfx/Makefile.am @@ -25,5 +25,8 @@ libvmwgfx_la_SOURCES = \ vmwgfx_ctrl.h \ vmwgfx_xa_composite.c \ vmwgfx_xa_surface.c \ + vmwgfx_hosted.c \ + vmwgfx_hosted.h \ + vmwgfx_hosted_priv.h \ wsbm_util.h endif diff --git a/vmwgfx/vmwgfx_dri2.c b/vmwgfx/vmwgfx_dri2.c index 4c74a6b..9e0bc71 100644 --- a/vmwgfx/vmwgfx_dri2.c +++ b/vmwgfx/vmwgfx_dri2.c @@ -43,6 +43,7 @@ #include "vmwgfx_saa.h" #include "wsbm_util.h" #include +#include "vmwgfx_hosted.h" #define VMWGFX_FD_PATH_LEN 80 @@ -381,6 +382,27 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, FreeScratchGC(gc); } +#if (DRI2INFOREC_VERSION >= 8 && DRI2INFOREC_VERSION < 10) +static int vmw_dri_auth_magic2(ScreenPtr pScreen, uint32_t magic) +{ + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + modesettingPtr ms = modesettingPTR(pScrn); + + return vmwgfx_hosted_dri_auth(ms->hdriver, ms->hosted, NULL, magic); +} +#endif + +#if (DRI2INFOREC_VERSION >= 10) +static int vmw_dri_auth_magic3(ClientPtr client, ScreenPtr pScreen, + uint32_t magic) +{ + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + modesettingPtr ms = modesettingPTR(pScrn); + + return vmwgfx_hosted_dri_auth(ms->hdriver, ms->hosted, client, magic); +} +#endif + Bool xorg_dri2_init(ScreenPtr pScreen) { @@ -391,6 +413,8 @@ xorg_dri2_init(ScreenPtr pScreen) char fdPath[VMWGFX_FD_PATH_LEN]; ssize_t numChar; + memset(&dri2info, 0, sizeof(dri2info)); + if (xf86LoaderCheckSymbol("DRI2Version")) { DRI2Version(&major, &minor); } else { @@ -427,6 +451,19 @@ xorg_dri2_init(ScreenPtr pScreen) dri2info.CopyRegion = dri2_copy_region; dri2info.Wait = NULL; +#if (DRI2INFOREC_VERSION >= 8 && DRI2INFOREC_VERSION < 10) + if (vmwgfx_is_hosted(ms->hdriver)) { + dri2info.version = 8; + dri2info.AuthMagic2 = vmw_dri_auth_magic2; + } +#endif +#if (DRI2INFOREC_VERSION >= 10) + if (vmwgfx_is_hosted(ms->hdriver)) { + dri2info.version = 10; + dri2info.AuthMagic3 = vmw_dri_auth_magic3; + } +#endif + return DRI2ScreenInit(pScreen, &dri2info); } diff --git a/vmwgfx/vmwgfx_driver.c b/vmwgfx/vmwgfx_driver.c index 4e28097..dc05b86 100644 --- a/vmwgfx/vmwgfx_driver.c +++ b/vmwgfx/vmwgfx_driver.c @@ -60,6 +60,7 @@ #include "vmwgfx_saa.h" #include "../src/vmware_bootstrap.h" #include "../src/vmware_common.h" +#include "vmwgfx_hosted.h" /* * We can't incude svga_types.h due to conflicting types for Bool. @@ -128,6 +129,12 @@ vmwgfx_hookup(ScrnInfoPtr pScrn) pScrn->ValidMode = drv_valid_mode; } +void +vmwgfx_modify_flags(CARD32 *flags) +{ + *flags &= ~(HW_IO); + vmwgfx_hosted_modify_flags(flags); +} /* * Internal function definitions */ @@ -243,18 +250,22 @@ drv_init_drm(ScrnInfoPtr pScrn) /* deal with server regeneration */ if (ms->fd < 0) { - char *BusID; - BusID = malloc(64); - sprintf(BusID, "PCI:%d:%d:%d", - ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), - ms->PciInfo->dev, ms->PciInfo->func - ); + ms->fd = vmwgfx_hosted_drm_fd(ms->hdriver, ms->hosted, ms->PciInfo); + + if (ms->fd < 0) { + char bus_id[64]; - ms->fd = drmOpen("vmwgfx", BusID); - ms->isMaster = TRUE; - free(BusID); + snprintf(bus_id, sizeof(bus_id), "PCI:%d:%d:%d", + ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), + ms->PciInfo->dev, ms->PciInfo->func + ); + + ms->fd = drmOpen("vmwgfx", bus_id); + ms->isMaster = TRUE; + + } if (ms->fd >= 0) { drmVersionPtr ver = drmGetVersion(ms->fd); @@ -333,14 +344,103 @@ vmwgfx_set_topology(ScrnInfoPtr pScrn, const char *topology, const char *info) return FALSE; } + +static Bool +vmwgfx_pre_init_mode(ScrnInfoPtr pScrn, int flags) +{ + modesettingPtr ms = modesettingPTR(pScrn); + Bool ret = TRUE; + + ms->from_dp = (xf86GetOptValBool(ms->Options, OPTION_DIRECT_PRESENTS, + &ms->direct_presents)) ? + X_CONFIG : X_DEFAULT; + + ms->from_hwp = (xf86GetOptValBool(ms->Options, OPTION_HW_PRESENTS, + &ms->only_hw_presents)) ? + X_CONFIG : X_DEFAULT; + + /* Allocate an xf86CrtcConfig */ + xf86CrtcConfigInit(pScrn, &crtc_config_funcs); + + /* get max width and height */ + { + drmModeResPtr res; + int max_width, max_height; + + res = drmModeGetResources(ms->fd); + max_width = res->max_width; + max_height = res->max_height; + + xf86CrtcSetSizeRange(pScrn, res->min_width, + res->min_height, max_width, max_height); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Min width %d, Max Width %d.\n", + res->min_width, max_width); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Min height %d, Max Height %d.\n", + res->min_height, max_height); + drmModeFreeResources(res); + } + + ms->SWCursor = FALSE; + if (!xf86ReturnOptValBool(ms->Options, OPTION_HW_CURSOR, TRUE)) { + ms->SWCursor = TRUE; + } + + if (xf86IsOptionSet(ms->Options, OPTION_GUI_LAYOUT)) { + char *topology = + xf86GetOptValString(ms->Options, OPTION_GUI_LAYOUT); + + ret = FALSE; + if (topology) { + ret = vmwgfx_set_topology(pScrn, topology, "gui"); + free(topology); + } + + } else if (xf86IsOptionSet(ms->Options, OPTION_STATIC_XINERAMA)) { + char *topology = + xf86GetOptValString(ms->Options, OPTION_STATIC_XINERAMA); + + ret = FALSE; + if (topology) { + ret = vmwgfx_set_topology(pScrn, topology, "static Xinerama"); + free(topology); + } + } + + if (!ret) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Falied parsing or setting " + "gui topology from config file.\n"); + + xorg_crtc_init(pScrn); + xorg_output_init(pScrn); + + if (!xf86InitialConfiguration(pScrn, TRUE)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + goto out_modes; + } + + if (pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No available modes.\n"); + goto out_modes; + } + + pScrn->currentMode = pScrn->modes; + + return TRUE; + + out_modes: + return FALSE; +} + static Bool drv_pre_init(ScrnInfoPtr pScrn, int flags) { modesettingPtr ms; rgb defaultWeight = { 0, 0, 0 }; + Gamma zeros = { 0.0, 0.0, 0.0 }; EntityInfoPtr pEnt; uint64_t cap; - Bool ret = TRUE; if (pScrn->numEntities != 1) return FALSE; @@ -374,9 +474,31 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index); xf86SetPrimInitDone(pScrn->entityList[0]); + ms->hdriver = vmwgfx_hosted_detect(); + ms->hosted = vmwgfx_hosted_create(ms->hdriver, pScrn); + if (ms->hdriver && !ms->hosted) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to set up compositor hosted environment.\n"); + goto out_err_bus; + } + + pScrn->monitor = pScrn->confScreen->monitor; + pScrn->progClock = TRUE; + pScrn->rgbBits = 8; + + if (!xf86SetDepthBpp + (pScrn, 0, 0, 0, + PreferConvert24to32 | SupportConvert24to32 | Support32bppFb)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set depth and bpp.\n"); + goto out_err_bus; + } + + if (!vmwgfx_hosted_pre_init(ms->hdriver, ms->hosted, flags)) + goto out_err_bus; + ms->fd = -1; if (!drv_init_drm(pScrn)) - goto out_err_bus; + goto out_no_drm; if (ms->drm_major != DRM_VERSION_MAJOR_REQUIRED || ms->drm_minor < DRM_VERSION_MINOR_REQUIRED) { @@ -397,17 +519,6 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) ms->check_fb_size = (vmwgfx_max_fb_size(ms->fd, &ms->max_fb_size) == 0); - pScrn->monitor = pScrn->confScreen->monitor; - pScrn->progClock = TRUE; - pScrn->rgbBits = 8; - - if (!xf86SetDepthBpp - (pScrn, 0, 0, 0, - PreferConvert24to32 | SupportConvert24to32 | Support32bppFb)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set depth and bpp.\n"); - goto out_depth; - } - if (vmwgfx_get_param(ms->fd, DRM_VMW_PARAM_HW_CAPS, &cap) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to detect device " "screen object capability.\n"); @@ -460,98 +571,23 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) X_CONFIG : X_PROBED; ms->direct_presents = FALSE; - ms->from_dp = xf86GetOptValBool(ms->Options, OPTION_DIRECT_PRESENTS, - &ms->direct_presents) ? - X_CONFIG : X_DEFAULT; - ms->only_hw_presents = FALSE; - ms->from_hwp = xf86GetOptValBool(ms->Options, OPTION_HW_PRESENTS, - &ms->only_hw_presents) ? - X_CONFIG : X_DEFAULT; - - /* Allocate an xf86CrtcConfig */ - xf86CrtcConfigInit(pScrn, &crtc_config_funcs); - - /* get max width and height */ - { - drmModeResPtr res; - int max_width, max_height; - - res = drmModeGetResources(ms->fd); - max_width = res->max_width; - max_height = res->max_height; - - xf86CrtcSetSizeRange(pScrn, res->min_width, - res->min_height, max_width, max_height); - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Min width %d, Max Width %d.\n", - res->min_width, max_width); - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Min height %d, Max Height %d.\n", - res->min_height, max_height); - drmModeFreeResources(res); - } - - - if (!xf86ReturnOptValBool(ms->Options, OPTION_HW_CURSOR, TRUE)) { - ms->SWCursor = TRUE; - } - - if (xf86IsOptionSet(ms->Options, OPTION_GUI_LAYOUT)) { - char *topology = - xf86GetOptValString(ms->Options, OPTION_GUI_LAYOUT); - - ret = FALSE; - if (topology) { - ret = vmwgfx_set_topology(pScrn, topology, "gui"); - free(topology); - } - - } else if (xf86IsOptionSet(ms->Options, OPTION_STATIC_XINERAMA)) { - char *topology = - xf86GetOptValString(ms->Options, OPTION_STATIC_XINERAMA); - - ret = FALSE; - if (topology) { - ret = vmwgfx_set_topology(pScrn, topology, "static Xinerama"); - free(topology); - } - } - - if (!ret) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Falied parsing or setting " - "gui topology from config file.\n"); - - xorg_crtc_init(pScrn); - xorg_output_init(pScrn); - - if (!xf86InitialConfiguration(pScrn, TRUE)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); - goto out_modes; - } - - /* - * If the driver can do gamma correction, it should call xf86SetGamma() here. - */ - { - Gamma zeros = { 0.0, 0.0, 0.0 }; - - if (!xf86SetGamma(pScrn, zeros)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set gamma.\n"); + ms->SWCursor = TRUE; + if (!vmwgfx_is_hosted(ms->hdriver)) { + if (!vmwgfx_pre_init_mode(pScrn, flags)) goto out_modes; - } + } else { + ms->from_dp = X_CONFIG; + ms->from_hwp = X_CONFIG; } - if (pScrn->modes == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No available modes.\n"); + xf86SetDpi(pScrn, 0, 0); + + if (!xf86SetGamma(pScrn, zeros)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set gamma.\n"); goto out_modes; } - pScrn->currentMode = pScrn->modes; - - /* Set display resolution */ - xf86SetDpi(pScrn, 0, 0); - /* Load the required sub modules */ if (!xf86LoadSubModule(pScrn, "fb")) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to load fb module.\n"); @@ -569,7 +605,10 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) free(ms->Options); out_depth: out_drm_version: - close(ms->fd); + if (!vmwgfx_is_hosted(ms->hdriver)) + close(ms->fd); + out_no_drm: + vmwgfx_hosted_destroy(ms->hdriver, ms->hosted); out_err_bus: drv_free_rec(pScrn); return FALSE; @@ -715,8 +754,10 @@ static void drv_block_handler(BLOCKHANDLER_ARGS_DECL) pScreen->BlockHandler(BLOCKHANDLER_ARGS); vmwgfx_swap(ms, pScreen, BlockHandler); - vmwgfx_flush_dri2(pScreen); - xorg_flush(pScreen); + if (vmwgfx_is_hosted(ms->hdriver)) + vmwgfx_hosted_post_damage(ms->hdriver, ms->hosted); + else + xorg_flush(pScreen); } static Bool @@ -742,7 +783,8 @@ drv_set_master(ScrnInfoPtr pScrn) { modesettingPtr ms = modesettingPTR(pScrn); - if (!ms->isMaster && drmSetMaster(ms->fd) != 0) { + if (!vmwgfx_is_hosted(ms->hdriver) && !ms->isMaster && + drmSetMaster(ms->fd) != 0) { if (errno == EINVAL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "drmSetMaster failed: 2.6.29 or newer kernel required for " @@ -996,6 +1038,12 @@ drv_screen_init(SCREEN_INIT_ARGS_DECL) } } + if (vmwgfx_is_hosted(ms->hdriver) && !ms->xat) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Can't run hosted without XA. Giving up.\n"); + return FALSE; + } + if (!vmwgfx_saa_init(pScreen, ms->fd, ms->xat, &xorg_flush, ms->direct_presents, ms->only_hw_presents, @@ -1039,6 +1087,12 @@ drv_screen_init(SCREEN_INIT_ARGS_DECL) xf86SetSilkenMouse(pScreen); miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + if (!vmwgfx_hosted_screen_init(ms->hdriver, ms->hosted, pScreen)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed hosted Screen init. Giving up.\n"); + return FALSE; + } + /* Need to extend HWcursor support to handle mask interleave */ if (!ms->SWCursor) { xf86_cursors_init(pScreen, 64, 64, @@ -1087,9 +1141,17 @@ static void drv_adjust_frame(ADJUST_FRAME_ARGS_DECL) { SCRN_INFO_PTR(arg); - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - xf86OutputPtr output = config->output[config->compat_output]; - xf86CrtcPtr crtc = output->crtc; + modesettingPtr ms = modesettingPTR(pScrn); + xf86CrtcConfigPtr config; + xf86OutputPtr output; + xf86CrtcPtr crtc; + + if (vmwgfx_is_hosted(ms->hdriver)) + return; + + config = XF86_CRTC_CONFIG_PTR(pScrn); + output = config->output[config->compat_output]; + crtc = output->crtc; if (crtc && crtc->enabled) { // crtc->funcs->set_mode_major(crtc, pScrn->currentMode, @@ -1103,6 +1165,9 @@ static void drv_free_screen(FREE_SCREEN_ARGS_DECL) { SCRN_INFO_PTR(arg); + modesettingPtr ms = modesettingPTR(pScrn); + + vmwgfx_hosted_destroy(ms->hdriver, ms->hosted); drv_free_rec(pScrn); } @@ -1112,14 +1177,16 @@ drv_leave_vt(VT_FUNC_ARGS_DECL) SCRN_INFO_PTR(arg); modesettingPtr ms = modesettingPTR(pScrn); - vmwgfx_cursor_bypass(ms->fd, 0, 0); - vmwgfx_disable_scanout(pScrn); + if (!vmwgfx_is_hosted(ms->hdriver)) { + vmwgfx_cursor_bypass(ms->fd, 0, 0); + vmwgfx_disable_scanout(pScrn); + } + vmwgfx_saa_drop_master(pScrn->pScreen); - if (drmDropMaster(ms->fd)) + if (!vmwgfx_is_hosted(ms->hdriver) && drmDropMaster(ms->fd)) xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "drmDropMaster failed: %s\n", strerror(errno)); - ms->isMaster = FALSE; pScrn->vtSema = FALSE; } @@ -1131,13 +1198,14 @@ static Bool drv_enter_vt(VT_FUNC_ARGS_DECL) { SCRN_INFO_PTR(arg); + modesettingPtr ms = modesettingPTR(pScrn); if (!drv_set_master(pScrn)) return FALSE; vmwgfx_saa_set_master(pScrn->pScreen); - if (!xf86SetDesiredModes(pScrn)) + if (!vmwgfx_is_hosted(ms->hdriver) && !xf86SetDesiredModes(pScrn)) return FALSE; return TRUE; @@ -1174,6 +1242,7 @@ drv_close_screen(CLOSE_SCREEN_ARGS_DECL) vmwgfx_unwrap(ms, pScrn, LeaveVT); vmwgfx_unwrap(ms, pScrn, AdjustFrame); vmwgfx_unwrap(ms, pScreen, CloseScreen); + vmwgfx_hosted_screen_close(ms->hdriver, ms->hosted); vmwgfx_unwrap(ms, pScreen, BlockHandler); vmwgfx_unwrap(ms, pScreen, CreateScreenResources); diff --git a/vmwgfx/vmwgfx_driver.h b/vmwgfx/vmwgfx_driver.h index f78a85f..c044a81 100644 --- a/vmwgfx/vmwgfx_driver.h +++ b/vmwgfx/vmwgfx_driver.h @@ -82,6 +82,8 @@ enum xorg_throttling_reason { THROTTLE_SWAP }; +struct vmwgfx_hosted; + typedef struct _modesettingRec { /* drm */ @@ -131,6 +133,8 @@ typedef struct _modesettingRec size_t max_fb_size; struct xa_tracker *xat; + const struct vmwgfx_hosted_driver *hdriver; + struct vmwgfx_hosted *hosted; #ifdef DRI2 Bool dri2_available; char dri2_device_name[VMWGFX_DRI_DEVICE_LEN]; diff --git a/vmwgfx/vmwgfx_hosted.c b/vmwgfx/vmwgfx_hosted.c new file mode 100644 index 0000000..b42d962 --- /dev/null +++ b/vmwgfx/vmwgfx_hosted.c @@ -0,0 +1,64 @@ +/* + * Copyright 2013 VMWare, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Author: Thomas Hellstrom + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "vmwgfx_hosted.h" +#include "vmwgfx_hosted_priv.h" + +/* + * Hook up hosted environments here. + */ + +/** + * vmwgfx_hosted_detect - Check whether we are hosted + * + * Check whether we are hosted by a compositor and + * in that case return a pointer to a valid struct vmwgfx_hosted_driver. + * If not hosted, return NULL. + */ +const struct vmwgfx_hosted_driver * +vmwgfx_hosted_detect(void) +{ + return NULL; +} + +/** + * vmwgfx_hosted_modify_flags - Modify driver flags if hosted. + * + * @flag: Pointer to the flag argument given to the vmware driver's + * DriverFunc function, when operation is GET_REQUIRED_HW_INTERFACES. + * + * Checks whether we are running hosted, and in that case modifies + * the flag according to the hosted environment's requirements. + */ +void +vmwgfx_hosted_modify_flags(uint32_t *flags) +{ +} diff --git a/vmwgfx/vmwgfx_hosted.h b/vmwgfx/vmwgfx_hosted.h new file mode 100644 index 0000000..8f3b243 --- /dev/null +++ b/vmwgfx/vmwgfx_hosted.h @@ -0,0 +1,257 @@ +/* + * Copyright 2013 VMWare, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Author: Thomas Hellstrom + */ + +#ifndef _VMWGFX_HOSTED_H +#define _VMWGFX_HOSTED_H + +#include +#include + + +/** + * struct vmwgfx_hosted - hosting environment private information. + * + * This struct is completely opaque to callers and should be defined + * by the hosting environment. + */ +struct vmwgfx_hosted; + +/** + * struct vmwgfx-hosted-driver - Driver for environments that we can run + * hosted under. + * + * @create: Initialize and create an opaque struct vmwgfx_hosted with + * environment private information. Should return NULL on failure. + * @destroy: Undo what's done in @create. + * @drm_fd: Return a file descriptor opened to DRM. + * @pre_init: Callback from vmwgfx preInit. + * @screen_init: Callback from vmwgfx screenInit. + * @screen_close: Callback from vmwgfx screenClose. + * @post_damage: Callback from vmwgfx blockHandler. This callback should + * instruct the hosting environment about damaged windows. + * @dri_auth: Authenticate a dri client. + */ +struct vmwgfx_hosted_driver { + struct vmwgfx_hosted *(*create)(ScrnInfoPtr); + void (*destroy)(struct vmwgfx_hosted *); + int (*drm_fd)(struct vmwgfx_hosted *, const struct pci_device *); + Bool (*pre_init)(struct vmwgfx_hosted *, int); + Bool (*screen_init)(struct vmwgfx_hosted *, ScreenPtr); + void (*screen_close)(struct vmwgfx_hosted *); + void (*post_damage)(struct vmwgfx_hosted *); + int (*dri_auth)(struct vmwgfx_hosted *, ClientPtr client, uint32_t magic); +}; + +extern const struct vmwgfx_hosted_driver *vmwgfx_hosted_detect(void); +extern void vmwgfx_hosted_modify_flags(uint32_t *flags); + +/** + * vmwgfx_is_hosted - Check whether we're running hosted. + * + * @driver: Pointer to a struct vmwgfx_hosted_driver as returned by + * vmwgfx_hosted_detect() + * + */ +static inline Bool +vmwgfx_is_hosted(const struct vmwgfx_hosted_driver *driver) +{ + return (driver != NULL); +} + +/** + * vmwgfx_hosted_create - Set up and initialize a struct vmwgfx_hosted + * + * @driver: Pointer to a struct vmwgfx_hosted_driver as returned by + * vmwgfx_hosted_detect() + * @pScrn: Pointer to a ScrnInfo structure, that has not been populated yet. + * + * Convenience wrapper around the hosted_driver function. + */ +static inline struct vmwgfx_hosted* +vmwgfx_hosted_create(const struct vmwgfx_hosted_driver *driver, + ScrnInfoPtr pScrn) +{ + if (!vmwgfx_is_hosted(driver)) + return NULL; + + return driver->create(pScrn); +} + +/** + * vmwgfx_hosted_destroy - free a struct vmwgfx_hosted and take down + * hosted environment. + * + * @driver: Pointer to a struct vmwgfx_hosted_driver as returned by + * vmwgfx_hosted_detect() + * @hosted: Pointer to a struct vmwgfx_hosted, as returned by + * vmwgfx_hosted_create() + * + * Convenience wrapper around the hosted_driver function. + */ +static inline void +vmwgfx_hosted_destroy(const struct vmwgfx_hosted_driver *driver, + struct vmwgfx_hosted *hosted) +{ + if (!vmwgfx_is_hosted(driver)) + return; + + driver->destroy(hosted); +} + +/** + * vmwgfx_hosted_drm_fd - Return a drm file descriptor + * + * @driver: Pointer to a struct vmwgfx_hosted_driver as returned by + * vmwgfx_hosted_detect() + * @hosted: Pointer to a struct vmwgfx_hosted, as returned by + * vmwgfx_hosted_create() + * @pci: Pointer to a valid struct pci_device, describing our device. + * + * Convenience wrapper around the hosted_driver function. Returns an + * invalid file descriptor if we're not hosted. + */ +static inline int +vmwgfx_hosted_drm_fd(const struct vmwgfx_hosted_driver *driver, + struct vmwgfx_hosted *hosted, + const struct pci_device *pci) +{ + if (!vmwgfx_is_hosted(driver)) + return -1; + + return driver->drm_fd(hosted, pci); +} + +/** + * vmwgfx_hosted_pre_init - Initiate preInit callback. + * + * @driver: Pointer to a struct vmwgfx_hosted_driver as returned by + * vmwgfx_hosted_detect() + * @hosted: Pointer to a struct vmwgfx_hosted, as returned by + * vmwgfx_hosted_create() + * @flags: Flags passed to the vmwgfx preInit function + * + * Convenience wrapper around the hosted_driver function. Returns TRUE + * (success) if not hosted. + */ +static inline Bool +vmwgfx_hosted_pre_init(const struct vmwgfx_hosted_driver *driver, + struct vmwgfx_hosted *hosted, int flags) +{ + if (!vmwgfx_is_hosted(driver)) + return TRUE; + + return driver->pre_init(hosted, flags); +} + +/** + * vmwgfx_hosted_screen_init - Initiate screenInit callback. + * + * @driver: Pointer to a struct vmwgfx_hosted_driver as returned by + * vmwgfx_hosted_detect() + * @hosted: Pointer to a struct vmwgfx_hosted, as returned by + * vmwgfx_hosted_create() + * @pScreen: ScreenPtr identifying the screen we're setting up. + * + * Convenience wrapper around the hosted_driver function. Returns TRUE + * (success) if not hosted. + */ +static inline Bool +vmwgfx_hosted_screen_init(const struct vmwgfx_hosted_driver *driver, + struct vmwgfx_hosted *hosted, ScreenPtr pScreen) +{ + if (!vmwgfx_is_hosted(driver)) + return TRUE; + + return driver->screen_init(hosted, pScreen); +} + +/** + * vmwgfx_hosted_screen_close - Initiate screenClose callback. + * + * @driver: Pointer to a struct vmwgfx_hosted_driver as returned by + * vmwgfx_hosted_detect() + * @hosted: Pointer to a struct vmwgfx_hosted, as returned by + * vmwgfx_hosted_create() + * + * Convenience wrapper around the hosted_driver function. + * Does nothing if not hosted. + */ +static inline void +vmwgfx_hosted_screen_close(const struct vmwgfx_hosted_driver *driver, + struct vmwgfx_hosted *hosted) +{ + if (!vmwgfx_is_hosted(driver)) + return; + + driver->screen_close(hosted); +} + +/** + * vmwgfx_hosted_post_damage - Inform the hosting environment about + * recent rendering + * + * @driver: Pointer to a struct vmwgfx_hosted_driver as returned by + * vmwgfx_hosted_detect() + * @hosted: Pointer to a struct vmwgfx_hosted, as returned by + * vmwgfx_hosted_create() + * + * Convenience wrapper around the hosted_driver function. + * Does nothing if not hosted. + */ +static inline void +vmwgfx_hosted_post_damage(const struct vmwgfx_hosted_driver *driver, + struct vmwgfx_hosted *hosted) +{ + if (!vmwgfx_is_hosted(driver)) + return; + + driver->post_damage(hosted); +} + +/** + * vmwgfx_hosted_dri_auth - Ask the hosting environment to authenticate a + * dri client. + * + * @driver: Pointer to a struct vmwgfx_hosted_driver as returned by + * vmwgfx_hosted_detect() + * @hosted: Pointer to a struct vmwgfx_hosted, as returned by + * vmwgfx_hosted_create() + * @client: The client to be authenticated + * @magic: The drm magic used for authentication + * + * Convenience wrapper around the hosted_driver function. + * Does nothing if not hosted. + */ +static inline int +vmwgfx_hosted_dri_auth(const struct vmwgfx_hosted_driver *driver, + struct vmwgfx_hosted *hosted, + ClientPtr client, + uint32_t magic) +{ + return driver->dri_auth(hosted, client, magic); +} +#endif /* _VMWGFX_HOSTED_H */ diff --git a/vmwgfx/vmwgfx_hosted_priv.h b/vmwgfx/vmwgfx_hosted_priv.h new file mode 100644 index 0000000..05ded25 --- /dev/null +++ b/vmwgfx/vmwgfx_hosted_priv.h @@ -0,0 +1,34 @@ +/* + * Copyright 2013 VMWare, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Author: Thomas Hellstrom + */ + +#ifndef _VMWGFX_HOSTED_PRIV_H_ +#define _VMWGFX_HOSTED_PRIV_H_ + +#include +#include "vmwgfx_hosted.h" + +#endif diff --git a/vmwgfx/vmwgfx_overlay.c b/vmwgfx/vmwgfx_overlay.c index 986dd06..c8c6bb9 100644 --- a/vmwgfx/vmwgfx_overlay.c +++ b/vmwgfx/vmwgfx_overlay.c @@ -64,6 +64,7 @@ typedef uint8_t uint8; #include "vmwgfx_drm.h" #include "vmwgfx_drmi.h" #include "vmwgfx_driver.h" +#include "vmwgfx_hosted.h" #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) @@ -287,6 +288,9 @@ vmw_video_init_adaptor(ScrnInfoPtr pScrn) DevUnion *dev_unions; uint32_t ntot, nfree; + if (vmwgfx_is_hosted(ms->hdriver)) + return NULL; + if (vmwgfx_num_streams(ms->fd, &ntot, &nfree) != 0) { debug_printf("No stream ioctl support\n"); return NULL; -- 2.7.4