diff options
Diffstat (limited to 'xorg-server/hw/kdrive')
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/Makefile.am | 20 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyr.c | 45 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyr.h | 14 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c | 331 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.h | 73 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyrinit.c | 14 | ||||
-rwxr-xr-x[-rw-r--r--] | xorg-server/hw/kdrive/ephyr/hostx.c | 131 |
7 files changed, 612 insertions, 16 deletions
diff --git a/xorg-server/hw/kdrive/ephyr/Makefile.am b/xorg-server/hw/kdrive/ephyr/Makefile.am index 6b790fddd..040993ce0 100644 --- a/xorg-server/hw/kdrive/ephyr/Makefile.am +++ b/xorg-server/hw/kdrive/ephyr/Makefile.am @@ -27,12 +27,20 @@ AM_CPPFLAGS = \ @XEPHYR_INCS@ \ @XEPHYR_CFLAGS@ \ -I$(top_srcdir) \ + -I$(top_srcdir)/glamor \ -I$(top_srcdir)/exa if XV XV_SRCS = ephyrvideo.c endif +if GLAMOR +GLAMOR_SRCS = \ + ephyr_glamor_glx.c \ + ephyr_glamor_glx.h \ + () +endif + if DRI DRI_SRCS = \ ephyrdriext.c \ @@ -59,14 +67,24 @@ Xephyr_SOURCES = \ hostx.h \ $(XV_SRCS) \ $(DRI_SRCS) \ + $(GLAMOR_SRCS) \ $() +if GLAMOR +AM_CPPFLAGS += $(XLIB_CFLAGS) +XEPHYR_GLAMOR_LIB = \ + $(top_builddir)/glamor/libglamor.la \ + $(top_builddir)/glamor/libglamor_egl_stubs.la \ + $() +endif + Xephyr_LDADD = \ $(top_builddir)/exa/libexa.la \ + $(XEPHYR_GLAMOR_LIB) \ @KDRIVE_LIBS@ \ @XEPHYR_LIBS@ -Xephyr_DEPENDENCIES = @KDRIVE_LOCAL_LIBS@ +Xephyr_DEPENDENCIES = @KDRIVE_LOCAL_LIBS@ $(XEPHYR_GLAMOR_LIB) Xephyr_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c index ba22ba225..42629692b 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyr.c +++ b/xorg-server/hw/kdrive/ephyr/ephyr.c @@ -43,9 +43,15 @@ #include "ephyrglxext.h" #endif /* XF86DRI */ +#ifdef GLAMOR +#include "glamor.h" +#endif +#include "ephyr_glamor_glx.h" + #include "xkbsrv.h" extern int KdTsPhyScreen; +extern Bool ephyr_glamor; KdKeyboardInfo *ephyrKbd; KdPointerInfo *ephyrMouse; @@ -329,15 +335,19 @@ ephyrInternalDamageRedisplay(ScreenPtr pScreen) int nbox; BoxPtr pbox; - nbox = RegionNumRects(pRegion); - pbox = RegionRects(pRegion); - - while (nbox--) { - hostx_paint_rect(screen, - pbox->x1, pbox->y1, - pbox->x1, pbox->y1, - pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); - pbox++; + if (ephyr_glamor) { + ephyr_glamor_damage_redisplay(scrpriv->glamor, pRegion); + } else { + nbox = RegionNumRects(pRegion); + pbox = RegionRects(pRegion); + + while (nbox--) { + hostx_paint_rect(screen, + pbox->x1, pbox->y1, + pbox->x1, pbox->y1, + pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); + pbox++; + } } DamageEmpty(scrpriv->pDamage); } @@ -665,6 +675,7 @@ ephyrInitScreen(ScreenPtr pScreen) return TRUE; } + Bool ephyrFinishInitScreen(ScreenPtr pScreen) { @@ -682,6 +693,12 @@ ephyrFinishInitScreen(ScreenPtr pScreen) return TRUE; } +/** + * Called by kdrive after calling down the + * pScreen->CreateScreenResources() chain, this gives us a chance to + * make any pixmaps after the screen and all extensions have been + * initialized. + */ Bool ephyrCreateResources(ScreenPtr pScreen) { @@ -696,8 +713,13 @@ ephyrCreateResources(ScreenPtr pScreen) return KdShadowSet(pScreen, scrpriv->randr, ephyrShadowUpdate, ephyrWindowLinear); - else + else { +#ifdef GLAMOR + if (ephyr_glamor) + ephyr_glamor_create_screen_resources(pScreen); +#endif return ephyrSetInternalDamage(pScreen); + } } void @@ -1212,6 +1234,9 @@ ephyrPoll(void) break; } + if (ephyr_glamor) + ephyr_glamor_process_event(xev); + free(xev); } } diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.h b/xorg-server/hw/kdrive/ephyr/ephyr.h index d66c76e1e..386143eff 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyr.h +++ b/xorg-server/hw/kdrive/ephyr/ephyr.h @@ -82,6 +82,12 @@ typedef struct _ephyrScrPriv { KdScreenInfo *screen; int mynum; /* Screen number */ + + /** + * Per-screen Xlib-using state for glamor (private to + * ephyr_glamor_glx.c) + */ + struct ephyr_glamor *glamor; } EphyrScrPriv; extern KdCardFuncs ephyrFuncs; @@ -207,6 +213,14 @@ void void ephyrDrawFini(ScreenPtr pScreen); +/* hostx.c glamor support */ +Bool ephyr_glamor_init(ScreenPtr pScreen); +Bool ephyr_glamor_create_screen_resources(ScreenPtr pScreen); +void ephyr_glamor_enable(ScreenPtr pScreen); +void ephyr_glamor_disable(ScreenPtr pScreen); +void ephyr_glamor_fini(ScreenPtr pScreen); +void ephyr_glamor_host_paint_rect(ScreenPtr pScreen); + /*ephyvideo.c*/ Bool ephyrInitVideo(ScreenPtr pScreen); diff --git a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c new file mode 100644 index 000000000..d56907fe7 --- /dev/null +++ b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c @@ -0,0 +1,331 @@ +/* + * Copyright © 2013 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +/** @file ephyr_glamor_glx.c + * + * Separate file for hiding Xlib and GLX-using parts of xephyr from + * the rest of the server-struct-aware build. + */ + +#include <stdlib.h> +#include <X11/Xlib.h> +#include <X11/Xlibint.h> +#undef Xcalloc +#undef Xrealloc +#undef Xfree +#include <X11/Xlib-xcb.h> +#include <xcb/xcb_aux.h> +#include <pixman.h> +#include <epoxy/glx.h> +#include "ephyr_glamor_glx.h" +#include "os.h" +#include <X11/Xproto.h> + +/** @{ + * + * global state for Xephyr with glamor. + * + * Xephyr can render with multiple windows, but all the windows have + * to be on the same X connection and all have to have the same + * visual. + */ +static Display *dpy; +static XVisualInfo *visual_info; +static GLXFBConfig fb_config; +/** @} */ + +/** + * Per-screen state for Xephyr with glamor. + */ +struct ephyr_glamor { + GLXContext ctx; + Window win; + GLXWindow glx_win; + + GLuint tex; + + GLuint texture_shader; + GLuint texture_shader_position_loc; + GLuint texture_shader_texcoord_loc; +}; + +static GLint +ephyr_glamor_compile_glsl_prog(GLenum type, const char *source) +{ + GLint ok; + GLint prog; + + prog = glCreateShader(type); + glShaderSource(prog, 1, (const GLchar **) &source, NULL); + glCompileShader(prog); + glGetShaderiv(prog, GL_COMPILE_STATUS, &ok); + if (!ok) { + GLchar *info; + GLint size; + + glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size); + info = malloc(size); + if (info) { + glGetShaderInfoLog(prog, size, NULL, info); + ErrorF("Failed to compile %s: %s\n", + type == GL_FRAGMENT_SHADER ? "FS" : "VS", info); + ErrorF("Program source:\n%s", source); + free(info); + } + else + ErrorF("Failed to get shader compilation info.\n"); + FatalError("GLSL compile failure\n"); + } + + return prog; +} + +static GLuint +ephyr_glamor_build_glsl_prog(GLuint vs, GLuint fs) +{ + GLint ok; + GLuint prog; + + prog = glCreateProgram(); + glAttachShader(prog, vs); + glAttachShader(prog, fs); + + glLinkProgram(prog); + glGetProgramiv(prog, GL_LINK_STATUS, &ok); + if (!ok) { + GLchar *info; + GLint size; + + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size); + info = malloc(size); + + glGetProgramInfoLog(prog, size, NULL, info); + ErrorF("Failed to link: %s\n", info); + FatalError("GLSL link failure\n"); + } + + return prog; +} + +static void +ephyr_glamor_setup_texturing_shader(struct ephyr_glamor *glamor) +{ + const char *vs_source = + "attribute vec2 texcoord;\n" + "attribute vec2 position;\n" + "varying vec2 t;\n" + "\n" + "void main()\n" + "{\n" + " t = texcoord;\n" + " gl_Position = vec4(position, 0, 1);\n" + "}\n"; + + const char *fs_source = + "varying vec2 t;\n" + "uniform sampler2D s; /* initially 0 */\n" + "\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(s, t);\n" + "}\n"; + + GLuint fs, vs, prog; + + vs = ephyr_glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); + fs = ephyr_glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source); + prog = ephyr_glamor_build_glsl_prog(vs, fs); + + glamor->texture_shader = prog; + glamor->texture_shader_position_loc = glGetAttribLocation(prog, "position"); + assert(glamor->texture_shader_position_loc != -1); + glamor->texture_shader_texcoord_loc = glGetAttribLocation(prog, "texcoord"); + assert(glamor->texture_shader_texcoord_loc != -1); +} + +xcb_connection_t * +ephyr_glamor_connect(void) +{ + dpy = XOpenDisplay(NULL); + if (!dpy) + return NULL; + + XSetEventQueueOwner(dpy, XCBOwnsEventQueue); + + return XGetXCBConnection(dpy); +} + +void +ephyr_glamor_set_texture(struct ephyr_glamor *glamor, uint32_t tex) +{ + glamor->tex = tex; +} + +void +ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor, + struct pixman_region16 *damage) +{ + /* Redraw the whole screen, since glXSwapBuffers leaves the back + * buffer undefined. + */ + static const float position[] = { + -1, -1, + 1, -1, + 1, 1, + -1, 1, + }; + static const float texcoords[] = { + 0, 1, + 1, 1, + 1, 0, + 0, 0, + }; + + glXMakeCurrent(dpy, glamor->glx_win, glamor->ctx); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glUseProgram(glamor->texture_shader); + + glVertexAttribPointer(glamor->texture_shader_position_loc, + 2, GL_FLOAT, FALSE, 0, position); + glVertexAttribPointer(glamor->texture_shader_texcoord_loc, + 2, GL_FLOAT, FALSE, 0, texcoords); + glEnableVertexAttribArray(glamor->texture_shader_position_loc); + glEnableVertexAttribArray(glamor->texture_shader_texcoord_loc); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, glamor->tex); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableVertexAttribArray(glamor->texture_shader_position_loc); + glDisableVertexAttribArray(glamor->texture_shader_texcoord_loc); + + glXSwapBuffers(dpy, glamor->glx_win); +} + +/** + * Xlib-based handling of xcb events for glamor. + * + * We need to let the Xlib event filtering run on the event so that + * Mesa's dri2_glx.c userspace event mangling gets run, and we + * correctly get our invalidate events propagated into the driver. + */ +void +ephyr_glamor_process_event(xcb_generic_event_t *xev) +{ + + uint32_t response_type = xev->response_type & 0x7f; + /* Note the types on wire_to_event: there's an Xlib XEvent (with + * the broken types) that it returns, and a protocol xEvent that + * it inspects. + */ + Bool (*wire_to_event)(Display *dpy, XEvent *ret, xEvent *event); + + XLockDisplay(dpy); + /* Set the event handler to NULL to get access to the current one. */ + wire_to_event = XESetWireToEvent(dpy, response_type, NULL); + if (wire_to_event) { + XEvent processed_event; + + /* OK they had an event handler. Plug it back in, and call + * through to it. + */ + XESetWireToEvent(dpy, response_type, wire_to_event); + xev->sequence = LastKnownRequestProcessed(dpy); + wire_to_event(dpy, &processed_event, (xEvent *)xev); + } + XUnlockDisplay(dpy); +} + +struct ephyr_glamor * +ephyr_glamor_glx_screen_init(xcb_window_t win) +{ + GLXContext ctx; + struct ephyr_glamor *glamor; + GLXWindow glx_win; + + glamor = calloc(1, sizeof(struct ephyr_glamor)); + if (!glamor) { + FatalError("malloc"); + return NULL; + } + + glx_win = glXCreateWindow(dpy, fb_config, win, NULL); + + ctx = glXCreateContext(dpy, visual_info, NULL, True); + if (ctx == NULL) + FatalError("glXCreateContext failed\n"); + + if (!glXMakeCurrent(dpy, glx_win, ctx)) + FatalError("glXMakeCurrent failed\n"); + + glamor->ctx = ctx; + glamor->win = win; + glamor->glx_win = glx_win; + ephyr_glamor_setup_texturing_shader(glamor); + + return glamor; +} + +void +ephyr_glamor_glx_screen_fini(struct ephyr_glamor *glamor) +{ + glXMakeCurrent(dpy, None, NULL); + glXDestroyContext(dpy, glamor->ctx); + glXDestroyWindow(dpy, glamor->glx_win); + + free(glamor); +} + +xcb_visualtype_t * +ephyr_glamor_get_visual(void) +{ + xcb_screen_t *xscreen = + xcb_aux_get_screen(XGetXCBConnection(dpy), DefaultScreen(dpy)); + int attribs[] = { + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, 1, + None + }; + int event_base = 0, error_base = 0, nelements; + GLXFBConfig *fbconfigs; + + if (!glXQueryExtension (dpy, &error_base, &event_base)) + FatalError("Couldn't find GLX extension\n"); + + fbconfigs = glXChooseFBConfig(dpy, DefaultScreen(dpy), attribs, &nelements); + if (!nelements) + FatalError("Couldn't choose an FBConfig\n"); + fb_config = fbconfigs[0]; + free(fbconfigs); + + visual_info = glXGetVisualFromFBConfig(dpy, fb_config); + if (visual_info == NULL) + FatalError("Couldn't get RGB visual\n"); + + return xcb_aux_find_visual_by_id(xscreen, visual_info->visualid); +} diff --git a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.h b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.h new file mode 100644 index 000000000..8995e1eca --- /dev/null +++ b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.h @@ -0,0 +1,73 @@ +/* + * Copyright © 2013 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +/** + * ephyr_glamor_glx.h + * + * Prototypes exposed by ephyr_glamor_glx.c, without including any + * server headers. + */ + +#include <xcb/xcb.h> +#include "dix-config.h" + +struct ephyr_glamor; +struct pixman_region16; + +xcb_connection_t * +ephyr_glamor_connect(void); + +void +ephyr_glamor_set_texture(struct ephyr_glamor *ephyr_glamor, uint32_t tex); + +xcb_visualtype_t * +ephyr_glamor_get_visual(void); + +struct ephyr_glamor * +ephyr_glamor_glx_screen_init(xcb_window_t win); + +void +ephyr_glamor_glx_screen_fini(struct ephyr_glamor *glamor); + +#ifdef GLAMOR +void +ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor, + struct pixman_region16 *damage); + +void +ephyr_glamor_process_event(xcb_generic_event_t *xev); + +#else /* !GLAMOR */ + +static inline void +ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor, + struct pixman_region16 *damage) +{ +} + +static inline void +ephyr_glamor_process_event(xcb_generic_event_t *xev) +{ +} + +#endif /* !GLAMOR */ diff --git a/xorg-server/hw/kdrive/ephyr/ephyrinit.c b/xorg-server/hw/kdrive/ephyr/ephyrinit.c index 20e8033a9..5b8d09ff0 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrinit.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrinit.c @@ -35,6 +35,7 @@ extern Bool EphyrWantGrayScale; extern Bool EphyrWantResize; extern Bool kdHasPointer; extern Bool kdHasKbd; +extern Bool ephyr_glamor; #ifdef GLXEXT extern Bool ephyrNoDRI; @@ -139,6 +140,9 @@ ddxUseMsg(void) ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n"); ErrorF("-grayscale Simulate 8bit grayscale\n"); ErrorF("-resizeable Make Xephyr windows resizeable\n"); +#ifdef GLAMOR + ErrorF("-glamor Enable 2D acceleration using glamor\n"); +#endif ErrorF ("-fakexa Simulate acceleration using software rendering\n"); ErrorF("-verbosity <level> Set log verbosity level\n"); @@ -244,6 +248,16 @@ ddxProcessArgument(int argc, char **argv, int i) EphyrWantResize = 1; return 1; } +#ifdef GLAMOR + else if (!strcmp (argv[i], "-glamor")) { + ephyr_glamor = TRUE; + ephyrFuncs.initAccel = ephyr_glamor_init; + ephyrFuncs.enableAccel = ephyr_glamor_enable; + ephyrFuncs.disableAccel = ephyr_glamor_disable; + ephyrFuncs.finiAccel = ephyr_glamor_fini; + return 1; + } +#endif else if (!strcmp(argv[i], "-fakexa")) { ephyrFuncs.initAccel = ephyrDrawInit; ephyrFuncs.enableAccel = ephyrDrawEnable; diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c index dcf7af006..1c3b57477 100644..100755 --- a/xorg-server/hw/kdrive/ephyr/hostx.c +++ b/xorg-server/hw/kdrive/ephyr/hostx.c @@ -36,6 +36,7 @@ #include <string.h> /* for memset */ #include <errno.h> #include <time.h> +#include <err.h> #ifndef _MSC_VER #include <sys/ipc.h> @@ -56,6 +57,11 @@ #include <xcb/xf86dri.h> #include <xcb/glx.h> #endif /* XF86DRI */ +#ifdef GLAMOR +#include <epoxy/gl.h> +#include "glamor.h" +#include "ephyr_glamor_glx.h" +#endif #include "ephyrlog.h" #include "ephyr.h" @@ -92,6 +98,7 @@ extern Bool EphyrWantResize; char *ephyrResName = NULL; int ephyrResNameFromCmd = 0; char *ephyrTitle = NULL; +Bool ephyr_glamor = FALSE; static void hostx_set_fullscreen_hint(void); @@ -308,7 +315,12 @@ hostx_init(void) | XCB_EVENT_MASK_STRUCTURE_NOTIFY; EPHYR_DBG("mark"); - HostX.conn = xcb_connect(NULL, &HostX.screen); +#ifdef GLAMOR + if (ephyr_glamor) + HostX.conn = ephyr_glamor_connect(); + else +#endif + HostX.conn = xcb_connect(NULL, &HostX.screen); if (xcb_connection_has_error(HostX.conn)) { fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n"); exit(1); @@ -318,7 +330,12 @@ hostx_init(void) HostX.winroot = xscreen->root; HostX.gc = xcb_generate_id(HostX.conn); HostX.depth = xscreen->root_depth; - HostX.visual = xcb_aux_find_visual_by_id(xscreen, xscreen->root_visual); +#ifdef GLAMOR + if (ephyr_glamor) + HostX.visual = ephyr_glamor_get_visual(); + else +#endif + HostX.visual = xcb_aux_find_visual_by_id(xscreen,xscreen->root_visual); xcb_create_gc(HostX.conn, HostX.gc, HostX.winroot, 0, NULL); cookie_WINDOW_STATE = xcb_intern_atom(HostX.conn, FALSE, @@ -656,7 +673,7 @@ hostx_screen_init(KdScreenInfo *screen, } } - if (HostX.have_shm) { + if (!ephyr_glamor && HostX.have_shm) { #ifdef _MSC_VER __asm int 3; #else @@ -695,7 +712,7 @@ __asm int 3; #endif } - if (!shm_success) { + if (!ephyr_glamor && !shm_success) { EPHYR_DBG("Creating image %dx%d for screen scrpriv=%p\n", width, buffer_height, scrpriv); scrpriv->ximg = xcb_image_create_native(HostX.conn, @@ -729,7 +746,11 @@ __asm int 3; scrpriv->win_width = width; scrpriv->win_height = height; - if (host_depth_matches_server(scrpriv)) { + if (ephyr_glamor) { + *bytes_per_line = 0; + *bits_per_pixel = 0; + return NULL; + } else if (host_depth_matches_server(scrpriv)) { *bytes_per_line = scrpriv->ximg->stride; *bits_per_pixel = scrpriv->ximg->bpp; @@ -760,6 +781,23 @@ hostx_paint_rect(KdScreenInfo *screen, EPHYR_DBG("painting in screen %d\n", scrpriv->mynum); +#ifdef GLAMOR + if (ephyr_glamor) { + BoxRec box; + RegionRec region; + + box.x1 = dx; + box.y1 = dy; + box.x2 = dx + width; + box.y2 = dy + height; + + RegionInit(®ion, &box, 1); + ephyr_glamor_damage_redisplay(scrpriv->glamor, ®ion); + RegionUninit(®ion); + return; + } +#endif + /* * Copy the image data updated by the shadow layer * on to the window @@ -1196,3 +1234,86 @@ hostx_get_resource_id_peer(int a_local_resource_id, int *a_remote_resource_id) } #endif /* XF86DRI */ + +#ifdef GLAMOR +Bool +ephyr_glamor_init(ScreenPtr screen) +{ + KdScreenPriv(screen); + KdScreenInfo *kd_screen = pScreenPriv->screen; + EphyrScrPriv *scrpriv = kd_screen->driver; + + scrpriv->glamor = ephyr_glamor_glx_screen_init(scrpriv->win); + + glamor_init(screen, + GLAMOR_USE_SCREEN | + GLAMOR_USE_PICTURE_SCREEN | + GLAMOR_INVERTED_Y_AXIS); + + return TRUE; +} + +Bool +ephyr_glamor_create_screen_resources(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *kd_screen = pScreenPriv->screen; + EphyrScrPriv *scrpriv = kd_screen->driver; + PixmapPtr screen_pixmap; + uint32_t tex; + + if (!ephyr_glamor) + return TRUE; + + if (!glamor_glyphs_init(pScreen)) + return FALSE; + + /* kdrive's fbSetupScreen() told mi to have + * miCreateScreenResources() (which is called before this) make a + * scratch pixmap wrapping ephyr-glamor's NULL + * KdScreenInfo->fb.framebuffer. + * + * We want a real (texture-based) screen pixmap at this point. + * This is what glamor will render into, and we'll then texture + * out of that into the host's window to present the results. + * + * Thus, delete the current screen pixmap, and put a fresh one in. + */ + screen_pixmap = pScreen->GetScreenPixmap(pScreen); + pScreen->DestroyPixmap(screen_pixmap); + + screen_pixmap = pScreen->CreatePixmap(pScreen, + pScreen->width, + pScreen->height, + pScreen->rootDepth, 0); + pScreen->SetScreenPixmap(screen_pixmap); + + /* Tell the GLX code what to GL texture to read from. */ + tex = glamor_get_pixmap_texture(screen_pixmap); + ephyr_glamor_set_texture(scrpriv->glamor, tex); + + return TRUE; +} + +void +ephyr_glamor_enable(ScreenPtr screen) +{ +} + +void +ephyr_glamor_disable(ScreenPtr screen) +{ +} + +void +ephyr_glamor_fini(ScreenPtr screen) +{ + KdScreenPriv(screen); + KdScreenInfo *kd_screen = pScreenPriv->screen; + EphyrScrPriv *scrpriv = kd_screen->driver; + + glamor_fini(screen); + ephyr_glamor_glx_screen_fini(scrpriv->glamor); + scrpriv->glamor = NULL; +} +#endif |