diff options
author | Eric Anholt <eric@anholt.net> | 2010-02-08 14:40:06 +0100 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-02-08 15:27:51 +0100 |
commit | 43ab7557d4254cf719e8f87c2cdeebd9557da866 (patch) | |
tree | 6d2c182d848d76eaaa21cb32995cfb0226ae6095 | |
parent | 0e9cf180170abb3c643e1daca9fd63d9d95cae64 (diff) |
glamor: Replace the glDrawPixels in glamor_finish_access with GLSL.
Root weave displays. \o/
-rw-r--r-- | glamor/glamor.c | 1 | ||||
-rw-r--r-- | glamor/glamor_core.c | 88 | ||||
-rw-r--r-- | glamor/glamor_priv.h | 4 |
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, |