From 3dd4b6420f686b0147d5b8136268cc63196e253b Mon Sep 17 00:00:00 2001 From: marha Date: Sun, 9 Mar 2014 21:32:55 +0100 Subject: fontconfig mesa xserver git update 9 Mar 2014 xserver commit 1c61d38528a573caadee2468ee59ea558c822e09 fontconfig commit f8ccf379eb1092592ae0b65deb563c5491f69de9 mesa commit 897f40f25d21af678b1b67c1a68c4a6722d19983 --- xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c | 331 +++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c (limited to 'xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c') 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 +#include +#include +#undef Xcalloc +#undef Xrealloc +#undef Xfree +#include +#include +#include +#include +#include "ephyr_glamor_glx.h" +#include "os.h" +#include + +/** @{ + * + * 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); +} -- cgit v1.2.3