xserver-multidpi/glamor/glamor_fill.c
Zhigang Gong 92fd83872f Remove the access mode from private pixmap structure.
Change the finish_access to pass in the access mode, and remove
the access mode from the pixmap structure. This element should
not be a pixmap's property.

Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
2013-12-18 11:23:46 -08:00

200 lines
5.9 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
*/
Bool
glamor_fill(DrawablePtr drawable,
GCPtr gc, int x, int y, int width, int height, Bool fallback)
{
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
int off_x, off_y;
glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y);
switch (gc->fillStyle) {
case FillSolid:
if (!glamor_solid(dst_pixmap,
x + off_x,
y + off_y,
width, height, gc->alu, gc->planemask,
gc->fgPixel))
goto fail;
break;
case FillStippled:
case FillOpaqueStippled:
if (!glamor_stipple(dst_pixmap,
gc->stipple,
x + off_x,
y + off_y,
width,
height,
gc->alu,
gc->planemask,
gc->fgPixel,
gc->bgPixel, gc->patOrg.x,
gc->patOrg.y))
goto fail;
break;
case FillTiled:
if (!glamor_tile(dst_pixmap,
gc->tile.pixmap,
x + off_x,
y + off_y,
width,
height,
gc->alu,
gc->planemask,
drawable->x + x + off_x - gc->patOrg.x,
drawable->y + y + off_y - gc->patOrg.y))
goto fail;
break;
}
return TRUE;
fail:
if (!fallback) return FALSE;
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
if (glamor_prepare_access_gc(gc)) {
fbFill(drawable, gc, x, y, width, height);
glamor_finish_access_gc(gc);
}
glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
}
return TRUE;
}
void
glamor_init_solid_shader(ScreenPtr screen)
{
glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
const char *solid_vs =
"attribute vec4 v_position;"
"void main()\n" "{\n" " gl_Position = v_position;\n"
"}\n";
const char *solid_fs =
GLAMOR_DEFAULT_PRECISION "uniform vec4 color;\n"
"void main()\n" "{\n" " gl_FragColor = color;\n" "}\n";
GLint fs_prog, vs_prog;
glamor_priv->solid_prog = dispatch->glCreateProgram();
vs_prog =
glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
fs_prog =
glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
solid_fs);
dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog);
dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog);
dispatch->glBindAttribLocation(glamor_priv->solid_prog,
GLAMOR_VERTEX_POS, "v_position");
glamor_link_glsl_prog(dispatch, glamor_priv->solid_prog);
glamor_priv->solid_color_uniform_location =
dispatch->glGetUniformLocation(glamor_priv->solid_prog,
"color");
}
Bool
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);
glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
int x1 = x;
int x2 = x + width;
int y1 = y;
int y2 = y + height;
GLfloat color[4];
float vertices[8];
GLfloat xscale, yscale;
if (!pixmap_priv || !GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
glamor_fallback("dest %p has no fbo.\n", pixmap);
goto fail;
}
glamor_set_alu(dispatch, alu);
if (!glamor_set_planemask(pixmap, planemask)) {
glamor_fallback
("Failedto set planemask in glamor_solid.\n");
goto fail;
}
glamor_get_rgba_from_pixel(fg_pixel,
&color[0],
&color[1],
&color[2],
&color[3], format_for_pixmap(pixmap));
#ifdef GLAMOR_DELAYED_FILLING
if (x == 0 && y == 0
&& width == pixmap->drawable.width
&& height == pixmap->drawable.height
&& pixmap_priv->fb != glamor_priv->screen_fbo) {
pixmap_priv->pending_op.type = GLAMOR_PENDING_FILL;
memcpy(&pixmap_priv->pending_op.fill.color4fv,
color, 4 * sizeof(GLfloat));
pixmap_priv->pending_op.fill.colori = fg_pixel;
return TRUE;
}
#endif
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap);
dispatch->glUseProgram(glamor_priv->solid_prog);
dispatch->glUniform4fv(glamor_priv->solid_color_uniform_location,
1, color);
dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
GL_FALSE, 2 * sizeof(float),
vertices);
dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);
glamor_set_normalize_vcoords(xscale, yscale, x1, y1, x2, y2,
glamor_priv->yInverted, vertices);
dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
dispatch->glUseProgram(0);
return TRUE;
fail:
glamor_set_alu(dispatch, GXcopy);
glamor_set_planemask(pixmap, ~0);
return FALSE;
}