summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-02-08 14:40:06 +0100
committerEric Anholt <eric@anholt.net>2010-02-08 15:27:51 +0100
commit43ab7557d4254cf719e8f87c2cdeebd9557da866 (patch)
tree6d2c182d848d76eaaa21cb32995cfb0226ae6095
parent0e9cf180170abb3c643e1daca9fd63d9d95cae64 (diff)
glamor: Replace the glDrawPixels in glamor_finish_access with GLSL.
Root weave displays. \o/
-rw-r--r--glamor/glamor.c1
-rw-r--r--glamor/glamor_core.c88
-rw-r--r--glamor/glamor_priv.h4
3 files changed, 91 insertions, 2 deletions
diff --git a/glamor/glamor.c b/glamor/glamor.c
index a2cd02a6a..ba16d63fc 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -224,6 +224,7 @@ glamor_init(ScreenPtr screen)
glamor_init_tile_shader(screen);
glamor_init_putimage_shaders(screen);
glamor_init_composite_shaders(screen);
+ glamor_init_finish_access_shaders(screen);
return TRUE;
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 9d0e40f44..f35baafa0 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -379,12 +379,66 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
}
void
+glamor_init_finish_access_shaders(ScreenPtr screen)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ const char *vs_source =
+ "void main()\n"
+ "{\n"
+ " gl_Position = gl_Vertex;\n"
+ " gl_TexCoord[0] = gl_MultiTexCoord0;\n"
+ "}\n";
+ const char *fs_source =
+ "varying vec2 texcoords;\n"
+ "uniform sampler2D sampler;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = texture2D(sampler, gl_TexCoord[0].xy);\n"
+ "}\n";
+ GLint fs_prog, vs_prog;
+
+ glamor_priv->finish_access_prog = glCreateProgramObjectARB();
+ if (GLEW_ARB_fragment_shader) {
+ vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
+ fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, fs_source);
+ glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog);
+ glAttachObjectARB(glamor_priv->finish_access_prog, fs_prog);
+ } else {
+ vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, vs_source);
+ glAttachObjectARB(glamor_priv->finish_access_prog, vs_prog);
+ }
+
+ glamor_link_glsl_prog(glamor_priv->finish_access_prog);
+
+ if (GLEW_ARB_fragment_shader) {
+ GLint sampler_uniform_location;
+
+ sampler_uniform_location =
+ glGetUniformLocationARB(glamor_priv->finish_access_prog, "sampler");
+ glUseProgramObjectARB(glamor_priv->finish_access_prog);
+ glUniform1iARB(sampler_uniform_location, 0);
+ glUseProgramObjectARB(0);
+ }
+}
+
+void
glamor_finish_access(DrawablePtr drawable)
{
+ glamor_screen_private *glamor_priv =
+ glamor_get_screen_private(drawable->pScreen);
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
unsigned int stride;
GLenum format, type;
+ static float vertices[4][2] = {{-1, -1},
+ { 1, -1},
+ { 1, 1},
+ {-1, 1}};
+ static float texcoords[4][2] = {{0, 1},
+ {1, 1},
+ {1, 0},
+ {0, 0}};
+ GLuint tex;
if (pixmap_priv == NULL)
return;
@@ -397,6 +451,10 @@ glamor_finish_access(DrawablePtr drawable)
return;
}
+ /* Check if finish_access was already called once on this */
+ if (pixmap->devPrivate.ptr == NULL)
+ return;
+
switch (drawable->depth) {
case 1:
format = GL_COLOR_INDEX;
@@ -420,18 +478,44 @@ glamor_finish_access(DrawablePtr drawable)
stride = PixmapBytePad(pixmap->drawable.width, drawable->depth);
+ glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ glClientActiveTexture(GL_TEXTURE0);
+ glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, texcoords);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
+ glViewport(0, 0, pixmap->drawable.width, pixmap->drawable.height);
+
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8 /
pixmap->drawable.bitsPerPixel);
- glRasterPos2i(0, 0);
- glDrawPixels(pixmap->drawable.width, pixmap->drawable.height,
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ pixmap->drawable.width, pixmap->drawable.height, 0,
format, type, pixmap->devPrivate.ptr);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glEnable(GL_TEXTURE_2D);
+
+ assert(GLEW_ARB_fragment_shader);
+ glUseProgramObjectARB(glamor_priv->finish_access_prog);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glDisable(GL_TEXTURE_2D);
+ glUseProgramObjectARB(0);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDeleteTextures(1, &tex);
xfree(pixmap->devPrivate.ptr);
pixmap->devPrivate.ptr = NULL;
}
+
/**
* Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the
* current fill style.
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 2045ed691..dc3b77860 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -63,6 +63,9 @@ typedef struct glamor_screen_private {
ChangeWindowAttributesProcPtr saved_change_window_attributes;
BitmapToRegionProcPtr saved_bitmap_to_region;
+ /* glamor_finishaccess */
+ GLint finish_access_prog;
+
/* glamor_solid */
GLint solid_prog;
GLint solid_color_uniform_location;
@@ -142,6 +145,7 @@ Bool glamor_prepare_access_window(WindowPtr window);
void glamor_finish_access_window(WindowPtr window);
Bool glamor_prepare_access_gc(GCPtr gc);
void glamor_finish_access_gc(GCPtr gc);
+void glamor_init_finish_access_shaders(ScreenPtr screen);
const Bool glamor_get_drawable_location(const DrawablePtr drawable);
Bool glamor_create_gc(GCPtr gc);
void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,