glamor: Move to using shader objects.
This commit is contained in:
parent
fbbdd788cb
commit
f1dbed5456
|
@ -97,12 +97,21 @@ glamor_init(ScreenPtr screen)
|
|||
|
||||
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
|
||||
|
||||
glewInit();
|
||||
|
||||
if (!GLEW_ARB_shader_objects) {
|
||||
ErrorF("GL_ARB_shader_objects required\n");
|
||||
goto fail;
|
||||
}
|
||||
if (!GLEW_ARB_vertex_shader) {
|
||||
ErrorF("GL_ARB_vertex_shader required\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!RegisterBlockAndWakeupHandlers(glamor_block_handler,
|
||||
glamor_wakeup_handler,
|
||||
NULL)) {
|
||||
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL);
|
||||
xfree(glamor_priv);
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
glamor_priv->saved_create_gc = screen->CreateGC;
|
||||
|
@ -114,9 +123,14 @@ glamor_init(ScreenPtr screen)
|
|||
glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap;
|
||||
screen->DestroyPixmap = glamor_destroy_pixmap;
|
||||
|
||||
glewInit();
|
||||
glamor_init_solid_shader(screen);
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
xfree(glamor_priv);
|
||||
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -39,16 +39,7 @@
|
|||
|
||||
#include "glamor_priv.h"
|
||||
|
||||
static void
|
||||
glamor_set_color_from_fgpixel(PixmapPtr pixmap, unsigned long fg_pixel)
|
||||
{
|
||||
glColor4ub((fg_pixel >> 16) & 0xff,
|
||||
(fg_pixel >> 8) & 0xff,
|
||||
(fg_pixel) & 0xff,
|
||||
(fg_pixel >> 24) & 0xff);
|
||||
}
|
||||
|
||||
static Bool
|
||||
Bool
|
||||
glamor_set_destination_pixmap(PixmapPtr pixmap)
|
||||
{
|
||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||
|
@ -63,37 +54,103 @@ glamor_set_destination_pixmap(PixmapPtr pixmap)
|
|||
screen_pixmap->drawable.width,
|
||||
screen_pixmap->drawable.height);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, screen_pixmap->drawable.width,
|
||||
0, screen_pixmap->drawable.height,
|
||||
-1.0, 1.0);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||
unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
|
||||
glamor_get_transform_uniform_locations(GLint prog,
|
||||
glamor_transform_uniforms *uniform_locations)
|
||||
{
|
||||
int x1 = x;
|
||||
int x2 = x + width;
|
||||
int y1 = y;
|
||||
int y2 = y + height;
|
||||
uniform_locations->x_bias = glGetUniformLocationARB(prog, "x_bias");
|
||||
uniform_locations->x_scale = glGetUniformLocationARB(prog, "x_scale");
|
||||
uniform_locations->y_bias = glGetUniformLocationARB(prog, "y_bias");
|
||||
uniform_locations->y_scale = glGetUniformLocationARB(prog, "y_scale");
|
||||
}
|
||||
|
||||
if (!glamor_set_destination_pixmap(pixmap))
|
||||
return;
|
||||
glamor_set_color_from_fgpixel(pixmap, fg_pixel);
|
||||
/* 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)
|
||||
{
|
||||
glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
|
||||
glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
|
||||
glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
|
||||
glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height);
|
||||
}
|
||||
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glVertex2f(x1, y1);
|
||||
glVertex2f(x1, y2);
|
||||
glVertex2f(x2, y2);
|
||||
glVertex2f(x2, y1);
|
||||
glEnd();
|
||||
GLint
|
||||
glamor_compile_glsl_prog(GLenum type, const char *source)
|
||||
{
|
||||
GLint ok;
|
||||
GLint prog;
|
||||
|
||||
prog = glCreateShaderObjectARB(type);
|
||||
glShaderSourceARB(prog, 1, (const GLchar **)&source, NULL);
|
||||
glCompileShaderARB(prog);
|
||||
glGetObjectParameterivARB(prog, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
|
||||
if (!ok) {
|
||||
GLchar *info;
|
||||
GLint size;
|
||||
|
||||
glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size);
|
||||
info = malloc(size);
|
||||
|
||||
glGetInfoLogARB(prog, size, NULL, info);
|
||||
ErrorF("Failed to compile %s: %s\n",
|
||||
type == GL_FRAGMENT_SHADER ? "FS" : "VS",
|
||||
info);
|
||||
ErrorF("Program source:\n%s", source);
|
||||
FatalError("GLSL compile failure\n");
|
||||
}
|
||||
|
||||
return prog;
|
||||
}
|
||||
|
||||
void
|
||||
glamor_link_glsl_prog(GLint prog)
|
||||
{
|
||||
GLint ok;
|
||||
|
||||
glLinkProgram(prog);
|
||||
glGetObjectParameterivARB(prog, GL_OBJECT_LINK_STATUS_ARB, &ok);
|
||||
if (!ok) {
|
||||
GLchar *info;
|
||||
GLint size;
|
||||
|
||||
glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size);
|
||||
info = malloc(size);
|
||||
|
||||
glGetInfoLogARB(prog, size, NULL, info);
|
||||
ErrorF("Failed to link: %s\n",
|
||||
info);
|
||||
FatalError("GLSL link failure\n");
|
||||
}
|
||||
}
|
||||
|
||||
static float ubyte_to_float(uint8_t b)
|
||||
{
|
||||
return b / 255.0f;
|
||||
}
|
||||
|
||||
void
|
||||
glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
|
||||
GLfloat *color)
|
||||
{
|
||||
if (pixmap->drawable.depth < 24) {
|
||||
ErrorF("pixmap with bad depth\n");
|
||||
color[0] = 1.0;
|
||||
color[1] = 0.0;
|
||||
color[2] = 1.0;
|
||||
color[3] = 1.0;
|
||||
} else {
|
||||
color[0] = ubyte_to_float(fg_pixel >> 16);
|
||||
color[1] = ubyte_to_float(fg_pixel >> 8);
|
||||
color[2] = ubyte_to_float(fg_pixel >> 0);
|
||||
color[3] = ubyte_to_float(fg_pixel >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -82,3 +82,89 @@ glamor_fill(DrawablePtr drawable,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
glamor_init_solid_shader(ScreenPtr screen)
|
||||
{
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
const char *solid_vs_only =
|
||||
"uniform vec4 color;\n"
|
||||
"uniform float x_bias;\n"
|
||||
"uniform float x_scale;\n"
|
||||
"uniform float y_bias;\n"
|
||||
"uniform float y_scale;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
|
||||
" (gl_Vertex.y + y_bias) * y_scale,\n"
|
||||
" 0,\n"
|
||||
" 1);\n"
|
||||
" gl_Color = color;\n"
|
||||
"}\n";
|
||||
const char *solid_vs =
|
||||
"uniform float x_bias;\n"
|
||||
"uniform float x_scale;\n"
|
||||
"uniform float y_bias;\n"
|
||||
"uniform float y_scale;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
|
||||
" (gl_Vertex.y + y_bias) * y_scale,\n"
|
||||
" 0,\n"
|
||||
" 1);\n"
|
||||
"}\n";
|
||||
const char *solid_fs =
|
||||
"uniform vec4 color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = color;\n"
|
||||
"}\n";
|
||||
GLint fs_prog, vs_prog;
|
||||
|
||||
glamor_priv->solid_prog = glCreateProgramObjectARB();
|
||||
if (GLEW_ARB_fragment_shader) {
|
||||
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, solid_vs);
|
||||
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, solid_fs);
|
||||
glAttachObjectARB(glamor_priv->solid_prog, vs_prog);
|
||||
glAttachObjectARB(glamor_priv->solid_prog, fs_prog);
|
||||
} else {
|
||||
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, solid_vs_only);
|
||||
glAttachObjectARB(glamor_priv->solid_prog, vs_prog);
|
||||
}
|
||||
glamor_link_glsl_prog(glamor_priv->solid_prog);
|
||||
|
||||
glamor_priv->solid_color_uniform_location =
|
||||
glGetUniformLocationARB(glamor_priv->solid_prog, "color");
|
||||
glamor_get_transform_uniform_locations(glamor_priv->solid_prog,
|
||||
&glamor_priv->solid_transform);
|
||||
}
|
||||
|
||||
void
|
||||
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||
unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
|
||||
{
|
||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
int x1 = x;
|
||||
int x2 = x + width;
|
||||
int y1 = y;
|
||||
int y2 = y + height;
|
||||
GLfloat color[4];
|
||||
|
||||
if (!glamor_set_destination_pixmap(pixmap))
|
||||
return;
|
||||
|
||||
glUseProgramObjectARB(glamor_priv->solid_prog);
|
||||
glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color);
|
||||
glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color);
|
||||
glamor_set_transform_for_pixmap(pixmap, &glamor_priv->solid_transform);
|
||||
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glVertex2f(x1, y1);
|
||||
glVertex2f(x1, y2);
|
||||
glVertex2f(x2, y2);
|
||||
glVertex2f(x2, y1);
|
||||
glEnd();
|
||||
|
||||
glUseProgramObjectARB(0);
|
||||
}
|
||||
|
|
|
@ -31,10 +31,22 @@
|
|||
#include "glamor.h"
|
||||
#include <GL/glew.h>
|
||||
|
||||
typedef struct glamor_transform_uniforms {
|
||||
GLint x_bias;
|
||||
GLint x_scale;
|
||||
GLint y_bias;
|
||||
GLint y_scale;
|
||||
} glamor_transform_uniforms;
|
||||
|
||||
typedef struct glamor_screen_private {
|
||||
CreateGCProcPtr saved_create_gc;
|
||||
CreatePixmapProcPtr saved_create_pixmap;
|
||||
DestroyPixmapProcPtr saved_destroy_pixmap;
|
||||
|
||||
/* glamor_solid */
|
||||
GLint solid_prog;
|
||||
GLint solid_color_uniform_location;
|
||||
glamor_transform_uniforms solid_transform;
|
||||
} glamor_screen_private;
|
||||
|
||||
extern DevPrivateKey glamor_screen_private_key;
|
||||
|
@ -50,9 +62,6 @@ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
|
|||
|
||||
/* glamor_core.c */
|
||||
Bool glamor_create_gc(GCPtr gc);
|
||||
void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||
unsigned char alu, unsigned long planemask,
|
||||
unsigned long fg_pixel);
|
||||
void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
|
||||
int x, int y, int width, int height,
|
||||
unsigned char alu, unsigned long planemask,
|
||||
|
@ -62,6 +71,15 @@ void glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
|||
int x, int y, int width, int height,
|
||||
unsigned char alu, unsigned long planemask,
|
||||
int tile_x, int tile_y);
|
||||
GLint glamor_compile_glsl_prog(GLenum type, const char *source);
|
||||
void glamor_link_glsl_prog(GLint prog);
|
||||
void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
|
||||
GLfloat *color);
|
||||
Bool glamor_set_destination_pixmap(PixmapPtr pixmap);
|
||||
void glamor_get_transform_uniform_locations(GLint prog,
|
||||
glamor_transform_uniforms *uniform_locations);
|
||||
void glamor_set_transform_for_pixmap(PixmapPtr pixmap,
|
||||
glamor_transform_uniforms *uniform_locations);
|
||||
|
||||
/* glamor_fill.c */
|
||||
void glamor_fill(DrawablePtr drawable,
|
||||
|
@ -70,6 +88,9 @@ void glamor_fill(DrawablePtr drawable,
|
|||
int y,
|
||||
int width,
|
||||
int height);
|
||||
void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||
unsigned char alu, unsigned long planemask,
|
||||
unsigned long fg_pixel);
|
||||
|
||||
/* glamor_fillspans.c */
|
||||
void glamor_fill_spans(DrawablePtr drawable,
|
||||
|
@ -79,4 +100,6 @@ void glamor_fill_spans(DrawablePtr drawable,
|
|||
int *widths,
|
||||
int sorted);
|
||||
|
||||
void glamor_init_solid_shader(ScreenPtr screen);
|
||||
|
||||
#endif /* GLAMOR_PRIV_H */
|
||||
|
|
Loading…
Reference in New Issue
Block a user