Commit b861aad8 authored by Zhigang Gong's avatar Zhigang Gong Committed by Eric Anholt

Initial version.

Signed-off-by: default avatarZhigang Gong <zhigang.gong@linux.intel.com>
parent 2dbbe256
noinst_LTLIBRARIES = libglamor.la inst_LTLIBRARIES = libglamor.la
# Override these since glamor doesn't need them and the needed files aren't # Override these since glamor doesn't need them and the needed files aren't
# built (in hw/xfree86/os-support/solaris) until after glamor is built # built (in hw/xfree86/os-support/solaris) until after glamor is built
SOLARIS_ASM_CFLAGS="" SOLARIS_ASM_CFLAGS=""
if XORG
sdk_HEADERS = glamor.h
endif
if GLAMOR_GLES2 if GLAMOR_GLES2
libglamor_la_LIBADD = $(GLESV2_LIBS) libglamor_la_LIBADD = $(GLESV2_LIBS)
else else
libglamor_la_LIBADD = $(GL_LIBS) libglamor_la_LIBADD = $(GL_LIBS)
endif endif
if XORG instdir = $(moduledir)
sdk_HEADERS = glamor.h
endif
INCLUDES = \ INCLUDES = \
$(XORG_INCS) $(XORG_INCS)
AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS) AM_CFLAGS = $(XORG_CFLAGS) $(DIX_CFLAGS) $(LIBDRM_CFLAGS)
libglamor_la_LDFLAGS = -avoid-version
libglamor_la_SOURCES = \ libglamor_la_SOURCES = \
glamor.c \ glamor.c \
glamor_copyarea.c \ glamor_copyarea.c \
...@@ -45,3 +40,17 @@ libglamor_la_SOURCES = \ ...@@ -45,3 +40,17 @@ libglamor_la_SOURCES = \
glamor_window.c\ glamor_window.c\
glamor_gl_dispatch.c\ glamor_gl_dispatch.c\
glamor.h glamor.h
sdk_HEADERS = glamor.h
if EGL
LIBGLAMOR_EGL = libglamor_egl.la
module_LTLIBRARIES = $(LIBGLAMOR_EGL)
libglamor_egl_la_DEPENDENCIES = libglamor.la
libglamor_egl_la_LDFLAGS = -avoid-version -module $(EGL_LIBS) -lglamor
#libglamor_egl_la_LIBADD = $(top_builddir)/src/libglamor.la
libglamor_egl_la_SOURCES = glamor_eglmodule.c $(top_srcdir)/src/glamor_egl.c
libglamor_egl_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/src $(LIBDRM_CFLAGS) $(EGL_CFLAGS)
endif
This diff is collapsed.
...@@ -39,25 +39,43 @@ ...@@ -39,25 +39,43 @@
#include "fb.h" #include "fb.h"
#include "fbpict.h" #include "fbpict.h"
#endif /* GLAMOR_H */ #endif /* GLAMOR_H */
#define GLAMOR_INVERTED_Y_AXIS 1 #define GLAMOR_INVERTED_Y_AXIS 1
#define GLAMOR_HOSTX 2 #define GLAMOR_USE_SCREEN 2
#define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS | GLAMOR_HOSTX) #define GLAMOR_USE_PICTURE_SCREEN 4
#define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS \
| GLAMOR_USE_SCREEN \
| GLAMOR_USE_PICTURE_SCREEN)
#define GLAMOR_EGL_EXTERNAL_BUFFER 3 #define GLAMOR_EGL_EXTERNAL_BUFFER 3
extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags); extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
extern _X_EXPORT void glamor_fini(ScreenPtr screen); extern _X_EXPORT void glamor_fini(ScreenPtr screen);
extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen, int w, int h, unsigned int tex); extern _X_EXPORT void glamor_set_screen_pixmap_texture(ScreenPtr screen,
extern _X_EXPORT Bool glamor_glyphs_init (ScreenPtr pScreen); int w, int h,
void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex); unsigned int tex);
extern _X_EXPORT Bool glamor_glyphs_init(ScreenPtr pScreen);
void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h,
unsigned int tex);
extern _X_EXPORT void glamor_destroy_textured_pixmap(PixmapPtr pixmap);
extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
#ifdef GLAMOR_FOR_XORG #ifdef GLAMOR_FOR_XORG
extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd); extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd);
extern _X_EXPORT Bool glamor_create_egl_screen_image(ScreenPtr screen, int handle, int stride); extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen,
extern _X_EXPORT Bool glamor_create_egl_pixmap_image(PixmapPtr pixmap, int handle, int stride); int handle,
extern _X_EXPORT Bool glamor_close_egl_screen(ScreenPtr screen); int stride);
extern _X_EXPORT void glamor_free_egl_screen(int scrnIndex, int flags); extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap,
int handle,
int stride);
extern _X_EXPORT Bool glamor_egl_close_screen(ScreenPtr screen);
extern _X_EXPORT void glamor_egl_free_screen(int scrnIndex, int flags);
extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen);
extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap);
#endif #endif
This diff is collapsed.
...@@ -32,29 +32,31 @@ ...@@ -32,29 +32,31 @@
* Screen CopyWindow implementation. * Screen CopyWindow implementation.
*/ */
void glamor_copy_window(WindowPtr win, DDXPointRec old_origin, void
RegionPtr src_region) glamor_copy_window(WindowPtr win, DDXPointRec old_origin,
RegionPtr src_region)
{ {
RegionRec dst_region; RegionRec dst_region;
int dx, dy; int dx, dy;
PixmapPtr pixmap = win->drawable.pScreen->GetWindowPixmap(win); PixmapPtr pixmap = win->drawable.pScreen->GetWindowPixmap(win);
dx = old_origin.x - win->drawable.x; dx = old_origin.x - win->drawable.x;
dy = old_origin.y - win->drawable.y; dy = old_origin.y - win->drawable.y;
REGION_TRANSLATE(win->drawable.pScreen, src_region, -dx, -dy); REGION_TRANSLATE(win->drawable.pScreen, src_region, -dx, -dy);
REGION_INIT(win->drawable.pScreen, &dst_region, NullBox, 0); REGION_INIT(win->drawable.pScreen, &dst_region, NullBox, 0);
REGION_INTERSECT(win->drawable.pScreen, &dst_region, &win->borderClip, REGION_INTERSECT(win->drawable.pScreen, &dst_region,
src_region); &win->borderClip, src_region);
#ifdef COMPOSITE #ifdef COMPOSITE
if (pixmap->screen_x || pixmap->screen_y) if (pixmap->screen_x || pixmap->screen_y)
REGION_TRANSLATE(win->drawable.pScreen, &dst_region, REGION_TRANSLATE(win->drawable.pScreen, &dst_region,
-pixmap->screen_x, -pixmap->screen_y); -pixmap->screen_x, -pixmap->screen_y);
#endif #endif
miCopyRegion(&pixmap->drawable, &pixmap->drawable, miCopyRegion(&pixmap->drawable, &pixmap->drawable,
NULL, &dst_region, dx, dy, glamor_copy_n_to_n, 0, NULL); NULL, &dst_region, dx, dy, glamor_copy_n_to_n, 0,
NULL);
REGION_UNINIT(win->drawable.pScreen, &dst_region); REGION_UNINIT(win->drawable.pScreen, &dst_region);
} }
This diff is collapsed.
...@@ -11,7 +11,8 @@ ...@@ -11,7 +11,8 @@
#define GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD 3 #define GLAMOR_DEBUG_TEXTURE_DYNAMIC_UPLOAD 3
extern void extern void
AbortServer(void) _X_NORETURN; AbortServer(void)
_X_NORETURN;
#define GLAMOR_PANIC(_format_, ...) \ #define GLAMOR_PANIC(_format_, ...) \
do { \ do { \
...@@ -19,9 +20,9 @@ AbortServer(void) _X_NORETURN; ...@@ -19,9 +20,9 @@ AbortServer(void) _X_NORETURN;
" at %32s line %d: " _format_ "\n", \ " at %32s line %d: " _format_ "\n", \
__FUNCTION__, __LINE__, \ __FUNCTION__, __LINE__, \
##__VA_ARGS__ ); \ ##__VA_ARGS__ ); \
AbortServer(); \ exit(1); \
} while(0) } while(0)
......
This diff is collapsed.
/*
* Copyright (C) 1998 The XFree86 Project, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of the XFree86 Project shall
* not be used in advertising or otherwise to promote the sale, use or other
* dealings in this Software without prior written authorization from the
* XFree86 Project.
*/
#include <xorg-server.h>
#include "xf86Module.h"
static XF86ModuleVersionInfo VersRec = {
"glamor_egl",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XORG_VERSION_CURRENT,
1, 0, 0,
ABI_CLASS_ANSIC, /* Only need the ansic layer */
ABI_ANSIC_VERSION,
MOD_CLASS_NONE,
{0, 0, 0, 0} /* signature, to be patched into the file by a tool */
};
_X_EXPORT XF86ModuleData glamor_eglModuleData = { &VersRec, NULL, NULL };
...@@ -32,174 +32,167 @@ ...@@ -32,174 +32,167 @@
* GC fill implementation, based loosely on fb_fill.c * GC fill implementation, based loosely on fb_fill.c
*/ */
void Bool
glamor_fill(DrawablePtr drawable, glamor_fill(DrawablePtr drawable,
GCPtr gc, GCPtr gc, int x, int y, int width, int height)
int x,
int y,
int width,
int height)
{ {
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
int off_x, off_y; int off_x, off_y;
glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y); glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y);
switch (gc->fillStyle) { switch (gc->fillStyle) {
case FillSolid: case FillSolid:
if (!glamor_solid(dst_pixmap, if (!glamor_solid(dst_pixmap,
x + off_x, x + off_x,
y + off_y, y + off_y,
width, width, height, gc->alu, gc->planemask,
height, gc->fgPixel))
gc->alu, goto fail;
gc->planemask, break;
gc->fgPixel)) case FillStippled:
goto fail; case FillOpaqueStippled:
break; if (!glamor_stipple(dst_pixmap,
case FillStippled: gc->stipple,
case FillOpaqueStippled: x + off_x,
if (!glamor_stipple(dst_pixmap, y + off_y,
gc->stipple, width,
x + off_x, height,
y + off_y, gc->alu,
width, gc->planemask,
height, gc->fgPixel,
gc->alu, gc->bgPixel, gc->patOrg.x,
gc->planemask, gc->patOrg.y))
gc->fgPixel, goto fail;
gc->bgPixel, break;
gc->patOrg.x, case FillTiled:
gc->patOrg.y)) if (!glamor_tile(dst_pixmap,
goto fail; gc->tile.pixmap,
return; x + off_x,
break; y + off_y,
case FillTiled: width,
if (!glamor_tile(dst_pixmap, height,
gc->tile.pixmap, gc->alu,
x + off_x, gc->planemask,
y + off_y, drawable->x + x + off_x - gc->patOrg.x,
width, drawable->y + y + off_y - gc->patOrg.y))
height, goto fail;
gc->alu, break;
gc->planemask, }
drawable->x + x + off_x - gc->patOrg.x, return TRUE;
drawable->y + y + off_y - gc->patOrg.y)) fail:
goto fail; if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
break; if (glamor_prepare_access_gc(gc)) {
} fbFill(drawable, gc, x, y, width, height);
return; glamor_finish_access_gc(gc);
fail: }
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { glamor_finish_access(drawable);
if (glamor_prepare_access_gc(gc)) {
fbFill(drawable, gc, x, y, width, height);
glamor_finish_access_gc(gc);
} }
glamor_finish_access(drawable); return TRUE;
}
return;
} }
void void
glamor_init_solid_shader(ScreenPtr screen) glamor_init_solid_shader(ScreenPtr screen)
{ {
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv =
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_get_screen_private(screen);
const char *solid_vs = glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
"attribute vec4 v_position;" const char *solid_vs =
"void main()\n" "attribute vec4 v_position;"
"{\n" "void main()\n" "{\n" " gl_Position = v_position;\n"
" gl_Position = v_position;\n" "}\n";
"}\n"; const char *solid_fs =
const char *solid_fs = GLAMOR_DEFAULT_PRECISION "uniform vec4 color;\n"
GLAMOR_DEFAULT_PRECISION "void main()\n" "{\n" " gl_FragColor = color;\n" "}\n";
"uniform vec4 color;\n" GLint fs_prog, vs_prog;
"void main()\n"
"{\n" glamor_priv->solid_prog = dispatch->glCreateProgram();
" gl_FragColor = color;\n" vs_prog =
"}\n"; glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
GLint fs_prog, vs_prog; fs_prog =
glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
glamor_priv->solid_prog = dispatch->glCreateProgram(); solid_fs);
vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs); dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog);
fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, solid_fs); dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog);
dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog);
dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog); dispatch->glBindAttribLocation(glamor_priv->solid_prog,
GLAMOR_VERTEX_POS, "v_position");
dispatch->glBindAttribLocation(glamor_priv->solid_prog, GLAMOR_VERTEX_POS, "v_position"); glamor_link_glsl_prog(dispatch, glamor_priv->solid_prog);
glamor_link_glsl_prog(dispatch, glamor_priv->solid_prog);
glamor_priv->solid_color_uniform_location =
glamor_priv->solid_color_uniform_location = dispatch->glGetUniformLocation(glamor_priv->solid_prog,
dispatch->glGetUniformLocation(glamor_priv->solid_prog, "color"); "color");
} }
Bool Bool
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
unsigned char alu, unsigned long planemask, unsigned long fg_pixel) unsigned char alu, unsigned long planemask,
unsigned long fg_pixel)
{ {
ScreenPtr screen = pixmap->drawable.pScreen; ScreenPtr screen = pixmap->drawable.pScreen;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv =
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch; glamor_pixmap_private *pixmap_priv =
int x1 = x; glamor_get_pixmap_private(pixmap);
int x2 = x + width; glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
int y1 = y; int x1 = x;
int y2 = y + height; int x2 = x + width;
GLfloat color[4]; int y1 = y;
float vertices[8]; int y2 = y + height;
GLfloat xscale, yscale; GLfloat color[4];
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { float vertices[8];
glamor_fallback("dest %p has no fbo.\n", pixmap); GLfloat xscale, yscale;
goto fail; if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
} glamor_fallback("dest %p has no fbo.\n", pixmap);
glamor_set_alu(dispatch, alu); goto fail;
if (!glamor_set_planemask(pixmap, planemask)) { }
glamor_fallback("Failedto set planemask in glamor_solid.\n"); glamor_set_alu(dispatch, alu);
goto fail; if (!glamor_set_planemask(pixmap, planemask)) {
} glamor_fallback
("Failedto set planemask in glamor_solid.\n");
glamor_get_rgba_from_pixel(fg_pixel, goto fail;
&color[0], }
&color[1],
&color[2], glamor_get_rgba_from_pixel(fg_pixel,
&color[3], &color[0],
format_for_pixmap(pixmap)); &color[1],
&color[2],
&color[3], format_for_pixmap(pixmap));
#ifdef GLAMOR_DELAYED_FILLING #ifdef GLAMOR_DELAYED_FILLING
if (x == 0 && y == 0 if (x == 0 && y == 0
&& width == pixmap->drawable.width && width == pixmap->drawable.width
&& height == pixmap->drawable.height && height == pixmap->drawable.height
&& pixmap_priv->fb != glamor_priv->screen_fbo ) { && pixmap_priv->fb != glamor_priv->screen_fbo) {
pixmap_priv->pending_op.type = GLAMOR_PENDING_FILL; pixmap_priv->pending_op.type = GLAMOR_PENDING_FILL;
memcpy(&pixmap_priv->pending_op.fill.color4fv, memcpy(&pixmap_priv->pending_op.fill.color4fv,
color, 4*sizeof(GLfloat)); color, 4 * sizeof(GLfloat));
pixmap_priv->pending_op.fill.colori = fg_pixel; pixmap_priv->pending_op.fill.colori = fg_pixel;
return TRUE; return TRUE;
} }
#endif #endif
glamor_set_destination_pixmap_priv_nc(pixmap_priv); glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap); glamor_validate_pixmap(pixmap);
dispatch->glUseProgram(glamor_priv->solid_prog); dispatch->glUseProgram(glamor_priv->solid_prog);
dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
1, color);
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
2 * sizeof(float), vertices); dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); GL_FALSE, 2 * sizeof(float),
pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); vertices);
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2, pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
glamor_priv->yInverted,
vertices); glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,
dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glamor_priv->yInverted, vertices);
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
dispatch->glUseProgram(0); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
return TRUE; dispatch->glUseProgram(0);
fail: return TRUE;
glamor_set_alu(dispatch, GXcopy); fail:
glamor_set_planemask(pixmap, ~0); glamor_set_alu(dispatch, GXcopy);
return FALSE; glamor_set_planemask(pixmap, ~0);
return FALSE;
} }
...@@ -32,58 +32,54 @@ ...@@ -32,58 +32,54 @@
void void
glamor_fill_spans(DrawablePtr drawable, glamor_fill_spans(DrawablePtr drawable,
GCPtr gc, GCPtr gc,
int n, int n, DDXPointPtr points, int *widths, int sorted)
DDXPointPtr points,
int *widths,
int sorted)
{ {
DDXPointPtr ppt; DDXPointPtr ppt;
int nbox; int nbox;
BoxPtr pbox; BoxPtr pbox;
int x1, x2, y; int x1, x2, y;
RegionPtr pClip = fbGetCompositeClip(gc); RegionPtr pClip = fbGetCompositeClip(gc);
if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled) if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
goto fail; goto fail;
ppt = points; ppt = points;
while (n--) { while (n--) {
x1 = ppt->x; x1 = ppt->x;
y = ppt->y; y = ppt->y;
x2 = x1 + (int)*widths; x2 = x1 + (int) *widths;
ppt++; ppt++;
widths++; widths++;
nbox = REGION_NUM_RECTS(pClip); nbox = REGION_NUM_RECTS(pClip);
pbox = REGION_RECTS(pClip); pbox = REGION_RECTS(pClip);
while (nbox--) { while (nbox--) {
if (pbox->y1 > y || pbox->y2 <= y) if (pbox->y1 > y || pbox->y2 <= y)
continue; continue;
if (x1 < pbox->x1) if (x1 < pbox->x1)
x1 = pbox->x1; x1 = pbox->x1;
if (x2 > pbox->x2) if (x2 > pbox->x2)
x2 = pbox->x2; x2 = pbox->x2;
if (x2 <= x1) if (x2 <= x1)
continue; continue;
glamor_fill (drawable,gc, glamor_fill(drawable, gc, x1, y, x2 - x1, 1);
x1, y, pbox++;
x2 - x1 , 1); }
pbox++; }
} return;
} fail:
return; glamor_fallback("to %p (%c)\n", drawable,
fail: glamor_get_drawable_location(drawable));
glamor_fallback("to %p (%c)\n", drawable, if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
glamor_get_drawable_location(drawable));