glamor: Don't direct call to any gl functions.

Create a new structure glamor_gl_dispatch to hold all the
gl function's pointer and initialize them at run time ,
rather than use them directly. To do this is to avoid
symbol conflicts.

Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
Zhigang Gong 2011-09-08 14:05:46 +08:00
parent 7daf9af086
commit 0dff23d65b
18 changed files with 638 additions and 422 deletions

View File

@ -43,4 +43,5 @@ libglamor_la_SOURCES = \
glamor_pixmap.c\ glamor_pixmap.c\
glamor_picture.c\ glamor_picture.c\
glamor_window.c\ glamor_window.c\
glamor_gl_dispatch.c\
glamor.h glamor.h

View File

@ -59,7 +59,7 @@ glamor_get_drawable_pixmap(DrawablePtr drawable)
return (PixmapPtr)drawable; return (PixmapPtr)drawable;
} }
static void void
glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex) glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex)
{ {
ScreenPtr screen = pixmap->drawable.pScreen; ScreenPtr screen = pixmap->drawable.pScreen;
@ -111,6 +111,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
int type = GLAMOR_PIXMAP_TEXTURE; int type = GLAMOR_PIXMAP_TEXTURE;
glamor_pixmap_private *pixmap_priv; glamor_pixmap_private *pixmap_priv;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
if (w > 32767 || h > 32767) if (w > 32767 || h > 32767)
return NullPixmap; return NullPixmap;
@ -141,6 +142,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
pixmap_priv = glamor_get_pixmap_private(pixmap); pixmap_priv = glamor_get_pixmap_private(pixmap);
pixmap_priv->container = pixmap; pixmap_priv->container = pixmap;
pixmap_priv->glamor_priv = glamor_priv;
if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY) if (w == 0 || h == 0 || type == GLAMOR_PIXMAP_MEMORY)
return pixmap; return pixmap;
@ -160,11 +162,11 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
} }
/* Create the texture used to store the pixmap's data. */ /* Create the texture used to store the pixmap's data. */
glGenTextures(1, &tex); dispatch->glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex); dispatch->glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, dispatch->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
format, GL_UNSIGNED_BYTE, NULL); format, GL_UNSIGNED_BYTE, NULL);
glamor_set_pixmap_texture(pixmap, w, h, tex); glamor_set_pixmap_texture(pixmap, w, h, tex);
@ -210,14 +212,16 @@ glamor_create_screen_pixmap(ScreenPtr screen, int w, int h, int depth,
static Bool static Bool
glamor_destroy_pixmap(PixmapPtr pixmap) glamor_destroy_pixmap(PixmapPtr pixmap)
{ {
glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
if (pixmap->refcnt == 1) { if (pixmap->refcnt == 1) {
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
if (pixmap_priv->fb) if (pixmap_priv->fb)
glDeleteFramebuffers(1, &pixmap_priv->fb); dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
if (pixmap_priv->tex) if (pixmap_priv->tex)
glDeleteTextures(1, &pixmap_priv->tex); dispatch->glDeleteTextures(1, &pixmap_priv->tex);
if (pixmap_priv->pbo) if (pixmap_priv->pbo)
glDeleteBuffers(1, &pixmap_priv->pbo); dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
dixFreePrivates(pixmap->devPrivates, PRIVATE_PIXMAP); dixFreePrivates(pixmap->devPrivates, PRIVATE_PIXMAP);
} }
@ -227,7 +231,8 @@ glamor_destroy_pixmap(PixmapPtr pixmap)
static void static void
glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask) glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask)
{ {
glFlush(); glamor_gl_dispatch *dispatch = data;
dispatch->glFlush();
} }
static void static void
@ -295,6 +300,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
goto fail; goto fail;
} }
glamor_gl_dispatch_init(screen, &glamor_priv->dispatch, gl_version);
#ifdef GLAMOR_GLES2 #ifdef GLAMOR_GLES2
if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) { if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) {
@ -305,11 +311,11 @@ glamor_init(ScreenPtr screen, unsigned int flags)
glamor_priv->has_pack_invert = glamor_gl_has_extension("GL_MESA_pack_invert"); glamor_priv->has_pack_invert = glamor_gl_has_extension("GL_MESA_pack_invert");
glamor_priv->has_fbo_blit = glamor_gl_has_extension("GL_EXT_framebuffer_blit"); glamor_priv->has_fbo_blit = glamor_gl_has_extension("GL_EXT_framebuffer_blit");
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size); glamor_priv->dispatch.glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size);
if (!RegisterBlockAndWakeupHandlers(glamor_block_handler, if (!RegisterBlockAndWakeupHandlers(glamor_block_handler,
glamor_wakeup_handler, glamor_wakeup_handler,
NULL)) { (void*)&glamor_priv->dispatch)) {
goto fail; goto fail;
} }

View File

@ -52,10 +52,12 @@ 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, int w, int h, unsigned int tex);
extern _X_EXPORT Bool glamor_glyphs_init (ScreenPtr pScreen); extern _X_EXPORT Bool glamor_glyphs_init (ScreenPtr pScreen);
void glamor_set_pixmap_texture(PixmapPtr pixmap, int w, int h, unsigned int tex);
#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_create_egl_screen_image(ScreenPtr screen, int handle, int stride);
extern _X_EXPORT Bool glamor_create_egl_pixmap_image(PixmapPtr pixmap, int handle, int stride);
extern _X_EXPORT Bool glamor_close_egl_screen(ScreenPtr screen); extern _X_EXPORT Bool glamor_close_egl_screen(ScreenPtr screen);
extern _X_EXPORT void glamor_free_egl_screen(int scrnIndex, int flags); extern _X_EXPORT void glamor_free_egl_screen(int scrnIndex, int flags);
#endif #endif

View File

@ -46,6 +46,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
glamor_pixmap_private *src_pixmap_priv; glamor_pixmap_private *src_pixmap_priv;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
int dst_x_off, dst_y_off, src_x_off, src_y_off, i; int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
if (!glamor_priv->has_fbo_blit) { if (!glamor_priv->has_fbo_blit) {
@ -78,14 +79,14 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
} }
glamor_validate_pixmap(dst_pixmap); glamor_validate_pixmap(dst_pixmap);
glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb); dispatch->glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb);
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
src_y_off += dy; src_y_off += dy;
for (i = 0; i < nbox; i++) { for (i = 0; i < nbox; i++) {
if(glamor_priv->yInverted) { if(glamor_priv->yInverted) {
glBlitFramebuffer((box[i].x1 + dx + src_x_off), dispatch->glBlitFramebuffer((box[i].x1 + dx + src_x_off),
(box[i].y1 + src_y_off), (box[i].y1 + src_y_off),
(box[i].x2 + dx + src_x_off), (box[i].x2 + dx + src_x_off),
(box[i].y2 + src_y_off), (box[i].y2 + src_y_off),
@ -101,7 +102,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
int flip_src_y1 = src_pixmap->drawable.height - (box[i].y2 + src_y_off); int flip_src_y1 = src_pixmap->drawable.height - (box[i].y2 + src_y_off);
int flip_src_y2 = src_pixmap->drawable.height - (box[i].y1 + src_y_off); int flip_src_y2 = src_pixmap->drawable.height - (box[i].y1 + src_y_off);
glBlitFramebuffer(box[i].x1 + dx + src_x_off, dispatch->glBlitFramebuffer(box[i].x1 + dx + src_x_off,
flip_src_y1, flip_src_y1,
box[i].x2 + dx + src_x_off, box[i].x2 + dx + src_x_off,
flip_src_y2, flip_src_y2,
@ -129,6 +130,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
{ {
glamor_screen_private *glamor_priv = glamor_screen_private *glamor_priv =
glamor_get_screen_private(dst->pScreen); glamor_get_screen_private(dst->pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
int i; int i;
@ -162,7 +164,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
flush_needed = 1; flush_needed = 1;
if (gc) { if (gc) {
glamor_set_alu(gc->alu); glamor_set_alu(dispatch, gc->alu);
if (!glamor_set_planemask(dst_pixmap, gc->planemask)) if (!glamor_set_planemask(dst_pixmap, gc->planemask))
goto fail; goto fail;
if (gc->alu != GXcopy) { if (gc->alu != GXcopy) {
@ -181,10 +183,10 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
2 * sizeof(float), 2 * sizeof(float),
vertices); vertices);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
@ -192,25 +194,25 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
dy += src_y_off; dy += src_y_off;
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
glActiveTexture(GL_TEXTURE0); dispatch->glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
glEnable(GL_TEXTURE_2D); dispatch->glEnable(GL_TEXTURE_2D);
#endif #endif
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
2 * sizeof(float), 2 * sizeof(float),
texcoords); texcoords);
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glUseProgram(glamor_priv->finish_access_prog[0]); dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
glUniform1i(glamor_priv->finish_access_no_revert[0], 1); dispatch->glUniform1i(glamor_priv->finish_access_no_revert[0], 1);
glUniform1i(glamor_priv->finish_access_swap_rb[0], 0); dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], 0);
} }
else { else {
GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv); GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv, src_pixmap_priv);
} }
for (i = 0; i < nbox; i++) { for (i = 0; i < nbox; i++) {
@ -230,24 +232,24 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
glamor_priv->yInverted, glamor_priv->yInverted,
texcoords); texcoords);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
} }
glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
glDisable(GL_TEXTURE_2D); dispatch->glDisable(GL_TEXTURE_2D);
#endif #endif
} }
glUseProgram(0); dispatch->glUseProgram(0);
/* The source texture is bound to a fbo, we have to flush it here. */ /* The source texture is bound to a fbo, we have to flush it here. */
if (flush_needed) if (flush_needed)
glFlush(); dispatch->glFlush();
return TRUE; return TRUE;
fail: fail:
glamor_set_alu(GXcopy); glamor_set_alu(dispatch, GXcopy);
glamor_set_planemask(dst_pixmap, ~0); glamor_set_planemask(dst_pixmap, ~0);
return FALSE; return FALSE;
} }

View File

@ -54,49 +54,24 @@ glamor_get_drawable_location(const DrawablePtr drawable)
return 'f'; return 'f';
} }
void
glamor_get_transform_uniform_locations(GLint prog,
glamor_transform_uniforms *uniform_locations)
{
uniform_locations->x_bias = glGetUniformLocation(prog, "x_bias");
uniform_locations->x_scale = glGetUniformLocation(prog, "x_scale");
uniform_locations->y_bias = glGetUniformLocation(prog, "y_bias");
uniform_locations->y_scale = glGetUniformLocation(prog, "y_scale");
}
/* We don't use a full matrix for our transformations because it's
* wasteful when all we want is to rescale to NDC and possibly do a flip
* if it's the front buffer.
*/
void
glamor_set_transform_for_pixmap(PixmapPtr pixmap,
glamor_transform_uniforms *uniform_locations)
{
glUniform1f(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
glUniform1f(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
glUniform1f(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
glUniform1f(uniform_locations->y_scale, -2.0f / pixmap->drawable.height);
}
GLint GLint
glamor_compile_glsl_prog(GLenum type, const char *source) glamor_compile_glsl_prog(glamor_gl_dispatch *dispatch, GLenum type, const char *source)
{ {
GLint ok; GLint ok;
GLint prog; GLint prog;
prog = glCreateShader(type); prog = dispatch->glCreateShader(type);
glShaderSource(prog, 1, (const GLchar **)&source, NULL); dispatch->glShaderSource(prog, 1, (const GLchar **)&source, NULL);
glCompileShader(prog); dispatch->glCompileShader(prog);
glGetShaderiv(prog, GL_COMPILE_STATUS, &ok); dispatch->glGetShaderiv(prog, GL_COMPILE_STATUS, &ok);
if (!ok) { if (!ok) {
GLchar *info; GLchar *info;
GLint size; GLint size;
glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size); dispatch->glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &size);
info = malloc(size); info = malloc(size);
glGetShaderInfoLog(prog, size, NULL, info); dispatch->glGetShaderInfoLog(prog, size, NULL, info);
ErrorF("Failed to compile %s: %s\n", ErrorF("Failed to compile %s: %s\n",
type == GL_FRAGMENT_SHADER ? "FS" : "VS", type == GL_FRAGMENT_SHADER ? "FS" : "VS",
info); info);
@ -108,20 +83,20 @@ glamor_compile_glsl_prog(GLenum type, const char *source)
} }
void void
glamor_link_glsl_prog(GLint prog) glamor_link_glsl_prog(glamor_gl_dispatch *dispatch, GLint prog)
{ {
GLint ok; GLint ok;
glLinkProgram(prog); dispatch->glLinkProgram(prog);
glGetProgramiv(prog, GL_LINK_STATUS, &ok); dispatch->glGetProgramiv(prog, GL_LINK_STATUS, &ok);
if (!ok) { if (!ok) {
GLchar *info; GLchar *info;
GLint size; GLint size;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size); dispatch->glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &size);
info = malloc(size); info = malloc(size);
glGetProgramInfoLog(prog, size, NULL, info); dispatch->glGetProgramInfoLog(prog, size, NULL, info);
ErrorF("Failed to link: %s\n", ErrorF("Failed to link: %s\n",
info); info);
FatalError("GLSL link failure\n"); FatalError("GLSL link failure\n");
@ -140,6 +115,7 @@ void
glamor_init_finish_access_shaders(ScreenPtr screen) glamor_init_finish_access_shaders(ScreenPtr screen)
{ {
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
const char *vs_source = const char *vs_source =
"attribute vec4 v_position;\n" "attribute vec4 v_position;\n"
"attribute vec4 v_texcoord0;\n" "attribute vec4 v_texcoord0;\n"
@ -200,51 +176,51 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
GLint fs_prog, vs_prog, avs_prog, set_alpha_prog; GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
GLint sampler_uniform_location; GLint sampler_uniform_location;
glamor_priv->finish_access_prog[0] = glCreateProgram(); glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram();
glamor_priv->finish_access_prog[1] = glCreateProgram(); glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram();
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source);
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_source); fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, fs_source);
glAttachShader(glamor_priv->finish_access_prog[0], vs_prog); dispatch->glAttachShader(glamor_priv->finish_access_prog[0], vs_prog);
glAttachShader(glamor_priv->finish_access_prog[0], fs_prog); dispatch->glAttachShader(glamor_priv->finish_access_prog[0], fs_prog);
avs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_source); avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, vs_source);
set_alpha_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, set_alpha_source); set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, set_alpha_source);
glAttachShader(glamor_priv->finish_access_prog[1], avs_prog); dispatch->glAttachShader(glamor_priv->finish_access_prog[1], avs_prog);
glAttachShader(glamor_priv->finish_access_prog[1], set_alpha_prog); dispatch->glAttachShader(glamor_priv->finish_access_prog[1], set_alpha_prog);
glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_POS, "v_position"); dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_POS, "v_position");
glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); dispatch->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(dispatch, glamor_priv->finish_access_prog[0]);
glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_POS, "v_position"); dispatch->glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_POS, "v_position");
glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); dispatch->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(dispatch, glamor_priv->finish_access_prog[1]);
glamor_priv->finish_access_no_revert[0] = glamor_priv->finish_access_no_revert[0] =
glGetUniformLocation(glamor_priv->finish_access_prog[0], "no_revert"); dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "no_revert");
glamor_priv->finish_access_swap_rb[0] = glamor_priv->finish_access_swap_rb[0] =
glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb"); dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "swap_rb");
sampler_uniform_location = sampler_uniform_location =
glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler"); dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[0], "sampler");
glUseProgram(glamor_priv->finish_access_prog[0]); dispatch->glUseProgram(glamor_priv->finish_access_prog[0]);
glUniform1i(sampler_uniform_location, 0); dispatch->glUniform1i(sampler_uniform_location, 0);
glUniform1i(glamor_priv->finish_access_no_revert[0],1); dispatch->glUniform1i(glamor_priv->finish_access_no_revert[0],1);
glUniform1i(glamor_priv->finish_access_swap_rb[0],0); dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0],0);
glUseProgram(0); dispatch->glUseProgram(0);
glamor_priv->finish_access_no_revert[1] = glamor_priv->finish_access_no_revert[1] =
glGetUniformLocation(glamor_priv->finish_access_prog[1], "no_revert"); dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "no_revert");
glamor_priv->finish_access_swap_rb[1] = glamor_priv->finish_access_swap_rb[1] =
glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb"); dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "swap_rb");
sampler_uniform_location = sampler_uniform_location =
glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler"); dispatch->glGetUniformLocation(glamor_priv->finish_access_prog[1], "sampler");
glUseProgram(glamor_priv->finish_access_prog[1]); dispatch->glUseProgram(glamor_priv->finish_access_prog[1]);
glUniform1i(glamor_priv->finish_access_no_revert[1],1); dispatch->glUniform1i(glamor_priv->finish_access_no_revert[1],1);
glUniform1i(sampler_uniform_location, 0); dispatch->glUniform1i(sampler_uniform_location, 0);
glUniform1i(glamor_priv->finish_access_swap_rb[1],0); dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[1],0);
glUseProgram(0); dispatch->glUseProgram(0);
} }
@ -254,6 +230,7 @@ glamor_finish_access(DrawablePtr drawable)
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
return; return;
@ -264,10 +241,10 @@ glamor_finish_access(DrawablePtr drawable)
if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) { if (pixmap_priv->pbo != 0 && pixmap_priv->pbo_valid) {
assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
glBindBuffer (GL_PIXEL_PACK_BUFFER, 0); dispatch->glBindBuffer (GL_PIXEL_PACK_BUFFER, 0);
glBindBuffer (GL_PIXEL_UNPACK_BUFFER, 0); dispatch->glBindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
pixmap_priv->pbo_valid = FALSE; pixmap_priv->pbo_valid = FALSE;
glDeleteBuffers(1, &pixmap_priv->pbo); dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
pixmap_priv->pbo = 0; pixmap_priv->pbo = 0;
} else { } else {
free(pixmap->devPrivate.ptr); free(pixmap->devPrivate.ptr);

View File

@ -54,6 +54,7 @@
#define GLAMOR_FOR_XORG #define GLAMOR_FOR_XORG
#include <glamor.h> #include <glamor.h>
#include <glamor_gl_dispatch.h>
#define GLAMOR_VERSION_MAJOR 0 #define GLAMOR_VERSION_MAJOR 0
#define GLAMOR_VERSION_MINOR 1 #define GLAMOR_VERSION_MINOR 1
@ -84,6 +85,7 @@ struct glamor_screen_private {
PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa; PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr; PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr;
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
struct glamor_gl_dispatch *dispatch;
}; };
int xf86GlamorEGLPrivateIndex = -1; int xf86GlamorEGLPrivateIndex = -1;
@ -127,10 +129,10 @@ _glamor_create_egl_screen_image(ScrnInfoPtr scrn, int width, int height, int str
if (image == EGL_NO_IMAGE_KHR) if (image == EGL_NO_IMAGE_KHR)
return FALSE; return FALSE;
glGenTextures(1, &texture); glamor->dispatch->glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture); glamor->dispatch->glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glamor->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glamor->dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
(glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image); (glamor->egl_image_target_texture2d_oes)(GL_TEXTURE_2D, image);
@ -296,3 +298,14 @@ glamor_free_egl_screen(int scrnIndex, int flags)
free(glamor); free(glamor);
} }
} }
Bool
glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version)
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
struct glamor_screen_private *glamor_egl = glamor_get_egl_screen_private(scrn);
if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, eglGetProcAddress))
return FALSE;
glamor_egl->dispatch = dispatch;
return TRUE;
}

View File

@ -105,6 +105,7 @@ 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_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
const char *solid_vs = const char *solid_vs =
"attribute vec4 v_position;" "attribute vec4 v_position;"
"void main()\n" "void main()\n"
@ -120,17 +121,17 @@ glamor_init_solid_shader(ScreenPtr screen)
"}\n"; "}\n";
GLint fs_prog, vs_prog; GLint fs_prog, vs_prog;
glamor_priv->solid_prog = glCreateProgram(); glamor_priv->solid_prog = dispatch->glCreateProgram();
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs); vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs); fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, solid_fs);
glAttachShader(glamor_priv->solid_prog, vs_prog); dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog);
glAttachShader(glamor_priv->solid_prog, fs_prog); dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog);
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(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 =
glGetUniformLocation(glamor_priv->solid_prog, "color"); dispatch->glGetUniformLocation(glamor_priv->solid_prog, "color");
} }
Bool Bool
@ -140,6 +141,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
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_get_screen_private(screen);
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
int x1 = x; int x1 = x;
int x2 = x + width; int x2 = x + width;
int y1 = y; int y1 = y;
@ -151,7 +153,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
glamor_fallback("dest %p has no fbo.\n", pixmap); glamor_fallback("dest %p has no fbo.\n", pixmap);
goto fail; goto fail;
} }
glamor_set_alu(alu); glamor_set_alu(dispatch, alu);
if (!glamor_set_planemask(pixmap, planemask)) { if (!glamor_set_planemask(pixmap, planemask)) {
glamor_fallback("Failedto set planemask in glamor_solid.\n"); glamor_fallback("Failedto set planemask in glamor_solid.\n");
goto fail; goto fail;
@ -178,24 +180,24 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
glamor_set_destination_pixmap_priv_nc(pixmap_priv); glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap); glamor_validate_pixmap(pixmap);
glUseProgram(glamor_priv->solid_prog); dispatch->glUseProgram(glamor_priv->solid_prog);
glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
2 * sizeof(float), vertices); 2 * sizeof(float), vertices);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2, glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,
glamor_priv->yInverted, glamor_priv->yInverted,
vertices); vertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glUseProgram(0); dispatch->glUseProgram(0);
return TRUE; return TRUE;
fail: fail:
glamor_set_alu(GXcopy); glamor_set_alu(dispatch, GXcopy);
glamor_set_planemask(pixmap, ~0); glamor_set_planemask(pixmap, ~0);
return FALSE; return FALSE;
} }

View File

@ -44,6 +44,7 @@ glamor_get_spans(DrawablePtr drawable,
int no_alpha, no_revert; int no_alpha, no_revert;
glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
PixmapPtr temp_pixmap = NULL; PixmapPtr temp_pixmap = NULL;
int i; int i;
uint8_t *readpixels_dst = (uint8_t *)dst; uint8_t *readpixels_dst = (uint8_t *)dst;
@ -79,14 +80,14 @@ glamor_get_spans(DrawablePtr drawable,
glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if (glamor_priv->yInverted) { if (glamor_priv->yInverted) {
glReadPixels(points[i].x + x_off, dispatch->glReadPixels(points[i].x + x_off,
(points[i].y + y_off), (points[i].y + y_off),
widths[i], widths[i],
1, 1,
format, type, format, type,
readpixels_dst); readpixels_dst);
} else { } else {
glReadPixels(points[i].x + x_off, dispatch->glReadPixels(points[i].x + x_off,
pixmap->drawable.height - 1 - (points[i].y + y_off), pixmap->drawable.height - 1 - (points[i].y + y_off),
widths[i], widths[i],
1, 1,

View File

@ -0,0 +1,73 @@
#include "glamor_priv.h"
#define INIT_FUNC(dst,func_name,get) \
dst->func_name = get(#func_name); \
if (dst->func_name == NULL) \
{ ErrorF("Failed to get fun %s", #func_name); \
goto fail; }
Bool
glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
int gl_version,
void *(*get_proc_address)(const char*))
{
INIT_FUNC(dispatch, glMatrixMode, get_proc_address);
INIT_FUNC(dispatch, glLoadIdentity, get_proc_address);
INIT_FUNC(dispatch, glViewport, get_proc_address);
INIT_FUNC(dispatch, glRasterPos2i, get_proc_address);
INIT_FUNC(dispatch, glDrawArrays, get_proc_address);
INIT_FUNC(dispatch, glReadPixels, get_proc_address);
INIT_FUNC(dispatch, glDrawPixels, get_proc_address);
INIT_FUNC(dispatch, glPixelStorei, get_proc_address);
INIT_FUNC(dispatch, glTexParameteri, get_proc_address);
INIT_FUNC(dispatch, glTexImage2D, get_proc_address);
INIT_FUNC(dispatch, glGenTextures, get_proc_address);
INIT_FUNC(dispatch, glDeleteTextures, get_proc_address);
INIT_FUNC(dispatch, glBindTexture, get_proc_address);
INIT_FUNC(dispatch, glTexSubImage2D, get_proc_address);
INIT_FUNC(dispatch, glFlush, get_proc_address);
INIT_FUNC(dispatch, glGetIntegerv, get_proc_address);
INIT_FUNC(dispatch, glGetString, get_proc_address);
INIT_FUNC(dispatch, glScissor, get_proc_address);
INIT_FUNC(dispatch, glEnable, get_proc_address);
INIT_FUNC(dispatch, glDisable, get_proc_address);
INIT_FUNC(dispatch, glBlendFunc, get_proc_address);
INIT_FUNC(dispatch, glLogicOp, get_proc_address);
INIT_FUNC(dispatch, glActiveTexture, get_proc_address);
INIT_FUNC(dispatch, glGenBuffers, get_proc_address);
INIT_FUNC(dispatch, glBufferData, get_proc_address);
INIT_FUNC(dispatch, glMapBuffer, get_proc_address);
INIT_FUNC(dispatch, glUnmapBuffer, get_proc_address);
INIT_FUNC(dispatch, glBindBuffer, get_proc_address);
INIT_FUNC(dispatch, glDeleteBuffers, get_proc_address);
INIT_FUNC(dispatch, glFramebufferTexture2D, get_proc_address);
INIT_FUNC(dispatch, glBindFramebuffer, get_proc_address);
INIT_FUNC(dispatch, glDeleteFramebuffers, get_proc_address);
INIT_FUNC(dispatch, glGenFramebuffers, get_proc_address);
INIT_FUNC(dispatch, glCheckFramebufferStatus, get_proc_address);
INIT_FUNC(dispatch, glBlitFramebuffer, get_proc_address);
INIT_FUNC(dispatch, glVertexAttribPointer, get_proc_address);
INIT_FUNC(dispatch, glDisableVertexAttribArray, get_proc_address);
INIT_FUNC(dispatch, glEnableVertexAttribArray, get_proc_address);
INIT_FUNC(dispatch, glBindAttribLocation, get_proc_address);
INIT_FUNC(dispatch, glLinkProgram, get_proc_address);
INIT_FUNC(dispatch, glShaderSource, get_proc_address);
INIT_FUNC(dispatch, glUseProgram, get_proc_address);
INIT_FUNC(dispatch, glUniform1i, get_proc_address);
INIT_FUNC(dispatch, glUniform4f, get_proc_address);
INIT_FUNC(dispatch, glUniform4fv, get_proc_address);
INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
INIT_FUNC(dispatch, glCreateShader, get_proc_address);
INIT_FUNC(dispatch, glCompileShader, get_proc_address);
INIT_FUNC(dispatch, glAttachShader, get_proc_address);
INIT_FUNC(dispatch, glGetShaderiv, get_proc_address);
INIT_FUNC(dispatch, glGetShaderInfoLog, get_proc_address);
INIT_FUNC(dispatch, glGetProgramiv, get_proc_address);
INIT_FUNC(dispatch, glGetProgramInfoLog, get_proc_address);
INIT_FUNC(dispatch, glGetUniformLocation, get_proc_address);
return TRUE;
fail:
return FALSE;
}

101
glamor/glamor_gl_dispatch.h Normal file
View File

@ -0,0 +1,101 @@
typedef struct glamor_gl_dispatch {
/* Transformation functions */
void (*glMatrixMode)(GLenum mode);
void (*glLoadIdentity)(void);
void (*glViewport)( GLint x, GLint y,
GLsizei width, GLsizei height );
/* Drawing functions */
void (*glRasterPos2i)( GLint x, GLint y );
/* Vertex Array */
void (*glDrawArrays)( GLenum mode, GLint first, GLsizei count );
/* Raster functions */
void (*glReadPixels)( GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
GLvoid *pixels );
void (*glDrawPixels)( GLsizei width, GLsizei height,
GLenum format, GLenum type,
const GLvoid *pixels );
void (*glPixelStorei)( GLenum pname, GLint param );
/* Texture Mapping */
void (*glTexParameteri)( GLenum target, GLenum pname, GLint param );
void (*glTexImage2D)( GLenum target, GLint level,
GLint internalFormat,
GLsizei width, GLsizei height,
GLint border, GLenum format, GLenum type,
const GLvoid *pixels );
/* 1.1 */
void (*glGenTextures)( GLsizei n, GLuint *textures );
void (*glDeleteTextures)( GLsizei n, const GLuint *textures);
void (*glBindTexture)( GLenum target, GLuint texture );
void (*glTexSubImage2D)( GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const GLvoid *pixels );
/* MISC */
void (*glFlush)( void );
void (*glGetIntegerv)( GLenum pname, GLint *params );
const GLubyte * (*glGetString)( GLenum name );
void (*glScissor)( GLint x, GLint y, GLsizei width, GLsizei height);
void (*glEnable)( GLenum cap );
void (*glDisable)( GLenum cap );
void (*glBlendFunc)( GLenum sfactor, GLenum dfactor );
void (*glLogicOp)( GLenum opcode );
/* 1.3 */
void (*glActiveTexture)( GLenum texture );
/* GL Extentions */
void (*glGenBuffers) (GLsizei n, GLuint *buffers);
void (*glBufferData) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
GLvoid* (*glMapBuffer) (GLenum target, GLenum access);
GLboolean (*glUnmapBuffer) (GLenum target);
void (*glBindBuffer) (GLenum target, GLuint buffer);
void (*glDeleteBuffers) (GLsizei n, const GLuint *buffers);
void (*glFramebufferTexture2D) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
void (*glBindFramebuffer) (GLenum target, GLuint framebuffer);
void (*glDeleteFramebuffers) (GLsizei n, const GLuint *framebuffers);
void (*glGenFramebuffers) (GLsizei n, GLuint *framebuffers);
GLenum (*glCheckFramebufferStatus) (GLenum target);
void (*glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
void (*glVertexAttribPointer) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
void (*glDisableVertexAttribArray) (GLuint index);
void (*glEnableVertexAttribArray) (GLuint index);
void (*glBindAttribLocation) (GLuint program, GLuint index, const GLchar *name);
void (*glLinkProgram) (GLuint program);
void (*glShaderSource) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
void (*glUseProgram) (GLuint program);
void (*glUniform1i) (GLint location, GLint v0);
void (*glUniform4f) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
void (*glUniform4fv) (GLint location, GLsizei count, const GLfloat *value);
GLuint (*glCreateProgram) (void);
GLuint (*glCreateShader) (GLenum type);
void (*glCompileShader) (GLuint shader);
void (*glAttachShader) (GLuint program, GLuint shader);
void (*glGetShaderiv) (GLuint shader, GLenum pname, GLint *params);
void (*glGetShaderInfoLog) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
void (*glGetProgramiv) (GLuint program, GLenum pname, GLint *params);
void (*glGetProgramInfoLog) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
GLint (*glGetUniformLocation) (GLuint program, const GLchar *name);
}glamor_gl_dispatch;
Bool
glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
int gl_version,
void *(*get_proc_address)(const char*));
Bool
glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version);

View File

@ -31,12 +31,13 @@ static void
_glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv, _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv,
glamor_pixmap_private *pixmap_priv) glamor_pixmap_private *pixmap_priv)
{ {
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
GLfloat vertices[8]; GLfloat vertices[8];
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
2 * sizeof(float), vertices); 2 * sizeof(float), vertices);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
glUseProgram(glamor_priv->solid_prog); dispatch->glUseProgram(glamor_priv->solid_prog);
glUniform4fv(glamor_priv->solid_color_uniform_location, dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
1, pixmap_priv->pending_op.fill.color4fv); 1, pixmap_priv->pending_op.fill.color4fv);
vertices[0] = -1; vertices[0] = -1;
vertices[1] = -1; vertices[1] = -1;
@ -46,9 +47,9 @@ _glamor_pixmap_validate_filling(glamor_screen_private *glamor_priv,
vertices[5] = 1; vertices[5] = 1;
vertices[6] = -1; vertices[6] = -1;
vertices[7] = 1; vertices[7] = 1;
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glUseProgram(0); dispatch->glUseProgram(0);
pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE; pixmap_priv->pending_op.type = GLAMOR_PENDING_NONE;
} }
@ -83,14 +84,15 @@ glamor_validate_pixmap(PixmapPtr pixmap)
void void
glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv) glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
{ {
glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
glMatrixMode(GL_PROJECTION); dispatch->glMatrixMode(GL_PROJECTION);
glLoadIdentity(); dispatch->glLoadIdentity();
glMatrixMode(GL_MODELVIEW); dispatch->glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); dispatch->glLoadIdentity();
#endif #endif
glViewport(0, 0, dispatch->glViewport(0, 0,
pixmap_priv->container->drawable.width, pixmap_priv->container->drawable.width,
pixmap_priv->container->drawable.height); pixmap_priv->container->drawable.height);
@ -130,59 +132,59 @@ glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
void void
glamor_set_alu(unsigned char alu) glamor_set_alu(struct glamor_gl_dispatch *dispatch, unsigned char alu)
{ {
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
if (alu == GXcopy) { if (alu == GXcopy) {
glDisable(GL_COLOR_LOGIC_OP); dispatch->glDisable(GL_COLOR_LOGIC_OP);
return; return;
} }
glEnable(GL_COLOR_LOGIC_OP); dispatch->glEnable(GL_COLOR_LOGIC_OP);
switch (alu) { switch (alu) {
case GXclear: case GXclear:
glLogicOp(GL_CLEAR); dispatch->glLogicOp(GL_CLEAR);
break; break;
case GXand: case GXand:
glLogicOp(GL_AND); dispatch->glLogicOp(GL_AND);
break; break;
case GXandReverse: case GXandReverse:
glLogicOp(GL_AND_REVERSE); dispatch->glLogicOp(GL_AND_REVERSE);
break; break;
case GXandInverted: case GXandInverted:
glLogicOp(GL_AND_INVERTED); dispatch->glLogicOp(GL_AND_INVERTED);
break; break;
case GXnoop: case GXnoop:
glLogicOp(GL_NOOP); dispatch->glLogicOp(GL_NOOP);
break; break;
case GXxor: case GXxor:
glLogicOp(GL_XOR); dispatch->glLogicOp(GL_XOR);
break; break;
case GXor: case GXor:
glLogicOp(GL_OR); dispatch->glLogicOp(GL_OR);
break; break;
case GXnor: case GXnor:
glLogicOp(GL_NOR); dispatch->glLogicOp(GL_NOR);
break; break;
case GXequiv: case GXequiv:
glLogicOp(GL_EQUIV); dispatch->glLogicOp(GL_EQUIV);
break; break;
case GXinvert: case GXinvert:
glLogicOp(GL_INVERT); dispatch->glLogicOp(GL_INVERT);
break; break;
case GXorReverse: case GXorReverse:
glLogicOp(GL_OR_REVERSE); dispatch->glLogicOp(GL_OR_REVERSE);
break; break;
case GXcopyInverted: case GXcopyInverted:
glLogicOp(GL_COPY_INVERTED); dispatch->glLogicOp(GL_COPY_INVERTED);
break; break;
case GXorInverted: case GXorInverted:
glLogicOp(GL_OR_INVERTED); dispatch->glLogicOp(GL_OR_INVERTED);
break; break;
case GXnand: case GXnand:
glLogicOp(GL_NAND); dispatch->glLogicOp(GL_NAND);
break; break;
case GXset: case GXset:
glLogicOp(GL_SET); dispatch->glLogicOp(GL_SET);
break; break;
default: default:
FatalError("unknown logic op\n"); FatalError("unknown logic op\n");
@ -206,6 +208,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
{ {
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
unsigned int stride, row_length; unsigned int stride, row_length;
void *texels; void *texels;
GLenum iformat; GLenum iformat;
@ -231,24 +234,24 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format, GLenum type,
stride = pixmap->devKind; stride = pixmap->devKind;
row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
glBindTexture(GL_TEXTURE_2D, tex); dispatch->glBindTexture(GL_TEXTURE_2D, tex);
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length); dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
} }
else { else {
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
} }
if (pixmap_priv->pbo && pixmap_priv->pbo_valid) { if (pixmap_priv->pbo && pixmap_priv->pbo_valid) {
texels = NULL; texels = NULL;
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixmap_priv->pbo); dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixmap_priv->pbo);
} }
else else
texels = pixmap->devPrivate.ptr; texels = pixmap->devPrivate.ptr;
glTexImage2D(GL_TEXTURE_2D, dispatch->glTexImage2D(GL_TEXTURE_2D,
0, 0,
iformat, iformat,
pixmap->drawable.width, pixmap->drawable.width,
@ -271,6 +274,7 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_screen_private *glamor_priv = glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen); glamor_get_screen_private(pixmap->drawable.pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
static float vertices[8] = {-1, -1, static float vertices[8] = {-1, -1,
1, -1, 1, -1,
1, 1, 1, 1,
@ -303,41 +307,41 @@ _glamor_upload_pixmap_to_texture(PixmapPtr pixmap, GLenum format,
ptexcoords = texcoords_inv; ptexcoords = texcoords_inv;
/* Slow path, we need to flip y or wire alpha to 1. */ /* Slow path, we need to flip y or wire alpha to 1. */
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
2 * sizeof(float), 2 * sizeof(float),
vertices); vertices);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
2 * sizeof(float), 2 * sizeof(float),
ptexcoords); ptexcoords);
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glamor_set_destination_pixmap_priv_nc(pixmap_priv); glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glGenTextures(1, &tex); dispatch->glGenTextures(1, &tex);
__glamor_upload_pixmap_to_texture(pixmap, format, type, tex); __glamor_upload_pixmap_to_texture(pixmap, format, type, tex);
glActiveTexture(GL_TEXTURE0); dispatch->glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex); dispatch->glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
glEnable(GL_TEXTURE_2D); dispatch->glEnable(GL_TEXTURE_2D);
#endif #endif
glUseProgram(glamor_priv->finish_access_prog[no_alpha]); dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); dispatch->glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],0); dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha],0);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
glDisable(GL_TEXTURE_2D); dispatch->glDisable(GL_TEXTURE_2D);
#endif #endif
glUseProgram(0); dispatch->glUseProgram(0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glDeleteTextures(1, &tex); dispatch->glDeleteTextures(1, &tex);
glBindFramebuffer(GL_FRAMEBUFFER, 0); dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }
void void
@ -345,16 +349,18 @@ glamor_pixmap_ensure_fb(PixmapPtr pixmap)
{ {
int status; int status;
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
if (pixmap_priv->fb == 0) if (pixmap_priv->fb == 0)
glGenFramebuffers(1, &pixmap_priv->fb); dispatch->glGenFramebuffers(1, &pixmap_priv->fb);
assert(pixmap_priv->tex != 0); assert(pixmap_priv->tex != 0);
glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb); dispatch->glBindFramebuffer(GL_FRAMEBUFFER, pixmap_priv->fb);
glFramebufferTexture2D(GL_FRAMEBUFFER, dispatch->glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, GL_TEXTURE_2D,
pixmap_priv->tex, pixmap_priv->tex,
0); 0);
status = glCheckFramebufferStatus (GL_FRAMEBUFFER); status = dispatch->glCheckFramebufferStatus (GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) { if (status != GL_FRAMEBUFFER_COMPLETE) {
const char *str; const char *str;
switch (status) { switch (status) {
@ -387,6 +393,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
int need_fbo; int need_fbo;
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); glamor_screen_private *glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
if (!glamor_check_fbo_size(glamor_priv, pixmap->drawable.width , pixmap->drawable.height) if (!glamor_check_fbo_size(glamor_priv, pixmap->drawable.width , pixmap->drawable.height)
|| !glamor_check_fbo_depth(pixmap->drawable.depth)) { || !glamor_check_fbo_depth(pixmap->drawable.depth)) {
@ -404,13 +411,13 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, int no_alpha, int no_revert)
need_fbo = 0; need_fbo = 0;
if (pixmap_priv->tex == 0) if (pixmap_priv->tex == 0)
glGenTextures(1, &pixmap_priv->tex); dispatch->glGenTextures(1, &pixmap_priv->tex);
if (need_fbo) { if (need_fbo) {
glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width, dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixmap->drawable.width,
pixmap->drawable.height, 0, pixmap->drawable.height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL); GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glamor_pixmap_ensure_fb(pixmap); glamor_pixmap_ensure_fb(pixmap);
@ -498,6 +505,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format,
ScreenPtr screen; ScreenPtr screen;
PixmapPtr temp_pixmap; PixmapPtr temp_pixmap;
glamor_pixmap_private *temp_pixmap_priv; glamor_pixmap_private *temp_pixmap_priv;
glamor_gl_dispatch *dispatch;
static float vertices[8] = {-1, -1, static float vertices[8] = {-1, -1,
1, -1, 1, -1,
1, 1, 1, 1,
@ -513,6 +521,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format,
glamor_priv = glamor_get_screen_private(screen); glamor_priv = glamor_get_screen_private(screen);
source_priv = glamor_get_pixmap_private(source); source_priv = glamor_get_pixmap_private(source);
dispatch = &glamor_priv->dispatch;
if (*format == GL_BGRA) { if (*format == GL_BGRA) {
*format = GL_RGBA; *format = GL_RGBA;
swap_rb = 1; swap_rb = 1;
@ -527,36 +536,35 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format,
temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap); temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex); dispatch->glBindTexture(GL_TEXTURE_2D, temp_pixmap_priv->tex);
glTexImage2D(GL_TEXTURE_2D, 0, *format, source->drawable.width, dispatch->glTexImage2D(GL_TEXTURE_2D, 0, *format, source->drawable.width,
source->drawable.height, 0, source->drawable.height, 0,
*format, *type, NULL); *format, *type, NULL);
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
2 * sizeof(float), 2 * sizeof(float),
vertices); vertices);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
2 * sizeof(float), 2 * sizeof(float),
texcoords); texcoords);
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glActiveTexture(GL_TEXTURE0); dispatch->glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, source_priv->tex); dispatch->glBindTexture(GL_TEXTURE_2D, source_priv->tex);
glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv); glamor_set_destination_pixmap_priv_nc(temp_pixmap_priv);
glUseProgram(glamor_priv->finish_access_prog[no_alpha]); dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); dispatch->glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb); dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glUseProgram(0); dispatch->glUseProgram(0);
glFlush();
return temp_pixmap; return temp_pixmap;
} }
@ -583,6 +591,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
ScreenPtr screen; ScreenPtr screen;
glamor_screen_private *glamor_priv = glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen); glamor_get_screen_private(pixmap->drawable.pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
screen = pixmap->drawable.pScreen; screen = pixmap->drawable.pScreen;
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
@ -641,43 +650,43 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
row_length = (stride * 8) / pixmap->drawable.bitsPerPixel; row_length = (stride * 8) / pixmap->drawable.bitsPerPixel;
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
glPixelStorei(GL_PACK_ALIGNMENT, 1); dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ROW_LENGTH, row_length); dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
} }
else { else {
glPixelStorei(GL_PACK_ALIGNMENT, 4); dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
// glPixelStorei(GL_PACK_ROW_LENGTH, 0); // dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, 0);
} }
if (glamor_priv->has_pack_invert || glamor_priv->yInverted) { if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
if (!glamor_priv->yInverted) { if (!glamor_priv->yInverted) {
assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
glPixelStorei(GL_PACK_INVERT_MESA, 1); dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 1);
} }
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
if (pixmap_priv->pbo == 0) if (pixmap_priv->pbo == 0)
glGenBuffers (1, &pixmap_priv->pbo); dispatch->glGenBuffers (1, &pixmap_priv->pbo);
glBindBuffer (GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo); dispatch->glBindBuffer (GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo);
glBufferData (GL_PIXEL_PACK_BUFFER, dispatch->glBufferData (GL_PIXEL_PACK_BUFFER,
stride * pixmap->drawable.height, stride * pixmap->drawable.height,
NULL, gl_usage); NULL, gl_usage);
glReadPixels (0, 0, dispatch->glReadPixels (0, 0,
row_length, pixmap->drawable.height, row_length, pixmap->drawable.height,
format, type, 0); format, type, 0);
data = glMapBuffer (GL_PIXEL_PACK_BUFFER, gl_access); data = dispatch->glMapBuffer (GL_PIXEL_PACK_BUFFER, gl_access);
pixmap_priv->pbo_valid = TRUE; pixmap_priv->pbo_valid = TRUE;
if (!glamor_priv->yInverted) { if (!glamor_priv->yInverted) {
assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP); assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
glPixelStorei(GL_PACK_INVERT_MESA, 0); dispatch->glPixelStorei(GL_PACK_INVERT_MESA, 0);
} }
glBindBuffer (GL_PIXEL_PACK_BUFFER, 0); dispatch->glBindBuffer (GL_PIXEL_PACK_BUFFER, 0);
} else { } else {
if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
type = GL_UNSIGNED_SHORT_5_5_5_1; type = GL_UNSIGNED_SHORT_5_5_5_1;
glReadPixels (0, 0, dispatch->glReadPixels (0, 0,
pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.width, pixmap->drawable.height,
format, type, data); format, type, data);
} }
@ -686,32 +695,31 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
assert(data); assert(data);
if (access != GLAMOR_ACCESS_WO) { if (access != GLAMOR_ACCESS_WO) {
if (pixmap_priv->pbo == 0) if (pixmap_priv->pbo == 0)
glGenBuffers(1, &pixmap_priv->pbo); dispatch->glGenBuffers(1, &pixmap_priv->pbo);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo); dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, pixmap_priv->pbo);
glBufferData(GL_PIXEL_PACK_BUFFER, dispatch->glBufferData(GL_PIXEL_PACK_BUFFER,
stride * pixmap->drawable.height, stride * pixmap->drawable.height,
NULL, GL_STREAM_READ); NULL, GL_STREAM_READ);
glReadPixels (0, 0, row_length, pixmap->drawable.height, dispatch->glReadPixels (0, 0, row_length, pixmap->drawable.height,
format, type, 0); format, type, 0);
read = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); read = dispatch->glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
for (y = 0; y < pixmap->drawable.height; y++) for (y = 0; y < pixmap->drawable.height; y++)
memcpy(data + y * stride, memcpy(data + y * stride,
read + (pixmap->drawable.height - y - 1) * stride, stride); read + (pixmap->drawable.height - y - 1) * stride, stride);
glUnmapBuffer(GL_PIXEL_PACK_BUFFER); dispatch->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); dispatch->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
pixmap_priv->pbo_valid = FALSE; pixmap_priv->pbo_valid = FALSE;
glDeleteBuffers(1, &pixmap_priv->pbo); dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
pixmap_priv->pbo = 0; pixmap_priv->pbo = 0;
} }
} }
glBindFramebuffer(GL_FRAMEBUFFER, 0); dispatch->glBindFramebuffer(GL_FRAMEBUFFER, 0);
done: done:
pixmap->devPrivate.ptr = data; pixmap->devPrivate.ptr = data;
if (temp_pixmap) { if (temp_pixmap) {
glFlush();
(*screen->DestroyPixmap)(temp_pixmap); (*screen->DestroyPixmap)(temp_pixmap);
} }
@ -724,14 +732,15 @@ static void
_glamor_destroy_upload_pixmap(PixmapPtr pixmap) _glamor_destroy_upload_pixmap(PixmapPtr pixmap)
{ {
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_gl_dispatch *dispatch = &pixmap_priv->glamor_priv->dispatch;
assert(pixmap_priv->gl_fbo == 0); assert(pixmap_priv->gl_fbo == 0);
if (pixmap_priv->fb) if (pixmap_priv->fb)
glDeleteFramebuffers(1, &pixmap_priv->fb); dispatch->glDeleteFramebuffers(1, &pixmap_priv->fb);
if (pixmap_priv->tex) if (pixmap_priv->tex)
glDeleteTextures(1, &pixmap_priv->tex); dispatch->glDeleteTextures(1, &pixmap_priv->tex);
if (pixmap_priv->pbo) if (pixmap_priv->pbo)
glDeleteBuffers(1, &pixmap_priv->pbo); dispatch->glDeleteBuffers(1, &pixmap_priv->pbo);
pixmap_priv->fb = pixmap_priv->tex = pixmap_priv->pbo = 0; pixmap_priv->fb = pixmap_priv->tex = pixmap_priv->pbo = 0;
} }

View File

@ -178,6 +178,8 @@ enum shader_in {
SHADER_IN_COUNT, SHADER_IN_COUNT,
}; };
#include "glamor_gl_dispatch.h"
struct glamor_screen_private; struct glamor_screen_private;
struct glamor_pixmap_private; struct glamor_pixmap_private;
typedef void (*glamor_pixmap_validate_function_t)(struct glamor_screen_private*, typedef void (*glamor_pixmap_validate_function_t)(struct glamor_screen_private*,
@ -251,6 +253,7 @@ typedef struct glamor_screen_private {
glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS]; glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
Bool glyph_cache_initialized; Bool glyph_cache_initialized;
struct glamor_gl_dispatch dispatch;
} glamor_screen_private; } glamor_screen_private;
typedef enum glamor_access { typedef enum glamor_access {
@ -310,18 +313,18 @@ typedef struct glamor_pixmap_private {
PictFormatShort pict_format; PictFormatShort pict_format;
glamor_pending_op pending_op; glamor_pending_op pending_op;
PixmapPtr container; PixmapPtr container;
glamor_screen_private *glamor_priv;
} glamor_pixmap_private; } glamor_pixmap_private;
#define GLAMOR_CHECK_PENDING_FILL(_glamor_priv_, _pixmap_priv_) do \ #define GLAMOR_CHECK_PENDING_FILL(_dispatch_, _glamor_priv_, _pixmap_priv_) do \
{ \ { \
if (_pixmap_priv_->pending_op.type == GLAMOR_PENDING_FILL) { \ if (_pixmap_priv_->pending_op.type == GLAMOR_PENDING_FILL) { \
glUseProgram(_glamor_priv_->solid_prog); \ _dispatch_->glUseProgram(_glamor_priv_->solid_prog); \
glUniform4fv(_glamor_priv_->solid_color_uniform_location, 1, \ _dispatch_->glUniform4fv(_glamor_priv_->solid_color_uniform_location, 1, \
_pixmap_priv_->pending_op.fill.color4fv); \ _pixmap_priv_->pending_op.fill.color4fv); \
} \ } \
} while(0) } while(0)
/* /*
* Pixmap dynamic status, used by dynamic upload feature. * Pixmap dynamic status, used by dynamic upload feature.
* *
@ -752,8 +755,8 @@ Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
unsigned char alu, unsigned long planemask, unsigned char alu, unsigned long planemask,
unsigned long fg_pixel, unsigned long bg_pixel, unsigned long fg_pixel, unsigned long bg_pixel,
int stipple_x, int stipple_y); int stipple_x, int stipple_y);
GLint glamor_compile_glsl_prog(GLenum type, const char *source); GLint glamor_compile_glsl_prog(glamor_gl_dispatch *dispatch, GLenum type, const char *source);
void glamor_link_glsl_prog(GLint prog); void glamor_link_glsl_prog(glamor_gl_dispatch *dispatch, GLint prog);
void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
GLfloat *color); GLfloat *color);
@ -770,7 +773,7 @@ PixmapPtr
glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format, glamor_es2_pixmap_read_prepare(PixmapPtr source, GLenum *format,
GLenum *type, int no_alpha, int no_revert); GLenum *type, int no_alpha, int no_revert);
void glamor_set_alu(unsigned char alu); void glamor_set_alu(struct glamor_gl_dispatch * dispatch, unsigned char alu);
Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask); Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
void glamor_get_transform_uniform_locations(GLint prog, void glamor_get_transform_uniform_locations(GLint prog,
glamor_transform_uniforms *uniform_locations); glamor_transform_uniforms *uniform_locations);

View File

@ -67,25 +67,25 @@ glamor_init_putimage_shaders(ScreenPtr screen)
if (!GLEW_ARB_fragment_shader) if (!GLEW_ARB_fragment_shader)
return; return;
prog = glCreateProgram(); prog = dispatch->glCreateProgram();
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs); vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs);
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs); fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs);
glAttachShader(prog, vs_prog); dispatch->glAttachShader(prog, vs_prog);
glAttachShader(prog, fs_prog); dispatch->glAttachShader(prog, fs_prog);
glamor_link_glsl_prog(prog); glamor_link_glsl_prog(prog);
glUseProgram(prog); dispatch->glUseProgram(prog);
sampler_uniform_location = glGetUniformLocation(prog, "bitmap_sampler"); sampler_uniform_location = dispatch->glGetUniformLocation(prog, "bitmap_sampler");
glUniform1i(sampler_uniform_location, 0); dispatch->glUniform1i(sampler_uniform_location, 0);
glamor_priv->put_image_xybitmap_fg_uniform_location = glamor_priv->put_image_xybitmap_fg_uniform_location =
glGetUniformLocation(prog, "fg"); dispatch->glGetUniformLocation(prog, "fg");
glamor_priv->put_image_xybitmap_bg_uniform_location = glamor_priv->put_image_xybitmap_bg_uniform_location =
glGetUniformLocation(prog, "bg"); dispatch->glGetUniformLocation(prog, "bg");
glamor_get_transform_uniform_locations(prog, glamor_get_transform_uniform_locations(prog,
&glamor_priv->put_image_xybitmap_transform); &glamor_priv->put_image_xybitmap_transform);
glamor_priv->put_image_xybitmap_prog = prog; glamor_priv->put_image_xybitmap_prog = prog;
glUseProgram(0); dispatch->glUseProgram(0);
#endif #endif
} }
@ -162,42 +162,42 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
if (!glamor_set_planemask(pixmap, gc->planemask)) if (!glamor_set_planemask(pixmap, gc->planemask))
goto fail; goto fail;
glUseProgram(glamor_priv->put_image_xybitmap_prog); dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog);
glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg); glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg);
glUniform4fv(glamor_priv->put_image_xybitmap_fg_uniform_location, dispatch->glUniform4fv(glamor_priv->put_image_xybitmap_fg_uniform_location,
1, fg); 1, fg);
glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg); glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg);
glUniform4fv(glamor_priv->put_image_xybitmap_bg_uniform_location, dispatch->glUniform4fv(glamor_priv->put_image_xybitmap_bg_uniform_location,
1, bg); 1, bg);
glGenTextures(1, &tex); dispatch->glGenTextures(1, &tex);
glActiveTexture(GL_TEXTURE0); dispatch->glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D); dispatch->glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex); dispatch->glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8); dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad); dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
w, h, 0, w, h, 0,
GL_COLOR_INDEX, GL_BITMAP, bits); GL_COLOR_INDEX, GL_BITMAP, bits);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glEnable(GL_TEXTURE_2D); dispatch->glEnable(GL_TEXTURE_2D);
/* Now that we've set up our bitmap texture and the shader, shove /* Now that we've set up our bitmap texture and the shader, shove
* the destination rectangle through the cliprects and run the * the destination rectangle through the cliprects and run the
* shader on the resulting fragments. * shader on the resulting fragments.
*/ */
glVertexPointer(2, GL_FLOAT, 0, dest_coords); dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords);
glEnableClientState(GL_VERTEX_ARRAY); dispatch->glEnableClientState(GL_VERTEX_ARRAY);
glClientActiveTexture(GL_TEXTURE0); dispatch->glClientActiveTexture(GL_TEXTURE0);
glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords); dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_SCISSOR_TEST); dispatch->glEnable(GL_SCISSOR_TEST);
clip = fbGetCompositeClip(gc); clip = fbGetCompositeClip(gc);
for (nbox = REGION_NUM_RECTS(clip), for (nbox = REGION_NUM_RECTS(clip),
box = REGION_RECTS(clip); box = REGION_RECTS(clip);
@ -220,20 +220,20 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
if (x1 >= x2 || y1 >= y2) if (x1 >= x2 || y1 >= y2)
continue; continue;
glScissor(box->x1, dispatch->glScissor(box->x1,
y_flip(pixmap, box->y1), y_flip(pixmap, box->y1),
box->x2 - box->x1, box->x2 - box->x1,
box->y2 - box->y1); box->y2 - box->y1);
glDrawArrays(GL_QUADS, 0, 4); dispatch->glDrawArrays(GL_QUADS, 0, 4);
} }
glDisable(GL_SCISSOR_TEST); dispatch->glDisable(GL_SCISSOR_TEST);
glamor_set_alu(GXcopy); glamor_set_alu(GXcopy);
glamor_set_planemask(pixmap, ~0); glamor_set_planemask(pixmap, ~0);
glDeleteTextures(1, &tex); dispatch->glDeleteTextures(1, &tex);
glDisable(GL_TEXTURE_2D); dispatch->glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_VERTEX_ARRAY); dispatch->glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
return; return;
glamor_set_alu(GXcopy); glamor_set_alu(GXcopy);
glamor_set_planemask(pixmap, ~0); glamor_set_planemask(pixmap, ~0);
@ -254,6 +254,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
{ {
glamor_screen_private *glamor_priv = glamor_screen_private *glamor_priv =
glamor_get_screen_private(drawable->pScreen); glamor_get_screen_private(drawable->pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
GLenum type, format, iformat; GLenum type, format, iformat;
@ -285,7 +286,7 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
if (!glamor_set_planemask(pixmap, gc->planemask)) { if (!glamor_set_planemask(pixmap, gc->planemask)) {
goto fail; goto fail;
} }
glamor_set_alu(gc->alu); glamor_set_alu(dispatch, gc->alu);
if (glamor_get_tex_format_type_from_pixmap(pixmap, if (glamor_get_tex_format_type_from_pixmap(pixmap,
&format, &format,
@ -301,29 +302,29 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
/* XXX consider to reuse a function to do the following work. */ /* XXX consider to reuse a function to do the following work. */
glamor_set_destination_pixmap_priv_nc(pixmap_priv); glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap); glamor_validate_pixmap(pixmap);
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
2 * sizeof(float), 2 * sizeof(float),
vertices); vertices);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
2 * sizeof(float), 2 * sizeof(float),
texcoords); texcoords);
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) { if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 / dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride * 8 /
pixmap->drawable.bitsPerPixel); pixmap->drawable.bitsPerPixel);
} }
else { else {
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
// glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
} }
glGenTextures(1, &tex); dispatch->glGenTextures(1, &tex);
glActiveTexture(GL_TEXTURE0); dispatch->glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex); dispatch->glBindTexture(GL_TEXTURE_2D, tex);
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
iformat = format; iformat = format;
} }
@ -331,19 +332,19 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
iformat = GL_RGBA; iformat = GL_RGBA;
} }
glTexImage2D(GL_TEXTURE_2D, 0, iformat, dispatch->glTexImage2D(GL_TEXTURE_2D, 0, iformat,
w, h, 0, w, h, 0,
format, type, bits); format, type, bits);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
glEnable(GL_TEXTURE_2D); dispatch->glEnable(GL_TEXTURE_2D);
#endif #endif
glUseProgram(glamor_priv->finish_access_prog[no_alpha]); dispatch->glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert); dispatch->glUniform1i(glamor_priv->finish_access_no_revert[no_alpha], no_revert);
glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], 0); dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], 0);
x += drawable->x; x += drawable->x;
y += drawable->y; y += drawable->y;
@ -388,19 +389,19 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
glamor_priv->yInverted, glamor_priv->yInverted,
vertices); vertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
} }
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
glDisable(GL_TEXTURE_2D); dispatch->glDisable(GL_TEXTURE_2D);
#endif #endif
glUseProgram(0); dispatch->glUseProgram(0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glDeleteTextures(1, &tex); dispatch->glDeleteTextures(1, &tex);
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glamor_set_alu(GXcopy); glamor_set_alu(dispatch, GXcopy);
glamor_set_planemask(pixmap, ~0); glamor_set_planemask(pixmap, ~0);
return; return;

View File

@ -68,7 +68,7 @@ static struct blendinfo composite_op_info[] = {
}; };
static GLuint static GLuint
glamor_create_composite_fs(struct shader_key *key) glamor_create_composite_fs(glamor_gl_dispatch *dispatch, struct shader_key *key)
{ {
const char *source_solid_fetch = const char *source_solid_fetch =
GLAMOR_DEFAULT_PRECISION GLAMOR_DEFAULT_PRECISION
@ -200,14 +200,14 @@ glamor_create_composite_fs(struct shader_key *key)
in); in);
prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source); prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, source);
free(source); free(source);
return prog; return prog;
} }
static GLuint static GLuint
glamor_create_composite_vs(struct shader_key *key) glamor_create_composite_vs(glamor_gl_dispatch *dispatch, struct shader_key *key)
{ {
const char *main_opening = const char *main_opening =
"attribute vec4 v_position;\n" "attribute vec4 v_position;\n"
@ -242,7 +242,7 @@ glamor_create_composite_vs(struct shader_key *key)
mask_coords_setup, mask_coords_setup,
main_closing); main_closing);
prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, source); prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, source);
free(source); free(source);
return prog; return prog;
@ -254,45 +254,47 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
{ {
GLuint vs, fs, prog; GLuint vs, fs, prog;
GLint source_sampler_uniform_location, mask_sampler_uniform_location; GLint source_sampler_uniform_location, mask_sampler_uniform_location;
glamor_screen_private *glamor = glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor->dispatch;
vs = glamor_create_composite_vs(key); vs = glamor_create_composite_vs(dispatch, key);
if (vs == 0) if (vs == 0)
return; return;
fs = glamor_create_composite_fs(key); fs = glamor_create_composite_fs(dispatch, key);
if (fs == 0) if (fs == 0)
return; return;
prog = glCreateProgram(); prog = dispatch->glCreateProgram();
glAttachShader(prog, vs); dispatch->glAttachShader(prog, vs);
glAttachShader(prog, fs); dispatch->glAttachShader(prog, fs);
glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position"); dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_POS, "v_position");
glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1"); dispatch->glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1");
glamor_link_glsl_prog(prog); glamor_link_glsl_prog(dispatch, prog);
shader->prog = prog; shader->prog = prog;
glUseProgram(prog); dispatch->glUseProgram(prog);
if (key->source == SHADER_SOURCE_SOLID) { if (key->source == SHADER_SOURCE_SOLID) {
shader->source_uniform_location = glGetUniformLocation(prog, shader->source_uniform_location = dispatch->glGetUniformLocation(prog,
"source"); "source");
} else { } else {
source_sampler_uniform_location = glGetUniformLocation(prog, source_sampler_uniform_location = dispatch->glGetUniformLocation(prog,
"source_sampler"); "source_sampler");
glUniform1i(source_sampler_uniform_location, 0); dispatch->glUniform1i(source_sampler_uniform_location, 0);
} }
if (key->mask != SHADER_MASK_NONE) { if (key->mask != SHADER_MASK_NONE) {
if (key->mask == SHADER_MASK_SOLID) { if (key->mask == SHADER_MASK_SOLID) {
shader->mask_uniform_location = glGetUniformLocation(prog, shader->mask_uniform_location = dispatch->glGetUniformLocation(prog,
"mask"); "mask");
} else { } else {
mask_sampler_uniform_location = glGetUniformLocation(prog, mask_sampler_uniform_location = dispatch->glGetUniformLocation(prog,
"mask_sampler"); "mask_sampler");
glUniform1i(mask_sampler_uniform_location, 1); dispatch->glUniform1i(mask_sampler_uniform_location, 1);
} }
} }
} }
@ -336,6 +338,8 @@ glamor_set_composite_op(ScreenPtr screen,
{ {
GLenum source_blend, dest_blend; GLenum source_blend, dest_blend;
struct blendinfo *op_info; struct blendinfo *op_info;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
if (op >= ARRAY_SIZE(composite_op_info)) { if (op >= ARRAY_SIZE(composite_op_info)) {
glamor_fallback("unsupported render op %d \n", op); glamor_fallback("unsupported render op %d \n", op);
@ -370,10 +374,10 @@ glamor_set_composite_op(ScreenPtr screen,
} }
if (source_blend == GL_ONE && dest_blend == GL_ZERO) { if (source_blend == GL_ONE && dest_blend == GL_ZERO) {
glDisable(GL_BLEND); dispatch->glDisable(GL_BLEND);
} else { } else {
glEnable(GL_BLEND); dispatch->glEnable(GL_BLEND);
glBlendFunc(source_blend, dest_blend); dispatch->glBlendFunc(source_blend, dest_blend);
} }
return TRUE; return TRUE;
} }
@ -382,50 +386,52 @@ static void
glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture, glamor_set_composite_texture(ScreenPtr screen, int unit, PicturePtr picture,
glamor_pixmap_private *pixmap_priv) glamor_pixmap_private *pixmap_priv)
{ {
glActiveTexture(GL_TEXTURE0 + unit); glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex); glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
dispatch->glActiveTexture(GL_TEXTURE0 + unit);
dispatch->glBindTexture(GL_TEXTURE_2D, pixmap_priv->tex);
switch (picture->repeatType) { switch (picture->repeatType) {
case RepeatNone: case RepeatNone:
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
/* XXX GLES2 doesn't support GL_CLAMP_TO_BORDER. */ /* XXX GLES2 doesn't support GL_CLAMP_TO_BORDER. */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
#endif #endif
break; break;
case RepeatNormal: case RepeatNormal:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
break; break;
case RepeatPad: case RepeatPad:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
break; break;
case RepeatReflect: case RepeatReflect:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
break; break;
} }
switch (picture->filter) { switch (picture->filter) {
case PictFilterNearest: case PictFilterNearest:
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
break; break;
case PictFilterBilinear: case PictFilterBilinear:
default: default:
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); dispatch->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
break; break;
} }
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
glEnable(GL_TEXTURE_2D); dispatch->glEnable(GL_TEXTURE_2D);
#endif #endif
} }
static void static void
glamor_set_composite_solid(float *color, GLint uniform_location) glamor_set_composite_solid(glamor_gl_dispatch *dispatch, float *color, GLint uniform_location)
{ {
glUniform4fv(uniform_location, 1, color); dispatch->glUniform4fv(uniform_location, 1, color);
} }
static int static int
@ -525,6 +531,7 @@ static void
glamor_setup_composite_vbo(ScreenPtr screen) glamor_setup_composite_vbo(ScreenPtr screen)
{ {
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
glamor_priv->vb_stride = 2 * sizeof(float); glamor_priv->vb_stride = 2 * sizeof(float);
if (glamor_priv->has_source_coords) if (glamor_priv->has_source_coords)
@ -532,27 +539,27 @@ glamor_setup_composite_vbo(ScreenPtr screen)
if (glamor_priv->has_mask_coords) if (glamor_priv->has_mask_coords)
glamor_priv->vb_stride += 2 * sizeof(float); glamor_priv->vb_stride += 2 * sizeof(float);
glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo); dispatch->glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
glamor_priv->vb_stride, glamor_priv->vb_stride,
(void *)((long)glamor_priv->vbo_offset)); (void *)((long)glamor_priv->vbo_offset));
glEnableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
if (glamor_priv->has_source_coords) { if (glamor_priv->has_source_coords) {
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
glamor_priv->vb_stride, glamor_priv->vb_stride,
(void *)((long)glamor_priv->vbo_offset + 2 * sizeof(float))); (void *)((long)glamor_priv->vbo_offset + 2 * sizeof(float)));
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
} }
if (glamor_priv->has_mask_coords) { if (glamor_priv->has_mask_coords) {
glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE,
glamor_priv->vb_stride, glamor_priv->vb_stride,
(void *)((long)glamor_priv->vbo_offset + (void *)((long)glamor_priv->vbo_offset +
(glamor_priv->has_source_coords ? 4 : 2) * (glamor_priv->has_source_coords ? 4 : 2) *
sizeof(float))); sizeof(float)));
glEnableVertexAttribArray(GLAMOR_VERTEX_MASK); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
} }
} }
@ -586,13 +593,13 @@ static void
glamor_flush_composite_rects(ScreenPtr screen) glamor_flush_composite_rects(ScreenPtr screen)
{ {
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
if (!glamor_priv->render_nr_verts) if (!glamor_priv->render_nr_verts)
return; return;
glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, glamor_priv->vb, dispatch->glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset, glamor_priv->vb,
GL_STREAM_DRAW); GL_STREAM_DRAW);
glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts); dispatch->glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts);
glamor_reset_composite_vbo(screen); glamor_reset_composite_vbo(screen);
} }
@ -603,6 +610,7 @@ glamor_emit_composite_rect(ScreenPtr screen,
const float *dst_coords) const float *dst_coords)
{ {
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
if (glamor_priv->vbo_offset + 6 * glamor_priv->vb_stride > if (glamor_priv->vbo_offset + 6 * glamor_priv->vb_stride >
glamor_priv->vbo_size) glamor_priv->vbo_size)
@ -612,7 +620,7 @@ glamor_emit_composite_rect(ScreenPtr screen,
if (glamor_priv->vbo_offset == 0) { if (glamor_priv->vbo_offset == 0) {
if (glamor_priv->vbo == 0) if (glamor_priv->vbo == 0)
glGenBuffers(1, &glamor_priv->vbo); dispatch->glGenBuffers(1, &glamor_priv->vbo);
glamor_setup_composite_vbo(screen); glamor_setup_composite_vbo(screen);
} }
@ -700,6 +708,7 @@ glamor_composite_with_shader(CARD8 op,
{ {
ScreenPtr screen = dest->pDrawable->pScreen; ScreenPtr screen = dest->pDrawable->pScreen;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable); PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
glamor_pixmap_private *source_pixmap_priv = NULL; glamor_pixmap_private *source_pixmap_priv = NULL;
@ -914,17 +923,17 @@ glamor_composite_with_shader(CARD8 op,
goto fail; goto fail;
} }
glUseProgram(shader->prog); dispatch->glUseProgram(shader->prog);
if (key.source == SHADER_SOURCE_SOLID) { if (key.source == SHADER_SOURCE_SOLID) {
glamor_set_composite_solid(source_solid_color, shader->source_uniform_location); glamor_set_composite_solid(dispatch, source_solid_color, shader->source_uniform_location);
} else { } else {
glamor_set_composite_texture(screen, 0, source, source_pixmap_priv); glamor_set_composite_texture(screen, 0, source, source_pixmap_priv);
} }
if (key.mask != SHADER_MASK_NONE) { if (key.mask != SHADER_MASK_NONE) {
if (key.mask == SHADER_MASK_SOLID) { if (key.mask == SHADER_MASK_SOLID) {
glamor_set_composite_solid(mask_solid_color, shader->mask_uniform_location); glamor_set_composite_solid(dispatch, mask_solid_color, shader->mask_uniform_location);
} else { } else {
glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv); glamor_set_composite_texture(screen, 1, mask, mask_pixmap_priv);
} }
@ -1042,19 +1051,19 @@ glamor_composite_with_shader(CARD8 op,
} }
glamor_flush_composite_rects(screen); glamor_flush_composite_rects(screen);
glBindBuffer(GL_ARRAY_BUFFER, 0); dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
REGION_UNINIT(dst->pDrawable->pScreen, &region); REGION_UNINIT(dst->pDrawable->pScreen, &region);
glDisable(GL_BLEND); dispatch->glDisable(GL_BLEND);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
glActiveTexture(GL_TEXTURE0); dispatch->glActiveTexture(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D); dispatch->glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1); dispatch->glActiveTexture(GL_TEXTURE1);
glDisable(GL_TEXTURE_2D); dispatch->glDisable(GL_TEXTURE_2D);
#endif #endif
glUseProgram(0); dispatch->glUseProgram(0);
if (saved_source_format) if (saved_source_format)
source->format = saved_source_format; source->format = saved_source_format;
return TRUE; return TRUE;
@ -1063,8 +1072,8 @@ glamor_composite_with_shader(CARD8 op,
if (saved_source_format) if (saved_source_format)
source->format = saved_source_format; source->format = saved_source_format;
glDisable(GL_BLEND); dispatch->glDisable(GL_BLEND);
glUseProgram(0); dispatch->glUseProgram(0);
return FALSE; return FALSE;
} }
@ -1138,6 +1147,7 @@ glamor_composite(CARD8 op,
int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask; int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
glamor_composite_rect_t rect; glamor_composite_rect_t rect;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
x_temp_src = x_source; x_temp_src = x_source;
y_temp_src = y_source; y_temp_src = y_source;
@ -1257,8 +1267,8 @@ fail:
dest->pDrawable->height, dest->pDrawable->height,
glamor_get_picture_location(dest)); glamor_get_picture_location(dest));
glUseProgram(0); dispatch->glUseProgram(0);
glDisable(GL_BLEND); dispatch->glDisable(GL_BLEND);
if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) { if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) {
if (glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO)) if (glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO))
{ {

View File

@ -36,7 +36,8 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
DDXPointPtr points, int *widths, int n, int sorted) DDXPointPtr points, int *widths, int n, int sorted)
{ {
PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
glamor_screen_private *glamor_priv; glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
GLenum format, type; GLenum format, type;
int no_alpha, no_revert, i; int no_alpha, no_revert, i;
uint8_t *drawpixels_src = (uint8_t *)src; uint8_t *drawpixels_src = (uint8_t *)src;
@ -44,8 +45,6 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
BoxRec *pbox; BoxRec *pbox;
int x_off, y_off; int x_off, y_off;
glamor_priv = glamor_get_screen_private(drawable->pScreen);
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
glamor_fallback("ES2 fallback.\n"); glamor_fallback("ES2 fallback.\n");
goto fail; goto fail;
@ -69,7 +68,7 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
glamor_validate_pixmap(dest_pixmap); glamor_validate_pixmap(dest_pixmap);
if (!glamor_set_planemask(dest_pixmap, gc->planemask)) if (!glamor_set_planemask(dest_pixmap, gc->planemask))
goto fail; goto fail;
glamor_set_alu(gc->alu); glamor_set_alu(dispatch, gc->alu);
if (!glamor_set_planemask(dest_pixmap, gc->planemask)) if (!glamor_set_planemask(dest_pixmap, gc->planemask))
goto fail; goto fail;
@ -82,14 +81,14 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
while (n--) { while (n--) {
if (pbox->y1 > points[i].y) if (pbox->y1 > points[i].y)
break; break;
glScissor(pbox->x1, dispatch->glScissor(pbox->x1,
points[i].y + y_off, points[i].y + y_off,
pbox->x2 - pbox->x1, pbox->x2 - pbox->x1,
1); 1);
glEnable(GL_SCISSOR_TEST); dispatch->glEnable(GL_SCISSOR_TEST);
glRasterPos2i(points[i].x + x_off, dispatch->glRasterPos2i(points[i].x + x_off,
points[i].y + y_off); points[i].y + y_off);
glDrawPixels(widths[i], dispatch->glDrawPixels(widths[i],
1, 1,
format, type, format, type,
drawpixels_src); drawpixels_src);
@ -97,8 +96,8 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
drawpixels_src += PixmapBytePad(widths[i], drawable->depth); drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
} }
glamor_set_planemask(dest_pixmap, ~0); glamor_set_planemask(dest_pixmap, ~0);
glamor_set_alu(GXcopy); glamor_set_alu(dispatch, GXcopy);
glDisable(GL_SCISSOR_TEST); dispatch->glDisable(GL_SCISSOR_TEST);
return; return;
fail: fail:

View File

@ -40,6 +40,7 @@ void
glamor_init_tile_shader(ScreenPtr screen) glamor_init_tile_shader(ScreenPtr screen)
{ {
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
const char *tile_vs = const char *tile_vs =
"attribute vec4 v_position;\n" "attribute vec4 v_position;\n"
"attribute vec4 v_texcoord0;\n" "attribute vec4 v_texcoord0;\n"
@ -60,21 +61,21 @@ glamor_init_tile_shader(ScreenPtr screen)
GLint fs_prog, vs_prog; GLint fs_prog, vs_prog;
GLint sampler_uniform_location; GLint sampler_uniform_location;
glamor_priv->tile_prog = glCreateProgram(); glamor_priv->tile_prog = dispatch->glCreateProgram();
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, tile_vs); vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, tile_vs);
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs); fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, tile_fs);
glAttachShader(glamor_priv->tile_prog, vs_prog); dispatch->glAttachShader(glamor_priv->tile_prog, vs_prog);
glAttachShader(glamor_priv->tile_prog, fs_prog); dispatch->glAttachShader(glamor_priv->tile_prog, fs_prog);
glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_POS, "v_position"); dispatch->glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_POS, "v_position");
glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); dispatch->glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
glamor_link_glsl_prog(glamor_priv->tile_prog); glamor_link_glsl_prog(dispatch, glamor_priv->tile_prog);
sampler_uniform_location = sampler_uniform_location =
glGetUniformLocation(glamor_priv->tile_prog, "sampler"); dispatch->glGetUniformLocation(glamor_priv->tile_prog, "sampler");
glUseProgram(glamor_priv->tile_prog); dispatch->glUseProgram(glamor_priv->tile_prog);
glUniform1i(sampler_uniform_location, 0); dispatch->glUniform1i(sampler_uniform_location, 0);
glUseProgram(0); dispatch->glUseProgram(0);
} }
Bool Bool
@ -85,6 +86,7 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
{ {
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_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
int x1 = x; int x1 = x;
int x2 = x + width; int x2 = x + width;
int y1 = y; int y1 = y;
@ -135,33 +137,33 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
glamor_validate_pixmap(pixmap); glamor_validate_pixmap(pixmap);
pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); pixmap_priv_get_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
glamor_set_alu(alu); glamor_set_alu(dispatch, alu);
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
glUseProgram(glamor_priv->tile_prog); dispatch->glUseProgram(glamor_priv->tile_prog);
glActiveTexture(GL_TEXTURE0); dispatch->glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex); dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
glEnable(GL_TEXTURE_2D); dispatch->glEnable(GL_TEXTURE_2D);
#endif #endif
glamor_set_normalize_tcoords(src_xscale, src_yscale, glamor_set_normalize_tcoords(src_xscale, src_yscale,
tile_x1, tile_y1, tile_x1, tile_y1,
tile_x2, tile_y2, tile_x2, tile_y2,
glamor_priv->yInverted, glamor_priv->yInverted,
source_texcoords); source_texcoords);
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
2 * sizeof(float), 2 * sizeof(float),
source_texcoords); source_texcoords);
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
} }
else { else {
GLAMOR_CHECK_PENDING_FILL(glamor_priv, src_pixmap_priv); GLAMOR_CHECK_PENDING_FILL(dispatch, glamor_priv, src_pixmap_priv);
} }
glamor_set_normalize_vcoords(dst_xscale, dst_yscale, glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
@ -169,21 +171,21 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
glamor_priv->yInverted, glamor_priv->yInverted,
vertices); vertices);
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
2 * sizeof(float), 2 * sizeof(float),
vertices); vertices);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) { if (GLAMOR_PIXMAP_PRIV_NO_PENDING(src_pixmap_priv)) {
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
#ifndef GLAMOR_GLES2 #ifndef GLAMOR_GLES2
glDisable(GL_TEXTURE_2D); dispatch->glDisable(GL_TEXTURE_2D);
#endif #endif
} }
glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glUseProgram(0); dispatch->glUseProgram(0);
glamor_set_alu(GXcopy); glamor_set_alu(dispatch, GXcopy);
glamor_set_planemask(pixmap, ~0); glamor_set_planemask(pixmap, ~0);
return TRUE; return TRUE;

View File

@ -584,6 +584,18 @@ glamor_setup(pointer module, pointer opts, int *errmaj, int *errmin)
} }
} }
Bool
glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, int gl_version)
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
struct glamor_screen_private *glamor_egl = glamor_get_screen_private(scrn);
if (!glamor_gl_dispatch_init_impl(dispatch, gl_version, eglGetProcAddress))
return FALSE;
glamor_egl->dispatch = dispatch;
return TRUE;
}
static XF86ModuleVersionInfo glamor_version_info = { static XF86ModuleVersionInfo glamor_version_info = {
glamor_name, glamor_name,
MODULEVENDORSTRING, MODULEVENDORSTRING,

View File

@ -16,6 +16,7 @@
#include <EGL/egl.h> #include <EGL/egl.h>
#include <EGL/eglext.h> #include <EGL/eglext.h>
#include "glamor_gl_dispatch.h"
struct glamor_screen_private { struct glamor_screen_private {
EGLDisplay display; EGLDisplay display;
EGLContext context; EGLContext context;
@ -30,6 +31,7 @@ struct glamor_screen_private {
PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa; PFNEGLCREATEDRMIMAGEMESA egl_create_drm_image_mesa;
PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa; PFNEGLEXPORTDRMIMAGEMESA egl_export_drm_image_mesa;
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes;
struct glamor_gl_dispatch *dispatch;
}; };
inline struct glamor_screen_private * inline struct glamor_screen_private *