aboutsummaryrefslogtreecommitdiff
path: root/xorg-server
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server')
-rw-r--r--xorg-server/Xi/exevents.c2
-rw-r--r--xorg-server/glamor/glamor.c37
-rw-r--r--xorg-server/glamor/glamor.h19
-rw-r--r--xorg-server/glamor/glamor_addtraps.c2
-rw-r--r--xorg-server/glamor/glamor_copyarea.c19
-rw-r--r--xorg-server/glamor/glamor_copyplane.c15
-rw-r--r--xorg-server/glamor/glamor_core.c65
-rw-r--r--xorg-server/glamor/glamor_egl.c129
-rw-r--r--xorg-server/glamor/glamor_fbo.c2
-rw-r--r--xorg-server/glamor/glamor_fill.c74
-rw-r--r--xorg-server/glamor/glamor_fillspans.c11
-rw-r--r--xorg-server/glamor/glamor_getimage.c2
-rw-r--r--xorg-server/glamor/glamor_getspans.c2
-rw-r--r--xorg-server/glamor/glamor_glx.c8
-rw-r--r--xorg-server/glamor/glamor_glyphblt.c251
-rw-r--r--xorg-server/glamor/glamor_glyphs.c21
-rw-r--r--xorg-server/glamor/glamor_gradient.c14
-rw-r--r--xorg-server/glamor/glamor_picture.c4
-rw-r--r--xorg-server/glamor/glamor_pixmap.c20
-rw-r--r--xorg-server/glamor/glamor_polyfillrect.c11
-rw-r--r--xorg-server/glamor/glamor_polylines.c28
-rw-r--r--xorg-server/glamor/glamor_priv.h56
-rw-r--r--xorg-server/glamor/glamor_putimage.c197
-rw-r--r--xorg-server/glamor/glamor_render.c38
-rw-r--r--xorg-server/glamor/glamor_setspans.c12
-rw-r--r--xorg-server/glamor/glamor_tile.c4
-rw-r--r--xorg-server/glamor/glamor_trapezoid.c6
-rw-r--r--xorg-server/glamor/glamor_triangles.c15
-rw-r--r--xorg-server/glamor/glamor_utils.h33
-rw-r--r--xorg-server/glamor/glamor_xv.c3
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c16
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.h10
-rw-r--r--xorg-server/hw/kdrive/ephyr/hostx.c7
-rw-r--r--xorg-server/include/input.h6
-rw-r--r--xorg-server/include/xkbsrv.h11
-rw-r--r--xorg-server/miext/sync/misyncstr.h1
-rw-r--r--xorg-server/xkb/ddxLoad.c244
-rw-r--r--xorg-server/xkb/xkb.c16
-rw-r--r--xorg-server/xkb/xkbInit.c42
-rw-r--r--xorg-server/xkb/xkbUtils.c37
40 files changed, 887 insertions, 603 deletions
diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c
index e9f670ec5..9c207eb23 100644
--- a/xorg-server/Xi/exevents.c
+++ b/xorg-server/Xi/exevents.c
@@ -230,7 +230,7 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
mk->sourceid = device->id;
- if (!XkbCopyDeviceKeymap(master, device))
+ if (!XkbDeviceApplyKeymap(master, device->key->xkbInfo->desc))
FatalError("Couldn't pivot keymap from device to core!\n");
}
diff --git a/xorg-server/glamor/glamor.c b/xorg-server/glamor/glamor.c
index e85617927..0f7d68b70 100644
--- a/xorg-server/glamor/glamor.c
+++ b/xorg-server/glamor/glamor.c
@@ -271,6 +271,29 @@ glamor_set_debug_level(int *debug_level)
int glamor_debug_level;
+/**
+ * Creates any pixmaps used internally by glamor, since those can't be
+ * allocated at ScreenInit time.
+ */
+static Bool
+glamor_create_screen_resources(ScreenPtr screen)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ Bool ret = TRUE;
+
+ screen->CreateScreenResources =
+ glamor_priv->saved_procs.create_screen_resources;
+ if (screen->CreateScreenResources)
+ ret = screen->CreateScreenResources(screen);
+ screen->CreateScreenResources = glamor_create_screen_resources;
+
+ if (!glamor_realize_glyph_caches(screen)) {
+ ErrorF("Failed to initialize glyph cache\n");
+ ret = FALSE;
+ }
+
+ return ret;
+}
/** Set up glamor for an already-configured GL context. */
Bool
@@ -290,6 +313,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
if (glamor_priv == NULL)
return FALSE;
+ glamor_priv->flags = flags;
if (flags & GLAMOR_INVERTED_Y_AXIS) {
glamor_priv->yInverted = TRUE;
}
@@ -349,6 +373,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
}
}
+ glamor_priv->has_khr_debug = glamor_gl_has_extension("GL_KHR_debug");
glamor_priv->has_pack_invert =
glamor_gl_has_extension("GL_MESA_pack_invert");
glamor_priv->has_fbo_blit =
@@ -374,6 +399,10 @@ glamor_init(ScreenPtr screen, unsigned int flags)
glamor_priv->saved_procs.close_screen = screen->CloseScreen;
screen->CloseScreen = glamor_close_screen;
+ glamor_priv->saved_procs.create_screen_resources =
+ screen->CreateScreenResources;
+ screen->CreateScreenResources = glamor_create_screen_resources;
+
if (flags & GLAMOR_USE_SCREEN) {
if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler,
_glamor_wakeup_handler,
@@ -457,8 +486,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
glamor_init_xv_shader(screen);
#endif
glamor_pixmap_init(screen);
+ glamor_glyphs_init(screen);
- glamor_priv->flags = flags;
glamor_priv->screen = screen;
return TRUE;
@@ -535,6 +564,8 @@ glamor_close_screen(ScreenPtr screen)
flags = glamor_priv->flags;
glamor_glyphs_fini(screen);
screen->CloseScreen = glamor_priv->saved_procs.close_screen;
+ screen->CreateScreenResources =
+ glamor_priv->saved_procs.create_screen_resources;
if (flags & GLAMOR_USE_SCREEN) {
screen->CreateGC = glamor_priv->saved_procs.create_gc;
@@ -617,7 +648,7 @@ glamor_fd_from_pixmap(ScreenPtr screen,
}
int
-glamor_name_from_pixmap(PixmapPtr pixmap)
+glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
{
glamor_pixmap_private *pixmap_priv;
glamor_screen_private *glamor_priv =
@@ -633,7 +664,7 @@ glamor_name_from_pixmap(PixmapPtr pixmap)
return glamor_egl_dri3_fd_name_from_tex(pixmap->drawable.pScreen,
pixmap,
pixmap_priv->base.fbo->tex,
- TRUE, NULL, NULL);
+ TRUE, stride, size);
default:
break;
}
diff --git a/xorg-server/glamor/glamor.h b/xorg-server/glamor/glamor.h
index e25dc735c..d05d2f4ea 100644
--- a/xorg-server/glamor/glamor.h
+++ b/xorg-server/glamor/glamor.h
@@ -131,14 +131,6 @@ extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap,
extern _X_EXPORT uint32_t glamor_get_pixmap_texture(PixmapPtr pixmap);
-/* @glamor_glyphs_init: Initialize glyphs internal data structures.
- *
- * @pScreen: Current screen pointer.
- *
- * This function must be called after the glamor_init and the texture
- * can be allocated. An example is to call it when create the screen
- * resources at DDX layer.
- */
extern _X_EXPORT Bool glamor_glyphs_init(ScreenPtr pScreen);
extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap,
@@ -218,7 +210,8 @@ extern _X_EXPORT int glamor_fd_from_pixmap(ScreenPtr screen,
*
* Returns the name on success, -1 on error.
* */
-extern _X_EXPORT int glamor_name_from_pixmap(PixmapPtr pixmap);
+extern _X_EXPORT int glamor_name_from_pixmap(PixmapPtr pixmap,
+ CARD16 *stride, CARD32 *size);
/* @glamor_pixmap_from_fd: Creates a pixmap to wrap a dma-buf fd.
*
@@ -255,14 +248,6 @@ extern _X_EXPORT PixmapPtr glamor_pixmap_from_fd(ScreenPtr screen,
* */
extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd);
-/* @glamor_egl_init_textured_pixmap: Initialization for textured pixmap allocation.
- *
- * @screen: Current screen pointer.
- *
- * This function must be called before any textured pixmap's creation including
- * the screen pixmap. Could be called from DDX's screenInit function after the calling
- * to glamor_init..
- */
extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen);
/* @glamor_egl_create_textured_screen: Create textured screen pixmap.
diff --git a/xorg-server/glamor/glamor_addtraps.c b/xorg-server/glamor/glamor_addtraps.c
index 655d87e3d..fdc0f4232 100644
--- a/xorg-server/glamor/glamor_addtraps.c
+++ b/xorg-server/glamor/glamor_addtraps.c
@@ -40,8 +40,8 @@ _glamor_add_traps(PicturePtr pPicture,
if (glamor_prepare_access_picture(pPicture, GLAMOR_ACCESS_RW)) {
fbAddTraps(pPicture, x_off, y_off, ntrap, traps);
- glamor_finish_access_picture(pPicture, GLAMOR_ACCESS_RW);
}
+ glamor_finish_access_picture(pPicture);
return TRUE;
}
diff --git a/xorg-server/glamor/glamor_copyarea.c b/xorg-server/glamor/glamor_copyarea.c
index d6bcacd36..996611c6c 100644
--- a/xorg-server/glamor/glamor_copyarea.c
+++ b/xorg-server/glamor/glamor_copyarea.c
@@ -137,7 +137,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
- if (!src_pixmap_priv->base.gl_fbo) {
+ if (src_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) {
#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
return FALSE;
@@ -205,7 +205,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- glUseProgram(0);
/* The source texture is bound to a fbo, we have to flush it here. */
glamor_put_context(glamor_priv);
glamor_priv->state = RENDER_STATE;
@@ -570,15 +569,15 @@ _glamor_copy_n_to_n(DrawablePtr src,
glamor_get_drawable_location(src),
glamor_get_drawable_location(dst));
- if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
- if (dst == src || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
- fbCopyNtoN(src, dst, gc, box, nbox,
- dx, dy, reverse, upsidedown, bitplane, closure);
- if (dst != src)
- glamor_finish_access(src, GLAMOR_ACCESS_RO);
- }
- glamor_finish_access(dst, GLAMOR_ACCESS_RW);
+ if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) &&
+ glamor_prepare_access(src, GLAMOR_ACCESS_RO) &&
+ glamor_prepare_access_gc(gc)) {
+ fbCopyNtoN(src, dst, gc, box, nbox,
+ dx, dy, reverse, upsidedown, bitplane, closure);
}
+ glamor_finish_access_gc(gc);
+ glamor_finish_access(src);
+ glamor_finish_access(dst);
ok = TRUE;
done:
diff --git a/xorg-server/glamor/glamor_copyplane.c b/xorg-server/glamor/glamor_copyplane.c
index c42d33e94..2bd2de30d 100644
--- a/xorg-server/glamor/glamor_copyplane.c
+++ b/xorg-server/glamor/glamor_copyplane.c
@@ -38,12 +38,15 @@ _glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
&& glamor_ddx_fallback_check_pixmap(pDst))
goto fail;
- glamor_prepare_access(pDst, GLAMOR_ACCESS_RW);
- glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO);
- *pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h,
- dstx, dsty, bitPlane);
- glamor_finish_access(pSrc, GLAMOR_ACCESS_RO);
- glamor_finish_access(pDst, GLAMOR_ACCESS_RW);
+ if (glamor_prepare_access(pDst, GLAMOR_ACCESS_RW) &&
+ glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO) &&
+ glamor_prepare_access_gc(pGC)) {
+ *pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h,
+ dstx, dsty, bitPlane);
+ }
+ glamor_finish_access_gc(pGC);
+ glamor_finish_access(pSrc);
+ glamor_finish_access(pDst);
return TRUE;
fail:
diff --git a/xorg-server/glamor/glamor_core.c b/xorg-server/glamor/glamor_core.c
index 58838095b..6c0b3c834 100644
--- a/xorg-server/glamor/glamor_core.c
+++ b/xorg-server/glamor/glamor_core.c
@@ -42,7 +42,8 @@ glamor_get_drawable_location(const DrawablePtr drawable)
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_screen_private *glamor_priv =
glamor_get_screen_private(drawable->pScreen);
- if (pixmap_priv == NULL || pixmap_priv->base.gl_fbo == 0)
+ if (pixmap_priv == NULL ||
+ pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED)
return 'm';
if (pixmap_priv->base.fbo->fb == glamor_priv->screen_fbo)
return 's';
@@ -82,9 +83,10 @@ glamor_compile_glsl_prog(GLenum type, const char *source)
}
void
-glamor_link_glsl_prog(GLint prog)
+glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...)
{
GLint ok;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glLinkProgram(prog);
glGetProgramiv(prog, GL_LINK_STATUS, &ok);
@@ -99,12 +101,36 @@ glamor_link_glsl_prog(GLint prog)
ErrorF("Failed to link: %s\n", info);
FatalError("GLSL link failure\n");
}
+
+ if (glamor_priv->has_khr_debug) {
+ char *label;
+ va_list va;
+
+ va_start(va, format);
+ XNFvasprintf(&label, format, va);
+ glObjectLabel(GL_PROGRAM, prog, -1, label);
+ free(label);
+ va_end(va);
+ }
}
Bool
glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
{
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+ if (pixmap->devPrivate.ptr) {
+ /* Already mapped, nothing needs to be done. Note that we
+ * aren't allowing promotion from RO to RW, because it would
+ * require re-mapping the PBO.
+ */
+ assert(!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) ||
+ access == GLAMOR_ACCESS_RO ||
+ pixmap_priv->base.mapped_for_write);
+ return TRUE;
+ }
+ pixmap_priv->base.map_access = access;
return glamor_download_pixmap_to_cpu(pixmap, access);
}
@@ -242,13 +268,15 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
GLAMOR_VERTEX_POS, "v_position");
glBindAttribLocation(glamor_priv->finish_access_prog[0],
GLAMOR_VERTEX_SOURCE, "v_texcoord0");
- glamor_link_glsl_prog(glamor_priv->finish_access_prog[0]);
+ glamor_link_glsl_prog(screen, glamor_priv->finish_access_prog[0],
+ "finish access 0");
glBindAttribLocation(glamor_priv->finish_access_prog[1],
GLAMOR_VERTEX_POS, "v_position");
glBindAttribLocation(glamor_priv->finish_access_prog[1],
GLAMOR_VERTEX_SOURCE, "v_texcoord0");
- glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]);
+ glamor_link_glsl_prog(screen, glamor_priv->finish_access_prog[1],
+ "finish access 1");
glamor_priv->finish_access_revert[0] =
glGetUniformLocation(glamor_priv->finish_access_prog[0], "revert");
@@ -261,7 +289,6 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
glUniform1i(sampler_uniform_location, 0);
glUniform1i(glamor_priv->finish_access_revert[0], 0);
glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
- glUseProgram(0);
glamor_priv->finish_access_revert[1] =
glGetUniformLocation(glamor_priv->finish_access_prog[1], "revert");
@@ -273,7 +300,6 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
glUniform1i(glamor_priv->finish_access_revert[1], 0);
glUniform1i(sampler_uniform_location, 0);
glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
- glUseProgram(0);
glamor_put_context(glamor_priv);
}
@@ -290,7 +316,7 @@ glamor_fini_finish_access_shaders(ScreenPtr screen)
}
void
-glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
+glamor_finish_access(DrawablePtr drawable)
{
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -300,7 +326,15 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv))
return;
- if (access_mode != GLAMOR_ACCESS_RO) {
+ /* If we are doing a series of unmaps from a nested map, we're
+ * done. None of the callers do any rendering to maps after
+ * starting an unmap sequence, so we don't need to delay until the
+ * last nested unmap.
+ */
+ if (!pixmap->devPrivate.ptr)
+ return;
+
+ if (pixmap_priv->base.map_access == GLAMOR_ACCESS_RW) {
glamor_restore_pixmap_to_texture(pixmap);
}
@@ -348,7 +382,7 @@ glamor_prepare_access_gc(GCPtr gc)
if (!glamor_prepare_access(&gc->tile.pixmap->drawable,
GLAMOR_ACCESS_RO)) {
if (gc->stipple)
- glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO);
+ glamor_finish_access(&gc->stipple->drawable);
return FALSE;
}
}
@@ -362,9 +396,9 @@ void
glamor_finish_access_gc(GCPtr gc)
{
if (gc->fillStyle == FillTiled)
- glamor_finish_access(&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RO);
+ glamor_finish_access(&gc->tile.pixmap->drawable);
if (gc->stipple)
- glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO);
+ glamor_finish_access(&gc->stipple->drawable);
}
Bool
@@ -438,7 +472,7 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
(&old_tile->drawable, GLAMOR_ACCESS_RO)) {
new_tile =
fb24_32ReformatTile(old_tile, drawable->bitsPerPixel);
- glamor_finish_access(&old_tile->drawable, GLAMOR_ACCESS_RO);
+ glamor_finish_access(&old_tile->drawable);
}
}
if (new_tile) {
@@ -461,8 +495,7 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
if (glamor_prepare_access
(&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW)) {
fbPadPixmap(gc->tile.pixmap);
- glamor_finish_access
- (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW);
+ glamor_finish_access(&gc->tile.pixmap->drawable);
}
}
}
@@ -478,7 +511,7 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
*/
if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) {
fbValidateGC(gc, changes, drawable);
- glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW);
+ glamor_finish_access(&gc->stipple->drawable);
}
}
else {
@@ -522,7 +555,7 @@ glamor_bitmap_to_region(PixmapPtr pixmap)
if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO))
return NULL;
ret = fbPixmapToRegion(pixmap);
- glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
+ glamor_finish_access(&pixmap->drawable);
return ret;
}
diff --git a/xorg-server/glamor/glamor_egl.c b/xorg-server/glamor/glamor_egl.c
index 05e6bd02e..812342129 100644
--- a/xorg-server/glamor/glamor_egl.c
+++ b/xorg-server/glamor/glamor_egl.c
@@ -54,10 +54,6 @@
static const char glamor_name[] = "glamor";
-static DevPrivateKeyRec glamor_egl_pixmap_private_key_index;
-DevPrivateKey glamor_egl_pixmap_private_key =
- &glamor_egl_pixmap_private_key_index;
-
static void
glamor_identify(int flags)
{
@@ -228,11 +224,13 @@ Bool
glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ struct glamor_pixmap_private *pixmap_priv;
struct glamor_egl_screen_private *glamor_egl;
PixmapPtr screen_pixmap;
glamor_egl = glamor_egl_get_screen_private(scrn);
screen_pixmap = screen->GetScreenPixmap(screen);
+ pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
if (!glamor_egl_create_textured_pixmap(screen_pixmap, handle, stride)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
@@ -240,8 +238,7 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
return FALSE;
}
- glamor_egl->front_image = dixLookupPrivate(&screen_pixmap->devPrivates,
- glamor_egl_pixmap_private_key);
+ glamor_egl->front_image = pixmap_priv->base.image;
glamor_set_screen_pixmap(screen_pixmap, glamor_egl->back_pixmap);
return TRUE;
}
@@ -282,6 +279,8 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
+ struct glamor_pixmap_private *pixmap_priv =
+ glamor_get_pixmap_private(pixmap);
struct glamor_egl_screen_private *glamor_egl;
EGLImageKHR image;
GLuint texture;
@@ -316,7 +315,7 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
glamor_create_texture_from_image(glamor_egl, image, &texture);
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
glamor_set_pixmap_texture(pixmap, texture);
- dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, image);
+ pixmap_priv->base.image = image;
ret = TRUE;
done:
@@ -331,6 +330,8 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
+ struct glamor_pixmap_private *pixmap_priv =
+ glamor_get_pixmap_private(pixmap);
struct glamor_egl_screen_private *glamor_egl;
EGLImageKHR image;
GLuint texture;
@@ -350,7 +351,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
glamor_create_texture_from_image(glamor_egl, image, &texture);
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
glamor_set_pixmap_texture(pixmap, texture);
- dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, image);
+ pixmap_priv->base.image = image;
ret = TRUE;
done:
@@ -395,6 +396,8 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
{
#ifdef GLAMOR_HAS_GBM
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ struct glamor_pixmap_private *pixmap_priv =
+ glamor_get_pixmap_private(pixmap);
struct glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
struct glamor_egl_screen_private *glamor_egl;
@@ -412,10 +415,8 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
glamor_get_context(glamor_priv);
- image = dixLookupPrivate(&pixmap->devPrivates,
- glamor_egl_pixmap_private_key);
-
- if (image == EGL_NO_IMAGE_KHR || image == NULL) {
+ image = pixmap_priv->base.image;
+ if (!image) {
image = eglCreateImageKHR(glamor_egl->display,
glamor_egl->context,
EGL_GL_TEXTURE_2D_KHR,
@@ -424,8 +425,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
if (image == EGL_NO_IMAGE_KHR)
goto failure;
- dixSetPrivate(&pixmap->devPrivates,
- glamor_egl_pixmap_private_key, image);
+ pixmap_priv->base.image = image;
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
}
@@ -441,10 +441,10 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
}
else {
if (glamor_get_fd_from_bo(glamor_egl->fd, bo, &fd)) {
- *stride = pixmap->devKind;
- *size = pixmap->devKind * gbm_bo_get_height(bo);
}
}
+ *stride = pixmap->devKind;
+ *size = pixmap->devKind * gbm_bo_get_height(bo);
gbm_bo_destroy(bo);
failure:
@@ -530,20 +530,18 @@ static void
_glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
- EGLImageKHR image;
struct glamor_egl_screen_private *glamor_egl =
glamor_egl_get_screen_private(scrn);
+ struct glamor_pixmap_private *pixmap_priv =
+ glamor_get_pixmap_private(pixmap);
- image = dixLookupPrivate(&pixmap->devPrivates,
- glamor_egl_pixmap_private_key);
- if (image != EGL_NO_IMAGE_KHR && image != NULL) {
+ if (pixmap_priv->base.image) {
/* Before destroy an image which was attached to
* a texture. we must call glFlush to make sure the
* operation on that texture has been done.*/
glamor_block_handler(pixmap->drawable.pScreen);
- eglDestroyImageKHR(glamor_egl->display, image);
- dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key,
- NULL);
+ eglDestroyImageKHR(glamor_egl->display, pixmap_priv->base.image);
+ pixmap_priv->base.image = NULL;
}
}
@@ -553,21 +551,21 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
ScrnInfoPtr scrn = xf86ScreenToScrn(front->drawable.pScreen);
struct glamor_egl_screen_private *glamor_egl =
glamor_egl_get_screen_private(scrn);
- EGLImageKHR old_front_image;
- EGLImageKHR new_front_image;
+ EGLImageKHR temp;
+ struct glamor_pixmap_private *front_priv =
+ glamor_get_pixmap_private(front);
+ struct glamor_pixmap_private *back_priv =
+ glamor_get_pixmap_private(back);
glamor_pixmap_exchange_fbos(front, back);
- new_front_image =
- dixLookupPrivate(&back->devPrivates, glamor_egl_pixmap_private_key);
- old_front_image =
- dixLookupPrivate(&front->devPrivates, glamor_egl_pixmap_private_key);
- dixSetPrivate(&front->devPrivates, glamor_egl_pixmap_private_key,
- new_front_image);
- dixSetPrivate(&back->devPrivates, glamor_egl_pixmap_private_key,
- old_front_image);
+
+ temp = back_priv->base.image;
+ back_priv->base.image = front_priv->base.image;
+ front_priv->base.image = temp;
+
glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM);
glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
- glamor_egl->front_image = new_front_image;
+ glamor_egl->front_image = front_priv->base.image;
}
@@ -584,24 +582,23 @@ glamor_egl_close_screen(ScreenPtr screen)
{
ScrnInfoPtr scrn;
struct glamor_egl_screen_private *glamor_egl;
+ struct glamor_pixmap_private *pixmap_priv;
PixmapPtr screen_pixmap;
- EGLImageKHR back_image;
scrn = xf86ScreenToScrn(screen);
glamor_egl = glamor_egl_get_screen_private(scrn);
screen_pixmap = screen->GetScreenPixmap(screen);
+ pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
- eglDestroyImageKHR(glamor_egl->display,glamor_egl->front_image);
- dixSetPrivate(&screen_pixmap->devPrivates, glamor_egl_pixmap_private_key,
- NULL);
+ eglDestroyImageKHR(glamor_egl->display, glamor_egl->front_image);
+ pixmap_priv->base.image = NULL;
glamor_egl->front_image = NULL;
+
if (glamor_egl->back_pixmap && *glamor_egl->back_pixmap) {
- back_image = dixLookupPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
- glamor_egl_pixmap_private_key);
- if (back_image != NULL && back_image != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(glamor_egl->display, back_image);
- dixSetPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
- glamor_egl_pixmap_private_key, NULL);
+ pixmap_priv = glamor_get_pixmap_private(*glamor_egl->back_pixmap);
+ if (pixmap_priv->base.image) {
+ eglDestroyImageKHR(glamor_egl->display, pixmap_priv->base.image);
+ pixmap_priv->base.image = NULL;
}
}
@@ -610,25 +607,6 @@ glamor_egl_close_screen(ScreenPtr screen)
return screen->CloseScreen(screen);
}
-static Bool
-glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl,
- const char *extension)
-{
- const char *pext;
- int ext_len;
-
- ext_len = strlen(extension);
- pext = (const char *) eglQueryString(glamor_egl->display, EGL_EXTENSIONS);
- if (pext == NULL || extension == NULL)
- return FALSE;
- while ((pext = strstr(pext, extension)) != NULL) {
- if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
- return TRUE;
- pext += ext_len;
- }
- return FALSE;
-}
-
static int
glamor_dri3_open(ScreenPtr screen,
RRProviderPtr provider,
@@ -799,14 +777,14 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version);
#define GLAMOR_CHECK_EGL_EXTENSION(EXT) \
- if (!glamor_egl_has_extension(glamor_egl, "EGL_" #EXT)) { \
+ if (!epoxy_has_egl_extension(glamor_egl->display, "EGL_" #EXT)) { \
ErrorF("EGL_" #EXT " required.\n"); \
return FALSE; \
}
#define GLAMOR_CHECK_EGL_EXTENSIONS(EXT1, EXT2) \
- if (!glamor_egl_has_extension(glamor_egl, "EGL_" #EXT1) && \
- !glamor_egl_has_extension(glamor_egl, "EGL_" #EXT2)) { \
+ if (!epoxy_has_egl_extension(glamor_egl->display, "EGL_" #EXT1) && \
+ !epoxy_has_egl_extension(glamor_egl->display, "EGL_" #EXT2)) { \
ErrorF("EGL_" #EXT1 " or EGL_" #EXT2 " required.\n"); \
return FALSE; \
}
@@ -821,8 +799,10 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
#endif
#ifdef GLAMOR_HAS_GBM
- if (glamor_egl_has_extension(glamor_egl, "EGL_KHR_gl_texture_2D_image") &&
- glamor_egl_has_extension(glamor_egl, "EGL_EXT_image_dma_buf_import"))
+ if (epoxy_has_egl_extension(glamor_egl->display,
+ "EGL_KHR_gl_texture_2D_image") &&
+ epoxy_has_egl_extension(glamor_egl->display,
+ "EGL_EXT_image_dma_buf_import"))
glamor_egl->dri3_capable = TRUE;
#endif
@@ -851,20 +831,9 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
return TRUE;
}
+/** Stub to retain compatibility with pre-server-1.16 ABI. */
Bool
glamor_egl_init_textured_pixmap(ScreenPtr screen)
{
- ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
- struct glamor_egl_screen_private *glamor_egl =
- glamor_egl_get_screen_private(scrn);
- if (!dixRegisterPrivateKey
- (glamor_egl_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
- LogMessage(X_WARNING,
- "glamor%d: Failed to allocate egl pixmap private\n",
- screen->myNum);
- return FALSE;
- }
- if (glamor_egl->dri3_capable)
- glamor_enable_dri3(screen);
return TRUE;
}
diff --git a/xorg-server/glamor/glamor_fbo.c b/xorg-server/glamor/glamor_fbo.c
index 281cf830e..640b6fd81 100644
--- a/xorg-server/glamor/glamor_fbo.c
+++ b/xorg-server/glamor/glamor_fbo.c
@@ -505,7 +505,7 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
case GLAMOR_TEXTURE_LARGE:
case GLAMOR_TEXTURE_ONLY:
case GLAMOR_TEXTURE_DRM:
- pixmap_priv->base.gl_fbo = 1;
+ pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL;
if (fbo->tex != 0)
pixmap_priv->base.gl_tex = 1;
else {
diff --git a/xorg-server/glamor/glamor_fill.c b/xorg-server/glamor/glamor_fill.c
index dda55eace..7461b62fa 100644
--- a/xorg-server/glamor/glamor_fill.c
+++ b/xorg-server/glamor/glamor_fill.c
@@ -27,10 +27,14 @@
#include "glamor_priv.h"
-/** @file glamor_fillspans.c
+/** @file glamor_fill.c
*
* GC fill implementation, based loosely on fb_fill.c
*/
+
+/**
+ * Fills the given rectangle of a drawable with the GC's fill style.
+ */
Bool
glamor_fill(DrawablePtr drawable,
GCPtr gc, int x, int y, int width, int height, Bool fallback)
@@ -108,13 +112,12 @@ glamor_fill(DrawablePtr drawable,
x = 0;
y = 0;
}
- if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
- if (glamor_prepare_access_gc(gc)) {
- fbFill(drawable, gc, x, y, width, height);
- glamor_finish_access_gc(gc);
- }
- glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
+ if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
+ glamor_prepare_access_gc(gc)) {
+ fbFill(drawable, gc, x, y, width, height);
}
+ glamor_finish_access_gc(gc);
+ glamor_finish_access(drawable);
if (sub_pixmap != NULL) {
if (gc->fillStyle != FillSolid) {
@@ -162,7 +165,7 @@ glamor_init_solid_shader(ScreenPtr screen)
glBindAttribLocation(glamor_priv->solid_prog,
GLAMOR_VERTEX_POS, "v_position");
- glamor_link_glsl_prog(glamor_priv->solid_prog);
+ glamor_link_glsl_prog(screen, glamor_priv->solid_prog, "solid");
glamor_priv->solid_color_uniform_location =
glGetUniformLocation(glamor_priv->solid_prog, "color");
@@ -187,9 +190,9 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
GLfloat xscale, yscale;
- float vertices[32];
- float *pvertices = vertices;
- int valid_nbox = ARRAY_SIZE(vertices);
+ float stack_vertices[32];
+ float *vertices = stack_vertices;
+ int valid_nbox = ARRAY_SIZE(stack_vertices) / (4 * 2);
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
@@ -200,20 +203,18 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
- if (_X_UNLIKELY(nbox * 4 * 2 > ARRAY_SIZE(vertices))) {
- int allocated_box;
+ if (nbox > valid_nbox) {
+ int allocated_nbox;
+ float *new_vertices;
- if (nbox * 6 > GLAMOR_COMPOSITE_VBO_VERT_CNT) {
- allocated_box = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6;
- }
+ if (nbox > GLAMOR_COMPOSITE_VBO_VERT_CNT / 6)
+ allocated_nbox = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6;
else
- allocated_box = nbox;
- pvertices = malloc(allocated_box * 4 * 2 * sizeof(float));
- if (pvertices)
- valid_nbox = allocated_box;
- else {
- pvertices = vertices;
- valid_nbox = ARRAY_SIZE(vertices) / (4 * 2);
+ allocated_nbox = nbox;
+ new_vertices = malloc(allocated_nbox * 4 * 2 * sizeof(float));
+ if (new_vertices) {
+ vertices = new_vertices;
+ valid_nbox = allocated_nbox;
}
}
@@ -221,22 +222,22 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
- GL_FALSE, 2 * sizeof(float), pvertices);
+ GL_FALSE, 2 * sizeof(float), vertices);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
while (nbox) {
int box_cnt, i;
- float *valid_vertices;
+ float *next_box;
- valid_vertices = pvertices;
+ next_box = vertices;
box_cnt = nbox > valid_nbox ? valid_nbox : nbox;
for (i = 0; i < box_cnt; i++) {
glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale,
box[i].x1, box[i].y1,
box[i].x2, box[i].y2,
glamor_priv->yInverted,
- valid_vertices);
- valid_vertices += 4 * 2;
+ next_box);
+ next_box += 4 * 2;
}
if (box_cnt == 1)
glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4);
@@ -253,16 +254,21 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
box += box_cnt;
}
- if (pvertices != vertices)
- free(pvertices);
+ if (vertices != stack_vertices)
+ free(vertices);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- glUseProgram(0);
glamor_put_context(glamor_priv);
glamor_priv->state = RENDER_STATE;
glamor_priv->render_idle_cnt = 0;
}
+/**
+ * Fills the given rectangles of pixmap with an X pixel value.
+ *
+ * This is a helper used by other code after clipping and translation
+ * of coordinates to a glamor backing pixmap.
+ */
Bool
glamor_solid_boxes(PixmapPtr pixmap,
BoxPtr box, int nbox, unsigned long fg_pixel)
@@ -310,6 +316,12 @@ glamor_solid_boxes(PixmapPtr pixmap,
return TRUE;
}
+/**
+ * Fills a rectangle of a pixmap with an X pixel value.
+ *
+ * This is a helper used by other glamor code mostly for clearing of
+ * buffers to 0.
+ */
Bool
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
diff --git a/xorg-server/glamor/glamor_fillspans.c b/xorg-server/glamor/glamor_fillspans.c
index 7261d2842..8cbd79f6d 100644
--- a/xorg-server/glamor/glamor_fillspans.c
+++ b/xorg-server/glamor/glamor_fillspans.c
@@ -79,13 +79,12 @@ _glamor_fill_spans(DrawablePtr drawable,
}
glamor_fallback("to %p (%c)\n", drawable,
glamor_get_drawable_location(drawable));
- if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
- if (glamor_prepare_access_gc(gc)) {
- fbFillSpans(drawable, gc, n, points, widths, sorted);
- glamor_finish_access_gc(gc);
- }
- glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
+ if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
+ glamor_prepare_access_gc(gc)) {
+ fbFillSpans(drawable, gc, n, points, widths, sorted);
}
+ glamor_finish_access_gc(gc);
+ glamor_finish_access(drawable);
ret = TRUE;
done:
diff --git a/xorg-server/glamor/glamor_getimage.c b/xorg-server/glamor/glamor_getimage.c
index 5609e707f..a932473e8 100644
--- a/xorg-server/glamor/glamor_getimage.c
+++ b/xorg-server/glamor/glamor_getimage.c
@@ -44,8 +44,6 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
if (format != ZPixmap)
goto fall_back;
- pixmap = glamor_get_drawable_pixmap(drawable);
- glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
if (!glamor_set_planemask(pixmap, planeMask)) {
glamor_fallback("Failedto set planemask in glamor_solid.\n");
diff --git a/xorg-server/glamor/glamor_getspans.c b/xorg-server/glamor/glamor_getspans.c
index ff58725d6..42df87f3d 100644
--- a/xorg-server/glamor/glamor_getspans.c
+++ b/xorg-server/glamor/glamor_getspans.c
@@ -69,8 +69,8 @@ _glamor_get_spans(DrawablePtr drawable,
ret = TRUE;
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) {
fbGetSpans(drawable, wmax, points, widths, count, dst);
- glamor_finish_access(drawable, GLAMOR_ACCESS_RO);
}
+ glamor_finish_access(drawable);
done:
return ret;
}
diff --git a/xorg-server/glamor/glamor_glx.c b/xorg-server/glamor/glamor_glx.c
index 311bf758d..8f47c3d2c 100644
--- a/xorg-server/glamor/glamor_glx.c
+++ b/xorg-server/glamor/glamor_glx.c
@@ -53,13 +53,7 @@ glamor_glx_get_context(struct glamor_context *glamor_ctx)
static void
glamor_glx_put_context(struct glamor_context *glamor_ctx)
{
- if (--glamor_ctx->get_count)
- return;
-
- /* We actually reset the context, so that indirect GLX's EGL usage
- * won't get confused by ours.
- */
- glXMakeCurrent(glamor_ctx->display, None, NULL);
+ --glamor_ctx->get_count;
}
Bool
diff --git a/xorg-server/glamor/glamor_glyphblt.c b/xorg-server/glamor/glamor_glyphblt.c
index 6f754ce2b..a58cef907 100644
--- a/xorg-server/glamor/glamor_glyphblt.c
+++ b/xorg-server/glamor/glamor_glyphblt.c
@@ -27,6 +27,140 @@
*/
#include "glamor_priv.h"
+#include <dixfontstr.h>
+
+static Bool
+glamor_poly_glyph_blt_pixels(DrawablePtr drawable, GCPtr gc,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci)
+{
+ ScreenPtr screen = drawable->pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_pixmap_private *pixmap_priv;
+ int off_x, off_y;
+ GLfloat xscale, yscale;
+ float color[4];
+ unsigned long fg_pixel = gc->fgPixel;
+ char *vbo_offset;
+ RegionPtr clip;
+ int num_points, max_points;
+ float *points = NULL;
+
+ x += drawable->x;
+ y += drawable->y;
+
+ if (gc->fillStyle != FillSolid) {
+ glamor_fallback("gc fillstyle not solid\n");
+ return FALSE;
+ }
+
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+ return FALSE;
+
+ glamor_get_context(glamor_priv);
+ if (!glamor_set_alu(screen, gc->alu)) {
+ if (gc->alu == GXclear)
+ fg_pixel = 0;
+ else {
+ glamor_fallback("unsupported alu %x\n", gc->alu);
+ glamor_put_context(glamor_priv);
+ return FALSE;
+ }
+ }
+
+ if (!glamor_set_planemask(pixmap, gc->planemask)) {
+ glamor_fallback("Failed to set planemask in %s.\n", __FUNCTION__);
+ glamor_put_context(glamor_priv);
+ return FALSE;
+ }
+
+ glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
+
+ glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+ pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
+
+ glUseProgram(glamor_priv->solid_prog);
+
+ glamor_get_rgba_from_pixel(fg_pixel,
+ &color[0], &color[1], &color[2], &color[3],
+ format_for_pixmap(pixmap));
+ glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
+
+ clip = fbGetCompositeClip(gc);
+
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+ max_points = 500;
+ num_points = 0;
+ while (nglyph--) {
+ CharInfoPtr charinfo = *ppci++;
+ int w = GLYPHWIDTHPIXELS(charinfo);
+ int h = GLYPHHEIGHTPIXELS(charinfo);
+ uint8_t *glyphbits = FONTGLYPHBITS(NULL, charinfo);
+
+ if (w && h) {
+ int glyph_x = x + charinfo->metrics.leftSideBearing;
+ int glyph_y = y - charinfo->metrics.ascent;
+ int glyph_stride = GLYPHWIDTHBYTESPADDED(charinfo);
+ int xx, yy;
+
+ for (yy = 0; yy < h; yy++) {
+ uint8_t *glyph_row = glyphbits + glyph_stride * yy;
+ for (xx = 0; xx < w; xx++) {
+ int pt_x_i = glyph_x + xx;
+ int pt_y_i = glyph_y + yy;
+ float pt_x_f, pt_y_f;
+ if (!(glyph_row[xx / 8] & (1 << xx % 8)))
+ continue;
+
+ if (!RegionContainsPoint(clip, pt_x_i, pt_y_i, NULL))
+ continue;
+
+ if (!num_points) {
+ points = glamor_get_vbo_space(screen,
+ max_points * 2 * sizeof(float),
+ &vbo_offset);
+
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+ GL_FALSE, 2 * sizeof(float),
+ vbo_offset);
+ }
+
+ pt_x_f = v_from_x_coord_x(xscale, pt_x_i + off_x + 0.5);
+ if (glamor_priv->yInverted)
+ pt_y_f = v_from_x_coord_y_inverted(yscale, pt_y_i + off_y + 0.5);
+ else
+ pt_y_f = v_from_x_coord_y(yscale, pt_y_i + off_y + 0.5);
+
+ points[num_points * 2 + 0] = pt_x_f;
+ points[num_points * 2 + 1] = pt_y_f;
+ num_points++;
+
+ if (num_points == max_points) {
+ glamor_put_vbo_space(screen);
+ glDrawArrays(GL_POINTS, 0, num_points);
+ num_points = 0;
+ }
+ }
+ }
+ }
+
+ x += charinfo->metrics.characterWidth;
+ }
+
+ if (num_points) {
+ glamor_put_vbo_space(screen);
+ glDrawArrays(GL_POINTS, 0, num_points);
+ }
+
+ glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+ glamor_put_context(glamor_priv);
+
+ return TRUE;
+}
static Bool
_glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
@@ -64,6 +198,9 @@ _glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, void *pglyphBase, Bool fallback)
{
+ if (glamor_poly_glyph_blt_pixels(pDrawable, pGC, x, y, nglyph, ppci))
+ return TRUE;
+
if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable)
&& glamor_ddx_fallback_check_gc(pGC))
return FALSE;
@@ -91,15 +228,129 @@ glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
}
static Bool
+glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap,
+ DrawablePtr drawable, int w, int h, int x, int y)
+{
+ ScreenPtr screen = drawable->pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_pixmap_private *pixmap_priv;
+ uint8_t *bitmap_data = bitmap->devPrivate.ptr;
+ int bitmap_stride = bitmap->devKind;
+ int off_x, off_y;
+ int yy, xx;
+ GLfloat xscale, yscale;
+ float color[4];
+ unsigned long fg_pixel = gc->fgPixel;
+ float *points, *next_point;
+ int num_points = 0;
+ char *vbo_offset;
+ RegionPtr clip;
+
+ if (w * h > MAXINT / (2 * sizeof(float)))
+ return FALSE;
+
+ if (gc->fillStyle != FillSolid) {
+ glamor_fallback("gc fillstyle not solid\n");
+ return FALSE;
+ }
+
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+ return FALSE;
+
+ glamor_get_context(glamor_priv);
+ if (!glamor_set_alu(screen, gc->alu)) {
+ if (gc->alu == GXclear)
+ fg_pixel = 0;
+ else {
+ glamor_fallback("unsupported alu %x\n", gc->alu);
+ glamor_put_context(glamor_priv);
+ return FALSE;
+ }
+ }
+
+ if (!glamor_set_planemask(pixmap, gc->planemask)) {
+ glamor_fallback("Failed to set planemask in %s.\n", __FUNCTION__);
+ glamor_put_context(glamor_priv);
+ return FALSE;
+ }
+
+ glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
+
+ glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+ pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
+
+ glUseProgram(glamor_priv->solid_prog);
+
+ glamor_get_rgba_from_pixel(fg_pixel,
+ &color[0], &color[1], &color[2], &color[3],
+ format_for_pixmap(pixmap));
+ glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
+
+ points = glamor_get_vbo_space(screen, w * h * sizeof(float) * 2,
+ &vbo_offset);
+ next_point = points;
+
+ clip = fbGetCompositeClip(gc);
+
+ /* Note that because fb sets miTranslate in the GC, our incoming X
+ * and Y are in screen coordinate space (same for spans, but not
+ * other operations).
+ */
+ for (yy = 0; yy < h; yy++) {
+ uint8_t *bitmap_row = bitmap_data + yy * bitmap_stride;
+ for (xx = 0; xx < w; xx++) {
+ if (bitmap_row[xx / 8] & (1 << xx % 8) &&
+ RegionContainsPoint(clip,
+ x + xx,
+ y + yy,
+ NULL)) {
+ next_point[0] = v_from_x_coord_x(xscale, x + xx + off_x + 0.5);
+ if (glamor_priv->yInverted)
+ next_point[1] = v_from_x_coord_y_inverted(yscale, y + yy + off_y + 0.5);
+ else
+ next_point[1] = v_from_x_coord_y(yscale, y + yy + off_y + 0.5);
+
+ next_point += 2;
+ num_points++;
+ }
+ }
+ }
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+ GL_FALSE, 2 * sizeof(float),
+ vbo_offset);
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+ glamor_put_vbo_space(screen);
+
+ glDrawArrays(GL_POINTS, 0, num_points);
+
+ glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+ glamor_put_context(glamor_priv);
+
+ return TRUE;
+}
+
+static Bool
_glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
DrawablePtr pDrawable, int w, int h, int x, int y,
Bool fallback)
{
+ glamor_pixmap_private *pixmap_priv;
+
if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable)
&& glamor_ddx_fallback_check_pixmap(&pBitmap->drawable)
&& glamor_ddx_fallback_check_gc(pGC))
return FALSE;
+ pixmap_priv = glamor_get_pixmap_private(pBitmap);
+ if (pixmap_priv->type == GLAMOR_MEMORY) {
+ if (glamor_push_pixels_points(pGC, pBitmap, pDrawable, w, h, x, y))
+ return TRUE;
+ }
+
miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
return TRUE;
}
diff --git a/xorg-server/glamor/glamor_glyphs.c b/xorg-server/glamor/glamor_glyphs.c
index caafa4348..2b2c735d4 100644
--- a/xorg-server/glamor/glamor_glyphs.c
+++ b/xorg-server/glamor/glamor_glyphs.c
@@ -303,7 +303,7 @@ glamor_glyphs_fini(ScreenPtr pScreen)
* rest of the allocated structures for all caches with the given format.
*/
-static Bool
+Bool
glamor_realize_glyph_caches(ScreenPtr pScreen)
{
glamor_screen_private *glamor = glamor_get_screen_private(pScreen);
@@ -314,10 +314,6 @@ glamor_realize_glyph_caches(ScreenPtr pScreen)
};
int i;
- if (glamor->glyph_cache_initialized)
- return TRUE;
-
- glamor->glyph_cache_initialized = TRUE;
memset(glamor->glyphCaches, 0, sizeof(glamor->glyphCaches));
for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
@@ -370,16 +366,27 @@ glamor_realize_glyph_caches(ScreenPtr pScreen)
return FALSE;
}
+/**
+ * Called by glamor_create_screen_resources() to set up the glyph cache.
+ *
+ * This was previously required to be called by the drivers, but not
+ * as of the xserver 1.16 ABI.
+ */
Bool
glamor_glyphs_init(ScreenPtr pScreen)
{
+ glamor_screen_private *glamor = glamor_get_screen_private(pScreen);
+
+ if (glamor->glyph_cache_initialized)
+ return TRUE;
+
if (!dixRegisterPrivateKey(&glamor_glyph_key,
PRIVATE_GLYPH, sizeof(struct glamor_glyph)))
return FALSE;
- /* Skip pixmap creation if we don't intend to use it. */
+ glamor->glyph_cache_initialized = TRUE;
- return glamor_realize_glyph_caches(pScreen);
+ return TRUE;
}
/* The most efficient thing to way to upload the glyph to the screen
diff --git a/xorg-server/glamor/glamor_gradient.c b/xorg-server/glamor/glamor_gradient.c
index 6a7b528f9..f77d6a8e3 100644
--- a/xorg-server/glamor/glamor_gradient.c
+++ b/xorg-server/glamor/glamor_gradient.c
@@ -377,9 +377,7 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
- glamor_link_glsl_prog(gradient_prog);
-
- glUseProgram(0);
+ glamor_link_glsl_prog(screen, gradient_prog, "radial gradient");
if (dyn_gen) {
index = 2;
@@ -590,9 +588,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position");
glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord");
- glamor_link_glsl_prog(gradient_prog);
-
- glUseProgram(0);
+ glamor_link_glsl_prog(screen, gradient_prog, "linear gradient");
if (dyn_gen) {
index = 2;
@@ -983,8 +979,6 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
"repeat_type");
n_stop_uniform_location = glGetUniformLocation(gradient_prog, "n_stop");
A_value_uniform_location = glGetUniformLocation(gradient_prog, "A_value");
- repeat_type_uniform_location =glGetUniformLocation(gradient_prog,
- "repeat_type");
c1_uniform_location = glGetUniformLocation(gradient_prog, "c1");
r1_uniform_location = glGetUniformLocation(gradient_prog, "r1");
c2_uniform_location = glGetUniformLocation(gradient_prog, "c2");
@@ -1171,7 +1165,6 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- glUseProgram(0);
glamor_put_context(glamor_priv);
return dst_picture;
@@ -1193,7 +1186,6 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- glUseProgram(0);
glamor_put_context(glamor_priv);
return NULL;
}
@@ -1524,7 +1516,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- glUseProgram(0);
glamor_put_context(glamor_priv);
return dst_picture;
@@ -1546,7 +1537,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- glUseProgram(0);
glamor_put_context(glamor_priv);
return NULL;
}
diff --git a/xorg-server/glamor/glamor_picture.c b/xorg-server/glamor/glamor_picture.c
index 8bbe2e98b..5fdc5f9b0 100644
--- a/xorg-server/glamor/glamor_picture.c
+++ b/xorg-server/glamor/glamor_picture.c
@@ -55,12 +55,12 @@ glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access)
}
void
-glamor_finish_access_picture(PicturePtr picture, glamor_access_t access)
+glamor_finish_access_picture(PicturePtr picture)
{
if (!picture || !picture->pDrawable)
return;
- glamor_finish_access(picture->pDrawable, access);
+ glamor_finish_access(picture->pDrawable);
}
/*
diff --git a/xorg-server/glamor/glamor_pixmap.c b/xorg-server/glamor/glamor_pixmap.c
index 119e4d9d1..615faad33 100644
--- a/xorg-server/glamor/glamor_pixmap.c
+++ b/xorg-server/glamor/glamor_pixmap.c
@@ -725,8 +725,11 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- if (bits == NULL)
+ assert(pbo || bits != 0);
+ if (bits == NULL) {
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
+ glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
+ }
if (non_sub)
glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits);
else
@@ -853,7 +856,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glUseProgram(0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glDeleteTextures(1, &tex);
@@ -886,7 +888,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
- if (pixmap_priv->base.gl_fbo)
+ if (pixmap_priv->base.gl_fbo != GLAMOR_FBO_UNATTACHED)
return 0;
if (pixmap_priv->base.fbo
@@ -1178,7 +1180,6 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- glUseProgram(0);
glamor_put_context(glamor_priv);
return temp_fbo;
}
@@ -1216,8 +1217,6 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
gl_access = GL_READ_ONLY;
gl_usage = GL_STREAM_READ;
break;
- case GLAMOR_ACCESS_WO:
- return bits;
case GLAMOR_ACCESS_RW:
gl_access = GL_READ_WRITE;
gl_usage = GL_DYNAMIC_DRAW;
@@ -1472,8 +1471,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
stride = pixmap->devKind;
- if (access == GLAMOR_ACCESS_WO
- || glamor_priv->gl_flavor == GLAMOR_GL_ES2
+ if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
|| (!glamor_priv->has_pack_invert && !glamor_priv->yInverted)
|| pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
data = malloc(stride * pixmap->drawable.height);
@@ -1603,12 +1601,6 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h,
return NULL;
w = (x + w) > pixmap->drawable.width ? (pixmap->drawable.width - x) : w;
h = (y + h) > pixmap->drawable.height ? (pixmap->drawable.height - y) : h;
- if (access == GLAMOR_ACCESS_WO) {
- sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
- pixmap->drawable.depth,
- GLAMOR_CREATE_PIXMAP_CPU);
- return sub_pixmap;
- }
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
pixmap_priv = glamor_get_pixmap_private(pixmap);
diff --git a/xorg-server/glamor/glamor_polyfillrect.c b/xorg-server/glamor/glamor_polyfillrect.c
index a25fc4ed5..1e361a44f 100644
--- a/xorg-server/glamor/glamor_polyfillrect.c
+++ b/xorg-server/glamor/glamor_polyfillrect.c
@@ -96,13 +96,12 @@ _glamor_poly_fill_rect(DrawablePtr drawable,
glamor_fallback(" to %p (%c)\n",
drawable, glamor_get_drawable_location(drawable));
- if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
- if (glamor_prepare_access_gc(gc)) {
- fbPolyFillRect(drawable, gc, nrect, prect);
- glamor_finish_access_gc(gc);
- }
- glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
+ if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
+ glamor_prepare_access_gc(gc)) {
+ fbPolyFillRect(drawable, gc, nrect, prect);
}
+ glamor_finish_access_gc(gc);
+ glamor_finish_access(drawable);
ret = TRUE;
done:
diff --git a/xorg-server/glamor/glamor_polylines.c b/xorg-server/glamor/glamor_polylines.c
index b94161760..1adf45ddc 100644
--- a/xorg-server/glamor/glamor_polylines.c
+++ b/xorg-server/glamor/glamor_polylines.c
@@ -51,8 +51,9 @@ _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
/* This ends up in miSetSpans, which is accelerated as well as we
* can hope X wide lines will be.
*/
- goto wide_line;
+ goto fail;
}
+
if (gc->lineStyle != LineSolid) {
glamor_fallback("non-solid fill line style %d\n", gc->lineStyle);
goto fail;
@@ -104,20 +105,19 @@ _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
&& glamor_ddx_fallback_check_gc(gc))
return FALSE;
- if (gc->lineWidth == 0) {
- if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
- if (glamor_prepare_access_gc(gc)) {
- fbPolyLine(drawable, gc, mode, n, points);
- glamor_finish_access_gc(gc);
- }
- glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
- }
- }
- else {
- wide_line:
- /* fb calls mi functions in the lineWidth != 0 case. */
- fbPolyLine(drawable, gc, mode, n, points);
+ switch (gc->lineStyle) {
+ case LineSolid:
+ if (gc->lineWidth == 0)
+ miZeroLine(drawable, gc, mode, n, points);
+ else
+ miWideLine(drawable, gc, mode, n, points);
+ break;
+ case LineOnOffDash:
+ case LineDoubleDash:
+ miWideDash(drawable, gc, mode, n, points);
+ break;
}
+
return TRUE;
}
diff --git a/xorg-server/glamor/glamor_priv.h b/xorg-server/glamor/glamor_priv.h
index d15eabd9e..bc7d3f827 100644
--- a/xorg-server/glamor/glamor_priv.h
+++ b/xorg-server/glamor/glamor_priv.h
@@ -36,6 +36,10 @@
#include "glamor.h"
#include <epoxy/gl.h>
+#if GLAMOR_HAS_GBM
+#define MESA_EGL_NO_X11_HEADERS
+#include <epoxy/egl.h>
+#endif
#define GLAMOR_DEFAULT_PRECISION \
"#ifdef GL_ES\n" \
@@ -169,6 +173,7 @@ typedef struct {
struct glamor_saved_procs {
CloseScreenProcPtr close_screen;
+ CreateScreenResourcesProcPtr create_screen_resources;
CreateGCProcPtr create_gc;
CreatePixmapProcPtr create_pixmap;
DestroyPixmapProcPtr destroy_pixmap;
@@ -209,6 +214,7 @@ typedef struct glamor_screen_private {
int has_pack_invert;
int has_fbo_blit;
int has_buffer_storage;
+ int has_khr_debug;
int max_fbo_size;
struct xorg_list
@@ -283,11 +289,23 @@ typedef struct glamor_screen_private {
typedef enum glamor_access {
GLAMOR_ACCESS_RO,
GLAMOR_ACCESS_RW,
- GLAMOR_ACCESS_WO,
} glamor_access_t;
-#define GLAMOR_FBO_NORMAL 1
-#define GLAMOR_FBO_DOWNLOADED 2
+enum glamor_fbo_state {
+ /** There is no storage attached to the pixmap. */
+ GLAMOR_FBO_UNATTACHED,
+ /**
+ * The pixmap has FBO storage attached, but devPrivate.ptr doesn't
+ * point at anything.
+ */
+ GLAMOR_FBO_NORMAL,
+ /**
+ * The FBO is present and can be accessed as a linear memory
+ * mapping through devPrivate.ptr.
+ */
+ GLAMOR_FBO_DOWNLOADED,
+};
+
/* glamor_pixmap_fbo:
* @list: to be used to link to the cache pool list.
* @expire: when push to cache pool list, set a expire count.
@@ -319,12 +337,6 @@ typedef struct glamor_pixmap_fbo {
/*
* glamor_pixmap_private - glamor pixmap's private structure.
- * @gl_fbo:
- * 0 - The pixmap doesn't has a fbo attached to it.
- * GLAMOR_FBO_NORMAL - The pixmap has a fbo and can be accessed normally.
- * GLAMOR_FBO_DOWNLOADED - The pixmap has a fbo and already downloaded to
- * CPU, so it can only be treated as a in-memory pixmap
- * if this bit is set.
* @gl_tex: The pixmap is in a gl texture originally.
* @is_picture: The drawable is attached to a picture.
* @pict_format: the corresponding picture's format.
@@ -398,7 +410,13 @@ typedef struct glamor_pixmap_clipped_regions {
typedef struct glamor_pixmap_private_base {
glamor_pixmap_type_t type;
- unsigned char gl_fbo:2;
+ enum glamor_fbo_state gl_fbo;
+ /**
+ * If devPrivate.ptr is non-NULL (meaning we're within
+ * glamor_prepare_access), determies whether we should re-upload
+ * that data on glamor_finish_access().
+ */
+ glamor_access_t map_access;
unsigned char is_picture:1;
unsigned char gl_tex:1;
glamor_pixmap_fbo *fbo;
@@ -406,6 +424,9 @@ typedef struct glamor_pixmap_private_base {
int drm_stride;
glamor_screen_private *glamor_priv;
PicturePtr picture;
+#if GLAMOR_HAS_GBM
+ EGLImageKHR image;
+#endif
} glamor_pixmap_private_base_t;
/*
@@ -558,7 +579,7 @@ void glamor_copy_window(WindowPtr win, DDXPointRec old_origin,
/* glamor_core.c */
Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access);
-void glamor_finish_access(DrawablePtr drawable, glamor_access_t access);
+void glamor_finish_access(DrawablePtr drawable);
Bool glamor_prepare_access_window(WindowPtr window);
void glamor_finish_access_window(WindowPtr window);
Bool glamor_prepare_access_gc(GCPtr gc);
@@ -574,7 +595,8 @@ Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
unsigned long fg_pixel, unsigned long bg_pixel,
int stipple_x, int stipple_y);
GLint glamor_compile_glsl_prog(GLenum type, const char *source);
-void glamor_link_glsl_prog(GLint prog);
+void glamor_link_glsl_prog(ScreenPtr screen, GLint prog,
+ const char *format, ...) _X_ATTRIBUTE_PRINTF(3,4);
void glamor_get_color_4f_from_pixel(PixmapPtr pixmap,
unsigned long fg_pixel, GLfloat *color);
@@ -627,6 +649,7 @@ void glamor_get_spans(DrawablePtr drawable,
int nspans, char *dst_start);
/* glamor_glyphs.c */
+Bool glamor_realize_glyph_caches(ScreenPtr screen);
void glamor_glyphs_fini(ScreenPtr screen);
void glamor_glyphs(CARD8 op,
PicturePtr pSrc,
@@ -768,7 +791,7 @@ glamor_put_vbo_space(ScreenPtr screen);
* One copy of current pixmap's texture will be put into
* the pixmap->devPrivate.ptr. Will use pbo to map to
* the pointer if possible.
- * The pixmap must be a gl texture pixmap. gl_fbo and
+ * The pixmap must be a gl texture pixmap. gl_fbo must be GLAMOR_FBO_NORMAL and
* gl_tex must be 1. Used by glamor_prepare_access.
*
*/
@@ -783,9 +806,8 @@ void *glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w,
* glamor_download_pixmap_to_cpu to its original
* gl texture. Used by glamor_finish_access.
*
- * The pixmap must be
- * in texture originally. In other word, the gl_fbo
- * must be 1.
+ * The pixmap must originally be a texture -- gl_fbo must be
+ * GLAMOR_FBO_NORMAL.
**/
void glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
@@ -884,7 +906,7 @@ void glamor_set_window_pixmap(WindowPtr pWindow, PixmapPtr pPixmap);
Bool glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access);
-void glamor_finish_access_picture(PicturePtr picture, glamor_access_t access);
+void glamor_finish_access_picture(PicturePtr picture);
void glamor_destroy_picture(PicturePtr picture);
diff --git a/xorg-server/glamor/glamor_putimage.c b/xorg-server/glamor/glamor_putimage.c
index 702e89f14..cf7197bfc 100644
--- a/xorg-server/glamor/glamor_putimage.c
+++ b/xorg-server/glamor/glamor_putimage.c
@@ -35,204 +35,7 @@
void
glamor_init_putimage_shaders(ScreenPtr screen)
{
-#if 0
- glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- const char *xybitmap_vs =
- "uniform float x_bias;\n"
- "uniform float x_scale;\n"
- "uniform float y_bias;\n"
- "uniform float y_scale;\n"
- "varying vec2 bitmap_coords;\n"
- "void main()\n"
- "{\n"
- " gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
- " (gl_Vertex.y + y_bias) * y_scale,\n"
- " 0,\n"
- " 1);\n"
- " bitmap_coords = gl_MultiTexCoord0.xy;\n"
- "}\n";
- const char *xybitmap_fs =
- "uniform vec4 fg, bg;\n"
- "varying vec2 bitmap_coords;\n"
- "uniform sampler2D bitmap_sampler;\n"
- "void main()\n"
- "{\n"
- " float bitmap_value = texture2D(bitmap_sampler,\n"
- " bitmap_coords).x;\n"
- " gl_FragColor = mix(bg, fg, bitmap_value);\n"
- "}\n";
- GLint fs_prog, vs_prog, prog;
- GLint sampler_uniform_location;
-
- if (!GLEW_ARB_fragment_shader)
- return;
-
- prog = glCreateProgram();
- vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs);
- fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs);
- glAttachShader(prog, vs_prog);
- glAttachShader(prog, fs_prog);
- glamor_link_glsl_prog(prog);
-
- glUseProgram(prog);
- sampler_uniform_location = glGetUniformLocation(prog, "bitmap_sampler");
- glUniform1i(sampler_uniform_location, 0);
-
- glamor_priv->put_image_xybitmap_fg_uniform_location =
- glGetUniformLocation(prog, "fg");
- glamor_priv->put_image_xybitmap_bg_uniform_location =
- glGetUniformLocation(prog, "bg");
- glamor_get_transform_uniform_locations(prog,
- &glamor_priv->
- put_image_xybitmap_transform);
- glamor_priv->put_image_xybitmap_prog = prog;
- glUseProgram(0);
-#endif
-}
-
-/* Do an XYBitmap putimage. The bits are byte-aligned rows of bitmap
- * data (where each row starts at a bit index of left_pad), and the
- * destination gets filled with the gc's fg color where the bitmap is set
- * and the bg color where the bitmap is unset.
- *
- * Implement this by passing the bitmap right through to GL, and sampling
- * it to choose between fg and bg in the fragment shader. The driver may
- * be exploding the bitmap up to be an 8-bit alpha texture, in which
- * case we might be better off just doing the fg/bg choosing in the CPU
- * and just draw the resulting texture to the destination.
- */
-#if 0
-
-static int
-y_flip(PixmapPtr pixmap, int y)
-{
- ScreenPtr screen = pixmap->drawable.pScreen;
- PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
-
- if (pixmap == screen_pixmap)
- return (pixmap->drawable.height - 1) - y;
- else
- return y;
-}
-
-static void
-glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
- int x, int y, int w, int h, int left_pad,
- int image_format, char *bits)
-{
- ScreenPtr screen = drawable->pScreen;
- PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
- glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- float fg[4], bg[4];
- GLuint tex;
- unsigned int stride = PixmapBytePad(1, w + left_pad);
- RegionPtr clip;
- BoxPtr box;
- int nbox;
- float dest_coords[8];
-
- const float bitmap_coords[8] = {
- 0.0, 0.0,
- 1.0, 0.0,
- 1.0, 1.0,
- 0.0, 1.0,
- };
- GLfloat xscale, yscale;
- glamor_pixmap_private *pixmap_priv;
-
- pixmap_priv = glamor_get_pixmap_private(pixmap);
-
- pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
-
- glamor_set_normalize_vcoords(xscale, yscale,
- x, y,
- x + w, y + h,
- glamor_priv->yInverted, dest_coords);
-
- glamor_fallback("glamor_put_image_xybitmap: disabled\n");
- goto fail;
-
- if (glamor_priv->put_image_xybitmap_prog == 0) {
- ErrorF("no program for xybitmap putimage\n");
- goto fail;
- }
-
- glamor_set_alu(gc->alu);
- if (!glamor_set_planemask(pixmap, gc->planemask))
- goto fail;
-
- glUseProgram(glamor_priv->put_image_xybitmap_prog);
-
- glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg);
- glUniform4fv(glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg);
- glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg);
- glUniform4fv(glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg);
-
- glGenTextures(1, &tex);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
- w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
-
- /* Now that we've set up our bitmap texture and the shader, shove
- * the destination rectangle through the cliprects and run the
- * shader on the resulting fragments.
- */
- glVertexPointer(2, GL_FLOAT, 0, dest_coords);
- glEnableClientState(GL_VERTEX_ARRAY);
- glClientActiveTexture(GL_TEXTURE0);
- glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glEnable(GL_SCISSOR_TEST);
- clip = fbGetCompositeClip(gc);
- for (nbox = REGION_NUM_RECTS(clip), box = REGION_RECTS(clip); nbox--; box++) {
- int x1 = x;
- int y1 = y;
- int x2 = x + w;
- int y2 = y + h;
-
- if (x1 < box->x1)
- x1 = box->x1;
- if (y1 < box->y1)
- y1 = box->y1;
- if (x2 > box->x2)
- x2 = box->x2;
- if (y2 > box->y2)
- y2 = box->y2;
- if (x1 >= x2 || y1 >= y2)
- continue;
-
- glScissor(box->x1, y_flip(pixmap, box->y1),
- box->x2 - box->x1, box->y2 - box->y1);
- glDrawArrays(GL_QUADS, 0, 4);
- }
-
- glDisable(GL_SCISSOR_TEST);
- glamor_set_alu(GXcopy);
- glamor_set_planemask(pixmap, ~0);
- glDeleteTextures(1, &tex);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- return;
- glamor_set_alu(GXcopy);
- glamor_set_planemask(pixmap, ~0);
- glamor_fallback(": to %p (%c)\n",
- drawable, glamor_get_drawable_location(drawable));
- fail:
- if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
- fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits);
- glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
- }
}
-#endif
void
glamor_fini_putimage_shaders(ScreenPtr screen)
diff --git a/xorg-server/glamor/glamor_render.c b/xorg-server/glamor/glamor_render.c
index 086526d2e..c0ee22c2f 100644
--- a/xorg-server/glamor/glamor_render.c
+++ b/xorg-server/glamor/glamor_render.c
@@ -332,7 +332,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1");
- glamor_link_glsl_prog(prog);
+ glamor_link_glsl_prog(screen, prog, "composite");
shader->prog = prog;
@@ -961,11 +961,7 @@ glamor_composite_choose_shader(CARD8 op,
* Does it need special handle? */
glamor_fallback("source == dest\n");
}
- if (source_pixmap_priv->base.gl_fbo == 0) {
- /* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex
- * equal to zero when the pixmap is screen pixmap. Then we may
- * refer the tex zero directly latter in the composition.
- * It seems that it works fine, but it may have potential problem*/
+ if (source_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) {
#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
source_status = GLAMOR_UPLOAD_PENDING;
#else
@@ -982,7 +978,7 @@ glamor_composite_choose_shader(CARD8 op,
glamor_fallback("mask == dest\n");
goto fail;
}
- if (mask_pixmap_priv->base.gl_fbo == 0) {
+ if (mask_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) {
#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
mask_status = GLAMOR_UPLOAD_PENDING;
#else
@@ -1339,7 +1335,6 @@ glamor_composite_with_shader(CARD8 op,
glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
glDisable(GL_BLEND);
DEBUGF("finish rendering.\n");
- glUseProgram(0);
glamor_priv->state = RENDER_STATE;
glamor_priv->render_idle_cnt = 0;
if (saved_source_format)
@@ -1788,22 +1783,17 @@ _glamor_composite(CARD8 op,
if (mask && mask->pDrawable && !mask->transform)
GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
- if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
- if (source_pixmap == dest_pixmap || glamor_prepare_access_picture
- (source, GLAMOR_ACCESS_RO)) {
- if (!mask || glamor_prepare_access_picture(mask, GLAMOR_ACCESS_RO)) {
- fbComposite(op,
- source, mask, dest,
- x_source, y_source,
- x_mask, y_mask, x_dest, y_dest, width, height);
- if (mask)
- glamor_finish_access_picture(mask, GLAMOR_ACCESS_RO);
- }
- if (source_pixmap != dest_pixmap)
- glamor_finish_access_picture(source, GLAMOR_ACCESS_RO);
- }
- glamor_finish_access_picture(dest, GLAMOR_ACCESS_RW);
- }
+ if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW) &&
+ glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO) &&
+ glamor_prepare_access_picture(mask, GLAMOR_ACCESS_RO)) {
+ fbComposite(op,
+ source, mask, dest,
+ x_source, y_source,
+ x_mask, y_mask, x_dest, y_dest, width, height);
+ }
+ glamor_finish_access_picture(mask);
+ glamor_finish_access_picture(source);
+ glamor_finish_access_picture(dest);
#define PUT_SUB_PICTURE(p, access) do { \
if (sub_ ##p ##_pixmap != NULL) { \
diff --git a/xorg-server/glamor/glamor_setspans.c b/xorg-server/glamor/glamor_setspans.c
index 22fe88ce5..a51e4c5be 100644
--- a/xorg-server/glamor/glamor_setspans.c
+++ b/xorg-server/glamor/glamor_setspans.c
@@ -48,7 +48,11 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
goto fail;
}
- /* XXX Shall we set alu here? */
+ if (gc->alu != GXcopy) {
+ glamor_fallback("SetSpans with non-copy ALU.\n");
+ goto fail;
+ }
+
if (!glamor_set_planemask(dest_pixmap, gc->planemask))
goto fail;
@@ -86,10 +90,12 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
glamor_fallback("to %p (%c)\n",
drawable, glamor_get_drawable_location(drawable));
- if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
+ if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
+ glamor_prepare_access_gc(gc)) {
fbSetSpans(drawable, gc, src, points, widths, numPoints, sorted);
- glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
}
+ glamor_finish_access_gc(gc);
+ glamor_finish_access(drawable);
ret = TRUE;
done:
diff --git a/xorg-server/glamor/glamor_tile.c b/xorg-server/glamor/glamor_tile.c
index 7288af30e..9e115cad1 100644
--- a/xorg-server/glamor/glamor_tile.c
+++ b/xorg-server/glamor/glamor_tile.c
@@ -73,7 +73,7 @@ glamor_init_tile_shader(ScreenPtr screen)
GLAMOR_VERTEX_POS, "v_position");
glBindAttribLocation(glamor_priv->tile_prog,
GLAMOR_VERTEX_SOURCE, "v_texcoord0");
- glamor_link_glsl_prog(glamor_priv->tile_prog);
+ glamor_link_glsl_prog(screen, glamor_priv->tile_prog, "tile");
sampler_uniform_location =
glGetUniformLocation(glamor_priv->tile_prog, "sampler");
@@ -82,7 +82,6 @@ glamor_init_tile_shader(ScreenPtr screen)
glamor_priv->tile_wh =
glGetUniformLocation(glamor_priv->tile_prog, "wh");
- glUseProgram(0);
glamor_put_context(glamor_priv);
}
@@ -156,7 +155,6 @@ _glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- glUseProgram(0);
glamor_put_context(glamor_priv);
glamor_priv->state = RENDER_STATE;
diff --git a/xorg-server/glamor/glamor_trapezoid.c b/xorg-server/glamor/glamor_trapezoid.c
index 0064f2a24..969ab68bc 100644
--- a/xorg-server/glamor/glamor_trapezoid.c
+++ b/xorg-server/glamor/glamor_trapezoid.c
@@ -982,7 +982,6 @@ _glamor_trapezoids_with_shader(CARD8 op,
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
glDisable(GL_BLEND);
- glUseProgram(0);
glamor_put_context(glamor_priv);
TRAPEZOID_OUT:
@@ -1357,9 +1356,7 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
glBindAttribLocation(glamor_priv->trapezoid_prog,
GLAMOR_VERTEX_RIGHT_PARAM, "v_right_param");
- glamor_link_glsl_prog(glamor_priv->trapezoid_prog);
-
- glUseProgram(0);
+ glamor_link_glsl_prog(screen, glamor_priv->trapezoid_prog, "trapezoid");
glamor_put_context(glamor_priv);
}
@@ -1573,7 +1570,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
- glUseProgram(0);
glamor_put_context(glamor_priv);
return TRUE;
}
diff --git a/xorg-server/glamor/glamor_triangles.c b/xorg-server/glamor/glamor_triangles.c
index 693eef10f..b89cb2de7 100644
--- a/xorg-server/glamor/glamor_triangles.c
+++ b/xorg-server/glamor/glamor_triangles.c
@@ -41,16 +41,13 @@ _glamor_triangles(CARD8 op,
|| glamor_ddx_fallback_check_pixmap(pSrc->pDrawable)))
return FALSE;
- if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW)) {
- if (glamor_prepare_access_picture(pSrc, GLAMOR_ACCESS_RO)) {
-
- fbTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris);
-
- glamor_finish_access_picture(pSrc, GLAMOR_ACCESS_RO);
- }
-
- glamor_finish_access_picture(pDst, GLAMOR_ACCESS_RW);
+ if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW) &&
+ glamor_prepare_access_picture(pSrc, GLAMOR_ACCESS_RO)) {
+ fbTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris);
}
+ glamor_finish_access_picture(pSrc);
+ glamor_finish_access_picture(pDst);
+
return TRUE;
}
diff --git a/xorg-server/glamor/glamor_utils.h b/xorg-server/glamor/glamor_utils.h
index f9550b73c..53b7d9bec 100644
--- a/xorg-server/glamor/glamor_utils.h
+++ b/xorg-server/glamor/glamor_utils.h
@@ -1177,7 +1177,7 @@ glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h)
default:
ErrorF("dump depth %d, not implemented.\n", pixmap->drawable.depth);
}
- glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
+ glamor_finish_access(&pixmap->drawable);
}
static inline void
@@ -1318,13 +1318,12 @@ glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2,
{
assert(pixmap1->drawable.depth == pixmap2->drawable.depth);
- glamor_prepare_access(&pixmap1->drawable, GLAMOR_ACCESS_RO);
- glamor_prepare_access(&pixmap2->drawable, GLAMOR_ACCESS_RO);
-
- _glamor_compare_pixmaps(pixmap1, pixmap2, x, y, w, h, -1, all, diffs);
-
- glamor_finish_access(&pixmap1->drawable, GLAMOR_ACCESS_RO);
- glamor_finish_access(&pixmap2->drawable, GLAMOR_ACCESS_RO);
+ if (glamor_prepare_access(&pixmap1->drawable, GLAMOR_ACCESS_RO) &&
+ glamor_prepare_access(&pixmap2->drawable, GLAMOR_ACCESS_RO)) {
+ _glamor_compare_pixmaps(pixmap1, pixmap2, x, y, w, h, -1, all, diffs);
+ }
+ glamor_finish_access(&pixmap1->drawable);
+ glamor_finish_access(&pixmap2->drawable);
}
/* This function is used to compare two pictures.
@@ -1432,9 +1431,6 @@ glamor_compare_pictures(ScreenPtr screen,
return;
}
- glamor_prepare_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO);
- glamor_prepare_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO);
-
if ((fst_type == SourcePictTypeLinear) ||
(fst_type == SourcePictTypeRadial) ||
(fst_type == SourcePictTypeConical) ||
@@ -1444,12 +1440,15 @@ glamor_compare_pictures(ScreenPtr screen,
x_source = y_source = 0;
}
- _glamor_compare_pixmaps(fst_pixmap, snd_pixmap,
- x_source, y_source,
- width, height, fst_picture->format, all, diffs);
-
- glamor_finish_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO);
- glamor_finish_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO);
+ if (glamor_prepare_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO) &&
+ glamor_prepare_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO)) {
+ _glamor_compare_pixmaps(fst_pixmap, snd_pixmap,
+ x_source, y_source,
+ width, height, fst_picture->format,
+ all, diffs);
+ }
+ glamor_finish_access(&fst_pixmap->drawable);
+ glamor_finish_access(&snd_pixmap->drawable);
if (fst_generated)
glamor_destroy_picture(fst_picture);
diff --git a/xorg-server/glamor/glamor_xv.c b/xorg-server/glamor/glamor_xv.c
index fb9045747..17745a4e8 100644
--- a/xorg-server/glamor/glamor_xv.c
+++ b/xorg-server/glamor/glamor_xv.c
@@ -109,7 +109,7 @@ glamor_init_xv_shader(ScreenPtr screen)
GLAMOR_VERTEX_POS, "v_position");
glBindAttribLocation(glamor_priv->xv_prog,
GLAMOR_VERTEX_SOURCE, "v_texcoord0");
- glamor_link_glsl_prog(glamor_priv->xv_prog);
+ glamor_link_glsl_prog(screen, glamor_priv->xv_prog, "xv");
glamor_put_context(glamor_priv);
}
@@ -416,7 +416,6 @@ glamor_display_textured_video(glamor_port_private *port_priv)
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- glUseProgram(0);
glamor_put_context(glamor_priv);
DamageDamageRegion(port_priv->pDraw, &port_priv->clip);
}
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c
index d56907fe7..9903cc772 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -67,6 +67,9 @@ struct ephyr_glamor {
GLuint texture_shader;
GLuint texture_shader_position_loc;
GLuint texture_shader_texcoord_loc;
+
+ /* Size of the window that we're rendering to. */
+ unsigned width, height;
};
static GLint
@@ -205,6 +208,7 @@ ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glUseProgram(glamor->texture_shader);
+ glViewport(0, 0, glamor->width, glamor->height);
glVertexAttribPointer(glamor->texture_shader_position_loc,
2, GL_FLOAT, FALSE, 0, position);
@@ -309,6 +313,7 @@ ephyr_glamor_get_visual(void)
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DOUBLEBUFFER, 1,
+ GLX_VISUAL_ID, DefaultVisual(dpy, DefaultScreen(dpy)),
None
};
int event_base = 0, error_base = 0, nelements;
@@ -329,3 +334,14 @@ ephyr_glamor_get_visual(void)
return xcb_aux_find_visual_by_id(xscreen, visual_info->visualid);
}
+
+void
+ephyr_glamor_set_window_size(struct ephyr_glamor *glamor,
+ unsigned width, unsigned height)
+{
+ if (!glamor)
+ return;
+
+ glamor->width = width;
+ glamor->height = height;
+}
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.h b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.h
index 8995e1eca..0c238cf5b 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.h
+++ b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.h
@@ -51,6 +51,10 @@ ephyr_glamor_glx_screen_fini(struct ephyr_glamor *glamor);
#ifdef GLAMOR
void
+ephyr_glamor_set_window_size(struct ephyr_glamor *glamor,
+ unsigned width, unsigned height);
+
+void
ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
struct pixman_region16 *damage);
@@ -60,6 +64,12 @@ ephyr_glamor_process_event(xcb_generic_event_t *xev);
#else /* !GLAMOR */
static inline void
+ephyr_glamor_set_window_size(struct ephyr_glamor *glamor,
+ unsigned width, unsigned height)
+{
+}
+
+static inline void
ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
struct pixman_region16 *damage)
{
diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c
index 859becaa6..3260d9527 100644
--- a/xorg-server/hw/kdrive/ephyr/hostx.c
+++ b/xorg-server/hw/kdrive/ephyr/hostx.c
@@ -731,6 +731,8 @@ hostx_screen_init(KdScreenInfo *screen,
if (ephyr_glamor) {
*bytes_per_line = 0;
*bits_per_pixel = 0;
+ ephyr_glamor_set_window_size(scrpriv->glamor,
+ scrpriv->win_width, scrpriv->win_height);
return NULL;
} else if (host_depth_matches_server(scrpriv)) {
*bytes_per_line = scrpriv->ximg->stride;
@@ -1218,6 +1220,8 @@ ephyr_glamor_init(ScreenPtr screen)
EphyrScrPriv *scrpriv = kd_screen->driver;
scrpriv->glamor = ephyr_glamor_glx_screen_init(scrpriv->win);
+ ephyr_glamor_set_window_size(scrpriv->glamor,
+ scrpriv->win_width, scrpriv->win_height);
glamor_init(screen,
GLAMOR_USE_SCREEN |
@@ -1239,9 +1243,6 @@ ephyr_glamor_create_screen_resources(ScreenPtr pScreen)
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
diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h
index 93c45107d..36463f2d1 100644
--- a/xorg-server/include/input.h
+++ b/xorg-server/include/input.h
@@ -385,6 +385,12 @@ extern _X_EXPORT Bool InitKeyboardDeviceStruct(DeviceIntPtr /*device */ ,
KbdCtrlProcPtr /*controlProc */
);
+extern _X_EXPORT Bool InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
+ const char *keymap,
+ int keymap_length,
+ BellProcPtr bell_func,
+ KbdCtrlProcPtr ctrl_func);
+
extern int ApplyPointerMapping(DeviceIntPtr /* pDev */ ,
CARD8 * /* map */ ,
int /* len */ ,
diff --git a/xorg-server/include/xkbsrv.h b/xorg-server/include/xkbsrv.h
index f857b2280..a80e11970 100644
--- a/xorg-server/include/xkbsrv.h
+++ b/xorg-server/include/xkbsrv.h
@@ -824,8 +824,8 @@ extern _X_EXPORT void XkbSendNewKeyboardNotify(DeviceIntPtr /* kbd */ ,
extern Bool XkbCopyKeymap(XkbDescPtr /* dst */ ,
XkbDescPtr /* src */ );
-extern _X_EXPORT Bool XkbCopyDeviceKeymap(DeviceIntPtr /* dst */ ,
- DeviceIntPtr /* src */ );
+extern _X_EXPORT Bool XkbDeviceApplyKeymap(DeviceIntPtr /* dst */ ,
+ XkbDescPtr /* src */ );
extern void XkbFilterEvents(ClientPtr /* pClient */ ,
int /* nEvents */ ,
@@ -841,6 +841,9 @@ extern void XkbFakeDeviceButton(DeviceIntPtr /* dev */ ,
int /* press */ ,
int /* button */ );
+extern _X_EXPORT void XkbCopyControls(XkbDescPtr /* dst */ ,
+ XkbDescPtr /* src */ );
+
#include "xkbfile.h"
#include "xkbrules.h"
@@ -873,4 +876,8 @@ extern _X_EXPORT XkbDescPtr XkbCompileKeymap(DeviceIntPtr /* dev */ ,
XkbRMLVOSet * /* rmlvo */
);
+extern _X_EXPORT XkbDescPtr XkbCompileKeymapFromString(DeviceIntPtr dev,
+ const char *keymap,
+ int keymap_length);
+
#endif /* _XKBSRV_H_ */
diff --git a/xorg-server/miext/sync/misyncstr.h b/xorg-server/miext/sync/misyncstr.h
index b5bf6fd91..ad69e8eca 100644
--- a/xorg-server/miext/sync/misyncstr.h
+++ b/xorg-server/miext/sync/misyncstr.h
@@ -29,6 +29,7 @@
#define _MISYNCSTR_H_
#include "dix.h"
+#include "misync.h"
#include "scrnintstr.h"
#include <X11/extensions/syncconst.h>
diff --git a/xorg-server/xkb/ddxLoad.c b/xorg-server/xkb/ddxLoad.c
index f458e3bde..1dc0e4eee 100644
--- a/xorg-server/xkb/ddxLoad.c
+++ b/xorg-server/xkb/ddxLoad.c
@@ -68,6 +68,9 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define PATHSEPARATOR "/"
#endif
+static unsigned
+LoadXKM(unsigned want, unsigned need, const char *keymap, XkbDescPtr *xkbRtrn);
+
static void
OutputDirectory(char *outdir, size_t size)
{
@@ -90,11 +93,17 @@ OutputDirectory(char *outdir, size_t size)
}
}
-static Bool
-XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
- XkbComponentNamesPtr names,
- unsigned want,
- unsigned need, char *nameRtrn, int nameRtrnLen)
+/**
+ * Callback invoked by XkbRunXkbComp. Write to out to talk to xkbcomp.
+ */
+typedef void (*xkbcomp_buffer_callback)(FILE *out, void *userdata);
+
+/**
+ * Start xkbcomp, let the callback write into xkbcomp's stdin. When done,
+ * return a strdup'd copy of the file name we've written to.
+ */
+static char *
+RunXkbComp(xkbcomp_buffer_callback callback, void *userdata)
{
FILE *out;
char *buf = NULL, keymap[PATH_MAX], xkm_output_dir[PATH_MAX];
@@ -155,7 +164,7 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
if (!buf) {
LogMessage(X_ERROR,
"XKB: Could not invoke xkbcomp: not enough memory\n");
- return FALSE;
+ return NULL;
}
#ifndef WIN32
@@ -165,13 +174,9 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
#endif
if (out != NULL) {
-#ifdef DEBUG
- if (xkbDebugFlags) {
- ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
- XkbWriteXKBKeymapForNames(stderr, names, xkb, want, need);
- }
-#endif
- XkbWriteXKBKeymapForNames(out, names, xkb, want, need);
+ /* Now write to xkbcomp */
+ (*callback)(out, userdata);
+
#ifndef WIN32
if (Pclose(out) == 0)
#else
@@ -180,14 +185,11 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
{
if (xkbDebugFlags)
DebugF("[xkb] xkb executes: %s\n", buf);
- if (nameRtrn) {
- strlcpy(nameRtrn, keymap, nameRtrnLen);
- }
free(buf);
#ifdef WIN32
unlink(tmpname);
#endif
- return TRUE;
+ return xnfstrdup(keymap);
}
else
LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap);
@@ -203,14 +205,101 @@ XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
LogMessage(X_ERROR, "Could not open file %s\n", tmpname);
#endif
}
- if (nameRtrn)
- nameRtrn[0] = '\0';
free(buf);
- return FALSE;
+ return NULL;
+}
+
+typedef struct {
+ XkbDescPtr xkb;
+ XkbComponentNamesPtr names;
+ unsigned int want;
+ unsigned int need;
+} XkbKeymapNamesCtx;
+
+static void
+xkb_write_keymap_for_names_cb(FILE *out, void *userdata)
+{
+ XkbKeymapNamesCtx *ctx = userdata;
+#ifdef DEBUG
+ if (xkbDebugFlags) {
+ ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
+ XkbWriteXKBKeymapForNames(stderr, ctx->names, ctx->xkb, ctx->want, ctx->need);
+ }
+#endif
+ XkbWriteXKBKeymapForNames(out, ctx->names, ctx->xkb, ctx->want, ctx->need);
+}
+
+static Bool
+XkbDDXCompileKeymapByNames(XkbDescPtr xkb,
+ XkbComponentNamesPtr names,
+ unsigned want,
+ unsigned need, char *nameRtrn, int nameRtrnLen)
+{
+ char *keymap;
+ Bool rc = FALSE;
+ XkbKeymapNamesCtx ctx = {
+ .xkb = xkb,
+ .names = names,
+ .want = want,
+ .need = need
+ };
+
+ keymap = RunXkbComp(xkb_write_keymap_for_names_cb, &ctx);
+
+ if (keymap) {
+ if(nameRtrn)
+ strlcpy(nameRtrn, keymap, nameRtrnLen);
+
+ free(keymap);
+ rc = TRUE;
+ } else if (nameRtrn)
+ *nameRtrn = '\0';
+
+ return rc;
+}
+
+typedef struct {
+ const char *keymap;
+ size_t len;
+} XkbKeymapString;
+
+static void
+xkb_write_keymap_string_cb(FILE *out, void *userdata)
+{
+ XkbKeymapString *s = userdata;
+ fwrite(s->keymap, s->len, 1, out);
+}
+
+static unsigned int
+XkbDDXLoadKeymapFromString(DeviceIntPtr keybd,
+ const char *keymap, int keymap_length,
+ unsigned int want,
+ unsigned int need,
+ XkbDescPtr *xkbRtrn)
+{
+ unsigned int have;
+ char *map_name;
+ XkbKeymapString map = {
+ .keymap = keymap,
+ .len = keymap_length
+ };
+
+ *xkbRtrn = NULL;
+
+ map_name = RunXkbComp(xkb_write_keymap_string_cb, &map);
+ if (!map_name) {
+ LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
+ return 0;
+ }
+
+ have = LoadXKM(want, need, map_name, xkbRtrn);
+ free(map_name);
+
+ return have;
}
static FILE *
-XkbDDXOpenConfigFile(char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
+XkbDDXOpenConfigFile(const char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
{
char buf[PATH_MAX], xkm_output_dir[PATH_MAX];
FILE *file;
@@ -245,6 +334,35 @@ XkbDDXOpenConfigFile(char *mapName, char *fileNameRtrn, int fileNameRtrnLen)
return file;
}
+static unsigned
+LoadXKM(unsigned want, unsigned need, const char *keymap, XkbDescPtr *xkbRtrn)
+{
+ FILE *file;
+ char fileName[PATH_MAX];
+ unsigned missing;
+
+ file = XkbDDXOpenConfigFile(keymap, fileName, PATH_MAX);
+ if (file == NULL) {
+ LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
+ fileName);
+ return 0;
+ }
+ missing = XkmReadFile(file, need, want, xkbRtrn);
+ if (*xkbRtrn == NULL) {
+ LogMessage(X_ERROR, "Error loading keymap %s\n", fileName);
+ fclose(file);
+ (void) unlink(fileName);
+ return 0;
+ }
+ else {
+ DebugF("Loaded XKB keymap %s, defined=0x%x\n", fileName,
+ (*xkbRtrn)->defined);
+ }
+ fclose(file);
+ (void) unlink(fileName);
+ return (need | want) & (~missing);
+}
+
unsigned
XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
XkbComponentNamesPtr names,
@@ -253,9 +371,6 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
XkbDescPtr *xkbRtrn, char *nameRtrn, int nameRtrnLen)
{
XkbDescPtr xkb;
- FILE *file;
- char fileName[PATH_MAX];
- unsigned missing;
*xkbRtrn = NULL;
if ((keybd == NULL) || (keybd->key == NULL) ||
@@ -275,26 +390,8 @@ XkbDDXLoadKeymapByNames(DeviceIntPtr keybd,
LogMessage(X_ERROR, "XKB: Couldn't compile keymap\n");
return 0;
}
- file = XkbDDXOpenConfigFile(nameRtrn, fileName, PATH_MAX);
- if (file == NULL) {
- LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",
- fileName);
- return 0;
- }
- missing = XkmReadFile(file, need, want, xkbRtrn);
- if (*xkbRtrn == NULL) {
- LogMessage(X_ERROR, "Error loading keymap %s\n", fileName);
- fclose(file);
- (void) unlink(fileName);
- return 0;
- }
- else {
- DebugF("Loaded XKB keymap %s, defined=0x%x\n", fileName,
- (*xkbRtrn)->defined);
- }
- fclose(file);
- (void) unlink(fileName);
- return (need | want) & (~missing);
+
+ return LoadXKM(want, need, nameRtrn, xkbRtrn);
}
Bool
@@ -390,6 +487,29 @@ XkbCompileKeymapForDevice(DeviceIntPtr dev, XkbRMLVOSet * rmlvo, int need)
return xkb;
}
+static XkbDescPtr
+KeymapOrDefaults(DeviceIntPtr dev, XkbDescPtr xkb)
+{
+ XkbRMLVOSet dflts;
+
+ if (xkb)
+ return xkb;
+
+ /* we didn't get what we really needed. And that will likely leave
+ * us with a keyboard that doesn't work. Use the defaults instead */
+ LogMessage(X_ERROR, "XKB: Failed to load keymap. Loading default "
+ "keymap instead.\n");
+
+ XkbGetRulesDflts(&dflts);
+
+ xkb = XkbCompileKeymapForDevice(dev, &dflts, 0);
+
+ XkbFreeRMLVOSet(&dflts, FALSE);
+
+ return xkb;
+}
+
+
XkbDescPtr
XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
{
@@ -407,20 +527,34 @@ XkbCompileKeymap(DeviceIntPtr dev, XkbRMLVOSet * rmlvo)
xkb = XkbCompileKeymapForDevice(dev, rmlvo, need);
- if (!xkb) {
- XkbRMLVOSet dflts;
-
- /* we didn't get what we really needed. And that will likely leave
- * us with a keyboard that doesn't work. Use the defaults instead */
- LogMessage(X_ERROR, "XKB: Failed to load keymap. Loading default "
- "keymap instead.\n");
+ return KeymapOrDefaults(dev, xkb);
+}
- XkbGetRulesDflts(&dflts);
+XkbDescPtr
+XkbCompileKeymapFromString(DeviceIntPtr dev,
+ const char *keymap, int keymap_length)
+{
+ XkbDescPtr xkb;
+ unsigned int need, provided;
- xkb = XkbCompileKeymapForDevice(dev, &dflts, 0);
+ if (!dev || !keymap) {
+ LogMessage(X_ERROR, "XKB: No device or keymap specified\n");
+ return NULL;
+ }
- XkbFreeRMLVOSet(&dflts, FALSE);
+ /* These are the components we really really need */
+ need = XkmSymbolsMask | XkmCompatMapMask | XkmTypesMask |
+ XkmKeyNamesMask | XkmVirtualModsMask;
+
+ provided =
+ XkbDDXLoadKeymapFromString(dev, keymap, keymap_length,
+ XkmAllIndicesMask, need, &xkb);
+ if ((need & provided) != need) {
+ if (xkb) {
+ XkbFreeKeyboard(xkb, 0, TRUE);
+ xkb = NULL;
+ }
}
- return xkb;
+ return KeymapOrDefaults(dev, xkb);
}
diff --git a/xorg-server/xkb/xkb.c b/xorg-server/xkb/xkb.c
index 31bb8d3c5..dc570f0e5 100644
--- a/xorg-server/xkb/xkb.c
+++ b/xorg-server/xkb/xkb.c
@@ -5950,25 +5950,13 @@ ProcXkbGetKbdByName(ClientPtr client)
if (rep.loaded) {
XkbDescPtr old_xkb;
xkbNewKeyboardNotify nkn;
- int i, nG, nTG;
old_xkb = xkb;
xkb = new;
dev->key->xkbInfo->desc = xkb;
new = old_xkb; /* so it'll get freed automatically */
- *xkb->ctrls = *old_xkb->ctrls;
- for (nG = nTG = 0, i = xkb->min_key_code; i <= xkb->max_key_code; i++) {
- nG = XkbKeyNumGroups(xkb, i);
- if (nG >= XkbNumKbdGroups) {
- nTG = XkbNumKbdGroups;
- break;
- }
- if (nG > nTG) {
- nTG = nG;
- }
- }
- xkb->ctrls->num_groups = nTG;
+ XkbCopyControls(xkb, old_xkb);
nkn.deviceID = nkn.oldDeviceID = dev->id;
nkn.minKeyCode = new->min_key_code;
@@ -5991,7 +5979,7 @@ ProcXkbGetKbdByName(ClientPtr client)
continue;
if (tmpd != dev)
- XkbCopyDeviceKeymap(tmpd, dev);
+ XkbDeviceApplyKeymap(tmpd, xkb);
if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
old_sli = tmpd->kbdfeed->xkb_sli;
diff --git a/xorg-server/xkb/xkbInit.c b/xorg-server/xkb/xkbInit.c
index 33420b6b6..06ec46e81 100644
--- a/xorg-server/xkb/xkbInit.c
+++ b/xorg-server/xkb/xkbInit.c
@@ -505,9 +505,10 @@ XkbInitControls(DeviceIntPtr pXDev, XkbSrvInfoPtr xkbi)
return Success;
}
-_X_EXPORT Bool
-InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
- BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+static Bool
+InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
+ const char *keymap, int keymap_length,
+ BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
{
int i;
unsigned int check;
@@ -521,8 +522,9 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
BUG_RETURN_VAL(dev == NULL, FALSE);
BUG_RETURN_VAL(dev->key != NULL, FALSE);
BUG_RETURN_VAL(dev->kbdfeed != NULL, FALSE);
+ BUG_RETURN_VAL(rmlvo && keymap, FALSE);
- if (!rmlvo) {
+ if (!rmlvo && !keymap) {
rmlvo = &rmlvo_dflts;
XkbGetRulesDflts(rmlvo);
}
@@ -550,7 +552,7 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
}
dev->key->xkbInfo = xkbi;
- if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) {
+ if (xkb_cached_map && (keymap || (rmlvo && !XkbCompareUsedRMLVO(rmlvo)))) {
XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE);
xkb_cached_map = NULL;
}
@@ -558,7 +560,11 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
if (xkb_cached_map)
LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n");
else {
- xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
+ if (rmlvo)
+ xkb_cached_map = XkbCompileKeymap(dev, rmlvo);
+ else
+ xkb_cached_map = XkbCompileKeymapFromString(dev, keymap, keymap_length);
+
if (!xkb_cached_map) {
ErrorF("XKB: Failed to compile keymap\n");
goto unwind_info;
@@ -627,8 +633,10 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
dev->kbdfeed->CtrlProc(dev, &dev->kbdfeed->ctrl);
- XkbSetRulesDflts(rmlvo);
- XkbSetRulesUsed(rmlvo);
+ if (rmlvo) {
+ XkbSetRulesDflts(rmlvo);
+ XkbSetRulesUsed(rmlvo);
+ }
XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
return TRUE;
@@ -647,6 +655,24 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
return FALSE;
}
+_X_EXPORT Bool
+InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
+ BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+{
+ return InitKeyboardDeviceStructInternal(dev, rmlvo,
+ NULL, 0, bell_func, ctrl_func);
+}
+
+_X_EXPORT Bool
+InitKeyboardDeviceStructFromString(DeviceIntPtr dev,
+ const char *keymap, int keymap_length,
+ BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func)
+{
+ return InitKeyboardDeviceStructInternal(dev, NULL,
+ keymap, keymap_length,
+ bell_func, ctrl_func);
+}
+
/***====================================================================***/
/*
diff --git a/xorg-server/xkb/xkbUtils.c b/xorg-server/xkb/xkbUtils.c
index 6c6af60f0..6cf6e79df 100644
--- a/xorg-server/xkb/xkbUtils.c
+++ b/xorg-server/xkb/xkbUtils.c
@@ -1999,28 +1999,28 @@ XkbCopyKeymap(XkbDescPtr dst, XkbDescPtr src)
}
Bool
-XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src)
+XkbDeviceApplyKeymap(DeviceIntPtr dst, XkbDescPtr desc)
{
xkbNewKeyboardNotify nkn;
Bool ret;
- if (!dst->key || !src->key)
+ if (!dst->key || !desc)
return FALSE;
memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
nkn.oldMinKeyCode = dst->key->xkbInfo->desc->min_key_code;
nkn.oldMaxKeyCode = dst->key->xkbInfo->desc->max_key_code;
nkn.deviceID = dst->id;
- nkn.oldDeviceID = dst->id; /* maybe src->id? */
- nkn.minKeyCode = src->key->xkbInfo->desc->min_key_code;
- nkn.maxKeyCode = src->key->xkbInfo->desc->max_key_code;
+ nkn.oldDeviceID = dst->id;
+ nkn.minKeyCode = desc->min_key_code;
+ nkn.maxKeyCode = desc->max_key_code;
nkn.requestMajor = XkbReqCode;
nkn.requestMinor = X_kbSetMap; /* Near enough's good enough. */
nkn.changed = XkbNKN_KeycodesMask;
- if (src->key->xkbInfo->desc->geom)
+ if (desc->geom)
nkn.changed |= XkbNKN_GeometryMask;
- ret = XkbCopyKeymap(dst->key->xkbInfo->desc, src->key->xkbInfo->desc);
+ ret = XkbCopyKeymap(dst->key->xkbInfo->desc, desc);
if (ret)
XkbSendNewKeyboardNotify(dst, &nkn);
@@ -2090,3 +2090,26 @@ XkbMergeLockedPtrBtns(DeviceIntPtr master)
xkbi->lockedPtrButtons |= d->key->xkbInfo->lockedPtrButtons;
}
}
+
+void
+XkbCopyControls(XkbDescPtr dst, XkbDescPtr src)
+{
+ int i, nG, nTG;
+
+ if (!dst || !src)
+ return;
+
+ *dst->ctrls = *src->ctrls;
+
+ for (nG = nTG = 0, i = dst->min_key_code; i <= dst->max_key_code; i++) {
+ nG = XkbKeyNumGroups(dst, i);
+ if (nG >= XkbNumKbdGroups) {
+ nTG = XkbNumKbdGroups;
+ break;
+ }
+ if (nG > nTG) {
+ nTG = nG;
+ }
+ }
+ dst->ctrls->num_groups = nTG;
+}