eb3487a448
Due to the coordinate system on EGL is different from FBO object. To support EGL surface well, we add this new feature. When calling glamor_init from EGL ddx driver, it should use the new flag GLAMOR_INVERTED_Y_AXIS.
199 lines
5.6 KiB
C
199 lines
5.6 KiB
C
/*
|
|
* Copyright © 2008 Intel Corporation
|
|
* Copyright © 1998 Keith Packard
|
|
*
|
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
* documentation for any purpose is hereby granted without fee, provided that
|
|
* the above copyright notice appear in all copies and that both that
|
|
* copyright notice and this permission notice appear in supporting
|
|
* documentation, and that the name of Keith Packard not be used in
|
|
* advertising or publicity pertaining to distribution of the software without
|
|
* specific, written prior permission. Keith Packard makes no
|
|
* representations about the suitability of this software for any purpose. It
|
|
* is provided "as is" without express or implied warranty.
|
|
*
|
|
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#ifdef HAVE_DIX_CONFIG_H
|
|
#include <dix-config.h>
|
|
#endif
|
|
|
|
#include "glamor_priv.h"
|
|
|
|
/** @file glamor_fillspans.c
|
|
*
|
|
* GC fill implementation, based loosely on fb_fill.c
|
|
*/
|
|
|
|
void
|
|
glamor_fill(DrawablePtr drawable,
|
|
GCPtr gc,
|
|
int x,
|
|
int y,
|
|
int width,
|
|
int height)
|
|
{
|
|
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
|
|
int x_off, y_off;
|
|
|
|
glamor_get_drawable_deltas(drawable, dst_pixmap, &x_off, &y_off);
|
|
|
|
switch (gc->fillStyle) {
|
|
case FillSolid:
|
|
glamor_solid(dst_pixmap,
|
|
x + x_off,
|
|
y + y_off,
|
|
width,
|
|
height,
|
|
gc->alu,
|
|
gc->planemask,
|
|
gc->fgPixel);
|
|
break;
|
|
case FillStippled:
|
|
case FillOpaqueStippled:
|
|
glamor_stipple(dst_pixmap,
|
|
gc->stipple,
|
|
x+ x_off,
|
|
y + y_off,
|
|
width,
|
|
height,
|
|
gc->alu,
|
|
gc->planemask,
|
|
gc->fgPixel,
|
|
gc->bgPixel,
|
|
gc->patOrg.x + x_off,
|
|
gc->patOrg.y + y_off);
|
|
break;
|
|
case FillTiled:
|
|
glamor_tile(dst_pixmap,
|
|
gc->tile.pixmap,
|
|
x + x_off,
|
|
y + y_off,
|
|
width,
|
|
height,
|
|
gc->alu,
|
|
gc->planemask,
|
|
drawable->x + x - gc->patOrg.x,
|
|
drawable->y + y - gc->patOrg.y);
|
|
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"
|
|
"void main()\n"
|
|
"{\n"
|
|
" gl_Position = gl_Vertex;\n"
|
|
" gl_Color = color;\n"
|
|
"}\n";
|
|
const char *solid_vs =
|
|
"void main()\n"
|
|
"{\n"
|
|
" gl_Position = gl_Vertex;\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");
|
|
}
|
|
|
|
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];
|
|
float vertices[4][2];
|
|
|
|
if (!glamor_set_destination_pixmap(pixmap))
|
|
return;
|
|
glamor_set_alu(alu);
|
|
if (!glamor_set_planemask(pixmap, planemask))
|
|
goto fail;
|
|
|
|
glUseProgramObjectARB(glamor_priv->solid_prog);
|
|
glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color);
|
|
glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color);
|
|
|
|
glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, vertices);
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
|
vertices[0][0] = v_from_x_coord_x(pixmap, x1);
|
|
vertices[1][0] = v_from_x_coord_x(pixmap, x2);
|
|
vertices[2][0] = v_from_x_coord_x(pixmap, x2);
|
|
vertices[3][0] = v_from_x_coord_x(pixmap, x1);
|
|
|
|
if (glamor_priv->yInverted) {
|
|
vertices[0][1] = v_from_x_coord_y_inverted(pixmap, y1);
|
|
vertices[1][1] = v_from_x_coord_y_inverted(pixmap, y1);
|
|
vertices[2][1] = v_from_x_coord_y_inverted(pixmap, y2);
|
|
vertices[3][1] = v_from_x_coord_y_inverted(pixmap, y2);
|
|
} else {
|
|
vertices[0][1] = v_from_x_coord_y(pixmap, y1);
|
|
vertices[1][1] = v_from_x_coord_y(pixmap, y1);
|
|
vertices[2][1] = v_from_x_coord_y(pixmap, y2);
|
|
vertices[3][1] = v_from_x_coord_y(pixmap, y2);
|
|
}
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
glUseProgramObjectARB(0);
|
|
fail:
|
|
glamor_set_alu(GXcopy);
|
|
glamor_set_planemask(pixmap, ~0);
|
|
}
|
|
|
|
/* Highlight places where we're doing it wrong. */
|
|
void
|
|
glamor_solid_fail_region(PixmapPtr pixmap, int x, int y, int width, int height)
|
|
{
|
|
unsigned long pixel;
|
|
|
|
switch (pixmap->drawable.depth) {
|
|
case 24:
|
|
case 32:
|
|
pixel = 0x00ff00ff; /* our favorite color */
|
|
break;
|
|
default:
|
|
case 8:
|
|
pixel = 0xd0d0d0d0;
|
|
break;
|
|
}
|
|
|
|
glamor_solid(pixmap, x, y, width, height, GXcopy, ~0, pixel);
|
|
}
|