123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- /*
- * Copyright © 2014 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 the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS 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.
- */
- #include "glamor_priv.h"
- #include "glamor_transform.h"
- /*
- * Set up rendering to target the specified drawable, computing an
- * appropriate transform for the vertex shader to convert
- * drawable-relative coordinates into pixmap-relative coordinates. If
- * requested, the offset from pixmap origin coordinates back to window
- * system coordinates will be returned in *p_off_x, *p_off_y so that
- * clipping computations can be adjusted as appropriate
- */
- void
- glamor_set_destination_drawable(DrawablePtr drawable,
- int box_x,
- int box_y,
- Bool do_drawable_translate,
- Bool center_offset,
- GLint matrix_uniform_location,
- int *p_off_x,
- int *p_off_y)
- {
- PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
- glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
- int off_x, off_y;
- BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y);
- int w = box->x2 - box->x1;
- int h = box->y2 - box->y1;
- float scale_x = 2.0f / (float) w;
- float scale_y = 2.0f / (float) h;
- float center_adjust = 0.0f;
- glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
- off_x -= box->x1;
- off_y -= box->y1;
- if (p_off_x) {
- *p_off_x = off_x;
- *p_off_y = off_y;
- }
- /* A tricky computation to find the right value for the two linear functions
- * that transform rendering coordinates to pixmap coordinates
- *
- * pixmap_x = render_x + drawable->x + off_x
- * pixmap_y = render_y + drawable->y + off_y
- *
- * gl_x = pixmap_x * 2 / width - 1
- * gl_y = pixmap_y * 2 / height - 1
- *
- * gl_x = (render_x + drawable->x + off_x) * 2 / width - 1
- *
- * gl_x = (render_x) * 2 / width + (drawable->x + off_x) * 2 / width - 1
- *
- * I'll think about yInverted later, when I have some way to test
- */
- if (do_drawable_translate) {
- off_x += drawable->x;
- off_y += drawable->y;
- }
- /*
- * To get GL_POINTS drawn in the right spot, we need to adjust the
- * coordinates by 1/2 a pixel.
- */
- if (center_offset)
- center_adjust = 0.5f;
- glUniform4f(matrix_uniform_location,
- scale_x, (off_x + center_adjust) * scale_x - 1.0f,
- scale_y, (off_y + center_adjust) * scale_y - 1.0f);
- glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y),
- 0, 0, w, h);
- }
- /*
- * Set up for solid rendering to the specified pixmap using alu, fg and planemask
- * from the specified GC. Load the target color into the specified uniform
- */
- void
- glamor_set_color(PixmapPtr pixmap,
- CARD32 pixel,
- GLint uniform)
- {
- float color[4];
- glamor_get_rgba_from_pixel(pixel,
- &color[0], &color[1], &color[2], &color[3],
- format_for_pixmap(pixmap));
- glUniform4fv(uniform, 1, color);
- }
- Bool
- glamor_set_solid(PixmapPtr pixmap,
- GCPtr gc,
- Bool use_alu,
- GLint uniform)
- {
- CARD32 pixel;
- int alu = use_alu ? gc->alu : GXcopy;
- if (!glamor_set_planemask(pixmap, gc->planemask))
- return FALSE;
- pixel = gc->fgPixel;
- if (!glamor_set_alu(pixmap->drawable.pScreen, alu)) {
- switch (gc->alu) {
- case GXclear:
- pixel = 0;
- break;
- case GXcopyInverted:
- pixel = ~pixel;
- break;
- case GXset:
- pixel = ~0 & gc->planemask;
- break;
- default:
- return FALSE;
- }
- }
- glamor_set_color(pixmap, gc->fgPixel, uniform);
- return TRUE;
- }
- Bool
- glamor_set_texture(PixmapPtr pixmap,
- PixmapPtr texture,
- int off_x,
- int off_y,
- GLint offset_uniform,
- GLint size_uniform)
- {
- glamor_pixmap_private *texture_priv;
- texture_priv = glamor_get_pixmap_private(texture);
- if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(texture_priv))
- return FALSE;
- if (texture_priv->type == GLAMOR_TEXTURE_LARGE)
- return FALSE;
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture_priv->base.fbo->tex);
- glUniform2f(offset_uniform, off_x, off_y);
- glUniform2f(size_uniform, texture->drawable.width, texture->drawable.height);
- return TRUE;
- }
- Bool
- glamor_set_tiled(PixmapPtr pixmap,
- GCPtr gc,
- GLint offset_uniform,
- GLint size_uniform)
- {
- if (!glamor_set_alu(pixmap->drawable.pScreen, gc->alu))
- return FALSE;
- if (!glamor_set_planemask(pixmap, gc->planemask))
- return FALSE;
- return glamor_set_texture(pixmap,
- gc->tile.pixmap,
- -gc->patOrg.x,
- -gc->patOrg.y,
- offset_uniform,
- size_uniform);
- }
- Bool
- glamor_set_stippled(PixmapPtr pixmap,
- GCPtr gc,
- GLint fg_uniform,
- GLint offset_uniform,
- GLint size_uniform)
- {
- if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform))
- return FALSE;
- if (!glamor_set_texture(pixmap, gc->stipple, gc->patOrg.x, gc->patOrg.y, offset_uniform, size_uniform))
- return FALSE;
- return TRUE;
- }
|