static EGLBoolean dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp) { struct dri2_egl_display *dri2_dpy; drv->API.CreateWindowSurface = dri2_create_window_surface; drv->API.CreatePixmapSurface = dri2_create_pixmap_surface; drv->API.CreatePbufferSurface = dri2_create_pbuffer_surface; drv->API.DestroySurface = dri2_destroy_surface; drv->API.SwapBuffers = dri2_swap_buffers; drv->API.CopyBuffers = dri2_copy_buffers; drv->API.CreateImageKHR = dri2_x11_create_image_khr; drv->API.SwapBuffersRegionNOK = dri2_swap_buffers_region; drv->API.PostSubBufferNV = dri2_post_sub_buffer; drv->API.SwapInterval = dri2_swap_interval; dri2_dpy = calloc(1, sizeof *dri2_dpy); if (!dri2_dpy) return _eglError(EGL_BAD_ALLOC, "eglInitialize"); disp->DriverData = (void *) dri2_dpy; if (disp->PlatformDisplay == NULL) { dri2_dpy->conn = xcb_connect(0, 0); } else { dri2_dpy->conn = XGetXCBConnection((Display *) disp->PlatformDisplay); } if (xcb_connection_has_error(dri2_dpy->conn)) { _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed"); goto cleanup_dpy; } if (dri2_dpy->conn) { if (!dri2_connect(dri2_dpy)) goto cleanup_conn; } if (!dri2_load_driver(disp)) goto cleanup_conn; #ifdef O_CLOEXEC dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC); if (dri2_dpy->fd == -1 && errno == EINVAL) #endif { dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR); if (dri2_dpy->fd != -1) fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | FD_CLOEXEC); } if (dri2_dpy->fd == -1) { _eglLog(_EGL_WARNING, "DRI2: could not open %s (%s)", dri2_dpy->device_name, strerror(errno)); goto cleanup_driver; } if (dri2_dpy->conn) { if (!dri2_authenticate(disp)) goto cleanup_fd; } if (dri2_dpy->dri2_minor >= 1) { dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER; dri2_dpy->dri2_loader_extension.base.version = 3; dri2_dpy->dri2_loader_extension.getBuffers = dri2_get_buffers; dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer; dri2_dpy->dri2_loader_extension.getBuffersWithFormat = dri2_get_buffers_with_format; } else { dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER; dri2_dpy->dri2_loader_extension.base.version = 2; dri2_dpy->dri2_loader_extension.getBuffers = dri2_get_buffers; dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer; dri2_dpy->dri2_loader_extension.getBuffersWithFormat = NULL; } dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base; dri2_dpy->extensions[1] = &image_lookup_extension.base; dri2_dpy->extensions[2] = NULL; dri2_dpy->swap_available = (dri2_dpy->dri2_minor >= 2); dri2_dpy->invalidate_available = (dri2_dpy->dri2_minor >= 3); if (!dri2_create_screen(disp)) goto cleanup_fd; dri2_setup_swap_interval(dri2_dpy); disp->Extensions.KHR_image_pixmap = EGL_TRUE; disp->Extensions.NOK_swap_region = EGL_TRUE; disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE; disp->Extensions.NV_post_sub_buffer = EGL_TRUE; #ifdef HAVE_WAYLAND_PLATFORM disp->Extensions.WL_bind_wayland_display = EGL_TRUE; #endif if (dri2_dpy->conn) { if (!dri2_add_configs_for_visuals(dri2_dpy, disp)) goto cleanup_configs; } dri2_dpy->authenticate = dri2_x11_authenticate; /* we're supporting EGL 1.4 */ disp->VersionMajor = 1; disp->VersionMinor = 4; return EGL_TRUE; cleanup_configs: _eglCleanupDisplay(disp); dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); cleanup_fd: close(dri2_dpy->fd); cleanup_driver: dlclose(dri2_dpy->driver); cleanup_conn: if (disp->PlatformDisplay == NULL) xcb_disconnect(dri2_dpy->conn); cleanup_dpy: free(dri2_dpy); return EGL_FALSE; }
/* * Function: XvMCCreateContext * Description: Create a XvMC context for the given surface parameters. * Arguments: * display - Connection to the X server. * port - XvPortID to use as avertised by the X connection. * surface_type_id - Unique identifier for the Surface type. * width - Width of the surfaces. * height - Height of the surfaces. * flags - one or more of the following * XVMC_DIRECT - A direct rendered context is requested. * * Notes: surface_type_id and width/height parameters must match those * returned by XvMCListSurfaceTypes. * Returns: Status */ _X_EXPORT Status XvMCCreateContext(Display * display, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext * context) { Status ret; CARD32 *priv_data = NULL; struct intel_xvmc_hw_context *comm; int major, minor; int error_base; int event_base; int priv_count; /* Verify Obvious things first */ if (!display || !context) return BadValue; if (!(flags & XVMC_DIRECT)) { XVMC_ERR("Indirect Rendering not supported! Using Direct."); return BadValue; } /* Width, Height, and flags are checked against surface_type_id and port for validity inside the X server, no need to check here. */ context->surface_type_id = surface_type_id; context->width = (unsigned short)((width + 15) & ~15); context->height = (unsigned short)((height + 15) & ~15); context->flags = flags; context->port = port; if (!XvMCQueryExtension(display, &event_base, &error_base)) { XVMC_ERR("XvMCExtension is not available!"); return BadValue; } ret = XvMCQueryVersion(display, &major, &minor); if (ret) { XVMC_ERR ("XvMCQueryVersion Failed, unable to determine protocol version."); return ret; } /* XXX: major and minor could be checked in future for XvMC * protocol capability (i.e H.264/AVC decode available) */ /* Pass control to the X server to create a drm_context_t for us and validate the with/height and flags. */ if ((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) { XVMC_ERR("Unable to create XvMC Context."); return ret; } comm = (struct intel_xvmc_hw_context *)priv_data; if (xvmc_driver == NULL || xvmc_driver->type != comm->type) { switch (comm->type) { case XVMC_I915_MPEG2_MC: xvmc_driver = &i915_xvmc_mc_driver; break; case XVMC_I965_MPEG2_MC: xvmc_driver = &i965_xvmc_mc_driver; break; case XVMC_I965_MPEG2_VLD: xvmc_driver = &xvmc_vld_driver; break; case XVMC_I945_MPEG2_VLD: default: XVMC_ERR("unimplemented xvmc type %d", comm->type); XFree(priv_data); priv_data = NULL; return BadValue; } } if (xvmc_driver == NULL || xvmc_driver->type != comm->type) { XVMC_ERR("fail to load xvmc driver for type %d\n", comm->type); return BadValue; } XVMC_INFO("decoder type is %s", intel_xvmc_decoder_string(comm->type)); /* check DRI2 */ ret = Success; xvmc_driver->fd = -1; ret = dri2_connect(display); if (ret != Success) { XFree(priv_data); context->privData = NULL; if (xvmc_driver->fd >= 0) close(xvmc_driver->fd); xvmc_driver = NULL; return ret; } if ((xvmc_driver->bufmgr = intel_bufmgr_gem_init(xvmc_driver->fd, 1024 * 64)) == NULL) { XVMC_ERR("Can't init bufmgr\n"); return BadAlloc; } drm_intel_bufmgr_gem_enable_reuse(xvmc_driver->bufmgr); /* call driver hook. * driver hook should free priv_data after return if success.*/ ret = (xvmc_driver->create_context) (display, context, priv_count, priv_data); if (ret) { XVMC_ERR("driver create context failed\n"); XFree(priv_data); context->privData = NULL; xvmc_driver = NULL; return ret; } pthread_mutex_init(&xvmc_driver->ctxmutex, NULL); intelInitBatchBuffer(); intel_xvmc_dump_open(); return Success; }