Merge remote-tracking branch 'anholt/glamor-next'
This commit is contained in:
commit
5c2e9fa3d6
|
@ -7,20 +7,21 @@ AM_CFLAGS = $(CWARNFLAGS) $(DIX_CFLAGS) $(GLAMOR_CFLAGS)
|
||||||
libglamor_la_SOURCES = \
|
libglamor_la_SOURCES = \
|
||||||
glamor.c \
|
glamor.c \
|
||||||
glamor_context.h \
|
glamor_context.h \
|
||||||
glamor_copyarea.c \
|
glamor_copy.c \
|
||||||
glamor_copywindow.c \
|
|
||||||
glamor_core.c \
|
glamor_core.c \
|
||||||
|
glamor_dash.c \
|
||||||
glamor_debug.h \
|
glamor_debug.h \
|
||||||
glamor_fill.c \
|
|
||||||
glamor_font.c \
|
glamor_font.c \
|
||||||
glamor_font.h \
|
glamor_font.h \
|
||||||
glamor_glx.c \
|
glamor_glx.c \
|
||||||
glamor_glyphs.c \
|
glamor_glyphs.c \
|
||||||
glamor_polylines.c \
|
|
||||||
glamor_segment.c \
|
|
||||||
glamor_image.c \
|
glamor_image.c \
|
||||||
|
glamor_lines.c \
|
||||||
|
glamor_segs.c \
|
||||||
glamor_render.c \
|
glamor_render.c \
|
||||||
glamor_gradient.c \
|
glamor_gradient.c \
|
||||||
|
glamor_prepare.c \
|
||||||
|
glamor_prepare.h \
|
||||||
glamor_program.c \
|
glamor_program.c \
|
||||||
glamor_program.h \
|
glamor_program.h \
|
||||||
glamor_rects.c \
|
glamor_rects.c \
|
||||||
|
@ -31,10 +32,8 @@ libglamor_la_SOURCES = \
|
||||||
glamor_transform.c \
|
glamor_transform.c \
|
||||||
glamor_transform.h \
|
glamor_transform.h \
|
||||||
glamor_trapezoid.c \
|
glamor_trapezoid.c \
|
||||||
glamor_tile.c \
|
|
||||||
glamor_triangles.c\
|
glamor_triangles.c\
|
||||||
glamor_addtraps.c\
|
glamor_addtraps.c\
|
||||||
glamor_copyplane.c\
|
|
||||||
glamor_glyphblt.c\
|
glamor_glyphblt.c\
|
||||||
glamor_points.c\
|
glamor_points.c\
|
||||||
glamor_priv.h\
|
glamor_priv.h\
|
||||||
|
@ -45,7 +44,9 @@ libglamor_la_SOURCES = \
|
||||||
glamor_window.c\
|
glamor_window.c\
|
||||||
glamor_fbo.c\
|
glamor_fbo.c\
|
||||||
glamor_compositerects.c\
|
glamor_compositerects.c\
|
||||||
|
glamor_utils.c\
|
||||||
glamor_utils.h\
|
glamor_utils.h\
|
||||||
|
glamor_xv.c \
|
||||||
glamor.h
|
glamor.h
|
||||||
|
|
||||||
libglamor_egl_stubs_la_SOURCES = glamor_egl_stubs.c
|
libglamor_egl_stubs_la_SOURCES = glamor_egl_stubs.c
|
||||||
|
|
|
@ -35,10 +35,9 @@
|
||||||
|
|
||||||
#include "glamor_priv.h"
|
#include "glamor_priv.h"
|
||||||
|
|
||||||
static DevPrivateKeyRec glamor_screen_private_key_index;
|
DevPrivateKeyRec glamor_screen_private_key;
|
||||||
DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index;
|
DevPrivateKeyRec glamor_pixmap_private_key;
|
||||||
static DevPrivateKeyRec glamor_pixmap_private_key_index;
|
DevPrivateKeyRec glamor_gc_private_key;
|
||||||
DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable.
|
* glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable.
|
||||||
|
@ -68,7 +67,7 @@ glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
|
||||||
glamor_get_screen_private(pixmap->drawable.pScreen);
|
glamor_get_screen_private(pixmap->drawable.pScreen);
|
||||||
|
|
||||||
pixmap_priv = dixLookupPrivate(&pixmap->devPrivates,
|
pixmap_priv = dixLookupPrivate(&pixmap->devPrivates,
|
||||||
glamor_pixmap_private_key);
|
&glamor_pixmap_private_key);
|
||||||
if (pixmap_priv == NULL) {
|
if (pixmap_priv == NULL) {
|
||||||
pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
|
pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
|
||||||
glamor_set_pixmap_private(pixmap, pixmap_priv);
|
glamor_set_pixmap_private(pixmap, pixmap_priv);
|
||||||
|
@ -251,11 +250,6 @@ glamor_block_handler(ScreenPtr screen)
|
||||||
glamor_priv->tick++;
|
glamor_priv->tick++;
|
||||||
glFlush();
|
glFlush();
|
||||||
glamor_fbo_expire(glamor_priv);
|
glamor_fbo_expire(glamor_priv);
|
||||||
if (glamor_priv->state == RENDER_STATE
|
|
||||||
&& glamor_priv->render_idle_cnt++ > RENDER_IDEL_MAX) {
|
|
||||||
glamor_priv->state = IDLE_STATE;
|
|
||||||
glamor_priv->render_idle_cnt = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -330,13 +324,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
glamor_priv->flags = flags;
|
glamor_priv->flags = flags;
|
||||||
if (flags & GLAMOR_INVERTED_Y_AXIS) {
|
|
||||||
glamor_priv->yInverted = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
glamor_priv->yInverted = FALSE;
|
|
||||||
|
|
||||||
if (!dixRegisterPrivateKey(glamor_screen_private_key, PRIVATE_SCREEN, 0)) {
|
if (!dixRegisterPrivateKey(&glamor_screen_private_key, PRIVATE_SCREEN, 0)) {
|
||||||
LogMessage(X_WARNING,
|
LogMessage(X_WARNING,
|
||||||
"glamor%d: Failed to allocate screen private\n",
|
"glamor%d: Failed to allocate screen private\n",
|
||||||
screen->myNum);
|
screen->myNum);
|
||||||
|
@ -345,11 +334,19 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
||||||
|
|
||||||
glamor_set_screen_private(screen, glamor_priv);
|
glamor_set_screen_private(screen, glamor_priv);
|
||||||
|
|
||||||
if (!dixRegisterPrivateKey(glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
|
if (!dixRegisterPrivateKey(&glamor_pixmap_private_key, PRIVATE_PIXMAP, 0)) {
|
||||||
LogMessage(X_WARNING,
|
LogMessage(X_WARNING,
|
||||||
"glamor%d: Failed to allocate pixmap private\n",
|
"glamor%d: Failed to allocate pixmap private\n",
|
||||||
screen->myNum);
|
screen->myNum);
|
||||||
goto fail;;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dixRegisterPrivateKey(&glamor_gc_private_key, PRIVATE_GC,
|
||||||
|
sizeof (glamor_gc_private))) {
|
||||||
|
LogMessage(X_WARNING,
|
||||||
|
"glamor%d: Failed to allocate gc private\n",
|
||||||
|
screen->myNum);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (epoxy_is_desktop_gl())
|
if (epoxy_is_desktop_gl())
|
||||||
|
@ -398,6 +395,10 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glamor_priv->has_rw_pbo = FALSE;
|
||||||
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
|
||||||
|
glamor_priv->has_rw_pbo = TRUE;
|
||||||
|
|
||||||
glamor_priv->has_khr_debug = epoxy_has_gl_extension("GL_KHR_debug");
|
glamor_priv->has_khr_debug = epoxy_has_gl_extension("GL_KHR_debug");
|
||||||
glamor_priv->has_pack_invert =
|
glamor_priv->has_pack_invert =
|
||||||
epoxy_has_gl_extension("GL_MESA_pack_invert");
|
epoxy_has_gl_extension("GL_MESA_pack_invert");
|
||||||
|
@ -407,6 +408,10 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
||||||
epoxy_has_gl_extension("GL_ARB_map_buffer_range");
|
epoxy_has_gl_extension("GL_ARB_map_buffer_range");
|
||||||
glamor_priv->has_buffer_storage =
|
glamor_priv->has_buffer_storage =
|
||||||
epoxy_has_gl_extension("GL_ARB_buffer_storage");
|
epoxy_has_gl_extension("GL_ARB_buffer_storage");
|
||||||
|
glamor_priv->has_nv_texture_barrier =
|
||||||
|
epoxy_has_gl_extension("GL_NV_texture_barrier");
|
||||||
|
|
||||||
|
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size);
|
||||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glamor_priv->max_fbo_size);
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glamor_priv->max_fbo_size);
|
||||||
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_viewport_size);
|
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_viewport_size);
|
||||||
glamor_priv->max_fbo_size = MIN(glamor_priv->max_fbo_size, max_viewport_size[0]);
|
glamor_priv->max_fbo_size = MIN(glamor_priv->max_fbo_size, max_viewport_size[0]);
|
||||||
|
@ -505,8 +510,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
||||||
|
|
||||||
glamor_init_vbo(screen);
|
glamor_init_vbo(screen);
|
||||||
glamor_init_pixmap_fbo(screen);
|
glamor_init_pixmap_fbo(screen);
|
||||||
glamor_init_solid_shader(screen);
|
|
||||||
glamor_init_tile_shader(screen);
|
|
||||||
#ifdef GLAMOR_TRAPEZOID_SHADER
|
#ifdef GLAMOR_TRAPEZOID_SHADER
|
||||||
glamor_init_trapezoid_shader(screen);
|
glamor_init_trapezoid_shader(screen);
|
||||||
#endif
|
#endif
|
||||||
|
@ -538,8 +541,6 @@ glamor_release_screen_priv(ScreenPtr screen)
|
||||||
#endif
|
#endif
|
||||||
glamor_fini_vbo(screen);
|
glamor_fini_vbo(screen);
|
||||||
glamor_fini_pixmap_fbo(screen);
|
glamor_fini_pixmap_fbo(screen);
|
||||||
glamor_fini_solid_shader(screen);
|
|
||||||
glamor_fini_tile_shader(screen);
|
|
||||||
#ifdef GLAMOR_TRAPEZOID_SHADER
|
#ifdef GLAMOR_TRAPEZOID_SHADER
|
||||||
glamor_fini_trapezoid_shader(screen);
|
glamor_fini_trapezoid_shader(screen);
|
||||||
#endif
|
#endif
|
||||||
|
@ -559,7 +560,7 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
|
||||||
glamor_pixmap_private *old_priv;
|
glamor_pixmap_private *old_priv;
|
||||||
glamor_pixmap_fbo *fbo;
|
glamor_pixmap_fbo *fbo;
|
||||||
|
|
||||||
old_priv = dixGetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
|
old_priv = dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
|
||||||
|
|
||||||
if (priv) {
|
if (priv) {
|
||||||
assert(old_priv == NULL);
|
assert(old_priv == NULL);
|
||||||
|
@ -572,7 +573,7 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
|
||||||
free(old_priv);
|
free(old_priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
dixSetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key, priv);
|
dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key, priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
|
|
|
@ -63,7 +63,7 @@ typedef enum glamor_pixmap_type {
|
||||||
} glamor_pixmap_type_t;
|
} glamor_pixmap_type_t;
|
||||||
|
|
||||||
#define GLAMOR_EGL_EXTERNAL_BUFFER 3
|
#define GLAMOR_EGL_EXTERNAL_BUFFER 3
|
||||||
#define GLAMOR_INVERTED_Y_AXIS 1
|
#define GLAMOR_INVERTED_Y_AXIS 1 /* compat stub */
|
||||||
#define GLAMOR_USE_SCREEN (1 << 1)
|
#define GLAMOR_USE_SCREEN (1 << 1)
|
||||||
#define GLAMOR_USE_PICTURE_SCREEN (1 << 2)
|
#define GLAMOR_USE_PICTURE_SCREEN (1 << 2)
|
||||||
#define GLAMOR_USE_EGL_SCREEN (1 << 3)
|
#define GLAMOR_USE_EGL_SCREEN (1 << 3)
|
||||||
|
@ -79,12 +79,6 @@ typedef enum glamor_pixmap_type {
|
||||||
* @screen: Current screen pointer.
|
* @screen: Current screen pointer.
|
||||||
* @flags: Please refer the flags description above.
|
* @flags: Please refer the flags description above.
|
||||||
*
|
*
|
||||||
* @GLAMOR_INVERTED_Y_AXIS:
|
|
||||||
* set 1 means the GL env's origin (0,0) is at top-left.
|
|
||||||
* EGL/DRM platform is an example need to set this bit.
|
|
||||||
* glx platform's origin is at bottom-left thus need to
|
|
||||||
* clear this bit.
|
|
||||||
*
|
|
||||||
* @GLAMOR_USE_SCREEN:
|
* @GLAMOR_USE_SCREEN:
|
||||||
* If running in an pre-existing X environment, and the
|
* If running in an pre-existing X environment, and the
|
||||||
* gl context is GLX, then you should set this bit and
|
* gl context is GLX, then you should set this bit and
|
||||||
|
@ -321,6 +315,10 @@ extern _X_EXPORT int glamor_create_gc(GCPtr gc);
|
||||||
extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes,
|
extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes,
|
||||||
DrawablePtr drawable);
|
DrawablePtr drawable);
|
||||||
|
|
||||||
|
extern _X_EXPORT void glamor_destroy_gc(GCPtr gc);
|
||||||
|
|
||||||
|
#define HAS_GLAMOR_DESTROY_GC 1
|
||||||
|
|
||||||
extern Bool _X_EXPORT glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
|
extern Bool _X_EXPORT glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
|
||||||
extern void _X_EXPORT glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region);
|
extern void _X_EXPORT glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region);
|
||||||
|
|
||||||
|
@ -354,6 +352,17 @@ extern _X_EXPORT Bool glamor_copy_n_to_n_nf(DrawablePtr src,
|
||||||
Bool upsidedown, Pixel bitplane,
|
Bool upsidedown, Pixel bitplane,
|
||||||
void *closure);
|
void *closure);
|
||||||
|
|
||||||
|
extern _X_EXPORT Bool glamor_copy_nf(DrawablePtr src,
|
||||||
|
DrawablePtr dst,
|
||||||
|
GCPtr gc,
|
||||||
|
BoxPtr box,
|
||||||
|
int nbox,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
Bool reverse,
|
||||||
|
Bool upsidedown, Pixel bitplane,
|
||||||
|
void *closure);
|
||||||
|
|
||||||
extern _X_EXPORT Bool glamor_composite_nf(CARD8 op,
|
extern _X_EXPORT Bool glamor_composite_nf(CARD8 op,
|
||||||
PicturePtr source,
|
PicturePtr source,
|
||||||
PicturePtr mask,
|
PicturePtr mask,
|
||||||
|
|
693
glamor/glamor_copy.c
Normal file
693
glamor/glamor_copy.c
Normal file
|
@ -0,0 +1,693 @@
|
||||||
|
/*
|
||||||
|
* 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_transfer.h"
|
||||||
|
#include "glamor_prepare.h"
|
||||||
|
#include "glamor_transform.h"
|
||||||
|
|
||||||
|
struct copy_args {
|
||||||
|
PixmapPtr src_pixmap;
|
||||||
|
glamor_pixmap_fbo *src;
|
||||||
|
uint32_t bitplane;
|
||||||
|
int dx, dy;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
use_copyarea(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
|
||||||
|
{
|
||||||
|
struct copy_args *args = arg;
|
||||||
|
glamor_pixmap_fbo *src = args->src;
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, src->tex);
|
||||||
|
|
||||||
|
glUniform2f(prog->fill_offset_uniform, args->dx, args->dy);
|
||||||
|
glUniform2f(prog->fill_size_uniform, src->width, src->height);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const glamor_facet glamor_facet_copyarea = {
|
||||||
|
"copy_area",
|
||||||
|
.vs_vars = "attribute vec2 primitive;\n",
|
||||||
|
.vs_exec = (GLAMOR_POS(gl_Position, primitive.xy)
|
||||||
|
" fill_pos = (fill_offset + primitive.xy) / fill_size;\n"),
|
||||||
|
.fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n",
|
||||||
|
.locations = glamor_program_location_fill,
|
||||||
|
.use = use_copyarea,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure the copy plane program for the current operation
|
||||||
|
*/
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
use_copyplane(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
|
||||||
|
{
|
||||||
|
struct copy_args *args = arg;
|
||||||
|
glamor_pixmap_fbo *src = args->src;
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, src->tex);
|
||||||
|
|
||||||
|
glUniform2f(prog->fill_offset_uniform, args->dx, args->dy);
|
||||||
|
glUniform2f(prog->fill_size_uniform, src->width, src->height);
|
||||||
|
|
||||||
|
glamor_set_color(dst, gc->fgPixel, prog->fg_uniform);
|
||||||
|
glamor_set_color(dst, gc->bgPixel, prog->bg_uniform);
|
||||||
|
|
||||||
|
/* XXX handle 2 10 10 10 and 1555 formats; presumably the pixmap private knows this? */
|
||||||
|
switch (args->src_pixmap->drawable.depth) {
|
||||||
|
case 24:
|
||||||
|
glUniform4ui(prog->bitplane_uniform,
|
||||||
|
(args->bitplane >> 16) & 0xff,
|
||||||
|
(args->bitplane >> 8) & 0xff,
|
||||||
|
(args->bitplane ) & 0xff,
|
||||||
|
0);
|
||||||
|
|
||||||
|
glUniform4f(prog->bitmul_uniform, 0xff, 0xff, 0xff, 0);
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
glUniform4ui(prog->bitplane_uniform,
|
||||||
|
(args->bitplane >> 16) & 0xff,
|
||||||
|
(args->bitplane >> 8) & 0xff,
|
||||||
|
(args->bitplane ) & 0xff,
|
||||||
|
(args->bitplane >> 24) & 0xff);
|
||||||
|
|
||||||
|
glUniform4f(prog->bitmul_uniform, 0xff, 0xff, 0xff, 0xff);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
glUniform4ui(prog->bitplane_uniform,
|
||||||
|
(args->bitplane >> 11) & 0x1f,
|
||||||
|
(args->bitplane >> 5) & 0x3f,
|
||||||
|
(args->bitplane ) & 0x1f,
|
||||||
|
0);
|
||||||
|
|
||||||
|
glUniform4f(prog->bitmul_uniform, 0x1f, 0x3f, 0x1f, 0);
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
glUniform4ui(prog->bitplane_uniform,
|
||||||
|
(args->bitplane >> 10) & 0x1f,
|
||||||
|
(args->bitplane >> 5) & 0x1f,
|
||||||
|
(args->bitplane ) & 0x1f,
|
||||||
|
0);
|
||||||
|
|
||||||
|
glUniform4f(prog->bitmul_uniform, 0x1f, 0x1f, 0x1f, 0);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
glUniform4ui(prog->bitplane_uniform,
|
||||||
|
0, 0, 0, args->bitplane);
|
||||||
|
glUniform4f(prog->bitmul_uniform, 0, 0, 0, 0xff);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
glUniform4ui(prog->bitplane_uniform,
|
||||||
|
0, 0, 0, args->bitplane);
|
||||||
|
glUniform4f(prog->bitmul_uniform, 0, 0, 0, 0xff);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const glamor_facet glamor_facet_copyplane = {
|
||||||
|
"copy_plane",
|
||||||
|
.version = 130,
|
||||||
|
.vs_vars = "attribute vec2 primitive;\n",
|
||||||
|
.vs_exec = (GLAMOR_POS(gl_Position, (primitive.xy))
|
||||||
|
" fill_pos = (fill_offset + primitive.xy) / fill_size;\n"),
|
||||||
|
.fs_exec = (" uvec4 bits = uvec4(round(texture2D(sampler, fill_pos) * bitmul));\n"
|
||||||
|
" if ((bits & bitplane) != uvec4(0,0,0,0))\n"
|
||||||
|
" gl_FragColor = fg;\n"
|
||||||
|
" else\n"
|
||||||
|
" gl_FragColor = bg;\n"),
|
||||||
|
.locations = glamor_program_location_fill|glamor_program_location_fg|glamor_program_location_bg|glamor_program_location_bitplane,
|
||||||
|
.use = use_copyplane,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When all else fails, pull the bits out of the GPU and do the
|
||||||
|
* operation with fb
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
glamor_copy_bail(DrawablePtr src,
|
||||||
|
DrawablePtr dst,
|
||||||
|
GCPtr gc,
|
||||||
|
BoxPtr box,
|
||||||
|
int nbox,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
Bool reverse,
|
||||||
|
Bool upsidedown,
|
||||||
|
Pixel bitplane,
|
||||||
|
void *closure)
|
||||||
|
{
|
||||||
|
if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) && glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
|
||||||
|
if (bitplane) {
|
||||||
|
if (src->bitsPerPixel > 1)
|
||||||
|
fbCopyNto1(src, dst, gc, box, nbox, dx, dy,
|
||||||
|
reverse, upsidedown, bitplane, closure);
|
||||||
|
else
|
||||||
|
fbCopy1toN(src, dst, gc, box, nbox, dx, dy,
|
||||||
|
reverse, upsidedown, bitplane, closure);
|
||||||
|
} else {
|
||||||
|
fbCopyNtoN(src, dst, gc, box, nbox, dx, dy,
|
||||||
|
reverse, upsidedown, bitplane, closure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glamor_finish_access(dst);
|
||||||
|
glamor_finish_access(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements CopyPlane and CopyArea from the GPU to the GPU by using
|
||||||
|
* the source as a texture and painting that into the destination.
|
||||||
|
*
|
||||||
|
* This requires that source and dest are different textures, or that
|
||||||
|
* (if the copy area doesn't overlap), GL_NV_texture_barrier is used
|
||||||
|
* to ensure that the caches are flushed at the right times.
|
||||||
|
*/
|
||||||
|
static Bool
|
||||||
|
glamor_copy_cpu_fbo(DrawablePtr src,
|
||||||
|
DrawablePtr dst,
|
||||||
|
GCPtr gc,
|
||||||
|
BoxPtr box,
|
||||||
|
int nbox,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
Bool reverse,
|
||||||
|
Bool upsidedown,
|
||||||
|
Pixel bitplane,
|
||||||
|
void *closure)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = dst->pScreen;
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||||
|
FbBits *src_bits;
|
||||||
|
FbStride src_stride;
|
||||||
|
int src_bpp;
|
||||||
|
int src_xoff, src_yoff;
|
||||||
|
int dst_xoff, dst_yoff;
|
||||||
|
|
||||||
|
if (gc && gc->alu != GXcopy)
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
if (gc && !glamor_pm_is_solid(dst, gc->planemask))
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
glamor_make_current(glamor_priv);
|
||||||
|
glamor_prepare_access(src, GLAMOR_ACCESS_RO);
|
||||||
|
|
||||||
|
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_xoff, &dst_yoff);
|
||||||
|
|
||||||
|
fbGetDrawable(src, src_bits, src_stride, src_bpp, src_xoff, src_yoff);
|
||||||
|
|
||||||
|
glamor_upload_boxes(dst_pixmap, box, nbox, src_xoff + dx, src_yoff + dy,
|
||||||
|
dst_xoff, dst_yoff,
|
||||||
|
(uint8_t *) src_bits, src_stride * sizeof (FbBits));
|
||||||
|
glamor_finish_access(src);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
bail:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy from GPU to GPU by using the source
|
||||||
|
* as a texture and painting that into the destination
|
||||||
|
*/
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
glamor_copy_fbo_fbo_draw(DrawablePtr src,
|
||||||
|
DrawablePtr dst,
|
||||||
|
GCPtr gc,
|
||||||
|
BoxPtr box,
|
||||||
|
int nbox,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
Bool reverse,
|
||||||
|
Bool upsidedown,
|
||||||
|
Pixel bitplane,
|
||||||
|
void *closure)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = dst->pScreen;
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
|
||||||
|
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||||
|
glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
|
||||||
|
glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||||
|
int src_box_x, src_box_y, dst_box_x, dst_box_y;
|
||||||
|
int dst_off_x, dst_off_y;
|
||||||
|
int src_off_x, src_off_y;
|
||||||
|
GLshort *v;
|
||||||
|
char *vbo_offset;
|
||||||
|
struct copy_args args;
|
||||||
|
glamor_program *prog;
|
||||||
|
const glamor_facet *copy_facet;
|
||||||
|
Bool set_scissor;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
|
if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask))
|
||||||
|
goto bail_ctx;
|
||||||
|
|
||||||
|
if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy))
|
||||||
|
goto bail_ctx;
|
||||||
|
|
||||||
|
if (bitplane) {
|
||||||
|
prog = &glamor_priv->copy_plane_prog;
|
||||||
|
copy_facet = &glamor_facet_copyplane;
|
||||||
|
} else {
|
||||||
|
prog = &glamor_priv->copy_area_prog;
|
||||||
|
copy_facet = &glamor_facet_copyarea;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prog->failed)
|
||||||
|
goto bail_ctx;
|
||||||
|
|
||||||
|
if (!prog->prog) {
|
||||||
|
if (!glamor_build_program(screen, prog,
|
||||||
|
copy_facet, NULL))
|
||||||
|
goto bail_ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.src_pixmap = src_pixmap;
|
||||||
|
args.bitplane = bitplane;
|
||||||
|
|
||||||
|
/* Set up the vertex buffers for the points */
|
||||||
|
|
||||||
|
v = glamor_get_vbo_space(dst->pScreen, nbox * 8 * sizeof (int16_t), &vbo_offset);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
|
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
|
||||||
|
2 * sizeof (GLshort), vbo_offset);
|
||||||
|
|
||||||
|
for (n = 0; n < nbox; n++) {
|
||||||
|
v[0] = box->x1; v[1] = box->y1;
|
||||||
|
v[2] = box->x1; v[3] = box->y2;
|
||||||
|
v[4] = box->x2; v[5] = box->y2;
|
||||||
|
v[6] = box->x2; v[7] = box->y1;
|
||||||
|
v += 8;
|
||||||
|
box++;
|
||||||
|
}
|
||||||
|
|
||||||
|
glamor_put_vbo_space(screen);
|
||||||
|
|
||||||
|
glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y);
|
||||||
|
|
||||||
|
set_scissor = src_priv->type == GLAMOR_TEXTURE_LARGE;
|
||||||
|
if (set_scissor)
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
glamor_pixmap_loop(src_priv, src_box_x, src_box_y) {
|
||||||
|
BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_x, src_box_y);
|
||||||
|
|
||||||
|
args.dx = dx + src_off_x - src_box->x1;
|
||||||
|
args.dy = dy + src_off_y - src_box->y1;
|
||||||
|
args.src = glamor_pixmap_fbo_at(src_priv, src_box_x, src_box_y);
|
||||||
|
|
||||||
|
if (!glamor_use_program(dst_pixmap, gc, prog, &args))
|
||||||
|
goto bail_ctx;
|
||||||
|
|
||||||
|
glamor_pixmap_loop(dst_priv, dst_box_x, dst_box_y) {
|
||||||
|
glamor_set_destination_drawable(dst, dst_box_x, dst_box_y, FALSE, FALSE,
|
||||||
|
prog->matrix_uniform, &dst_off_x, &dst_off_y);
|
||||||
|
|
||||||
|
if (set_scissor)
|
||||||
|
glScissor(dst_off_x - args.dx,
|
||||||
|
dst_off_y - args.dy,
|
||||||
|
src_box->x2 - src_box->x1,
|
||||||
|
src_box->y2 - src_box->y1);
|
||||||
|
|
||||||
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
|
||||||
|
glDrawArrays(GL_QUADS, 0, nbox * 4);
|
||||||
|
else {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < nbox; i++)
|
||||||
|
glDrawArrays(GL_TRIANGLE_FAN, i*4, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (set_scissor)
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
|
|
||||||
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
bail_ctx:
|
||||||
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies from the GPU to the GPU using a temporary pixmap in between,
|
||||||
|
* to correctly handle overlapping copies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
glamor_copy_fbo_fbo_temp(DrawablePtr src,
|
||||||
|
DrawablePtr dst,
|
||||||
|
GCPtr gc,
|
||||||
|
BoxPtr box,
|
||||||
|
int nbox,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
Bool reverse,
|
||||||
|
Bool upsidedown,
|
||||||
|
Pixel bitplane,
|
||||||
|
void *closure)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = dst->pScreen;
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||||
|
PixmapPtr tmp_pixmap;
|
||||||
|
BoxRec bounds;
|
||||||
|
int n;
|
||||||
|
BoxPtr tmp_box;
|
||||||
|
|
||||||
|
if (nbox == 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* Sanity check state to avoid getting halfway through and bailing
|
||||||
|
* at the last second. Might be nice to have checks that didn't
|
||||||
|
* involve setting state.
|
||||||
|
*/
|
||||||
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
|
if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask))
|
||||||
|
goto bail_ctx;
|
||||||
|
|
||||||
|
if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy))
|
||||||
|
goto bail_ctx;
|
||||||
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
|
|
||||||
|
/* Find the size of the area to copy
|
||||||
|
*/
|
||||||
|
bounds = box[0];
|
||||||
|
for (n = 1; n < nbox; n++) {
|
||||||
|
bounds.x1 = min(bounds.x1, box[n].x1);
|
||||||
|
bounds.x2 = max(bounds.x2, box[n].x2);
|
||||||
|
bounds.y1 = min(bounds.y1, box[n].y1);
|
||||||
|
bounds.y2 = max(bounds.y2, box[n].y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a suitable temporary pixmap
|
||||||
|
*/
|
||||||
|
tmp_pixmap = glamor_create_pixmap(screen,
|
||||||
|
bounds.x2 - bounds.x1,
|
||||||
|
bounds.y2 - bounds.y1,
|
||||||
|
src->depth, 0);
|
||||||
|
if (!tmp_pixmap)
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
tmp_box = calloc(nbox, sizeof (BoxRec));
|
||||||
|
if (!tmp_box)
|
||||||
|
goto bail_pixmap;
|
||||||
|
|
||||||
|
/* Convert destination boxes into tmp pixmap boxes
|
||||||
|
*/
|
||||||
|
for (n = 0; n < nbox; n++) {
|
||||||
|
tmp_box[n].x1 = box[n].x1 - bounds.x1;
|
||||||
|
tmp_box[n].x2 = box[n].x2 - bounds.x1;
|
||||||
|
tmp_box[n].y1 = box[n].y1 - bounds.y1;
|
||||||
|
tmp_box[n].y2 = box[n].y2 - bounds.y1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!glamor_copy_fbo_fbo_draw(src,
|
||||||
|
&tmp_pixmap->drawable,
|
||||||
|
NULL,
|
||||||
|
tmp_box,
|
||||||
|
nbox,
|
||||||
|
dx + bounds.x1,
|
||||||
|
dy + bounds.y1,
|
||||||
|
FALSE, FALSE,
|
||||||
|
0, NULL))
|
||||||
|
goto bail_box;
|
||||||
|
|
||||||
|
if (!glamor_copy_fbo_fbo_draw(&tmp_pixmap->drawable,
|
||||||
|
dst,
|
||||||
|
gc,
|
||||||
|
box,
|
||||||
|
nbox,
|
||||||
|
-bounds.x1,
|
||||||
|
-bounds.y1,
|
||||||
|
FALSE, FALSE,
|
||||||
|
bitplane, closure))
|
||||||
|
goto bail_box;
|
||||||
|
|
||||||
|
free(tmp_box);
|
||||||
|
|
||||||
|
glamor_destroy_pixmap(tmp_pixmap);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
bail_box:
|
||||||
|
free(tmp_box);
|
||||||
|
bail_pixmap:
|
||||||
|
glamor_destroy_pixmap(tmp_pixmap);
|
||||||
|
bail:
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
bail_ctx:
|
||||||
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns TRUE if the copy has to be implemented with
|
||||||
|
* glamor_copy_fbo_fbo_temp() instead of glamor_copy_fbo_fbo().
|
||||||
|
*
|
||||||
|
* If the src and dst are in the same pixmap, then glamor_copy_fbo_fbo()'s
|
||||||
|
* sampling would give undefined results (since the same texture would be
|
||||||
|
* bound as an FBO destination and as a texture source). However, if we
|
||||||
|
* have GL_NV_texture_barrier, we can take advantage of the exception it
|
||||||
|
* added:
|
||||||
|
*
|
||||||
|
* "- If a texel has been written, then in order to safely read the result
|
||||||
|
* a texel fetch must be in a subsequent Draw separated by the command
|
||||||
|
*
|
||||||
|
* void TextureBarrierNV(void);
|
||||||
|
*
|
||||||
|
* TextureBarrierNV() will guarantee that writes have completed and caches
|
||||||
|
* have been invalidated before subsequent Draws are executed."
|
||||||
|
*/
|
||||||
|
static Bool
|
||||||
|
glamor_copy_needs_temp(DrawablePtr src,
|
||||||
|
DrawablePtr dst,
|
||||||
|
BoxPtr box,
|
||||||
|
int nbox,
|
||||||
|
int dx,
|
||||||
|
int dy)
|
||||||
|
{
|
||||||
|
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
|
||||||
|
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||||
|
ScreenPtr screen = dst->pScreen;
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
int n;
|
||||||
|
int dst_off_x, dst_off_y;
|
||||||
|
int src_off_x, src_off_y;
|
||||||
|
BoxRec bounds;
|
||||||
|
|
||||||
|
if (src_pixmap != dst_pixmap)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (nbox == 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!glamor_priv->has_nv_texture_barrier)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y);
|
||||||
|
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_off_x, &dst_off_y);
|
||||||
|
|
||||||
|
bounds = box[0];
|
||||||
|
for (n = 1; n < nbox; n++) {
|
||||||
|
bounds.x1 = min(bounds.x1, box[n].x1);
|
||||||
|
bounds.y1 = min(bounds.y1, box[n].y1);
|
||||||
|
|
||||||
|
bounds.x2 = max(bounds.x2, box[n].x2);
|
||||||
|
bounds.y2 = max(bounds.y2, box[n].y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check to see if the pixmap-relative boxes overlap in both X and Y,
|
||||||
|
* in which case we can't rely on NV_texture_barrier and must
|
||||||
|
* make a temporary copy
|
||||||
|
*
|
||||||
|
* dst.x1 < src.x2 &&
|
||||||
|
* src.x1 < dst.x2 &&
|
||||||
|
*
|
||||||
|
* dst.y1 < src.y2 &&
|
||||||
|
* src.y1 < dst.y2
|
||||||
|
*/
|
||||||
|
if (bounds.x1 + dst_off_x < bounds.x2 + dx + src_off_x &&
|
||||||
|
bounds.x1 + dx + src_off_x < bounds.x2 + dst_off_x &&
|
||||||
|
|
||||||
|
bounds.y1 + dst_off_y < bounds.y2 + dy + src_off_y &&
|
||||||
|
bounds.y1 + dy + src_off_y < bounds.y2 + dst_off_y) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
glTextureBarrierNV();
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
glamor_copy_gl(DrawablePtr src,
|
||||||
|
DrawablePtr dst,
|
||||||
|
GCPtr gc,
|
||||||
|
BoxPtr box,
|
||||||
|
int nbox,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
Bool reverse,
|
||||||
|
Bool upsidedown,
|
||||||
|
Pixel bitplane,
|
||||||
|
void *closure)
|
||||||
|
{
|
||||||
|
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
|
||||||
|
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||||
|
glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
|
||||||
|
glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||||
|
|
||||||
|
if (GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_priv)) {
|
||||||
|
if (GLAMOR_PIXMAP_PRIV_HAS_FBO(src_priv)) {
|
||||||
|
if (glamor_copy_needs_temp(src, dst, box, nbox, dx, dy))
|
||||||
|
return glamor_copy_fbo_fbo_temp(src, dst, gc, box, nbox, dx, dy,
|
||||||
|
reverse, upsidedown, bitplane, closure);
|
||||||
|
else
|
||||||
|
return glamor_copy_fbo_fbo_draw(src, dst, gc, box, nbox, dx, dy,
|
||||||
|
reverse, upsidedown, bitplane, closure);
|
||||||
|
}
|
||||||
|
if (bitplane == 0)
|
||||||
|
return glamor_copy_cpu_fbo(src, dst, gc, box, nbox, dx, dy,
|
||||||
|
reverse, upsidedown, bitplane, closure);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_copy(DrawablePtr src,
|
||||||
|
DrawablePtr dst,
|
||||||
|
GCPtr gc,
|
||||||
|
BoxPtr box,
|
||||||
|
int nbox,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
Bool reverse,
|
||||||
|
Bool upsidedown,
|
||||||
|
Pixel bitplane,
|
||||||
|
void *closure)
|
||||||
|
{
|
||||||
|
if (glamor_copy_gl(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure))
|
||||||
|
return;
|
||||||
|
glamor_copy_bail(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionPtr
|
||||||
|
glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||||
|
int srcx, int srcy, int width, int height, int dstx, int dsty)
|
||||||
|
{
|
||||||
|
return miDoCopy(src, dst, gc,
|
||||||
|
srcx, srcy, width, height,
|
||||||
|
dstx, dsty, glamor_copy, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionPtr
|
||||||
|
glamor_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||||
|
int srcx, int srcy, int width, int height, int dstx, int dsty,
|
||||||
|
unsigned long bitplane)
|
||||||
|
{
|
||||||
|
if ((bitplane & FbFullMask(src->depth)) == 0)
|
||||||
|
return miHandleExposures(src, dst, gc,
|
||||||
|
srcx, srcy, width, height, dstx, dsty,
|
||||||
|
bitplane);
|
||||||
|
return miDoCopy(src, dst, gc,
|
||||||
|
srcx, srcy, width, height,
|
||||||
|
dstx, dsty, glamor_copy, bitplane, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region)
|
||||||
|
{
|
||||||
|
PixmapPtr pixmap = glamor_get_drawable_pixmap(&window->drawable);
|
||||||
|
DrawablePtr drawable = &pixmap->drawable;
|
||||||
|
RegionRec dst_region;
|
||||||
|
int dx, dy;
|
||||||
|
|
||||||
|
dx = old_origin.x - window->drawable.x;
|
||||||
|
dy = old_origin.y - window->drawable.y;
|
||||||
|
RegionTranslate(src_region, -dx, -dy);
|
||||||
|
|
||||||
|
RegionNull(&dst_region);
|
||||||
|
|
||||||
|
RegionIntersect(&dst_region, &window->borderClip, src_region);
|
||||||
|
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
if (pixmap->screen_x || pixmap->screen_y)
|
||||||
|
RegionTranslate(&dst_region, -pixmap->screen_x, -pixmap->screen_y);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
miCopyRegion(drawable, drawable,
|
||||||
|
0, &dst_region, dx, dy, glamor_copy, 0, 0);
|
||||||
|
|
||||||
|
RegionUninit(&dst_region);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_copy_n_to_n_nf(DrawablePtr src,
|
||||||
|
DrawablePtr dst,
|
||||||
|
GCPtr gc,
|
||||||
|
BoxPtr box,
|
||||||
|
int nbox,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
Bool reverse,
|
||||||
|
Bool upsidedown, Pixel bitplane,
|
||||||
|
void *closure)
|
||||||
|
{
|
||||||
|
if (glamor_copy_gl(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure))
|
||||||
|
return TRUE;
|
||||||
|
if (glamor_ddx_fallback_check_pixmap(src) && glamor_ddx_fallback_check_pixmap(dst))
|
||||||
|
return FALSE;
|
||||||
|
glamor_copy_bail(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_copy_plane_nf(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||||
|
int srcx, int srcy, int w, int h, int dstx, int dsty,
|
||||||
|
unsigned long bitplane, RegionPtr *region)
|
||||||
|
{
|
||||||
|
if (glamor_ddx_fallback_check_pixmap(src) &&
|
||||||
|
glamor_ddx_fallback_check_pixmap(dst) &&
|
||||||
|
glamor_ddx_fallback_check_gc(gc))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*region = glamor_copy_plane(src, dst, gc,
|
||||||
|
srcx, srcy, w, h, dstx, dsty,
|
||||||
|
bitplane);
|
||||||
|
return TRUE;
|
||||||
|
}
|
|
@ -1,626 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Eric Anholt <eric@anholt.net>
|
|
||||||
* Zhigang Gong <zhigang.gong@linux.intel.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "glamor_priv.h"
|
|
||||||
|
|
||||||
/** @file glamor_copyarea.c
|
|
||||||
*
|
|
||||||
* GC CopyArea implementation
|
|
||||||
*/
|
|
||||||
static Bool
|
|
||||||
glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
|
|
||||||
DrawablePtr dst,
|
|
||||||
GCPtr gc, BoxPtr box, int nbox, int dx, int dy)
|
|
||||||
{
|
|
||||||
ScreenPtr screen = dst->pScreen;
|
|
||||||
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
|
||||||
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
|
|
||||||
glamor_pixmap_private *src_pixmap_priv, *dst_pixmap_priv;
|
|
||||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
|
||||||
int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
|
|
||||||
int fbo_x_off, fbo_y_off;
|
|
||||||
int src_fbo_x_off, src_fbo_y_off;
|
|
||||||
|
|
||||||
if (!glamor_priv->has_fbo_blit) {
|
|
||||||
glamor_delayed_fallback(screen, "no EXT_framebuffer_blit\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
|
||||||
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
|
||||||
|
|
||||||
if (gc) {
|
|
||||||
if (gc->alu != GXcopy) {
|
|
||||||
glamor_delayed_fallback(screen, "non-copy ALU\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
|
|
||||||
glamor_delayed_fallback(screen, "no src fbo\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glamor_set_destination_pixmap(dst_pixmap))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
pixmap_priv_get_fbo_off(dst_pixmap_priv, &fbo_x_off, &fbo_y_off);
|
|
||||||
pixmap_priv_get_fbo_off(src_pixmap_priv, &src_fbo_x_off, &src_fbo_y_off);
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->base.fbo->fb);
|
|
||||||
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
|
|
||||||
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
|
|
||||||
dst_x_off += fbo_x_off;
|
|
||||||
dst_y_off += fbo_y_off;
|
|
||||||
src_y_off += dy + src_fbo_y_off;
|
|
||||||
src_x_off += src_fbo_x_off;
|
|
||||||
|
|
||||||
for (i = 0; i < nbox; i++) {
|
|
||||||
if (glamor_priv->yInverted) {
|
|
||||||
glBlitFramebuffer(box[i].x1 + dx + src_x_off,
|
|
||||||
box[i].y1 + src_y_off,
|
|
||||||
box[i].x2 + dx + src_x_off,
|
|
||||||
box[i].y2 + src_y_off,
|
|
||||||
box[i].x1 + dst_x_off,
|
|
||||||
box[i].y1 + dst_y_off,
|
|
||||||
box[i].x2 + dst_x_off,
|
|
||||||
box[i].y2 + dst_y_off,
|
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int flip_dst_y1 =
|
|
||||||
dst_pixmap->drawable.height - (box[i].y2 + dst_y_off);
|
|
||||||
int flip_dst_y2 =
|
|
||||||
dst_pixmap->drawable.height - (box[i].y1 + dst_y_off);
|
|
||||||
int flip_src_y1 =
|
|
||||||
src_pixmap->drawable.height - (box[i].y2 + src_y_off);
|
|
||||||
int flip_src_y2 =
|
|
||||||
src_pixmap->drawable.height - (box[i].y1 + src_y_off);
|
|
||||||
|
|
||||||
glBlitFramebuffer(box[i].x1 + dx + src_x_off,
|
|
||||||
flip_src_y1,
|
|
||||||
box[i].x2 + dx + src_x_off,
|
|
||||||
flip_src_y2,
|
|
||||||
box[i].x1 + dst_x_off,
|
|
||||||
flip_dst_y1,
|
|
||||||
box[i].x2 + dst_x_off,
|
|
||||||
flip_dst_y2,
|
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
glamor_priv->state = BLIT_STATE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
glamor_copy_n_to_n_textured(DrawablePtr src,
|
|
||||||
DrawablePtr dst,
|
|
||||||
GCPtr gc, BoxPtr box, int nbox, int dx, int dy)
|
|
||||||
{
|
|
||||||
glamor_screen_private *glamor_priv =
|
|
||||||
glamor_get_screen_private(dst->pScreen);
|
|
||||||
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
|
|
||||||
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
|
||||||
int i;
|
|
||||||
float vertices[8], texcoords[8];
|
|
||||||
glamor_pixmap_private *src_pixmap_priv;
|
|
||||||
glamor_pixmap_private *dst_pixmap_priv;
|
|
||||||
int src_x_off, src_y_off, dst_x_off, dst_y_off;
|
|
||||||
enum glamor_pixmap_status src_status = GLAMOR_NONE;
|
|
||||||
GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
|
|
||||||
|
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
|
||||||
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
|
||||||
|
|
||||||
if (src_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) {
|
|
||||||
#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
|
|
||||||
glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
|
|
||||||
return FALSE;
|
|
||||||
#else
|
|
||||||
src_status = glamor_upload_pixmap_to_texture(src_pixmap);
|
|
||||||
if (src_status != GLAMOR_UPLOAD_DONE)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
|
|
||||||
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
|
|
||||||
|
|
||||||
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
|
|
||||||
glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
|
||||||
GL_FALSE, 2 * sizeof(float), vertices);
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
|
||||||
|
|
||||||
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
|
|
||||||
dx += src_x_off;
|
|
||||||
dy += src_y_off;
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex);
|
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
||||||
}
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
|
|
||||||
2 * sizeof(float), texcoords);
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
|
||||||
glUseProgram(glamor_priv->finish_access_prog[0]);
|
|
||||||
glUniform1i(glamor_priv->finish_access_revert[0], REVERT_NONE);
|
|
||||||
glUniform1i(glamor_priv->finish_access_swap_rb[0], SWAP_NONE_UPLOADING);
|
|
||||||
|
|
||||||
for (i = 0; i < nbox; i++) {
|
|
||||||
|
|
||||||
glamor_set_normalize_vcoords(dst_pixmap_priv,
|
|
||||||
dst_xscale, dst_yscale,
|
|
||||||
box[i].x1 + dst_x_off,
|
|
||||||
box[i].y1 + dst_y_off,
|
|
||||||
box[i].x2 + dst_x_off,
|
|
||||||
box[i].y2 + dst_y_off,
|
|
||||||
glamor_priv->yInverted, vertices);
|
|
||||||
|
|
||||||
glamor_set_normalize_tcoords(src_pixmap_priv,
|
|
||||||
src_xscale,
|
|
||||||
src_yscale,
|
|
||||||
box[i].x1 + dx,
|
|
||||||
box[i].y1 + dy,
|
|
||||||
box[i].x2 + dx,
|
|
||||||
box[i].y2 + dy,
|
|
||||||
glamor_priv->yInverted, texcoords);
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
|
||||||
/* The source texture is bound to a fbo, we have to flush it here. */
|
|
||||||
glamor_priv->state = RENDER_STATE;
|
|
||||||
glamor_priv->render_idle_cnt = 0;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
__glamor_copy_n_to_n(DrawablePtr src,
|
|
||||||
DrawablePtr dst,
|
|
||||||
GCPtr gc,
|
|
||||||
BoxPtr box,
|
|
||||||
int nbox,
|
|
||||||
int dx,
|
|
||||||
int dy,
|
|
||||||
Bool reverse,
|
|
||||||
Bool upsidedown, Pixel bitplane, void *closure)
|
|
||||||
{
|
|
||||||
PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL;
|
|
||||||
DrawablePtr temp_src = src;
|
|
||||||
glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
|
|
||||||
glamor_screen_private *glamor_priv;
|
|
||||||
BoxRec bound;
|
|
||||||
ScreenPtr screen;
|
|
||||||
int temp_dx = dx;
|
|
||||||
int temp_dy = dy;
|
|
||||||
int src_x_off, src_y_off, dst_x_off, dst_y_off;
|
|
||||||
int i;
|
|
||||||
int overlaped = 0;
|
|
||||||
Bool ret = FALSE;
|
|
||||||
|
|
||||||
dst_pixmap = glamor_get_drawable_pixmap(dst);
|
|
||||||
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
|
||||||
src_pixmap = glamor_get_drawable_pixmap(src);
|
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
|
||||||
screen = dst_pixmap->drawable.pScreen;
|
|
||||||
glamor_priv = glamor_get_screen_private(dst->pScreen);
|
|
||||||
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
|
|
||||||
|
|
||||||
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
|
|
||||||
|
|
||||||
if (src_pixmap_priv->base.fbo
|
|
||||||
&& src_pixmap_priv->base.fbo->fb == dst_pixmap_priv->base.fbo->fb) {
|
|
||||||
int x_shift = abs(src_x_off - dx - dst_x_off);
|
|
||||||
int y_shift = abs(src_y_off - dy - dst_y_off);
|
|
||||||
|
|
||||||
for (i = 0; i < nbox; i++) {
|
|
||||||
if (x_shift < abs(box[i].x2 - box[i].x1)
|
|
||||||
&& y_shift < abs(box[i].y2 - box[i].y1)) {
|
|
||||||
overlaped = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n",
|
|
||||||
box[0].x1, box[0].y1,
|
|
||||||
box[0].x2 - box[0].x1, box[0].y2 - box[0].y1,
|
|
||||||
dx, dy, src_pixmap, dst_pixmap);
|
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
|
|
||||||
!overlaped &&
|
|
||||||
(glamor_priv->state != RENDER_STATE
|
|
||||||
|| !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex)
|
|
||||||
&& glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
|
|
||||||
ret = TRUE;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
glamor_calculate_boxes_bound(&bound, box, nbox);
|
|
||||||
|
|
||||||
/* Overlaped indicate the src and dst are the same pixmap. */
|
|
||||||
if (overlaped || (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)
|
|
||||||
&& (((bound.x2 - bound.x1) * (bound.y2 - bound.y1)
|
|
||||||
* 4 >
|
|
||||||
src_pixmap->drawable.width *
|
|
||||||
src_pixmap->drawable.height)
|
|
||||||
|| !(glamor_check_fbo_size(glamor_priv,
|
|
||||||
src_pixmap->drawable.width,
|
|
||||||
src_pixmap->drawable.
|
|
||||||
height))))) {
|
|
||||||
|
|
||||||
temp_pixmap = glamor_create_pixmap(screen,
|
|
||||||
bound.x2 - bound.x1,
|
|
||||||
bound.y2 - bound.y1,
|
|
||||||
src_pixmap->drawable.depth,
|
|
||||||
overlaped ? 0 :
|
|
||||||
GLAMOR_CREATE_PIXMAP_CPU);
|
|
||||||
assert(bound.x2 - bound.x1 <= glamor_priv->max_fbo_size);
|
|
||||||
assert(bound.y2 - bound.y1 <= glamor_priv->max_fbo_size);
|
|
||||||
if (!temp_pixmap)
|
|
||||||
goto done;
|
|
||||||
glamor_translate_boxes(box, nbox, -bound.x1, -bound.y1);
|
|
||||||
temp_src = &temp_pixmap->drawable;
|
|
||||||
|
|
||||||
if (overlaped)
|
|
||||||
glamor_copy_n_to_n_textured(src, temp_src, gc, box,
|
|
||||||
nbox,
|
|
||||||
temp_dx + bound.x1, temp_dy + bound.y1);
|
|
||||||
else
|
|
||||||
fbCopyNtoN(src, temp_src, gc, box, nbox,
|
|
||||||
temp_dx + bound.x1, temp_dy + bound.y1,
|
|
||||||
reverse, upsidedown, bitplane, closure);
|
|
||||||
glamor_translate_boxes(box, nbox, bound.x1, bound.y1);
|
|
||||||
temp_dx = -bound.x1;
|
|
||||||
temp_dy = -bound.y1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
temp_dx = dx;
|
|
||||||
temp_dy = dy;
|
|
||||||
temp_src = src;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glamor_copy_n_to_n_textured
|
|
||||||
(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
|
|
||||||
ret = TRUE;
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
if (temp_src != src)
|
|
||||||
glamor_destroy_pixmap(temp_pixmap);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
_glamor_copy_n_to_n(DrawablePtr src,
|
|
||||||
DrawablePtr dst,
|
|
||||||
GCPtr gc,
|
|
||||||
BoxPtr box,
|
|
||||||
int nbox,
|
|
||||||
int dx,
|
|
||||||
int dy,
|
|
||||||
Bool reverse,
|
|
||||||
Bool upsidedown, Pixel bitplane,
|
|
||||||
void *closure, Bool fallback)
|
|
||||||
{
|
|
||||||
ScreenPtr screen = dst->pScreen;
|
|
||||||
PixmapPtr dst_pixmap, src_pixmap;
|
|
||||||
glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
|
|
||||||
glamor_screen_private *glamor_priv;
|
|
||||||
BoxPtr extent;
|
|
||||||
RegionRec region;
|
|
||||||
int src_x_off, src_y_off, dst_x_off, dst_y_off;
|
|
||||||
Bool ok = FALSE;
|
|
||||||
int force_clip = 0;
|
|
||||||
|
|
||||||
if (nbox == 0)
|
|
||||||
return TRUE;
|
|
||||||
dst_pixmap = glamor_get_drawable_pixmap(dst);
|
|
||||||
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
|
||||||
src_pixmap = glamor_get_drawable_pixmap(src);
|
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
|
||||||
|
|
||||||
glamor_priv = glamor_get_screen_private(screen);
|
|
||||||
|
|
||||||
DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n",
|
|
||||||
box[0].x1, box[0].y1,
|
|
||||||
box[0].x2 - box[0].x1, box[0].y2 - box[0].y1,
|
|
||||||
dx, dy, src_pixmap, dst_pixmap);
|
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv))
|
|
||||||
goto fall_back;
|
|
||||||
|
|
||||||
if (gc) {
|
|
||||||
if (!glamor_set_planemask(dst_pixmap, gc->planemask))
|
|
||||||
goto fall_back;
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
if (!glamor_set_alu(screen, gc->alu)) {
|
|
||||||
goto fail_noregion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!src_pixmap_priv) {
|
|
||||||
glamor_set_pixmap_type(src_pixmap, GLAMOR_MEMORY);
|
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
|
|
||||||
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
|
|
||||||
|
|
||||||
RegionInitBoxes(®ion, box, nbox);
|
|
||||||
extent = RegionExtents(®ion);
|
|
||||||
|
|
||||||
if (!glamor_check_fbo_size(glamor_priv,
|
|
||||||
extent->x2 - extent->x1, extent->y2 - extent->y1)
|
|
||||||
&& (src_pixmap_priv->type == GLAMOR_MEMORY
|
|
||||||
|| (src_pixmap_priv == dst_pixmap_priv))) {
|
|
||||||
force_clip = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (force_clip || dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
|
|
||||||
|| src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
|
||||||
glamor_pixmap_clipped_regions *clipped_dst_regions;
|
|
||||||
int n_dst_region, i, j;
|
|
||||||
PixmapPtr temp_source_pixmap;
|
|
||||||
glamor_pixmap_private *temp_source_priv = NULL;
|
|
||||||
|
|
||||||
RegionTranslate(®ion, dst_x_off, dst_y_off);
|
|
||||||
if (!force_clip)
|
|
||||||
clipped_dst_regions =
|
|
||||||
glamor_compute_clipped_regions(dst_pixmap_priv, ®ion,
|
|
||||||
&n_dst_region, 0, reverse,
|
|
||||||
upsidedown);
|
|
||||||
else
|
|
||||||
clipped_dst_regions =
|
|
||||||
glamor_compute_clipped_regions_ext(dst_pixmap_priv, ®ion,
|
|
||||||
&n_dst_region,
|
|
||||||
glamor_priv->max_fbo_size,
|
|
||||||
glamor_priv->max_fbo_size,
|
|
||||||
reverse, upsidedown);
|
|
||||||
for (i = 0; i < n_dst_region; i++) {
|
|
||||||
int n_src_region;
|
|
||||||
glamor_pixmap_clipped_regions *clipped_src_regions;
|
|
||||||
BoxPtr current_boxes;
|
|
||||||
int n_current_boxes;
|
|
||||||
|
|
||||||
SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv,
|
|
||||||
clipped_dst_regions[i].block_idx);
|
|
||||||
|
|
||||||
temp_source_pixmap = NULL;
|
|
||||||
if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
|
||||||
RegionTranslate(clipped_dst_regions[i].region,
|
|
||||||
-dst_x_off + src_x_off + dx,
|
|
||||||
-dst_y_off + src_y_off + dy);
|
|
||||||
clipped_src_regions =
|
|
||||||
glamor_compute_clipped_regions(src_pixmap_priv,
|
|
||||||
clipped_dst_regions[i].
|
|
||||||
region, &n_src_region, 0,
|
|
||||||
reverse, upsidedown);
|
|
||||||
DEBUGF("Source is large pixmap.\n");
|
|
||||||
for (j = 0; j < n_src_region; j++) {
|
|
||||||
if (src_pixmap_priv != dst_pixmap_priv)
|
|
||||||
SET_PIXMAP_FBO_CURRENT(src_pixmap_priv,
|
|
||||||
clipped_src_regions[j].
|
|
||||||
block_idx);
|
|
||||||
else if (src_pixmap_priv == dst_pixmap_priv &&
|
|
||||||
clipped_src_regions[j].block_idx !=
|
|
||||||
clipped_dst_regions[i].block_idx) {
|
|
||||||
/* source and the dest are the same, but need different block_idx.
|
|
||||||
* we create a empty pixmap and fill the required source fbo and box to
|
|
||||||
* it. It's a little hacky, but avoid extra copy. */
|
|
||||||
temp_source_pixmap =
|
|
||||||
glamor_create_pixmap(src->pScreen, 0, 0, src->depth,
|
|
||||||
0);
|
|
||||||
if (!temp_source_pixmap) {
|
|
||||||
ok = FALSE;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
src->pScreen->ModifyPixmapHeader(temp_source_pixmap,
|
|
||||||
src_pixmap->drawable.
|
|
||||||
width,
|
|
||||||
src_pixmap->drawable.
|
|
||||||
height, 0, 0,
|
|
||||||
src_pixmap->devKind,
|
|
||||||
NULL);
|
|
||||||
temp_source_priv =
|
|
||||||
glamor_get_pixmap_private(temp_source_pixmap);
|
|
||||||
*temp_source_priv = *src_pixmap_priv;
|
|
||||||
temp_source_priv->large.box =
|
|
||||||
src_pixmap_priv->large.
|
|
||||||
box_array[clipped_src_regions[j].block_idx];
|
|
||||||
temp_source_priv->base.fbo =
|
|
||||||
src_pixmap_priv->large.
|
|
||||||
fbo_array[clipped_src_regions[j].block_idx];
|
|
||||||
temp_source_priv->base.pixmap = temp_source_pixmap;
|
|
||||||
}
|
|
||||||
assert(temp_source_pixmap ||
|
|
||||||
!(src_pixmap_priv == dst_pixmap_priv &&
|
|
||||||
(clipped_src_regions[j].block_idx !=
|
|
||||||
clipped_dst_regions[i].block_idx)));
|
|
||||||
|
|
||||||
RegionTranslate(clipped_src_regions[j].region,
|
|
||||||
-src_x_off - dx, -src_y_off - dy);
|
|
||||||
current_boxes = RegionRects(clipped_src_regions[j].region);
|
|
||||||
n_current_boxes =
|
|
||||||
RegionNumRects(clipped_src_regions[j].region);
|
|
||||||
DEBUGF("dst pixmap fbo idx %d src pixmap fbo idx %d \n",
|
|
||||||
clipped_dst_regions[i].block_idx,
|
|
||||||
clipped_src_regions[j].block_idx);
|
|
||||||
DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n",
|
|
||||||
current_boxes[0].x1, current_boxes[0].y1,
|
|
||||||
current_boxes[0].x2, current_boxes[0].y2, dx, dy,
|
|
||||||
src_pixmap, dst_pixmap);
|
|
||||||
if (!temp_source_pixmap)
|
|
||||||
ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes,
|
|
||||||
n_current_boxes, dx, dy,
|
|
||||||
reverse, upsidedown, bitplane,
|
|
||||||
closure);
|
|
||||||
else {
|
|
||||||
ok = __glamor_copy_n_to_n(&temp_source_pixmap->drawable,
|
|
||||||
dst, gc, current_boxes,
|
|
||||||
n_current_boxes, dx, dy,
|
|
||||||
reverse, upsidedown, bitplane,
|
|
||||||
closure);
|
|
||||||
temp_source_priv->type = GLAMOR_MEMORY;
|
|
||||||
temp_source_priv->base.fbo = NULL;
|
|
||||||
glamor_destroy_pixmap(temp_source_pixmap);
|
|
||||||
temp_source_pixmap = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
RegionDestroy(clipped_src_regions[j].region);
|
|
||||||
if (!ok) {
|
|
||||||
assert(0);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n_src_region == 0)
|
|
||||||
ok = TRUE;
|
|
||||||
free(clipped_src_regions);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
RegionTranslate(clipped_dst_regions[i].region,
|
|
||||||
-dst_x_off, -dst_y_off);
|
|
||||||
current_boxes = RegionRects(clipped_dst_regions[i].region);
|
|
||||||
n_current_boxes = RegionNumRects(clipped_dst_regions[i].region);
|
|
||||||
|
|
||||||
DEBUGF("dest pixmap fbo idx %d \n",
|
|
||||||
clipped_dst_regions[i].block_idx);
|
|
||||||
DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n",
|
|
||||||
current_boxes[0].x1, current_boxes[0].y1,
|
|
||||||
current_boxes[0].x2, current_boxes[0].y2,
|
|
||||||
dx, dy, src_pixmap, dst_pixmap);
|
|
||||||
|
|
||||||
ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes,
|
|
||||||
n_current_boxes, dx, dy, reverse,
|
|
||||||
upsidedown, bitplane, closure);
|
|
||||||
|
|
||||||
}
|
|
||||||
RegionDestroy(clipped_dst_regions[i].region);
|
|
||||||
}
|
|
||||||
if (n_dst_region == 0)
|
|
||||||
ok = TRUE;
|
|
||||||
free(clipped_dst_regions);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ok = __glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, dy,
|
|
||||||
reverse, upsidedown, bitplane, closure);
|
|
||||||
}
|
|
||||||
|
|
||||||
fail:
|
|
||||||
RegionUninit(®ion);
|
|
||||||
fail_noregion:
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
glamor_set_alu(screen, GXcopy);
|
|
||||||
|
|
||||||
if (ok)
|
|
||||||
return TRUE;
|
|
||||||
fall_back:
|
|
||||||
if (!fallback && glamor_ddx_fallback_check_pixmap(src)
|
|
||||||
&& glamor_ddx_fallback_check_pixmap(dst))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (src_pixmap_priv->type == GLAMOR_DRM_ONLY
|
|
||||||
|| dst_pixmap_priv->type == GLAMOR_DRM_ONLY) {
|
|
||||||
LogMessage(X_WARNING,
|
|
||||||
"Access a DRM only pixmap is not allowed within glamor.\n");
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
glamor_report_delayed_fallbacks(src->pScreen);
|
|
||||||
glamor_report_delayed_fallbacks(dst->pScreen);
|
|
||||||
|
|
||||||
glamor_fallback("from %p to %p (%c,%c)\n", src, dst,
|
|
||||||
glamor_get_drawable_location(src),
|
|
||||||
glamor_get_drawable_location(dst));
|
|
||||||
|
|
||||||
if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) &&
|
|
||||||
glamor_prepare_access(src, GLAMOR_ACCESS_RO) &&
|
|
||||||
glamor_prepare_access_gc(gc)) {
|
|
||||||
fbCopyNtoN(src, dst, gc, box, nbox,
|
|
||||||
dx, dy, reverse, upsidedown, bitplane, closure);
|
|
||||||
}
|
|
||||||
glamor_finish_access_gc(gc);
|
|
||||||
glamor_finish_access(src);
|
|
||||||
glamor_finish_access(dst);
|
|
||||||
ok = TRUE;
|
|
||||||
|
|
||||||
done:
|
|
||||||
glamor_clear_delayed_fallbacks(src->pScreen);
|
|
||||||
glamor_clear_delayed_fallbacks(dst->pScreen);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
RegionPtr
|
|
||||||
glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
|
||||||
int srcx, int srcy, int width, int height, int dstx, int dsty)
|
|
||||||
{
|
|
||||||
RegionPtr region;
|
|
||||||
|
|
||||||
region = miDoCopy(src, dst, gc,
|
|
||||||
srcx, srcy, width, height,
|
|
||||||
dstx, dsty, glamor_copy_n_to_n, 0, NULL);
|
|
||||||
|
|
||||||
return region;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
glamor_copy_n_to_n(DrawablePtr src,
|
|
||||||
DrawablePtr dst,
|
|
||||||
GCPtr gc,
|
|
||||||
BoxPtr box,
|
|
||||||
int nbox,
|
|
||||||
int dx,
|
|
||||||
int dy,
|
|
||||||
Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
|
|
||||||
{
|
|
||||||
_glamor_copy_n_to_n(src, dst, gc, box, nbox, dx,
|
|
||||||
dy, reverse, upsidedown, bitplane, closure, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bool
|
|
||||||
glamor_copy_n_to_n_nf(DrawablePtr src,
|
|
||||||
DrawablePtr dst,
|
|
||||||
GCPtr gc,
|
|
||||||
BoxPtr box,
|
|
||||||
int nbox,
|
|
||||||
int dx,
|
|
||||||
int dy,
|
|
||||||
Bool reverse,
|
|
||||||
Bool upsidedown, Pixel bitplane, void *closure)
|
|
||||||
{
|
|
||||||
return _glamor_copy_n_to_n(src, dst, gc, box, nbox, dx,
|
|
||||||
dy, reverse, upsidedown, bitplane, closure,
|
|
||||||
FALSE);
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright © 2009 Intel Corporation
|
|
||||||
* Copyright © 1998 Keith Packard
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the next
|
|
||||||
* paragraph) shall be included in all copies or substantial portions of the
|
|
||||||
* Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
* IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Zhigang Gong <zhigang.gong@gmail.com>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "glamor_priv.h"
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
_glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
|
||||||
int srcx, int srcy, int w, int h, int dstx, int dsty,
|
|
||||||
unsigned long bitPlane, RegionPtr *pRegion, Bool fallback)
|
|
||||||
{
|
|
||||||
if (!fallback && glamor_ddx_fallback_check_gc(pGC)
|
|
||||||
&& glamor_ddx_fallback_check_pixmap(pSrc)
|
|
||||||
&& glamor_ddx_fallback_check_pixmap(pDst))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if (glamor_prepare_access(pDst, GLAMOR_ACCESS_RW) &&
|
|
||||||
glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO) &&
|
|
||||||
glamor_prepare_access_gc(pGC)) {
|
|
||||||
*pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h,
|
|
||||||
dstx, dsty, bitPlane);
|
|
||||||
}
|
|
||||||
glamor_finish_access_gc(pGC);
|
|
||||||
glamor_finish_access(pSrc);
|
|
||||||
glamor_finish_access(pDst);
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
RegionPtr
|
|
||||||
glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
|
||||||
int srcx, int srcy, int w, int h, int dstx, int dsty,
|
|
||||||
unsigned long bitPlane)
|
|
||||||
{
|
|
||||||
RegionPtr ret;
|
|
||||||
|
|
||||||
_glamor_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h,
|
|
||||||
dstx, dsty, bitPlane, &ret, TRUE);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bool
|
|
||||||
glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
|
||||||
int srcx, int srcy, int w, int h, int dstx, int dsty,
|
|
||||||
unsigned long bitPlane, RegionPtr *pRegion)
|
|
||||||
{
|
|
||||||
return _glamor_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h,
|
|
||||||
dstx, dsty, bitPlane, pRegion, FALSE);
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "glamor_priv.h"
|
|
||||||
|
|
||||||
/** @file glamor_copywindow.c
|
|
||||||
*
|
|
||||||
* Screen CopyWindow implementation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
glamor_copy_window(WindowPtr win, DDXPointRec old_origin, RegionPtr src_region)
|
|
||||||
{
|
|
||||||
RegionRec dst_region;
|
|
||||||
int dx, dy;
|
|
||||||
PixmapPtr pixmap = win->drawable.pScreen->GetWindowPixmap(win);
|
|
||||||
|
|
||||||
dx = old_origin.x - win->drawable.x;
|
|
||||||
dy = old_origin.y - win->drawable.y;
|
|
||||||
REGION_TRANSLATE(win->drawable.pScreen, src_region, -dx, -dy);
|
|
||||||
|
|
||||||
REGION_INIT(win->drawable.pScreen, &dst_region, NullBox, 0);
|
|
||||||
|
|
||||||
REGION_INTERSECT(win->drawable.pScreen, &dst_region,
|
|
||||||
&win->borderClip, src_region);
|
|
||||||
#ifdef COMPOSITE
|
|
||||||
if (pixmap->screen_x || pixmap->screen_y)
|
|
||||||
REGION_TRANSLATE(win->drawable.pScreen, &dst_region,
|
|
||||||
-pixmap->screen_x, -pixmap->screen_y);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
miCopyRegion(&pixmap->drawable, &pixmap->drawable,
|
|
||||||
NULL, &dst_region, dx, dy, glamor_copy_n_to_n, 0, NULL);
|
|
||||||
|
|
||||||
REGION_UNINIT(win->drawable.pScreen, &dst_region);
|
|
||||||
}
|
|
|
@ -114,27 +114,6 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
|
||||||
glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
|
|
||||||
{
|
|
||||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
|
||||||
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
|
||||||
|
|
||||||
if (pixmap->devPrivate.ptr) {
|
|
||||||
/* Already mapped, nothing needs to be done. Note that we
|
|
||||||
* aren't allowing promotion from RO to RW, because it would
|
|
||||||
* require re-mapping the PBO.
|
|
||||||
*/
|
|
||||||
assert(!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) ||
|
|
||||||
access == GLAMOR_ACCESS_RO ||
|
|
||||||
pixmap_priv->base.map_access == GLAMOR_ACCESS_RW);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
pixmap_priv->base.map_access = access;
|
|
||||||
|
|
||||||
return glamor_download_pixmap_to_cpu(pixmap, access);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When downloading a unsupported color format to CPU memory,
|
* When downloading a unsupported color format to CPU memory,
|
||||||
we need to shuffle the color elements and then use a supported
|
we need to shuffle the color elements and then use a supported
|
||||||
|
@ -313,102 +292,6 @@ glamor_fini_finish_access_shaders(ScreenPtr screen)
|
||||||
glDeleteProgram(glamor_priv->finish_access_prog[1]);
|
glDeleteProgram(glamor_priv->finish_access_prog[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
glamor_finish_access(DrawablePtr drawable)
|
|
||||||
{
|
|
||||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
|
||||||
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
|
||||||
glamor_screen_private *glamor_priv =
|
|
||||||
glamor_get_screen_private(drawable->pScreen);
|
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* If we are doing a series of unmaps from a nested map, we're
|
|
||||||
* done. None of the callers do any rendering to maps after
|
|
||||||
* starting an unmap sequence, so we don't need to delay until the
|
|
||||||
* last nested unmap.
|
|
||||||
*/
|
|
||||||
if (!pixmap->devPrivate.ptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (pixmap_priv->base.map_access == GLAMOR_ACCESS_RW) {
|
|
||||||
glamor_restore_pixmap_to_texture(pixmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pixmap_priv->base.fbo->pbo != 0 && pixmap_priv->base.fbo->pbo_valid) {
|
|
||||||
assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
|
||||||
glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo);
|
|
||||||
|
|
||||||
pixmap_priv->base.fbo->pbo_valid = FALSE;
|
|
||||||
pixmap_priv->base.fbo->pbo = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
free(pixmap->devPrivate.ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pixmap_priv->type == GLAMOR_TEXTURE_DRM)
|
|
||||||
pixmap->devKind = pixmap_priv->base.drm_stride;
|
|
||||||
|
|
||||||
if (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED)
|
|
||||||
pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL;
|
|
||||||
|
|
||||||
pixmap->devPrivate.ptr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the
|
|
||||||
* current fill style.
|
|
||||||
*
|
|
||||||
* Solid doesn't use an extra pixmap source, so we don't worry about them.
|
|
||||||
* Stippled/OpaqueStippled are 1bpp and can be in fb, so we should worry
|
|
||||||
* about them.
|
|
||||||
*/
|
|
||||||
Bool
|
|
||||||
glamor_prepare_access_gc(GCPtr gc)
|
|
||||||
{
|
|
||||||
if (gc->stipple) {
|
|
||||||
if (!glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (gc->fillStyle == FillTiled) {
|
|
||||||
if (!glamor_prepare_access(&gc->tile.pixmap->drawable,
|
|
||||||
GLAMOR_ACCESS_RO)) {
|
|
||||||
if (gc->stipple)
|
|
||||||
glamor_finish_access(&gc->stipple->drawable);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finishes access to the tile in the GC, if used.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
glamor_finish_access_gc(GCPtr gc)
|
|
||||||
{
|
|
||||||
if (gc->fillStyle == FillTiled)
|
|
||||||
glamor_finish_access(&gc->tile.pixmap->drawable);
|
|
||||||
if (gc->stipple)
|
|
||||||
glamor_finish_access(&gc->stipple->drawable);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bool
|
|
||||||
glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
|
|
||||||
int x, int y, int width, int height,
|
|
||||||
unsigned char alu, unsigned long planemask,
|
|
||||||
unsigned long fg_pixel, unsigned long bg_pixel,
|
|
||||||
int stipple_x, int stipple_y)
|
|
||||||
{
|
|
||||||
glamor_fallback("stubbed out stipple depth %d\n", pixmap->drawable.depth);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GCOps glamor_gc_ops = {
|
GCOps glamor_gc_ops = {
|
||||||
.FillSpans = glamor_fill_spans,
|
.FillSpans = glamor_fill_spans,
|
||||||
.SetSpans = glamor_set_spans,
|
.SetSpans = glamor_set_spans,
|
||||||
|
@ -432,6 +315,58 @@ GCOps glamor_gc_ops = {
|
||||||
.PushPixels = glamor_push_pixels,
|
.PushPixels = glamor_push_pixels,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When the stipple is changed or drawn to, invalidate any
|
||||||
|
* cached copy
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
glamor_invalidate_stipple(GCPtr gc)
|
||||||
|
{
|
||||||
|
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||||
|
|
||||||
|
if (gc_priv->stipple) {
|
||||||
|
if (gc_priv->stipple_damage)
|
||||||
|
DamageUnregister(gc_priv->stipple_damage);
|
||||||
|
glamor_destroy_pixmap(gc_priv->stipple);
|
||||||
|
gc_priv->stipple = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
glamor_stipple_damage_report(DamagePtr damage, RegionPtr region,
|
||||||
|
void *closure)
|
||||||
|
{
|
||||||
|
GCPtr gc = closure;
|
||||||
|
|
||||||
|
glamor_invalidate_stipple(gc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
glamor_stipple_damage_destroy(DamagePtr damage, void *closure)
|
||||||
|
{
|
||||||
|
GCPtr gc = closure;
|
||||||
|
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||||
|
|
||||||
|
gc_priv->stipple_damage = NULL;
|
||||||
|
glamor_invalidate_stipple(gc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_track_stipple(GCPtr gc)
|
||||||
|
{
|
||||||
|
if (gc->stipple) {
|
||||||
|
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||||
|
|
||||||
|
if (!gc_priv->stipple_damage)
|
||||||
|
gc_priv->stipple_damage = DamageCreate(glamor_stipple_damage_report,
|
||||||
|
glamor_stipple_damage_destroy,
|
||||||
|
DamageReportNonEmpty,
|
||||||
|
TRUE, gc->pScreen, gc);
|
||||||
|
if (gc_priv->stipple_damage)
|
||||||
|
DamageRegister(&gc->stipple->drawable, gc_priv->stipple_damage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* uxa_validate_gc() sets the ops to glamor's implementations, which may be
|
* uxa_validate_gc() sets the ops to glamor's implementations, which may be
|
||||||
* accelerated or may sync the card and fall back to fb.
|
* accelerated or may sync the card and fall back to fb.
|
||||||
|
@ -502,6 +437,9 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
|
||||||
changes &= ~GCTile;
|
changes &= ~GCTile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changes & GCStipple)
|
||||||
|
glamor_invalidate_stipple(gc);
|
||||||
|
|
||||||
if (changes & GCStipple && gc->stipple) {
|
if (changes & GCStipple && gc->stipple) {
|
||||||
/* We can't inline stipple handling like we do for GCTile because
|
/* We can't inline stipple handling like we do for GCTile because
|
||||||
* it sets fbgc privates.
|
* it sets fbgc privates.
|
||||||
|
@ -515,14 +453,38 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable)
|
||||||
fbValidateGC(gc, changes, drawable);
|
fbValidateGC(gc, changes, drawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changes & GCDashList) {
|
||||||
|
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||||
|
|
||||||
|
if (gc_priv->dash) {
|
||||||
|
glamor_destroy_pixmap(gc_priv->dash);
|
||||||
|
gc_priv->dash = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gc->ops = &glamor_gc_ops;
|
gc->ops = &glamor_gc_ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_destroy_gc(GCPtr gc)
|
||||||
|
{
|
||||||
|
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||||
|
|
||||||
|
if (gc_priv->dash) {
|
||||||
|
glamor_destroy_pixmap(gc_priv->dash);
|
||||||
|
gc_priv->dash = NULL;
|
||||||
|
}
|
||||||
|
glamor_invalidate_stipple(gc);
|
||||||
|
if (gc_priv->stipple_damage)
|
||||||
|
DamageDestroy(gc_priv->stipple_damage);
|
||||||
|
miDestroyGC(gc);
|
||||||
|
}
|
||||||
|
|
||||||
static GCFuncs glamor_gc_funcs = {
|
static GCFuncs glamor_gc_funcs = {
|
||||||
glamor_validate_gc,
|
glamor_validate_gc,
|
||||||
miChangeGC,
|
miChangeGC,
|
||||||
miCopyGC,
|
miCopyGC,
|
||||||
miDestroyGC,
|
glamor_destroy_gc,
|
||||||
miChangeClip,
|
miChangeClip,
|
||||||
miDestroyClip,
|
miDestroyClip,
|
||||||
miCopyClip
|
miCopyClip
|
||||||
|
@ -535,6 +497,10 @@ static GCFuncs glamor_gc_funcs = {
|
||||||
int
|
int
|
||||||
glamor_create_gc(GCPtr gc)
|
glamor_create_gc(GCPtr gc)
|
||||||
{
|
{
|
||||||
|
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||||
|
|
||||||
|
gc_priv->dash = NULL;
|
||||||
|
gc_priv->stipple = NULL;
|
||||||
if (!fbCreateGC(gc))
|
if (!fbCreateGC(gc))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
|
370
glamor/glamor_dash.c
Normal file
370
glamor/glamor_dash.c
Normal file
|
@ -0,0 +1,370 @@
|
||||||
|
/*
|
||||||
|
* 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_program.h"
|
||||||
|
#include "glamor_transform.h"
|
||||||
|
#include "glamor_transfer.h"
|
||||||
|
#include "glamor_prepare.h"
|
||||||
|
|
||||||
|
static const char dash_vs_vars[] =
|
||||||
|
"attribute vec3 primitive;\n"
|
||||||
|
"varying float dash_offset;\n";
|
||||||
|
|
||||||
|
static const char dash_vs_exec[] =
|
||||||
|
" dash_offset = primitive.z / dash_length;\n"
|
||||||
|
GLAMOR_POS(gl_Position, primitive.xy);
|
||||||
|
|
||||||
|
static const char dash_fs_vars[] =
|
||||||
|
"varying float dash_offset;\n";
|
||||||
|
|
||||||
|
static const char on_off_fs_exec[] =
|
||||||
|
" float pattern = texture2D(dash, vec2(dash_offset, 0.5)).w;\n"
|
||||||
|
" if (pattern == 0.0)\n"
|
||||||
|
" discard;\n";
|
||||||
|
|
||||||
|
/* XXX deal with stippled double dashed lines once we have stippling support */
|
||||||
|
static const char double_fs_exec[] =
|
||||||
|
" float pattern = texture2D(dash, vec2(dash_offset, 0.5)).w;\n"
|
||||||
|
" if (pattern == 0.0)\n"
|
||||||
|
" gl_FragColor = bg;\n"
|
||||||
|
" else\n"
|
||||||
|
" gl_FragColor = fg;\n";
|
||||||
|
|
||||||
|
|
||||||
|
static const glamor_facet glamor_facet_on_off_dash_lines = {
|
||||||
|
.version = 130,
|
||||||
|
.name = "poly_lines_on_off_dash",
|
||||||
|
.vs_vars = dash_vs_vars,
|
||||||
|
.vs_exec = dash_vs_exec,
|
||||||
|
.fs_vars = dash_fs_vars,
|
||||||
|
.fs_exec = on_off_fs_exec,
|
||||||
|
.locations = glamor_program_location_dash,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const glamor_facet glamor_facet_double_dash_lines = {
|
||||||
|
.version = 130,
|
||||||
|
.name = "poly_lines_double_dash",
|
||||||
|
.vs_vars = dash_vs_vars,
|
||||||
|
.vs_exec = dash_vs_exec,
|
||||||
|
.fs_vars = dash_fs_vars,
|
||||||
|
.fs_exec = double_fs_exec,
|
||||||
|
.locations = (glamor_program_location_dash|
|
||||||
|
glamor_program_location_fg|
|
||||||
|
glamor_program_location_bg),
|
||||||
|
};
|
||||||
|
|
||||||
|
static PixmapPtr
|
||||||
|
glamor_get_dash_pixmap(GCPtr gc)
|
||||||
|
{
|
||||||
|
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||||
|
ScreenPtr screen = gc->pScreen;
|
||||||
|
PixmapPtr pixmap;
|
||||||
|
int offset;
|
||||||
|
int d;
|
||||||
|
uint32_t pixel;
|
||||||
|
GCPtr scratch_gc;
|
||||||
|
|
||||||
|
if (gc_priv->dash)
|
||||||
|
return gc_priv->dash;
|
||||||
|
|
||||||
|
offset = 0;
|
||||||
|
for (d = 0; d < gc->numInDashList; d++)
|
||||||
|
offset += gc->dash[d];
|
||||||
|
|
||||||
|
pixmap = glamor_create_pixmap(screen, offset, 1, 8, 0);
|
||||||
|
if (!pixmap)
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
scratch_gc = GetScratchGC(8, screen);
|
||||||
|
if (!scratch_gc)
|
||||||
|
goto bail_pixmap;
|
||||||
|
|
||||||
|
pixel = 0xffffffff;
|
||||||
|
offset = 0;
|
||||||
|
for (d = 0; d < gc->numInDashList; d++) {
|
||||||
|
xRectangle rect;
|
||||||
|
ChangeGCVal changes;
|
||||||
|
|
||||||
|
changes.val = pixel;
|
||||||
|
(void) ChangeGC(NullClient, scratch_gc,
|
||||||
|
GCForeground, &changes);
|
||||||
|
ValidateGC(&pixmap->drawable, scratch_gc);
|
||||||
|
rect.x = offset;
|
||||||
|
rect.y = 0;
|
||||||
|
rect.width = gc->dash[d];
|
||||||
|
rect.height = 1;
|
||||||
|
scratch_gc->ops->PolyFillRect (&pixmap->drawable, scratch_gc, 1, &rect);
|
||||||
|
offset += gc->dash[d];
|
||||||
|
pixel = ~pixel;
|
||||||
|
}
|
||||||
|
FreeScratchGC(scratch_gc);
|
||||||
|
|
||||||
|
gc_priv->dash = pixmap;
|
||||||
|
return pixmap;
|
||||||
|
|
||||||
|
bail_pixmap:
|
||||||
|
glamor_destroy_pixmap(pixmap);
|
||||||
|
bail:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static glamor_program *
|
||||||
|
glamor_dash_setup(DrawablePtr drawable, GCPtr gc)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = drawable->pScreen;
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||||
|
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
PixmapPtr dash_pixmap;
|
||||||
|
glamor_pixmap_private *dash_priv;
|
||||||
|
glamor_program *prog;
|
||||||
|
|
||||||
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
if (gc->lineWidth != 0)
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
dash_pixmap = glamor_get_dash_pixmap(gc);
|
||||||
|
dash_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
|
||||||
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dash_priv))
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
|
switch (gc->lineStyle) {
|
||||||
|
case LineOnOffDash:
|
||||||
|
prog = glamor_use_program_fill(pixmap, gc,
|
||||||
|
&glamor_priv->on_off_dash_line_progs,
|
||||||
|
&glamor_facet_on_off_dash_lines);
|
||||||
|
if (!prog)
|
||||||
|
goto bail_ctx;
|
||||||
|
break;
|
||||||
|
case LineDoubleDash:
|
||||||
|
if (gc->fillStyle != FillSolid)
|
||||||
|
goto bail_ctx;
|
||||||
|
|
||||||
|
prog = &glamor_priv->double_dash_line_prog;
|
||||||
|
|
||||||
|
if (!prog->prog) {
|
||||||
|
if (!glamor_build_program(screen, prog,
|
||||||
|
&glamor_facet_double_dash_lines,
|
||||||
|
NULL))
|
||||||
|
goto bail_ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!glamor_use_program(pixmap, gc, prog, NULL))
|
||||||
|
goto bail_ctx;
|
||||||
|
|
||||||
|
glamor_set_color(pixmap, gc->fgPixel, prog->fg_uniform);
|
||||||
|
glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
goto bail_ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Set the dash pattern as texture 1 */
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, dash_priv->base.fbo->tex);
|
||||||
|
glUniform1i(prog->dash_uniform, 1);
|
||||||
|
glUniform1f(prog->dash_length_uniform, dash_pixmap->drawable.width);
|
||||||
|
|
||||||
|
return prog;
|
||||||
|
|
||||||
|
bail_ctx:
|
||||||
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
|
bail:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
glamor_dash_loop(DrawablePtr drawable, GCPtr gc, glamor_program *prog,
|
||||||
|
int n, GLenum mode)
|
||||||
|
{
|
||||||
|
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||||
|
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
int box_x, box_y;
|
||||||
|
int off_x, off_y;
|
||||||
|
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
|
||||||
|
int nbox = RegionNumRects(gc->pCompositeClip);
|
||||||
|
BoxPtr box = RegionRects(gc->pCompositeClip);
|
||||||
|
|
||||||
|
glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE,
|
||||||
|
prog->matrix_uniform, &off_x, &off_y);
|
||||||
|
|
||||||
|
while (nbox--) {
|
||||||
|
glScissor(box->x1 + off_x,
|
||||||
|
box->y1 + off_y,
|
||||||
|
box->x2 - box->x1,
|
||||||
|
box->y2 - box->y1);
|
||||||
|
box++;
|
||||||
|
glDrawArrays(mode, 0, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
|
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
glamor_line_length(short x1, short y1, short x2, short y2)
|
||||||
|
{
|
||||||
|
return max(abs(x2 - x1), abs(y2 - y1));
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_poly_lines_dash_gl(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int mode, int n, DDXPointPtr points)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = drawable->pScreen;
|
||||||
|
glamor_program *prog;
|
||||||
|
short *v;
|
||||||
|
char *vbo_offset;
|
||||||
|
int add_last;
|
||||||
|
int dash_pos;
|
||||||
|
int prev_x, prev_y;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (n < 2)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (!(prog = glamor_dash_setup(drawable, gc)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
add_last = 0;
|
||||||
|
if (gc->capStyle != CapNotLast)
|
||||||
|
add_last = 1;
|
||||||
|
|
||||||
|
/* Set up the vertex buffers for the points */
|
||||||
|
|
||||||
|
v = glamor_get_vbo_space(drawable->pScreen,
|
||||||
|
(n + add_last) * 3 * sizeof (short),
|
||||||
|
&vbo_offset);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
|
glVertexAttribPointer(GLAMOR_VERTEX_POS, 3, GL_SHORT, GL_FALSE,
|
||||||
|
3 * sizeof (short), vbo_offset);
|
||||||
|
|
||||||
|
dash_pos = gc->dashOffset;
|
||||||
|
prev_x = prev_y = 0;
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
int this_x = points[i].x;
|
||||||
|
int this_y = points[i].y;
|
||||||
|
if (i) {
|
||||||
|
if (mode == CoordModePrevious) {
|
||||||
|
this_x += prev_x;
|
||||||
|
this_y += prev_y;
|
||||||
|
}
|
||||||
|
dash_pos += glamor_line_length(prev_x, prev_y,
|
||||||
|
this_x, this_y);
|
||||||
|
}
|
||||||
|
v[0] = prev_x = this_x;
|
||||||
|
v[1] = prev_y = this_y;
|
||||||
|
v[2] = dash_pos;
|
||||||
|
v += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add_last) {
|
||||||
|
v[0] = prev_x + 1;
|
||||||
|
v[1] = prev_y;
|
||||||
|
v[2] = dash_pos + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
glamor_put_vbo_space(screen);
|
||||||
|
|
||||||
|
glamor_dash_loop(drawable, gc, prog, n + add_last, GL_LINE_STRIP);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static short *
|
||||||
|
glamor_add_segment(short *v, short x1, short y1, short x2, short y2,
|
||||||
|
int dash_start, int dash_end)
|
||||||
|
{
|
||||||
|
v[0] = x1;
|
||||||
|
v[1] = y1;
|
||||||
|
v[2] = dash_start;
|
||||||
|
|
||||||
|
v[3] = x2;
|
||||||
|
v[4] = y2;
|
||||||
|
v[5] = dash_end;
|
||||||
|
return v + 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_poly_segment_dash_gl(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int nseg, xSegment *segs)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = drawable->pScreen;
|
||||||
|
glamor_program *prog;
|
||||||
|
short *v;
|
||||||
|
char *vbo_offset;
|
||||||
|
int dash_start = gc->dashOffset;
|
||||||
|
int add_last;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!(prog = glamor_dash_setup(drawable, gc)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
add_last = 0;
|
||||||
|
if (gc->capStyle != CapNotLast)
|
||||||
|
add_last = 1;
|
||||||
|
|
||||||
|
/* Set up the vertex buffers for the points */
|
||||||
|
|
||||||
|
v = glamor_get_vbo_space(drawable->pScreen,
|
||||||
|
(nseg<<add_last) * 6 * sizeof (short),
|
||||||
|
&vbo_offset);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
|
glVertexAttribPointer(GLAMOR_VERTEX_POS, 3, GL_SHORT, GL_FALSE,
|
||||||
|
3 * sizeof (short), vbo_offset);
|
||||||
|
|
||||||
|
for (i = 0; i < nseg; i++) {
|
||||||
|
int dash_end = dash_start + glamor_line_length(segs[i].x1, segs[i].y1,
|
||||||
|
segs[i].x2, segs[i].y2);
|
||||||
|
v = glamor_add_segment(v,
|
||||||
|
segs[i].x1, segs[i].y1,
|
||||||
|
segs[i].x2, segs[i].y2,
|
||||||
|
dash_start, dash_end);
|
||||||
|
if (add_last)
|
||||||
|
v = glamor_add_segment(v,
|
||||||
|
segs[i].x2, segs[i].y2,
|
||||||
|
segs[i].x2 + 1, segs[i].y2,
|
||||||
|
dash_end, dash_end + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
glamor_put_vbo_space(screen);
|
||||||
|
|
||||||
|
glamor_dash_loop(drawable, gc, prog, nseg << (1 + add_last), GL_LINES);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
|
@ -1,356 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Eric Anholt <eric@anholt.net>
|
|
||||||
* Zhigang Gong <zhigang.gong@linux.intel.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "glamor_priv.h"
|
|
||||||
|
|
||||||
/** @file glamor_fill.c
|
|
||||||
*
|
|
||||||
* GC fill implementation, based loosely on fb_fill.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fills the given rectangle of a drawable with the GC's fill style.
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
PixmapPtr sub_pixmap = NULL;
|
|
||||||
glamor_access_t sub_pixmap_access;
|
|
||||||
DrawablePtr saved_drawable = NULL;
|
|
||||||
int saved_x = x, saved_y = 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,
|
|
||||||
x - drawable->x - gc->patOrg.x,
|
|
||||||
y - drawable->y - gc->patOrg.y))
|
|
||||||
goto fail;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
if (!fallback) {
|
|
||||||
if (glamor_ddx_fallback_check_pixmap(&dst_pixmap->drawable)
|
|
||||||
&& glamor_ddx_fallback_check_gc(gc))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
/* Is it possible to set the access as WO? */
|
|
||||||
|
|
||||||
sub_pixmap_access = GLAMOR_ACCESS_RW;
|
|
||||||
|
|
||||||
sub_pixmap = glamor_get_sub_pixmap(dst_pixmap, x + off_x,
|
|
||||||
y + off_y, width, height,
|
|
||||||
sub_pixmap_access);
|
|
||||||
|
|
||||||
if (sub_pixmap != NULL) {
|
|
||||||
if (gc->fillStyle != FillSolid) {
|
|
||||||
gc->patOrg.x += (drawable->x - x);
|
|
||||||
gc->patOrg.y += (drawable->y - y);
|
|
||||||
}
|
|
||||||
saved_drawable = drawable;
|
|
||||||
drawable = &sub_pixmap->drawable;
|
|
||||||
saved_x = x;
|
|
||||||
saved_y = y;
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
}
|
|
||||||
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
|
|
||||||
glamor_prepare_access_gc(gc)) {
|
|
||||||
fbFill(drawable, gc, x, y, width, height);
|
|
||||||
}
|
|
||||||
glamor_finish_access_gc(gc);
|
|
||||||
glamor_finish_access(drawable);
|
|
||||||
|
|
||||||
if (sub_pixmap != NULL) {
|
|
||||||
if (gc->fillStyle != FillSolid) {
|
|
||||||
gc->patOrg.x -= (saved_drawable->x - saved_x);
|
|
||||||
gc->patOrg.y -= (saved_drawable->y - saved_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
x = saved_x;
|
|
||||||
y = saved_y;
|
|
||||||
|
|
||||||
glamor_put_sub_pixmap(sub_pixmap, dst_pixmap,
|
|
||||||
x + off_x, y + off_y,
|
|
||||||
width, height, sub_pixmap_access);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
glamor_init_solid_shader(ScreenPtr screen)
|
|
||||||
{
|
|
||||||
glamor_screen_private *glamor_priv;
|
|
||||||
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 = glamor_get_screen_private(screen);
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
glamor_priv->solid_prog = glCreateProgram();
|
|
||||||
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs);
|
|
||||||
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs);
|
|
||||||
glAttachShader(glamor_priv->solid_prog, vs_prog);
|
|
||||||
glAttachShader(glamor_priv->solid_prog, fs_prog);
|
|
||||||
|
|
||||||
glBindAttribLocation(glamor_priv->solid_prog,
|
|
||||||
GLAMOR_VERTEX_POS, "v_position");
|
|
||||||
glamor_link_glsl_prog(screen, glamor_priv->solid_prog, "solid");
|
|
||||||
|
|
||||||
glamor_priv->solid_color_uniform_location =
|
|
||||||
glGetUniformLocation(glamor_priv->solid_prog, "color");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
glamor_fini_solid_shader(ScreenPtr screen)
|
|
||||||
{
|
|
||||||
glamor_screen_private *glamor_priv;
|
|
||||||
|
|
||||||
glamor_priv = glamor_get_screen_private(screen);
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
glDeleteProgram(glamor_priv->solid_prog);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
GLfloat xscale, yscale;
|
|
||||||
float stack_vertices[32];
|
|
||||||
float *vertices = stack_vertices;
|
|
||||||
int valid_nbox = ARRAY_SIZE(stack_vertices) / (4 * 2);
|
|
||||||
|
|
||||||
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
glUseProgram(glamor_priv->solid_prog);
|
|
||||||
|
|
||||||
glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
|
|
||||||
|
|
||||||
pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
|
|
||||||
|
|
||||||
if (nbox > valid_nbox) {
|
|
||||||
int allocated_nbox;
|
|
||||||
float *new_vertices;
|
|
||||||
|
|
||||||
if (nbox > GLAMOR_COMPOSITE_VBO_VERT_CNT / 6)
|
|
||||||
allocated_nbox = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6;
|
|
||||||
else
|
|
||||||
allocated_nbox = nbox;
|
|
||||||
new_vertices = malloc(allocated_nbox * 4 * 2 * sizeof(float));
|
|
||||||
if (new_vertices) {
|
|
||||||
vertices = new_vertices;
|
|
||||||
valid_nbox = allocated_nbox;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
|
||||||
GL_FALSE, 2 * sizeof(float), vertices);
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
|
||||||
|
|
||||||
while (nbox) {
|
|
||||||
int box_cnt, i;
|
|
||||||
float *next_box;
|
|
||||||
|
|
||||||
next_box = vertices;
|
|
||||||
box_cnt = nbox > valid_nbox ? valid_nbox : nbox;
|
|
||||||
for (i = 0; i < box_cnt; i++) {
|
|
||||||
glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale,
|
|
||||||
box[i].x1, box[i].y1,
|
|
||||||
box[i].x2, box[i].y2,
|
|
||||||
glamor_priv->yInverted,
|
|
||||||
next_box);
|
|
||||||
next_box += 4 * 2;
|
|
||||||
}
|
|
||||||
if (box_cnt == 1)
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4);
|
|
||||||
else {
|
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
|
||||||
glDrawRangeElements(GL_TRIANGLES, 0, box_cnt * 4, box_cnt * 6,
|
|
||||||
GL_UNSIGNED_SHORT, NULL);
|
|
||||||
} else {
|
|
||||||
glDrawElements(GL_TRIANGLES, box_cnt * 6, GL_UNSIGNED_SHORT,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nbox -= box_cnt;
|
|
||||||
box += box_cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vertices != stack_vertices)
|
|
||||||
free(vertices);
|
|
||||||
|
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
|
||||||
glamor_priv->state = RENDER_STATE;
|
|
||||||
glamor_priv->render_idle_cnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fills the given rectangles of pixmap with an X pixel value.
|
|
||||||
*
|
|
||||||
* This is a helper used by other code after clipping and translation
|
|
||||||
* of coordinates to a glamor backing pixmap.
|
|
||||||
*/
|
|
||||||
Bool
|
|
||||||
glamor_solid_boxes(PixmapPtr pixmap,
|
|
||||||
BoxPtr box, int nbox, unsigned long fg_pixel)
|
|
||||||
{
|
|
||||||
glamor_pixmap_private *pixmap_priv;
|
|
||||||
GLfloat color[4];
|
|
||||||
|
|
||||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
glamor_get_rgba_from_pixel(fg_pixel,
|
|
||||||
&color[0],
|
|
||||||
&color[1],
|
|
||||||
&color[2], &color[3], format_for_pixmap(pixmap));
|
|
||||||
|
|
||||||
if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
|
||||||
RegionRec region;
|
|
||||||
int n_region;
|
|
||||||
glamor_pixmap_clipped_regions *clipped_regions;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
RegionInitBoxes(®ion, box, nbox);
|
|
||||||
clipped_regions =
|
|
||||||
glamor_compute_clipped_regions(pixmap_priv, ®ion, &n_region, 0,
|
|
||||||
0, 0);
|
|
||||||
for (i = 0; i < n_region; i++) {
|
|
||||||
BoxPtr inner_box;
|
|
||||||
int inner_nbox;
|
|
||||||
|
|
||||||
SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
|
|
||||||
|
|
||||||
inner_box = RegionRects(clipped_regions[i].region);
|
|
||||||
inner_nbox = RegionNumRects(clipped_regions[i].region);
|
|
||||||
_glamor_solid_boxes(pixmap, inner_box, inner_nbox, color);
|
|
||||||
RegionDestroy(clipped_regions[i].region);
|
|
||||||
}
|
|
||||||
free(clipped_regions);
|
|
||||||
RegionUninit(®ion);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_glamor_solid_boxes(pixmap, box, nbox, color);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fills a rectangle of a pixmap with an X pixel value.
|
|
||||||
*
|
|
||||||
* This is a helper used by other glamor code mostly for clearing of
|
|
||||||
* buffers to 0.
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
BoxRec box;
|
|
||||||
|
|
||||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (!glamor_set_planemask(pixmap, planemask)) {
|
|
||||||
glamor_fallback("Failedto set planemask in glamor_solid.\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
if (!glamor_set_alu(screen, alu)) {
|
|
||||||
if (alu == GXclear)
|
|
||||||
fg_pixel = 0;
|
|
||||||
else {
|
|
||||||
glamor_fallback("unsupported alu %x\n", alu);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
box.x1 = x;
|
|
||||||
box.y1 = y;
|
|
||||||
box.x2 = x + width;
|
|
||||||
box.y2 = y + height;
|
|
||||||
glamor_solid_boxes(pixmap, &box, 1, fg_pixel);
|
|
||||||
|
|
||||||
glamor_set_alu(screen, GXcopy);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
|
@ -56,7 +56,8 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_glyph_blt_progs,
|
prog = glamor_use_program_fill(pixmap, gc,
|
||||||
|
&glamor_priv->poly_glyph_blt_progs,
|
||||||
&glamor_facet_poly_glyph_blt);
|
&glamor_facet_poly_glyph_blt);
|
||||||
if (!prog)
|
if (!prog)
|
||||||
goto bail_ctx;
|
goto bail_ctx;
|
||||||
|
@ -74,7 +75,8 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
|
||||||
int off_x, off_y;
|
int off_x, off_y;
|
||||||
char *vbo_offset;
|
char *vbo_offset;
|
||||||
|
|
||||||
glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE, prog->matrix_uniform, &off_x, &off_y);
|
glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE,
|
||||||
|
prog->matrix_uniform, &off_x, &off_y);
|
||||||
|
|
||||||
max_points = 500;
|
max_points = 500;
|
||||||
num_points = 0;
|
num_points = 0;
|
||||||
|
@ -105,10 +107,12 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
|
||||||
|
|
||||||
if (!num_points) {
|
if (!num_points) {
|
||||||
points = glamor_get_vbo_space(screen,
|
points = glamor_get_vbo_space(screen,
|
||||||
max_points * (2 * sizeof (INT16)),
|
max_points *
|
||||||
|
(2 * sizeof (INT16)),
|
||||||
&vbo_offset);
|
&vbo_offset);
|
||||||
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT,
|
glVertexAttribPointer(GLAMOR_VERTEX_POS,
|
||||||
|
2, GL_SHORT,
|
||||||
GL_FALSE, 0, vbo_offset);
|
GL_FALSE, 0, vbo_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +153,8 @@ glamor_poly_glyph_blt(DrawablePtr drawable, GCPtr gc,
|
||||||
int start_x, int y, unsigned int nglyph,
|
int start_x, int y, unsigned int nglyph,
|
||||||
CharInfoPtr *ppci, void *pglyph_base)
|
CharInfoPtr *ppci, void *pglyph_base)
|
||||||
{
|
{
|
||||||
if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, pglyph_base))
|
if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci,
|
||||||
|
pglyph_base))
|
||||||
return;
|
return;
|
||||||
miPolyGlyphBlt(drawable, gc, start_x, y, nglyph,
|
miPolyGlyphBlt(drawable, gc, start_x, y, nglyph,
|
||||||
ppci, pglyph_base);
|
ppci, pglyph_base);
|
||||||
|
@ -160,10 +165,13 @@ glamor_poly_glyph_blt_nf(DrawablePtr drawable, GCPtr gc,
|
||||||
int start_x, int y, unsigned int nglyph,
|
int start_x, int y, unsigned int nglyph,
|
||||||
CharInfoPtr *ppci, void *pglyph_base)
|
CharInfoPtr *ppci, void *pglyph_base)
|
||||||
{
|
{
|
||||||
if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci, pglyph_base))
|
if (glamor_poly_glyph_blt_gl(drawable, gc, start_x, y, nglyph, ppci,
|
||||||
|
pglyph_base))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
|
if (glamor_ddx_fallback_check_pixmap(drawable) &&
|
||||||
|
glamor_ddx_fallback_check_gc(gc)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
miPolyGlyphBlt(drawable, gc, start_x, y, nglyph,
|
miPolyGlyphBlt(drawable, gc, start_x, y, nglyph,
|
||||||
ppci, pglyph_base);
|
ppci, pglyph_base);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -179,8 +187,8 @@ glamor_image_glyph_blt_nf(DrawablePtr drawable, GCPtr gc,
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap,
|
glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
|
||||||
DrawablePtr drawable, int w, int h, int x, int y)
|
DrawablePtr drawable, int w, int h, int x, int y)
|
||||||
{
|
{
|
||||||
ScreenPtr screen = drawable->pScreen;
|
ScreenPtr screen = drawable->pScreen;
|
||||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
@ -188,65 +196,40 @@ glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap,
|
||||||
glamor_pixmap_private *pixmap_priv;
|
glamor_pixmap_private *pixmap_priv;
|
||||||
uint8_t *bitmap_data = bitmap->devPrivate.ptr;
|
uint8_t *bitmap_data = bitmap->devPrivate.ptr;
|
||||||
int bitmap_stride = bitmap->devKind;
|
int bitmap_stride = bitmap->devKind;
|
||||||
int off_x, off_y;
|
glamor_program *prog;
|
||||||
|
RegionPtr clip = gc->pCompositeClip;
|
||||||
|
int box_x, box_y;
|
||||||
int yy, xx;
|
int yy, xx;
|
||||||
GLfloat xscale, yscale;
|
int num_points;
|
||||||
float color[4];
|
INT16 *points = NULL;
|
||||||
unsigned long fg_pixel = gc->fgPixel;
|
|
||||||
float *points, *next_point;
|
|
||||||
int num_points = 0;
|
|
||||||
char *vbo_offset;
|
char *vbo_offset;
|
||||||
RegionPtr clip;
|
|
||||||
|
|
||||||
if (w * h > MAXINT / (2 * sizeof(float)))
|
if (w * h > MAXINT / (2 * sizeof(float)))
|
||||||
return FALSE;
|
goto bail;
|
||||||
|
|
||||||
if (gc->fillStyle != FillSolid) {
|
|
||||||
glamor_fallback("gc fillstyle not solid\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||||
return FALSE;
|
goto bail;
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
glamor_make_current(glamor_priv);
|
||||||
if (!glamor_set_alu(screen, gc->alu)) {
|
|
||||||
if (gc->alu == GXclear)
|
|
||||||
fg_pixel = 0;
|
|
||||||
else {
|
|
||||||
glamor_fallback("unsupported alu %x\n", gc->alu);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!glamor_set_planemask(pixmap, gc->planemask)) {
|
prog = glamor_use_program_fill(pixmap, gc,
|
||||||
glamor_fallback("Failed to set planemask in %s.\n", __FUNCTION__);
|
&glamor_priv->poly_glyph_blt_progs,
|
||||||
return FALSE;
|
&glamor_facet_poly_glyph_blt);
|
||||||
}
|
if (!prog)
|
||||||
|
goto bail_ctx;
|
||||||
|
|
||||||
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
|
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
|
|
||||||
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
|
points = glamor_get_vbo_space(screen, w * h * sizeof(INT16) * 2,
|
||||||
pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
|
|
||||||
|
|
||||||
glUseProgram(glamor_priv->solid_prog);
|
|
||||||
|
|
||||||
glamor_get_rgba_from_pixel(fg_pixel,
|
|
||||||
&color[0], &color[1], &color[2], &color[3],
|
|
||||||
format_for_pixmap(pixmap));
|
|
||||||
glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
|
|
||||||
|
|
||||||
points = glamor_get_vbo_space(screen, w * h * sizeof(float) * 2,
|
|
||||||
&vbo_offset);
|
&vbo_offset);
|
||||||
next_point = points;
|
num_points = 0;
|
||||||
|
|
||||||
clip = fbGetCompositeClip(gc);
|
|
||||||
|
|
||||||
/* Note that because fb sets miTranslate in the GC, our incoming X
|
/* Note that because fb sets miTranslate in the GC, our incoming X
|
||||||
* and Y are in screen coordinate space (same for spans, but not
|
* and Y are in screen coordinate space (same for spans, but not
|
||||||
* other operations).
|
* other operations).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (yy = 0; yy < h; yy++) {
|
for (yy = 0; yy < h; yy++) {
|
||||||
uint8_t *bitmap_row = bitmap_data + yy * bitmap_stride;
|
uint8_t *bitmap_row = bitmap_data + yy * bitmap_stride;
|
||||||
for (xx = 0; xx < w; xx++) {
|
for (xx = 0; xx < w; xx++) {
|
||||||
|
@ -255,63 +238,58 @@ glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap,
|
||||||
x + xx,
|
x + xx,
|
||||||
y + yy,
|
y + yy,
|
||||||
NULL)) {
|
NULL)) {
|
||||||
next_point[0] = v_from_x_coord_x(xscale, x + xx + off_x + 0.5);
|
*points++ = x + xx;
|
||||||
if (glamor_priv->yInverted)
|
*points++ = y + yy;
|
||||||
next_point[1] = v_from_x_coord_y_inverted(yscale, y + yy + off_y + 0.5);
|
|
||||||
else
|
|
||||||
next_point[1] = v_from_x_coord_y(yscale, y + yy + off_y + 0.5);
|
|
||||||
|
|
||||||
next_point += 2;
|
|
||||||
num_points++;
|
num_points++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT,
|
||||||
GL_FALSE, 2 * sizeof(float),
|
GL_FALSE, 0, vbo_offset);
|
||||||
vbo_offset);
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
|
||||||
|
|
||||||
glamor_put_vbo_space(screen);
|
glamor_put_vbo_space(screen);
|
||||||
|
|
||||||
glDrawArrays(GL_POINTS, 0, num_points);
|
glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
|
||||||
|
glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE,
|
||||||
|
prog->matrix_uniform, NULL, NULL);
|
||||||
|
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
glDrawArrays(GL_POINTS, 0, num_points);
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
_glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
|
|
||||||
DrawablePtr pDrawable, int w, int h, int x, int y,
|
|
||||||
Bool fallback)
|
|
||||||
{
|
|
||||||
glamor_pixmap_private *pixmap_priv;
|
|
||||||
|
|
||||||
if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable)
|
|
||||||
&& glamor_ddx_fallback_check_pixmap(&pBitmap->drawable)
|
|
||||||
&& glamor_ddx_fallback_check_gc(pGC))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
pixmap_priv = glamor_get_pixmap_private(pBitmap);
|
|
||||||
if (pixmap_priv->type == GLAMOR_MEMORY) {
|
|
||||||
if (glamor_push_pixels_points(pGC, pBitmap, pDrawable, w, h, x, y))
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
|
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
bail_ctx:
|
||||||
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
|
bail:
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
|
glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
|
||||||
DrawablePtr pDrawable, int w, int h, int x, int y)
|
DrawablePtr pDrawable, int w, int h, int x, int y)
|
||||||
{
|
{
|
||||||
_glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, TRUE);
|
if (glamor_push_pixels_gl(pGC, pBitmap, pDrawable, w, h, x, y))
|
||||||
|
return;
|
||||||
|
|
||||||
|
miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap,
|
glamor_push_pixels_nf(GCPtr gc, PixmapPtr bitmap,
|
||||||
DrawablePtr pDrawable, int w, int h, int x, int y)
|
DrawablePtr drawable, int w, int h, int x, int y)
|
||||||
{
|
{
|
||||||
return _glamor_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y, FALSE);
|
if (glamor_push_pixels_gl(gc, bitmap, drawable, w, h, x, y))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (glamor_ddx_fallback_check_pixmap(drawable) &&
|
||||||
|
glamor_ddx_fallback_check_pixmap(&bitmap->drawable) &&
|
||||||
|
glamor_ddx_fallback_check_gc(gc))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
miPushPixels(gc, bitmap, drawable, w, h, x, y);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,7 +168,7 @@ clear_mask_cache(struct glamor_glyph_mask_cache *maskcache)
|
||||||
struct glamor_glyph_mask_cache_entry *mce;
|
struct glamor_glyph_mask_cache_entry *mce;
|
||||||
|
|
||||||
glamor_solid(maskcache->pixmap, 0, CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE,
|
glamor_solid(maskcache->pixmap, 0, CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE,
|
||||||
MASK_CACHE_MAX_SIZE, GXcopy, 0xFFFFFFFF, 0);
|
MASK_CACHE_MAX_SIZE, 0);
|
||||||
mce = &maskcache->mcache[0];
|
mce = &maskcache->mcache[0];
|
||||||
while (cnt--) {
|
while (cnt--) {
|
||||||
mce->width = 0;
|
mce->width = 0;
|
||||||
|
@ -448,9 +448,9 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen,
|
||||||
box.y1 = y;
|
box.y1 = y;
|
||||||
box.x2 = x + glyph->info.width;
|
box.x2 = x + glyph->info.width;
|
||||||
box.y2 = y + glyph->info.height;
|
box.y2 = y + glyph->info.height;
|
||||||
glamor_copy_n_to_n_nf(&scratch->drawable,
|
glamor_copy(&scratch->drawable,
|
||||||
&pCachePixmap->drawable, NULL,
|
&pCachePixmap->drawable, NULL,
|
||||||
&box, 1, -x, -y, FALSE, FALSE, 0, NULL);
|
&box, 1, -x, -y, FALSE, FALSE, 0, NULL);
|
||||||
if (scratch != pGlyphPixmap)
|
if (scratch != pGlyphPixmap)
|
||||||
screen->DestroyPixmap(scratch);
|
screen->DestroyPixmap(scratch);
|
||||||
|
|
||||||
|
@ -1433,7 +1433,7 @@ glamor_glyphs_via_mask(CARD8 op,
|
||||||
glamor_destroy_pixmap(mask_pixmap);
|
glamor_destroy_pixmap(mask_pixmap);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
glamor_solid(mask_pixmap, 0, 0, width, height, GXcopy, 0xFFFFFFFF, 0);
|
glamor_solid(mask_pixmap, 0, 0, width, height, 0);
|
||||||
component_alpha = NeedsComponent(mask_format->format);
|
component_alpha = NeedsComponent(mask_format->format);
|
||||||
mask = CreatePicture(0, &mask_pixmap->drawable,
|
mask = CreatePicture(0, &mask_pixmap->drawable,
|
||||||
mask_format, CPComponentAlpha,
|
mask_format, CPComponentAlpha,
|
||||||
|
|
|
@ -699,7 +699,7 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
|
||||||
width),
|
width),
|
||||||
(INT16) (dst_picture->pDrawable->
|
(INT16) (dst_picture->pDrawable->
|
||||||
height),
|
height),
|
||||||
glamor_priv->yInverted, vertices);
|
vertices);
|
||||||
|
|
||||||
if (tex_normalize) {
|
if (tex_normalize) {
|
||||||
glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale,
|
glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale,
|
||||||
|
@ -710,17 +710,14 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
|
||||||
(INT16) (dst_picture->
|
(INT16) (dst_picture->
|
||||||
pDrawable->height +
|
pDrawable->height +
|
||||||
y_source),
|
y_source),
|
||||||
glamor_priv->yInverted,
|
|
||||||
tex_vertices);
|
tex_vertices);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
glamor_set_tcoords_tri_strip((INT16) (dst_picture->pDrawable->width),
|
glamor_set_tcoords_tri_strip(x_source, y_source,
|
||||||
(INT16) (dst_picture->pDrawable->height),
|
|
||||||
x_source, y_source,
|
|
||||||
(INT16) (dst_picture->pDrawable->width) +
|
(INT16) (dst_picture->pDrawable->width) +
|
||||||
x_source,
|
x_source,
|
||||||
(INT16) (dst_picture->pDrawable->height) +
|
(INT16) (dst_picture->pDrawable->height) +
|
||||||
y_source, glamor_priv->yInverted,
|
y_source,
|
||||||
tex_vertices);
|
tex_vertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1084,13 +1081,11 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
|
||||||
r2 = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.
|
r2 = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.
|
||||||
radius);
|
radius);
|
||||||
|
|
||||||
glamor_set_circle_centre(width, height, c1x, c1y, glamor_priv->yInverted,
|
glamor_set_circle_centre(width, height, c1x, c1y, cxy);
|
||||||
cxy);
|
|
||||||
glUniform2fv(c1_uniform_location, 1, cxy);
|
glUniform2fv(c1_uniform_location, 1, cxy);
|
||||||
glUniform1f(r1_uniform_location, r1);
|
glUniform1f(r1_uniform_location, r1);
|
||||||
|
|
||||||
glamor_set_circle_centre(width, height, c2x, c2y, glamor_priv->yInverted,
|
glamor_set_circle_centre(width, height, c2x, c2y, cxy);
|
||||||
cxy);
|
|
||||||
glUniform2fv(c2_uniform_location, 1, cxy);
|
glUniform2fv(c2_uniform_location, 1, cxy);
|
||||||
glUniform1f(r2_uniform_location, r2);
|
glUniform1f(r2_uniform_location, r2);
|
||||||
|
|
||||||
|
@ -1322,7 +1317,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
|
||||||
linear.p1.x),
|
linear.p1.x),
|
||||||
pixman_fixed_to_double(src_picture->pSourcePict->
|
pixman_fixed_to_double(src_picture->pSourcePict->
|
||||||
linear.p1.y),
|
linear.p1.y),
|
||||||
glamor_priv->yInverted, pt1);
|
pt1);
|
||||||
DEBUGF("pt1:(%f, %f) ---> (%f %f)\n",
|
DEBUGF("pt1:(%f, %f) ---> (%f %f)\n",
|
||||||
pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.x),
|
pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.x),
|
||||||
pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.y),
|
pixman_fixed_to_double(src_picture->pSourcePict->linear.p1.y),
|
||||||
|
@ -1333,7 +1328,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
|
||||||
linear.p2.x),
|
linear.p2.x),
|
||||||
pixman_fixed_to_double(src_picture->pSourcePict->
|
pixman_fixed_to_double(src_picture->pSourcePict->
|
||||||
linear.p2.y),
|
linear.p2.y),
|
||||||
glamor_priv->yInverted, pt2);
|
pt2);
|
||||||
DEBUGF("pt2:(%f, %f) ---> (%f %f)\n",
|
DEBUGF("pt2:(%f, %f) ---> (%f %f)\n",
|
||||||
pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.x),
|
pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.x),
|
||||||
pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.y),
|
pixman_fixed_to_double(src_picture->pSourcePict->linear.p2.y),
|
||||||
|
|
|
@ -797,9 +797,9 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
|
||||||
copy_box.y2 = temp_extent->y2 - temp_extent->y1;
|
copy_box.y2 = temp_extent->y2 - temp_extent->y1;
|
||||||
dx = temp_extent->x1;
|
dx = temp_extent->x1;
|
||||||
dy = temp_extent->y1;
|
dy = temp_extent->y1;
|
||||||
glamor_copy_n_to_n(&priv->base.pixmap->drawable,
|
glamor_copy(&priv->base.pixmap->drawable,
|
||||||
&temp_pixmap->drawable,
|
&temp_pixmap->drawable,
|
||||||
NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL);
|
NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL);
|
||||||
// glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width,
|
// glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width,
|
||||||
// temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff00);
|
// temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff00);
|
||||||
}
|
}
|
||||||
|
@ -829,9 +829,10 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
|
||||||
copy_box.x1, copy_box.y1, copy_box.x2,
|
copy_box.x1, copy_box.y1, copy_box.x2,
|
||||||
copy_box.y2, dx, dy);
|
copy_box.y2, dx, dy);
|
||||||
|
|
||||||
glamor_copy_n_to_n(&priv->base.pixmap->drawable,
|
glamor_copy(&priv->base.pixmap->drawable,
|
||||||
&temp_pixmap->drawable,
|
&temp_pixmap->drawable,
|
||||||
NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL);
|
NULL, ©_box, 1, dx, dy, 0, 0, 0, NULL);
|
||||||
|
|
||||||
box++;
|
box++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
187
glamor/glamor_lines.c
Normal file
187
glamor/glamor_lines.c
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
/*
|
||||||
|
* 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_program.h"
|
||||||
|
#include "glamor_transform.h"
|
||||||
|
#include "glamor_prepare.h"
|
||||||
|
|
||||||
|
static const glamor_facet glamor_facet_poly_lines = {
|
||||||
|
.name = "poly_lines",
|
||||||
|
.vs_vars = "attribute vec2 primitive;\n",
|
||||||
|
.vs_exec = (" vec2 pos = vec2(0.0,0.0);\n"
|
||||||
|
GLAMOR_POS(gl_Position, primitive.xy)),
|
||||||
|
};
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int mode, int n, DDXPointPtr points)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = drawable->pScreen;
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||||
|
glamor_pixmap_private *pixmap_priv;
|
||||||
|
glamor_program *prog;
|
||||||
|
int off_x, off_y;
|
||||||
|
DDXPointPtr v;
|
||||||
|
char *vbo_offset;
|
||||||
|
int box_x, box_y;
|
||||||
|
int add_last;
|
||||||
|
|
||||||
|
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
add_last = 0;
|
||||||
|
if (gc->capStyle != CapNotLast)
|
||||||
|
add_last = 1;
|
||||||
|
|
||||||
|
if (n < 2)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
|
prog = glamor_use_program_fill(pixmap, gc,
|
||||||
|
&glamor_priv->poly_line_program,
|
||||||
|
&glamor_facet_poly_lines);
|
||||||
|
|
||||||
|
if (!prog)
|
||||||
|
goto bail_ctx;
|
||||||
|
|
||||||
|
/* Set up the vertex buffers for the points */
|
||||||
|
|
||||||
|
v = glamor_get_vbo_space(drawable->pScreen,
|
||||||
|
(n + add_last) * sizeof (DDXPointRec),
|
||||||
|
&vbo_offset);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
|
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
|
||||||
|
sizeof (DDXPointRec), vbo_offset);
|
||||||
|
|
||||||
|
if (mode == CoordModePrevious) {
|
||||||
|
int i;
|
||||||
|
DDXPointRec here = { 0, 0 };
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
here.x += points[i].x;
|
||||||
|
here.y += points[i].y;
|
||||||
|
v[i] = here;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(v, points, n * sizeof (DDXPointRec));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add_last) {
|
||||||
|
v[n].x = v[n-1].x + 1;
|
||||||
|
v[n].y = v[n-1].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
glamor_put_vbo_space(screen);
|
||||||
|
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
|
||||||
|
int nbox = RegionNumRects(gc->pCompositeClip);
|
||||||
|
BoxPtr box = RegionRects(gc->pCompositeClip);
|
||||||
|
|
||||||
|
glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE,
|
||||||
|
prog->matrix_uniform, &off_x, &off_y);
|
||||||
|
|
||||||
|
while (nbox--) {
|
||||||
|
glScissor(box->x1 + off_x,
|
||||||
|
box->y1 + off_y,
|
||||||
|
box->x2 - box->x1,
|
||||||
|
box->y2 - box->y1);
|
||||||
|
box++;
|
||||||
|
glDrawArrays(GL_LINE_STRIP, 0, n + add_last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
|
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
bail_ctx:
|
||||||
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
|
bail:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
glamor_poly_lines_gl(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int mode, int n, DDXPointPtr points)
|
||||||
|
{
|
||||||
|
if (gc->lineWidth != 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (gc->lineStyle) {
|
||||||
|
case LineSolid:
|
||||||
|
return glamor_poly_lines_solid_gl(drawable, gc, mode, n, points);
|
||||||
|
case LineOnOffDash:
|
||||||
|
return glamor_poly_lines_dash_gl(drawable, gc, mode, n, points);
|
||||||
|
case LineDoubleDash:
|
||||||
|
if (gc->fillStyle == FillTiled)
|
||||||
|
return glamor_poly_lines_solid_gl(drawable, gc, mode, n, points);
|
||||||
|
else
|
||||||
|
return glamor_poly_lines_dash_gl(drawable, gc, mode, n, points);
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
glamor_poly_lines_bail(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int mode, int n, DDXPointPtr points)
|
||||||
|
{
|
||||||
|
glamor_fallback("to %p (%c)\n", drawable,
|
||||||
|
glamor_get_drawable_location(drawable));
|
||||||
|
|
||||||
|
miPolylines(drawable, gc, mode, n, points);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_poly_lines(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int mode, int n, DDXPointPtr points)
|
||||||
|
{
|
||||||
|
if (glamor_poly_lines_gl(drawable, gc, mode, n, points))
|
||||||
|
return;
|
||||||
|
glamor_poly_lines_bail(drawable, gc, mode, n, points);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int mode, int n, DDXPointPtr points)
|
||||||
|
{
|
||||||
|
if (glamor_poly_lines_gl(drawable, gc, mode, n, points))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (glamor_ddx_fallback_check_pixmap(drawable) &&
|
||||||
|
glamor_ddx_fallback_check_gc(gc))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
glamor_poly_lines_bail(drawable, gc, mode, n, points);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -45,24 +45,6 @@ glamor_upload_picture_to_texture(PicturePtr picture)
|
||||||
return glamor_upload_pixmap_to_texture(pixmap);
|
return glamor_upload_pixmap_to_texture(pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
|
||||||
glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access)
|
|
||||||
{
|
|
||||||
if (!picture || !picture->pDrawable)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
return glamor_prepare_access(picture->pDrawable, access);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
glamor_finish_access_picture(PicturePtr picture)
|
|
||||||
{
|
|
||||||
if (!picture || !picture->pDrawable)
|
|
||||||
return;
|
|
||||||
|
|
||||||
glamor_finish_access(picture->pDrawable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We should already have drawable attached to it, if it has one.
|
* We should already have drawable attached to it, if it has one.
|
||||||
* Then set the attached pixmap to is_picture format, and set
|
* Then set the attached pixmap to is_picture format, and set
|
||||||
|
|
|
@ -747,11 +747,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
|
||||||
glamor_get_screen_private(pixmap->drawable.pScreen);
|
glamor_get_screen_private(pixmap->drawable.pScreen);
|
||||||
static float vertices[8];
|
static float vertices[8];
|
||||||
|
|
||||||
static float texcoords[8] = { 0, 1,
|
|
||||||
1, 1,
|
|
||||||
1, 0,
|
|
||||||
0, 0
|
|
||||||
};
|
|
||||||
static float texcoords_inv[8] = { 0, 0,
|
static float texcoords_inv[8] = { 0, 0,
|
||||||
1, 0,
|
1, 0,
|
||||||
1, 1,
|
1, 1,
|
||||||
|
@ -760,11 +755,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
|
||||||
float *ptexcoords;
|
float *ptexcoords;
|
||||||
float dst_xscale, dst_yscale;
|
float dst_xscale, dst_yscale;
|
||||||
GLuint tex = 0;
|
GLuint tex = 0;
|
||||||
int need_flip;
|
|
||||||
int need_free_bits = 0;
|
int need_free_bits = 0;
|
||||||
|
|
||||||
need_flip = !glamor_priv->yInverted;
|
|
||||||
|
|
||||||
if (bits == NULL)
|
if (bits == NULL)
|
||||||
goto ready_to_upload;
|
goto ready_to_upload;
|
||||||
|
|
||||||
|
@ -798,7 +790,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
|
||||||
/* Try fast path firstly, upload the pixmap to the texture attached
|
/* Try fast path firstly, upload the pixmap to the texture attached
|
||||||
* to the fbo directly. */
|
* to the fbo directly. */
|
||||||
if (no_alpha == 0
|
if (no_alpha == 0
|
||||||
&& revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING && !need_flip
|
&& revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING
|
||||||
#ifdef WALKAROUND_LARGE_TEXTURE_MAP
|
#ifdef WALKAROUND_LARGE_TEXTURE_MAP
|
||||||
&& pixmap_priv->type != GLAMOR_TEXTURE_LARGE
|
&& pixmap_priv->type != GLAMOR_TEXTURE_LARGE
|
||||||
#endif
|
#endif
|
||||||
|
@ -818,17 +810,14 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_flip)
|
ptexcoords = texcoords_inv;
|
||||||
ptexcoords = texcoords;
|
|
||||||
else
|
|
||||||
ptexcoords = texcoords_inv;
|
|
||||||
|
|
||||||
pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
|
pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
|
||||||
glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
|
glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
|
||||||
dst_yscale,
|
dst_yscale,
|
||||||
x, y,
|
x, y,
|
||||||
x + w, y + h,
|
x + w, y + h,
|
||||||
glamor_priv->yInverted, vertices);
|
vertices);
|
||||||
/* Slow path, we need to flip y or wire alpha to 1. */
|
/* Slow path, we need to flip y or wire alpha to 1. */
|
||||||
glamor_make_current(glamor_priv);
|
glamor_make_current(glamor_priv);
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
||||||
|
@ -865,10 +854,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
|
||||||
/*
|
/*
|
||||||
* Prepare to upload a pixmap to texture memory.
|
* Prepare to upload a pixmap to texture memory.
|
||||||
* no_alpha equals 1 means the format needs to wire alpha to 1.
|
* no_alpha equals 1 means the format needs to wire alpha to 1.
|
||||||
* Two condtion need to setup a fbo for a pixmap
|
*/
|
||||||
* 1. !yInverted, we need to do flip if we are not yInverted.
|
|
||||||
* 2. no_alpha != 0, we need to wire the alpha.
|
|
||||||
* */
|
|
||||||
static int
|
static int
|
||||||
glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
|
glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
|
||||||
int revert, int swap_rb)
|
int revert, int swap_rb)
|
||||||
|
@ -896,8 +882,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!(no_alpha || (revert == REVERT_NORMAL)
|
if (!(no_alpha || (revert == REVERT_NORMAL)
|
||||||
|| (swap_rb != SWAP_NONE_UPLOADING)
|
|| (swap_rb != SWAP_NONE_UPLOADING))) {
|
||||||
|| !glamor_priv->yInverted)) {
|
|
||||||
/* We don't need a fbo, a simple texture uploading should work. */
|
/* We don't need a fbo, a simple texture uploading should work. */
|
||||||
|
|
||||||
flag = GLAMOR_CREATE_FBO_NO_FBO;
|
flag = GLAMOR_CREATE_FBO_NO_FBO;
|
||||||
|
@ -939,26 +924,6 @@ glamor_put_bits(char *dst_bits, int dst_stride, char *src_bits,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* download sub region from a large region.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
glamor_get_bits(char *dst_bits, int dst_stride, char *src_bits,
|
|
||||||
int src_stride, int bpp, int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
int byte_per_pixel;
|
|
||||||
|
|
||||||
byte_per_pixel = bpp / 8;
|
|
||||||
dst_bits += y * dst_stride + x * byte_per_pixel;
|
|
||||||
|
|
||||||
for (j = y; j < y + h; j++) {
|
|
||||||
memcpy(dst_bits, src_bits, w * byte_per_pixel);
|
|
||||||
src_bits += src_stride;
|
|
||||||
dst_bits += dst_stride;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
|
glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
|
||||||
int h, int stride, void *bits, int pbo)
|
int h, int stride, void *bits, int pbo)
|
||||||
|
@ -1100,13 +1065,6 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
glamor_restore_pixmap_to_texture(PixmapPtr pixmap)
|
|
||||||
{
|
|
||||||
if (glamor_upload_pixmap_to_texture(pixmap) != GLAMOR_UPLOAD_DONE)
|
|
||||||
LogMessage(X_WARNING, "Failed to restore pixmap to texture.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* as gles2 only support a very small set of color format and
|
* as gles2 only support a very small set of color format and
|
||||||
* type when do glReadPixel,
|
* type when do glReadPixel,
|
||||||
|
@ -1142,7 +1100,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
|
||||||
|
|
||||||
glamor_set_normalize_vcoords((struct glamor_pixmap_private *) NULL,
|
glamor_set_normalize_vcoords((struct glamor_pixmap_private *) NULL,
|
||||||
temp_xscale, temp_yscale, 0, 0, w, h,
|
temp_xscale, temp_yscale, 0, 0, w, h,
|
||||||
glamor_priv->yInverted, vertices);
|
vertices);
|
||||||
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
|
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
|
||||||
2 * sizeof(float), vertices);
|
2 * sizeof(float), vertices);
|
||||||
|
@ -1153,7 +1111,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
|
||||||
source_yscale,
|
source_yscale,
|
||||||
x, y,
|
x, y,
|
||||||
x + w, y + h,
|
x + w, y + h,
|
||||||
glamor_priv->yInverted, texcoords);
|
texcoords);
|
||||||
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
|
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
|
||||||
2 * sizeof(float), texcoords);
|
2 * sizeof(float), texcoords);
|
||||||
|
@ -1176,330 +1134,6 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
|
||||||
return temp_fbo;
|
return temp_fbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Download a sub region of pixmap to a specified memory region.
|
|
||||||
* The pixmap must have a valid FBO, otherwise return a NULL.
|
|
||||||
* */
|
|
||||||
|
|
||||||
static void *
|
|
||||||
_glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
|
|
||||||
GLenum type, int no_alpha,
|
|
||||||
int revert, int swap_rb,
|
|
||||||
int x, int y, int w, int h,
|
|
||||||
int stride, void *bits, int pbo,
|
|
||||||
glamor_access_t access)
|
|
||||||
{
|
|
||||||
glamor_pixmap_private *pixmap_priv;
|
|
||||||
GLenum gl_access = 0, gl_usage = 0;
|
|
||||||
void *data, *read;
|
|
||||||
glamor_screen_private *glamor_priv =
|
|
||||||
glamor_get_screen_private(pixmap->drawable.pScreen);
|
|
||||||
glamor_pixmap_fbo *temp_fbo = NULL;
|
|
||||||
int need_post_conversion = 0;
|
|
||||||
int need_free_data = 0;
|
|
||||||
int fbo_x_off, fbo_y_off;
|
|
||||||
|
|
||||||
data = bits;
|
|
||||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
switch (access) {
|
|
||||||
case GLAMOR_ACCESS_RO:
|
|
||||||
gl_access = GL_READ_ONLY;
|
|
||||||
gl_usage = GL_STREAM_READ;
|
|
||||||
break;
|
|
||||||
case GLAMOR_ACCESS_RW:
|
|
||||||
gl_access = GL_READ_WRITE;
|
|
||||||
gl_usage = GL_DYNAMIC_DRAW;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ErrorF("Glamor: Invalid access code. %d\n", access);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
|
|
||||||
|
|
||||||
need_post_conversion = (revert > REVERT_NORMAL);
|
|
||||||
if (need_post_conversion) {
|
|
||||||
if (pixmap->drawable.depth == 1) {
|
|
||||||
int temp_stride;
|
|
||||||
|
|
||||||
temp_stride = (((w * 8 + 7) / 8) + 3) & ~3;
|
|
||||||
data = malloc(temp_stride * h);
|
|
||||||
if (data == NULL)
|
|
||||||
return NULL;
|
|
||||||
need_free_data = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
|
|
||||||
|
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
|
|
||||||
&& !need_post_conversion
|
|
||||||
&& (swap_rb != SWAP_NONE_DOWNLOADING || revert != REVERT_NONE)) {
|
|
||||||
if (!(temp_fbo = glamor_es2_pixmap_read_prepare(pixmap, x, y, w, h,
|
|
||||||
format, type, no_alpha,
|
|
||||||
revert, swap_rb))) {
|
|
||||||
free(data);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
fbo_x_off = 0;
|
|
||||||
fbo_y_off = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
|
||||||
|
|
||||||
if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
|
|
||||||
|
|
||||||
if (!glamor_priv->yInverted) {
|
|
||||||
assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
|
|
||||||
glPixelStorei(GL_PACK_INVERT_MESA, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && data == NULL) {
|
|
||||||
assert(pbo > 0);
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
|
|
||||||
glBufferData(GL_PIXEL_PACK_BUFFER, stride * h, NULL, gl_usage);
|
|
||||||
}
|
|
||||||
|
|
||||||
glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, data);
|
|
||||||
|
|
||||||
if (!glamor_priv->yInverted) {
|
|
||||||
assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
|
|
||||||
glPixelStorei(GL_PACK_INVERT_MESA, 0);
|
|
||||||
}
|
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && bits == NULL) {
|
|
||||||
bits = glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access);
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
unsigned int temp_pbo;
|
|
||||||
int yy;
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
glGenBuffers(1, &temp_pbo);
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, temp_pbo);
|
|
||||||
glBufferData(GL_PIXEL_PACK_BUFFER, stride * h, NULL, GL_STREAM_READ);
|
|
||||||
glReadPixels(x + fbo_x_off, y + fbo_y_off, w, h, format, type, 0);
|
|
||||||
read = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
|
|
||||||
for (yy = 0; yy < pixmap->drawable.height; yy++)
|
|
||||||
memcpy((char *) data + yy * stride,
|
|
||||||
(char *) read + (h - yy - 1) * stride, stride);
|
|
||||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
|
||||||
glDeleteBuffers(1, &temp_pbo);
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
|
|
||||||
if (need_post_conversion) {
|
|
||||||
/* As OpenGL desktop version never enters here.
|
|
||||||
* Don't need to consider if the pbo is valid.*/
|
|
||||||
bits = glamor_color_convert_to_bits(data, bits,
|
|
||||||
w, h,
|
|
||||||
stride, no_alpha, revert, swap_rb);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (temp_fbo != NULL)
|
|
||||||
glamor_destroy_fbo(temp_fbo);
|
|
||||||
if (need_free_data)
|
|
||||||
free(data);
|
|
||||||
|
|
||||||
return bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
|
|
||||||
int stride, void *bits, int pbo,
|
|
||||||
glamor_access_t access)
|
|
||||||
{
|
|
||||||
GLenum format, type;
|
|
||||||
int no_alpha, revert, swap_rb;
|
|
||||||
glamor_pixmap_private *pixmap_priv;
|
|
||||||
Bool force_clip;
|
|
||||||
|
|
||||||
if (glamor_get_tex_format_type_from_pixmap(pixmap,
|
|
||||||
&format,
|
|
||||||
&type,
|
|
||||||
&no_alpha,
|
|
||||||
&revert, &swap_rb, 0)) {
|
|
||||||
glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
force_clip = pixmap_priv->base.glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
|
|
||||||
&& !glamor_check_fbo_size(pixmap_priv->base.glamor_priv, w, h);
|
|
||||||
|
|
||||||
if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE || force_clip) {
|
|
||||||
|
|
||||||
RegionRec region;
|
|
||||||
BoxRec box;
|
|
||||||
int n_region;
|
|
||||||
glamor_pixmap_clipped_regions *clipped_regions;
|
|
||||||
void *sub_bits;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
sub_bits = malloc(h * stride);
|
|
||||||
if (sub_bits == NULL)
|
|
||||||
return FALSE;
|
|
||||||
box.x1 = x;
|
|
||||||
box.y1 = y;
|
|
||||||
box.x2 = x + w;
|
|
||||||
box.y2 = y + h;
|
|
||||||
RegionInitBoxes(®ion, &box, 1);
|
|
||||||
|
|
||||||
if (!force_clip)
|
|
||||||
clipped_regions =
|
|
||||||
glamor_compute_clipped_regions(pixmap_priv, ®ion, &n_region,
|
|
||||||
0, 0, 0);
|
|
||||||
else
|
|
||||||
clipped_regions =
|
|
||||||
glamor_compute_clipped_regions_ext(pixmap_priv, ®ion,
|
|
||||||
&n_region,
|
|
||||||
pixmap_priv->large.block_w,
|
|
||||||
pixmap_priv->large.block_h,
|
|
||||||
0,
|
|
||||||
0);
|
|
||||||
|
|
||||||
DEBUGF("start download large pixmap %p %dx%d \n", pixmap, w, h);
|
|
||||||
for (i = 0; i < n_region; i++) {
|
|
||||||
BoxPtr boxes;
|
|
||||||
int nbox;
|
|
||||||
int temp_stride;
|
|
||||||
void *temp_bits;
|
|
||||||
|
|
||||||
assert(pbo == 0);
|
|
||||||
SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
|
|
||||||
|
|
||||||
boxes = RegionRects(clipped_regions[i].region);
|
|
||||||
nbox = RegionNumRects(clipped_regions[i].region);
|
|
||||||
for (j = 0; j < nbox; j++) {
|
|
||||||
temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
|
|
||||||
pixmap->drawable.depth);
|
|
||||||
|
|
||||||
if (boxes[j].x1 == x && temp_stride == stride) {
|
|
||||||
temp_bits = (char *) bits + (boxes[j].y1 - y) * stride;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
temp_bits = sub_bits;
|
|
||||||
}
|
|
||||||
DEBUGF("download x %d y %d w %d h %d temp stride %d \n",
|
|
||||||
boxes[j].x1, boxes[j].y1,
|
|
||||||
boxes[j].x2 - boxes[j].x1,
|
|
||||||
boxes[j].y2 - boxes[j].y1, temp_stride);
|
|
||||||
|
|
||||||
/* For large pixmap, we don't support pbo currently. */
|
|
||||||
assert(pbo == 0);
|
|
||||||
if (_glamor_download_sub_pixmap_to_cpu
|
|
||||||
(pixmap, format, type, no_alpha, revert, swap_rb,
|
|
||||||
boxes[j].x1, boxes[j].y1, boxes[j].x2 - boxes[j].x1,
|
|
||||||
boxes[j].y2 - boxes[j].y1, temp_stride, temp_bits, pbo,
|
|
||||||
access) == FALSE) {
|
|
||||||
RegionUninit(®ion);
|
|
||||||
free(sub_bits);
|
|
||||||
assert(0);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (boxes[j].x1 != x || temp_stride != stride)
|
|
||||||
glamor_get_bits(bits, stride, temp_bits, temp_stride,
|
|
||||||
pixmap->drawable.bitsPerPixel,
|
|
||||||
boxes[j].x1 - x, boxes[j].y1 - y,
|
|
||||||
boxes[j].x2 - boxes[j].x1,
|
|
||||||
boxes[j].y2 - boxes[j].y1);
|
|
||||||
}
|
|
||||||
|
|
||||||
RegionDestroy(clipped_regions[i].region);
|
|
||||||
}
|
|
||||||
free(sub_bits);
|
|
||||||
free(clipped_regions);
|
|
||||||
RegionUninit(®ion);
|
|
||||||
return bits;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return _glamor_download_sub_pixmap_to_cpu(pixmap, format, type,
|
|
||||||
no_alpha, revert, swap_rb, x,
|
|
||||||
y, w, h, stride, bits, pbo,
|
|
||||||
access);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Move a pixmap to CPU memory.
|
|
||||||
* The input data is the pixmap's fbo.
|
|
||||||
* The output data is at pixmap->devPrivate.ptr. We always use pbo
|
|
||||||
* to read the fbo and then map it to va. If possible, we will use
|
|
||||||
* it directly as devPrivate.ptr.
|
|
||||||
* If successfully download a fbo to cpu then return TRUE.
|
|
||||||
* Otherwise return FALSE.
|
|
||||||
**/
|
|
||||||
Bool
|
|
||||||
glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
|
|
||||||
{
|
|
||||||
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
|
||||||
unsigned int stride;
|
|
||||||
void *data = NULL, *dst;
|
|
||||||
glamor_screen_private *glamor_priv =
|
|
||||||
glamor_get_screen_private(pixmap->drawable.pScreen);
|
|
||||||
int pbo = 0;
|
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
glamor_debug_output(GLAMOR_DEBUG_TEXTURE_DOWNLOAD,
|
|
||||||
"Downloading pixmap %p %dx%d depth%d\n",
|
|
||||||
pixmap,
|
|
||||||
pixmap->drawable.width,
|
|
||||||
pixmap->drawable.height, pixmap->drawable.depth);
|
|
||||||
|
|
||||||
stride = pixmap->devKind;
|
|
||||||
|
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
|
|
||||||
|| (!glamor_priv->has_pack_invert && !glamor_priv->yInverted)
|
|
||||||
|| pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
|
||||||
data = malloc(stride * pixmap->drawable.height);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
if (pixmap_priv->base.fbo->pbo == 0)
|
|
||||||
glGenBuffers(1, &pixmap_priv->base.fbo->pbo);
|
|
||||||
pbo = pixmap_priv->base.fbo->pbo;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pixmap_priv->type == GLAMOR_TEXTURE_DRM) {
|
|
||||||
stride = PixmapBytePad(pixmap->drawable.width, pixmap->drawable.depth);
|
|
||||||
pixmap_priv->base.drm_stride = pixmap->devKind;
|
|
||||||
pixmap->devKind = stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
dst = glamor_download_sub_pixmap_to_cpu(pixmap, 0, 0,
|
|
||||||
pixmap->drawable.width,
|
|
||||||
pixmap->drawable.height,
|
|
||||||
pixmap->devKind, data, pbo, access);
|
|
||||||
|
|
||||||
if (!dst) {
|
|
||||||
if (data)
|
|
||||||
free(data);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pbo != 0)
|
|
||||||
pixmap_priv->base.fbo->pbo_valid = 1;
|
|
||||||
|
|
||||||
pixmap_priv->base.gl_fbo = GLAMOR_FBO_DOWNLOADED;
|
|
||||||
|
|
||||||
pixmap->devPrivate.ptr = dst;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fixup a fbo to the exact size as the pixmap. */
|
/* fixup a fbo to the exact size as the pixmap. */
|
||||||
/* XXX LARGE pixmap? */
|
/* XXX LARGE pixmap? */
|
||||||
Bool
|
Bool
|
||||||
|
@ -1558,132 +1192,3 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* We may use this function to reduce a large pixmap to a small sub
|
|
||||||
* pixmap. Two scenarios currently:
|
|
||||||
* 1. When fallback a large textured pixmap to CPU but we do need to
|
|
||||||
* do rendering within a small sub region, then we can just get a
|
|
||||||
* sub region.
|
|
||||||
*
|
|
||||||
* 2. When uploading a large pixmap to texture but we only need to
|
|
||||||
* use part of the source/mask picture. As glTexImage2D will be more
|
|
||||||
* efficient to upload a contingent region rather than a sub block
|
|
||||||
* in a large buffer. We use this function to gather the sub region
|
|
||||||
* to a contingent sub pixmap.
|
|
||||||
*
|
|
||||||
* The sub-pixmap must have the same format as the source pixmap.
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
PixmapPtr
|
|
||||||
glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h,
|
|
||||||
glamor_access_t access)
|
|
||||||
{
|
|
||||||
glamor_screen_private *glamor_priv;
|
|
||||||
PixmapPtr sub_pixmap;
|
|
||||||
glamor_pixmap_private *sub_pixmap_priv, *pixmap_priv;
|
|
||||||
void *data;
|
|
||||||
int pbo;
|
|
||||||
int flag;
|
|
||||||
|
|
||||||
if (x < 0 || y < 0)
|
|
||||||
return NULL;
|
|
||||||
w = (x + w) > pixmap->drawable.width ? (pixmap->drawable.width - x) : w;
|
|
||||||
h = (y + h) > pixmap->drawable.height ? (pixmap->drawable.height - y) : h;
|
|
||||||
|
|
||||||
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
|
|
||||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
|
||||||
return NULL;
|
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 ||
|
|
||||||
pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
|
|
||||||
flag = GLAMOR_CREATE_PIXMAP_CPU;
|
|
||||||
else
|
|
||||||
flag = GLAMOR_CREATE_PIXMAP_MAP;
|
|
||||||
|
|
||||||
sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
|
|
||||||
pixmap->drawable.depth, flag);
|
|
||||||
|
|
||||||
if (sub_pixmap == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
|
|
||||||
pbo =
|
|
||||||
sub_pixmap_priv ? (sub_pixmap_priv->base.fbo ? sub_pixmap_priv->base.
|
|
||||||
fbo->pbo : 0) : 0;
|
|
||||||
|
|
||||||
if (pixmap_priv->base.is_picture) {
|
|
||||||
sub_pixmap_priv->base.picture = pixmap_priv->base.picture;
|
|
||||||
sub_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pbo)
|
|
||||||
data = NULL;
|
|
||||||
else
|
|
||||||
data = sub_pixmap->devPrivate.ptr;
|
|
||||||
|
|
||||||
data =
|
|
||||||
glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h,
|
|
||||||
sub_pixmap->devKind, data, pbo,
|
|
||||||
access);
|
|
||||||
if (data == NULL) {
|
|
||||||
fbDestroyPixmap(sub_pixmap);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (pbo) {
|
|
||||||
assert(sub_pixmap->devPrivate.ptr == NULL);
|
|
||||||
sub_pixmap->devPrivate.ptr = data;
|
|
||||||
sub_pixmap_priv->base.fbo->pbo_valid = 1;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
struct pixman_box16 box;
|
|
||||||
PixmapPtr new_sub_pixmap;
|
|
||||||
int dx, dy;
|
|
||||||
|
|
||||||
box.x1 = 0;
|
|
||||||
box.y1 = 0;
|
|
||||||
box.x2 = w;
|
|
||||||
box.y2 = h;
|
|
||||||
|
|
||||||
dx = x;
|
|
||||||
dy = y;
|
|
||||||
|
|
||||||
new_sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h,
|
|
||||||
pixmap->drawable.depth,
|
|
||||||
GLAMOR_CREATE_PIXMAP_CPU);
|
|
||||||
glamor_copy_n_to_n(&pixmap->drawable, &new_sub_pixmap->drawable, NULL, &box,
|
|
||||||
1, dx, dy, 0, 0, 0, NULL);
|
|
||||||
glamor_compare_pixmaps(new_sub_pixmap, sub_pixmap, 0, 0, w, h, 1, 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return sub_pixmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
|
|
||||||
int w, int h, glamor_access_t access)
|
|
||||||
{
|
|
||||||
void *bits;
|
|
||||||
int pbo;
|
|
||||||
glamor_pixmap_private *sub_pixmap_priv;
|
|
||||||
|
|
||||||
if (access != GLAMOR_ACCESS_RO) {
|
|
||||||
sub_pixmap_priv = glamor_get_pixmap_private(sub_pixmap);
|
|
||||||
if (sub_pixmap_priv->base.fbo && sub_pixmap_priv->base.fbo->pbo_valid) {
|
|
||||||
bits = NULL;
|
|
||||||
pbo = sub_pixmap_priv->base.fbo->pbo;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bits = sub_pixmap->devPrivate.ptr;
|
|
||||||
pbo = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(x >= 0 && y >= 0);
|
|
||||||
w = (w > sub_pixmap->drawable.width) ? sub_pixmap->drawable.width : w;
|
|
||||||
h = (h > sub_pixmap->drawable.height) ? sub_pixmap->drawable.height : h;
|
|
||||||
glamor_upload_sub_pixmap_to_texture(pixmap, x, y, w, h,
|
|
||||||
sub_pixmap->devKind, bits, pbo);
|
|
||||||
}
|
|
||||||
glamor_destroy_pixmap(sub_pixmap);
|
|
||||||
}
|
|
||||||
|
|
|
@ -105,9 +105,6 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
|
||||||
glDisable(GL_COLOR_LOGIC_OP);
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
|
|
||||||
glamor_priv->state = RENDER_STATE;
|
|
||||||
glamor_priv->render_idle_cnt = 0;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
bail_ctx:
|
bail_ctx:
|
||||||
|
|
|
@ -1,136 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright © 2009 Intel Corporation
|
|
||||||
* Copyright © 1998 Keith Packard
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the next
|
|
||||||
* paragraph) shall be included in all copies or substantial portions of the
|
|
||||||
* Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
* IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Eric Anholt <eric@anholt.net>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "glamor_priv.h"
|
|
||||||
|
|
||||||
/** @file glamor_polylines.c
|
|
||||||
*
|
|
||||||
* GC PolyFillRect implementation, taken straight from fb_fill.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* glamor_poly_lines() checks if it can accelerate the lines as a group of
|
|
||||||
* horizontal or vertical lines (rectangles), and uses existing rectangle fill
|
|
||||||
* acceleration if so.
|
|
||||||
*/
|
|
||||||
static Bool
|
|
||||||
_glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
|
|
||||||
DDXPointPtr points, Bool fallback)
|
|
||||||
{
|
|
||||||
xRectangle *rects;
|
|
||||||
int x1, x2, y1, y2;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Don't try to do wide lines or non-solid fill style. */
|
|
||||||
if (gc->lineWidth != 0) {
|
|
||||||
/* This ends up in miSetSpans, which is accelerated as well as we
|
|
||||||
* can hope X wide lines will be.
|
|
||||||
*/
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gc->lineStyle != LineSolid) {
|
|
||||||
glamor_fallback("non-solid fill line style %d\n", gc->lineStyle);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
rects = malloc(sizeof(xRectangle) * (n - 1));
|
|
||||||
x1 = points[0].x;
|
|
||||||
y1 = points[0].y;
|
|
||||||
/* If we have any non-horizontal/vertical, fall back. */
|
|
||||||
for (i = 0; i < n - 1; i++) {
|
|
||||||
if (mode == CoordModePrevious) {
|
|
||||||
x2 = x1 + points[i + 1].x;
|
|
||||||
y2 = y1 + points[i + 1].y;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
x2 = points[i + 1].x;
|
|
||||||
y2 = points[i + 1].y;
|
|
||||||
}
|
|
||||||
if (x1 != x2 && y1 != y2) {
|
|
||||||
free(rects);
|
|
||||||
glamor_fallback("stub diagonal poly_line\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if (x1 < x2) {
|
|
||||||
rects[i].x = x1;
|
|
||||||
rects[i].width = x2 - x1 + 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rects[i].x = x2;
|
|
||||||
rects[i].width = x1 - x2 + 1;
|
|
||||||
}
|
|
||||||
if (y1 < y2) {
|
|
||||||
rects[i].y = y1;
|
|
||||||
rects[i].height = y2 - y1 + 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rects[i].y = y2;
|
|
||||||
rects[i].height = y1 - y2 + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
x1 = x2;
|
|
||||||
y1 = y2;
|
|
||||||
}
|
|
||||||
gc->ops->PolyFillRect(drawable, gc, n - 1, rects);
|
|
||||||
free(rects);
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
if (!fallback && glamor_ddx_fallback_check_pixmap(drawable)
|
|
||||||
&& glamor_ddx_fallback_check_gc(gc))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
switch (gc->lineStyle) {
|
|
||||||
case LineSolid:
|
|
||||||
if (gc->lineWidth == 0)
|
|
||||||
miZeroLine(drawable, gc, mode, n, points);
|
|
||||||
else
|
|
||||||
miWideLine(drawable, gc, mode, n, points);
|
|
||||||
break;
|
|
||||||
case LineOnOffDash:
|
|
||||||
case LineDoubleDash:
|
|
||||||
miWideDash(drawable, gc, mode, n, points);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
|
|
||||||
DDXPointPtr points)
|
|
||||||
{
|
|
||||||
_glamor_poly_lines(drawable, gc, mode, n, points, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bool
|
|
||||||
glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc, int mode, int n,
|
|
||||||
DDXPointPtr points)
|
|
||||||
{
|
|
||||||
return _glamor_poly_lines(drawable, gc, mode, n, points, FALSE);
|
|
||||||
}
|
|
274
glamor/glamor_prepare.c
Normal file
274
glamor/glamor_prepare.c
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
/*
|
||||||
|
* 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_prepare.h"
|
||||||
|
#include "glamor_transfer.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make a pixmap ready to draw with fb by
|
||||||
|
* creating a PBO large enough for the whole object
|
||||||
|
* and downloading all of the FBOs into it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
int gl_access, gl_usage;
|
||||||
|
RegionRec region;
|
||||||
|
|
||||||
|
if (priv->type == GLAMOR_DRM_ONLY)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
RegionInit(®ion, box, 1);
|
||||||
|
|
||||||
|
/* See if it's already mapped */
|
||||||
|
if (pixmap->devPrivate.ptr) {
|
||||||
|
/*
|
||||||
|
* Someone else has mapped this pixmap;
|
||||||
|
* we'll assume that it's directly mapped
|
||||||
|
* by a lower level driver
|
||||||
|
*/
|
||||||
|
if (!priv->base.prepared)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* In X, multiple Drawables can be stored in the same Pixmap (such as
|
||||||
|
* each individual window in a non-composited screen pixmap, or the
|
||||||
|
* reparented window contents inside the window-manager-decorated window
|
||||||
|
* pixmap on a composited screen).
|
||||||
|
*
|
||||||
|
* As a result, when doing a series of mappings for a fallback, we may
|
||||||
|
* need to add more boxes to the set of data we've downloaded, as we go.
|
||||||
|
*/
|
||||||
|
RegionSubtract(®ion, ®ion, &priv->base.prepare_region);
|
||||||
|
if (!RegionNotEmpty(®ion))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (access == GLAMOR_ACCESS_RW)
|
||||||
|
FatalError("attempt to remap buffer as writable");
|
||||||
|
|
||||||
|
if (priv->base.pbo) {
|
||||||
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo);
|
||||||
|
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||||
|
pixmap->devPrivate.ptr = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
RegionInit(&priv->base.prepare_region, box, 1);
|
||||||
|
|
||||||
|
if (glamor_priv->has_rw_pbo) {
|
||||||
|
if (priv->base.pbo == 0)
|
||||||
|
glGenBuffers(1, &priv->base.pbo);
|
||||||
|
|
||||||
|
if (access == GLAMOR_ACCESS_RW)
|
||||||
|
gl_usage = GL_DYNAMIC_DRAW;
|
||||||
|
else
|
||||||
|
gl_usage = GL_STREAM_READ;
|
||||||
|
|
||||||
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo);
|
||||||
|
glBufferData(GL_PIXEL_PACK_BUFFER,
|
||||||
|
pixmap->devKind * pixmap->drawable.height, NULL,
|
||||||
|
gl_usage);
|
||||||
|
} else {
|
||||||
|
pixmap->devPrivate.ptr = malloc(pixmap->devKind *
|
||||||
|
pixmap->drawable.height);
|
||||||
|
if (!pixmap->devPrivate.ptr)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
priv->base.map_access = access;
|
||||||
|
}
|
||||||
|
|
||||||
|
glamor_download_boxes(pixmap, RegionRects(®ion), RegionNumRects(®ion),
|
||||||
|
0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind);
|
||||||
|
|
||||||
|
RegionUninit(®ion);
|
||||||
|
|
||||||
|
if (glamor_priv->has_rw_pbo) {
|
||||||
|
if (priv->base.map_access == GLAMOR_ACCESS_RW)
|
||||||
|
gl_access = GL_READ_WRITE;
|
||||||
|
else
|
||||||
|
gl_access = GL_READ_ONLY;
|
||||||
|
|
||||||
|
pixmap->devPrivate.ptr = glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access);
|
||||||
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->base.prepared = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When we're done with the drawable, unmap the PBO, reupload
|
||||||
|
* if we were writing to it and then unbind it to release the memory
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
glamor_fini_pixmap(PixmapPtr pixmap)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
|
||||||
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!priv->base.prepared)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (glamor_priv->has_rw_pbo) {
|
||||||
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->base.pbo);
|
||||||
|
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||||
|
pixmap->devPrivate.ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->base.map_access == GLAMOR_ACCESS_RW) {
|
||||||
|
glamor_upload_boxes(pixmap,
|
||||||
|
RegionRects(&priv->base.prepare_region),
|
||||||
|
RegionNumRects(&priv->base.prepare_region),
|
||||||
|
0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionUninit(&priv->base.prepare_region);
|
||||||
|
|
||||||
|
if (glamor_priv->has_rw_pbo) {
|
||||||
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
|
glDeleteBuffers(1, &priv->base.pbo);
|
||||||
|
priv->base.pbo = 0;
|
||||||
|
} else {
|
||||||
|
free(pixmap->devPrivate.ptr);
|
||||||
|
pixmap->devPrivate.ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->base.prepared = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
|
||||||
|
{
|
||||||
|
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||||
|
BoxRec box;
|
||||||
|
int off_x, off_y;
|
||||||
|
|
||||||
|
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
|
||||||
|
|
||||||
|
box.x1 = drawable->x + off_x;
|
||||||
|
box.x2 = box.x1 + drawable->width;
|
||||||
|
box.y1 = drawable->y + off_y;
|
||||||
|
box.y2 = box.y1 + drawable->height;
|
||||||
|
return glamor_prep_pixmap_box(pixmap, access, &box);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_prepare_access_box(DrawablePtr drawable, glamor_access_t access,
|
||||||
|
int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||||
|
BoxRec box;
|
||||||
|
int off_x, off_y;
|
||||||
|
|
||||||
|
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
|
||||||
|
box.x1 = drawable->x + x + off_x;
|
||||||
|
box.x2 = box.x1 + w;
|
||||||
|
box.y1 = drawable->y + y + off_y;
|
||||||
|
box.y2 = box.y1 + h;
|
||||||
|
return glamor_prep_pixmap_box(pixmap, access, &box);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_finish_access(DrawablePtr drawable)
|
||||||
|
{
|
||||||
|
glamor_fini_pixmap(glamor_get_drawable_pixmap(drawable));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make a picture ready to use with fb.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access)
|
||||||
|
{
|
||||||
|
if (!picture || !picture->pDrawable)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return glamor_prepare_access(picture->pDrawable, access);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_prepare_access_picture_box(PicturePtr picture, glamor_access_t access,
|
||||||
|
int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
if (!picture || !picture->pDrawable)
|
||||||
|
return TRUE;
|
||||||
|
return glamor_prepare_access_box(picture->pDrawable, access,
|
||||||
|
x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_finish_access_picture(PicturePtr picture)
|
||||||
|
{
|
||||||
|
if (!picture || !picture->pDrawable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glamor_finish_access(picture->pDrawable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make a GC ready to use with fb. This just
|
||||||
|
* means making sure the appropriate fill pixmap is
|
||||||
|
* in CPU memory again
|
||||||
|
*/
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_prepare_access_gc(GCPtr gc)
|
||||||
|
{
|
||||||
|
switch (gc->fillStyle) {
|
||||||
|
case FillTiled:
|
||||||
|
return glamor_prepare_access(&gc->tile.pixmap->drawable,
|
||||||
|
GLAMOR_ACCESS_RO);
|
||||||
|
case FillStippled:
|
||||||
|
case FillOpaqueStippled:
|
||||||
|
return glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free any temporary CPU pixmaps for the GC
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
glamor_finish_access_gc(GCPtr gc)
|
||||||
|
{
|
||||||
|
switch (gc->fillStyle) {
|
||||||
|
case FillTiled:
|
||||||
|
glamor_finish_access(&gc->tile.pixmap->drawable);
|
||||||
|
break;
|
||||||
|
case FillStippled:
|
||||||
|
case FillOpaqueStippled:
|
||||||
|
glamor_finish_access(&gc->stipple->drawable);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,25 +20,33 @@
|
||||||
* OF THIS SOFTWARE.
|
* OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "glamor_priv.h"
|
#ifndef _GLAMOR_PREPARE_H_
|
||||||
|
#define _GLAMOR_PREPARE_H_
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
glamor_poly_segment_nf(DrawablePtr drawable, GCPtr gc, int nseg,
|
glamor_prepare_access(DrawablePtr drawable, glamor_access_t access);
|
||||||
xSegment *seg)
|
|
||||||
{
|
|
||||||
if (glamor_ddx_fallback_check_pixmap(drawable) &&
|
|
||||||
glamor_ddx_fallback_check_gc(gc)) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
miPolySegment(drawable, gc, nseg, seg);
|
Bool
|
||||||
|
glamor_prepare_access_box(DrawablePtr drawable, glamor_access_t access,
|
||||||
return TRUE;
|
int x, int y, int w, int h);
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
glamor_poly_segment(DrawablePtr drawable, GCPtr gc, int nseg,
|
glamor_finish_access(DrawablePtr drawable);
|
||||||
xSegment *seg)
|
|
||||||
{
|
Bool
|
||||||
miPolySegment(drawable, gc, nseg, seg);
|
glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access);
|
||||||
}
|
|
||||||
|
Bool
|
||||||
|
glamor_prepare_access_picture_box(PicturePtr picture, glamor_access_t access,
|
||||||
|
int x, int y, int w, int h);
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_finish_access_picture(PicturePtr picture);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_prepare_access_gc(GCPtr gc);
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_finish_access_gc(GCPtr gc);
|
||||||
|
|
||||||
|
#endif /* _GLAMOR_PREPARE_H_ */
|
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
#include <xorg-server.h>
|
#include <xorg-server.h>
|
||||||
#include "glamor.h"
|
#include "glamor.h"
|
||||||
|
#include "xvdix.h"
|
||||||
|
|
||||||
#include <epoxy/gl.h>
|
#include <epoxy/gl.h>
|
||||||
#if GLAMOR_HAS_GBM
|
#if GLAMOR_HAS_GBM
|
||||||
|
@ -193,13 +194,7 @@ struct glamor_saved_procs {
|
||||||
#define GLAMOR_TICK_AFTER(t0, t1) \
|
#define GLAMOR_TICK_AFTER(t0, t1) \
|
||||||
(((int)(t1) - (int)(t0)) < 0)
|
(((int)(t1) - (int)(t0)) < 0)
|
||||||
|
|
||||||
#define IDLE_STATE 0
|
|
||||||
#define RENDER_STATE 1
|
|
||||||
#define BLIT_STATE 2
|
|
||||||
#define RENDER_IDEL_MAX 32
|
|
||||||
|
|
||||||
typedef struct glamor_screen_private {
|
typedef struct glamor_screen_private {
|
||||||
Bool yInverted;
|
|
||||||
unsigned int tick;
|
unsigned int tick;
|
||||||
enum glamor_gl_flavor gl_flavor;
|
enum glamor_gl_flavor gl_flavor;
|
||||||
int glsl_version;
|
int glsl_version;
|
||||||
|
@ -208,16 +203,14 @@ typedef struct glamor_screen_private {
|
||||||
int has_map_buffer_range;
|
int has_map_buffer_range;
|
||||||
int has_buffer_storage;
|
int has_buffer_storage;
|
||||||
int has_khr_debug;
|
int has_khr_debug;
|
||||||
|
int has_nv_texture_barrier;
|
||||||
int max_fbo_size;
|
int max_fbo_size;
|
||||||
|
int has_rw_pbo;
|
||||||
|
|
||||||
struct xorg_list
|
struct xorg_list
|
||||||
fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
|
fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
|
||||||
unsigned long fbo_cache_watermark;
|
unsigned long fbo_cache_watermark;
|
||||||
|
|
||||||
/* glamor_solid */
|
|
||||||
GLint solid_prog;
|
|
||||||
GLint solid_color_uniform_location;
|
|
||||||
|
|
||||||
/* glamor point shader */
|
/* glamor point shader */
|
||||||
glamor_program point_prog;
|
glamor_program point_prog;
|
||||||
|
|
||||||
|
@ -235,6 +228,20 @@ typedef struct glamor_screen_private {
|
||||||
glamor_program te_text_prog;
|
glamor_program te_text_prog;
|
||||||
glamor_program image_text_prog;
|
glamor_program image_text_prog;
|
||||||
|
|
||||||
|
/* glamor copy shaders */
|
||||||
|
glamor_program copy_area_prog;
|
||||||
|
glamor_program copy_plane_prog;
|
||||||
|
|
||||||
|
/* glamor line shader */
|
||||||
|
glamor_program_fill poly_line_program;
|
||||||
|
|
||||||
|
/* glamor segment shaders */
|
||||||
|
glamor_program_fill poly_segment_program;
|
||||||
|
|
||||||
|
/* glamor dash line shader */
|
||||||
|
glamor_program_fill on_off_dash_line_progs;
|
||||||
|
glamor_program double_dash_line_prog;
|
||||||
|
|
||||||
/* vertext/elment_index buffer object for render */
|
/* vertext/elment_index buffer object for render */
|
||||||
GLuint vbo, ebo;
|
GLuint vbo, ebo;
|
||||||
/** Next offset within the VBO that glamor_get_vbo_space() will use. */
|
/** Next offset within the VBO that glamor_get_vbo_space() will use. */
|
||||||
|
@ -261,10 +268,6 @@ typedef struct glamor_screen_private {
|
||||||
GLint finish_access_revert[2];
|
GLint finish_access_revert[2];
|
||||||
GLint finish_access_swap_rb[2];
|
GLint finish_access_swap_rb[2];
|
||||||
|
|
||||||
/* glamor_tile */
|
|
||||||
GLint tile_prog;
|
|
||||||
GLint tile_wh;
|
|
||||||
|
|
||||||
/* glamor gradient, 0 for small nstops, 1 for
|
/* glamor gradient, 0 for small nstops, 1 for
|
||||||
large nstops and 2 for dynamic generate. */
|
large nstops and 2 for dynamic generate. */
|
||||||
GLint gradient_prog[SHADER_GRADIENT_COUNT][3];
|
GLint gradient_prog[SHADER_GRADIENT_COUNT][3];
|
||||||
|
@ -280,8 +283,6 @@ typedef struct glamor_screen_private {
|
||||||
char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
|
char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
|
||||||
int delayed_fallback_pending;
|
int delayed_fallback_pending;
|
||||||
int flags;
|
int flags;
|
||||||
int state;
|
|
||||||
unsigned int render_idle_cnt;
|
|
||||||
ScreenPtr screen;
|
ScreenPtr screen;
|
||||||
int dri3_enabled;
|
int dri3_enabled;
|
||||||
|
|
||||||
|
@ -430,6 +431,9 @@ typedef struct glamor_pixmap_private_base {
|
||||||
int drm_stride;
|
int drm_stride;
|
||||||
glamor_screen_private *glamor_priv;
|
glamor_screen_private *glamor_priv;
|
||||||
PicturePtr picture;
|
PicturePtr picture;
|
||||||
|
GLuint pbo;
|
||||||
|
RegionRec prepare_region;
|
||||||
|
Bool prepared;
|
||||||
#if GLAMOR_HAS_GBM
|
#if GLAMOR_HAS_GBM
|
||||||
EGLImageKHR image;
|
EGLImageKHR image;
|
||||||
#endif
|
#endif
|
||||||
|
@ -544,19 +548,29 @@ typedef enum glamor_pixmap_status {
|
||||||
GLAMOR_UPLOAD_FAILED
|
GLAMOR_UPLOAD_FAILED
|
||||||
} glamor_pixmap_status_t;
|
} glamor_pixmap_status_t;
|
||||||
|
|
||||||
extern DevPrivateKey glamor_screen_private_key;
|
/* GC private structure. Currently holds only any computed dash pixmap */
|
||||||
extern DevPrivateKey glamor_pixmap_private_key;
|
|
||||||
|
typedef struct {
|
||||||
|
PixmapPtr dash;
|
||||||
|
PixmapPtr stipple;
|
||||||
|
DamagePtr stipple_damage;
|
||||||
|
} glamor_gc_private;
|
||||||
|
|
||||||
|
extern DevPrivateKeyRec glamor_gc_private_key;
|
||||||
|
extern DevPrivateKeyRec glamor_screen_private_key;
|
||||||
|
extern DevPrivateKeyRec glamor_pixmap_private_key;
|
||||||
|
|
||||||
static inline glamor_screen_private *
|
static inline glamor_screen_private *
|
||||||
glamor_get_screen_private(ScreenPtr screen)
|
glamor_get_screen_private(ScreenPtr screen)
|
||||||
{
|
{
|
||||||
return (glamor_screen_private *)
|
return (glamor_screen_private *)
|
||||||
dixLookupPrivate(&screen->devPrivates, glamor_screen_private_key);
|
dixLookupPrivate(&screen->devPrivates, &glamor_screen_private_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv)
|
glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv)
|
||||||
{
|
{
|
||||||
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, priv);
|
dixSetPrivate(&screen->devPrivates, &glamor_screen_private_key, priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline glamor_pixmap_private *
|
static inline glamor_pixmap_private *
|
||||||
|
@ -564,17 +578,23 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
|
||||||
{
|
{
|
||||||
glamor_pixmap_private *priv;
|
glamor_pixmap_private *priv;
|
||||||
|
|
||||||
priv = dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
|
priv = dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
|
||||||
if (!priv) {
|
if (!priv) {
|
||||||
glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
|
glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
|
||||||
priv = dixLookupPrivate(&pixmap->devPrivates,
|
priv = dixLookupPrivate(&pixmap->devPrivates,
|
||||||
glamor_pixmap_private_key);
|
&glamor_pixmap_private_key);
|
||||||
}
|
}
|
||||||
return priv;
|
return priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
|
void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
|
||||||
|
|
||||||
|
static inline glamor_gc_private *
|
||||||
|
glamor_get_gc_private(GCPtr gc)
|
||||||
|
{
|
||||||
|
return dixLookupPrivate(&gc->devPrivates, &glamor_gc_private_key);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns TRUE if the given planemask covers all the significant bits in the
|
* Returns TRUE if the given planemask covers all the significant bits in the
|
||||||
* pixel values for pDrawable.
|
* pixel values for pDrawable.
|
||||||
|
@ -614,32 +634,13 @@ glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private *glamor_priv,
|
||||||
int flag, int block_w, int block_h,
|
int flag, int block_w, int block_h,
|
||||||
glamor_pixmap_private *);
|
glamor_pixmap_private *);
|
||||||
|
|
||||||
/* glamor_copyarea.c */
|
|
||||||
RegionPtr
|
|
||||||
|
|
||||||
glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
|
||||||
int srcx, int srcy, int width, int height, int dstx, int dsty);
|
|
||||||
void glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
|
||||||
BoxPtr box, int nbox, int dx, int dy, Bool reverse,
|
|
||||||
Bool upsidedown, Pixel bitplane, void *closure);
|
|
||||||
|
|
||||||
/* glamor_core.c */
|
/* glamor_core.c */
|
||||||
Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access);
|
|
||||||
void glamor_finish_access(DrawablePtr drawable);
|
|
||||||
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);
|
void glamor_init_finish_access_shaders(ScreenPtr screen);
|
||||||
void glamor_fini_finish_access_shaders(ScreenPtr screen);
|
void glamor_fini_finish_access_shaders(ScreenPtr screen);
|
||||||
|
|
||||||
const Bool glamor_get_drawable_location(const DrawablePtr drawable);
|
const Bool glamor_get_drawable_location(const DrawablePtr drawable);
|
||||||
void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
|
void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
|
||||||
int *x, int *y);
|
int *x, int *y);
|
||||||
Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
|
|
||||||
int x, int y, int width, int height,
|
|
||||||
unsigned char alu, unsigned long planemask,
|
|
||||||
unsigned long fg_pixel, unsigned long bg_pixel,
|
|
||||||
int stipple_x, int stipple_y);
|
|
||||||
GLint glamor_compile_glsl_prog(GLenum type, const char *source);
|
GLint glamor_compile_glsl_prog(GLenum type, const char *source);
|
||||||
void glamor_link_glsl_prog(ScreenPtr screen, GLint prog,
|
void glamor_link_glsl_prog(ScreenPtr screen, GLint prog,
|
||||||
const char *format, ...) _X_ATTRIBUTE_PRINTF(3,4);
|
const char *format, ...) _X_ATTRIBUTE_PRINTF(3,4);
|
||||||
|
@ -665,17 +666,8 @@ Bool glamor_set_alu(ScreenPtr screen, unsigned char alu);
|
||||||
Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
|
Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
|
||||||
RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
|
RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
|
||||||
|
|
||||||
/* glamor_fill.c */
|
void
|
||||||
Bool glamor_fill(DrawablePtr drawable,
|
glamor_track_stipple(GCPtr gc);
|
||||||
GCPtr gc, int x, int y, int width, int height, Bool fallback);
|
|
||||||
Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
|
||||||
unsigned char alu, unsigned long planemask,
|
|
||||||
unsigned long fg_pixel);
|
|
||||||
Bool glamor_solid_boxes(PixmapPtr pixmap,
|
|
||||||
BoxPtr box, int nbox, unsigned long fg_pixel);
|
|
||||||
|
|
||||||
void glamor_init_solid_shader(ScreenPtr screen);
|
|
||||||
void glamor_fini_solid_shader(ScreenPtr screen);
|
|
||||||
|
|
||||||
/* glamor_glyphs.c */
|
/* glamor_glyphs.c */
|
||||||
Bool glamor_realize_glyph_caches(ScreenPtr screen);
|
Bool glamor_realize_glyph_caches(ScreenPtr screen);
|
||||||
|
@ -687,10 +679,6 @@ void glamor_glyphs(CARD8 op,
|
||||||
INT16 xSrc,
|
INT16 xSrc,
|
||||||
INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs);
|
INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs);
|
||||||
|
|
||||||
/* glamor_polylines.c */
|
|
||||||
void glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
|
|
||||||
DDXPointPtr points);
|
|
||||||
|
|
||||||
/* glamor_render.c */
|
/* glamor_render.c */
|
||||||
Bool glamor_composite_clipped_region(CARD8 op,
|
Bool glamor_composite_clipped_region(CARD8 op,
|
||||||
PicturePtr source,
|
PicturePtr source,
|
||||||
|
@ -756,14 +744,6 @@ void glamor_trapezoids(CARD8 op,
|
||||||
PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
|
PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
|
||||||
int ntrap, xTrapezoid *traps);
|
int ntrap, xTrapezoid *traps);
|
||||||
|
|
||||||
/* glamor_tile.c */
|
|
||||||
Bool 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);
|
|
||||||
void glamor_init_tile_shader(ScreenPtr screen);
|
|
||||||
void glamor_fini_tile_shader(ScreenPtr screen);
|
|
||||||
|
|
||||||
/* glamor_gradient.c */
|
/* glamor_gradient.c */
|
||||||
void glamor_init_gradient_shader(ScreenPtr screen);
|
void glamor_init_gradient_shader(ScreenPtr screen);
|
||||||
void glamor_fini_gradient_shader(ScreenPtr screen);
|
void glamor_fini_gradient_shader(ScreenPtr screen);
|
||||||
|
@ -801,31 +781,6 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset);
|
||||||
void
|
void
|
||||||
glamor_put_vbo_space(ScreenPtr screen);
|
glamor_put_vbo_space(ScreenPtr screen);
|
||||||
|
|
||||||
/**
|
|
||||||
* Download a pixmap's texture to cpu memory. If success,
|
|
||||||
* One copy of current pixmap's texture will be put into
|
|
||||||
* the pixmap->devPrivate.ptr. Will use pbo to map to
|
|
||||||
* the pointer if possible.
|
|
||||||
* The pixmap must be a gl texture pixmap. gl_fbo must be GLAMOR_FBO_NORMAL and
|
|
||||||
* gl_tex must be 1. Used by glamor_prepare_access.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
Bool glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access);
|
|
||||||
|
|
||||||
void *glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w,
|
|
||||||
int h, int stride, void *bits, int pbo,
|
|
||||||
glamor_access_t access);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Restore a pixmap's data which is downloaded by
|
|
||||||
* glamor_download_pixmap_to_cpu to its original
|
|
||||||
* gl texture. Used by glamor_finish_access.
|
|
||||||
*
|
|
||||||
* The pixmap must originally be a texture -- gl_fbo must be
|
|
||||||
* GLAMOR_FBO_NORMAL.
|
|
||||||
**/
|
|
||||||
void glamor_restore_pixmap_to_texture(PixmapPtr pixmap);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* According to the flag,
|
* According to the flag,
|
||||||
* if the flag is GLAMOR_CREATE_FBO_NO_FBO then just ensure
|
* if the flag is GLAMOR_CREATE_FBO_NO_FBO then just ensure
|
||||||
|
@ -846,11 +801,6 @@ Bool glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
|
||||||
int h, int stride, void *bits,
|
int h, int stride, void *bits,
|
||||||
int pbo);
|
int pbo);
|
||||||
|
|
||||||
PixmapPtr glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y,
|
|
||||||
int w, int h, glamor_access_t access);
|
|
||||||
void glamor_put_sub_pixmap(PixmapPtr sub_pixmap, PixmapPtr pixmap, int x, int y,
|
|
||||||
int w, int h, glamor_access_t access);
|
|
||||||
|
|
||||||
glamor_pixmap_clipped_regions *
|
glamor_pixmap_clipped_regions *
|
||||||
glamor_compute_clipped_regions(glamor_pixmap_private *priv,
|
glamor_compute_clipped_regions(glamor_pixmap_private *priv,
|
||||||
RegionPtr region, int *clipped_nbox,
|
RegionPtr region, int *clipped_nbox,
|
||||||
|
@ -909,20 +859,10 @@ Bool glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
|
||||||
GLenum type, int no_alpha, int revert,
|
GLenum type, int no_alpha, int revert,
|
||||||
int swap_rb, void *bits);
|
int swap_rb, void *bits);
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy all the resources allocated on the uploading
|
|
||||||
* phase, includs the tex and fbo.
|
|
||||||
**/
|
|
||||||
void glamor_destroy_upload_pixmap(PixmapPtr pixmap);
|
|
||||||
|
|
||||||
int glamor_create_picture(PicturePtr picture);
|
int glamor_create_picture(PicturePtr picture);
|
||||||
|
|
||||||
void glamor_set_window_pixmap(WindowPtr pWindow, PixmapPtr pPixmap);
|
void glamor_set_window_pixmap(WindowPtr pWindow, PixmapPtr pPixmap);
|
||||||
|
|
||||||
Bool glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access);
|
|
||||||
|
|
||||||
void glamor_finish_access_picture(PicturePtr picture);
|
|
||||||
|
|
||||||
void glamor_destroy_picture(PicturePtr picture);
|
void glamor_destroy_picture(PicturePtr picture);
|
||||||
|
|
||||||
/* fixup a fbo to the exact size as the pixmap. */
|
/* fixup a fbo to the exact size as the pixmap. */
|
||||||
|
@ -935,11 +875,6 @@ void glamor_picture_format_fixup(PicturePtr picture,
|
||||||
void glamor_add_traps(PicturePtr pPicture,
|
void glamor_add_traps(PicturePtr pPicture,
|
||||||
INT16 x_off, INT16 y_off, int ntrap, xTrap *traps);
|
INT16 x_off, INT16 y_off, int ntrap, xTrap *traps);
|
||||||
|
|
||||||
RegionPtr glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
|
||||||
int srcx, int srcy, int w, int h,
|
|
||||||
int dstx, int dsty,
|
|
||||||
unsigned long bitPlane);
|
|
||||||
|
|
||||||
/* glamor_text.c */
|
/* glamor_text.c */
|
||||||
int glamor_poly_text8(DrawablePtr pDrawable, GCPtr pGC,
|
int glamor_poly_text8(DrawablePtr pDrawable, GCPtr pGC,
|
||||||
int x, int y, int count, char *chars);
|
int x, int y, int count, char *chars);
|
||||||
|
@ -981,6 +916,48 @@ void
|
||||||
glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
|
glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
|
||||||
unsigned int format, unsigned long planeMask, char *d);
|
unsigned int format, unsigned long planeMask, char *d);
|
||||||
|
|
||||||
|
/* glamor_dash.c */
|
||||||
|
Bool
|
||||||
|
glamor_poly_lines_dash_gl(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int mode, int n, DDXPointPtr points);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_poly_segment_dash_gl(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int nseg, xSegment *segs);
|
||||||
|
|
||||||
|
/* glamor_lines.c */
|
||||||
|
void
|
||||||
|
glamor_poly_lines(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int mode, int n, DDXPointPtr points);
|
||||||
|
|
||||||
|
/* glamor_segs.c */
|
||||||
|
void
|
||||||
|
glamor_poly_segment(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int nseg, xSegment *segs);
|
||||||
|
|
||||||
|
/* glamor_copy.c */
|
||||||
|
void
|
||||||
|
glamor_copy(DrawablePtr src,
|
||||||
|
DrawablePtr dst,
|
||||||
|
GCPtr gc,
|
||||||
|
BoxPtr box,
|
||||||
|
int nbox,
|
||||||
|
int dx,
|
||||||
|
int dy,
|
||||||
|
Bool reverse,
|
||||||
|
Bool upsidedown,
|
||||||
|
Pixel bitplane,
|
||||||
|
void *closure);
|
||||||
|
|
||||||
|
RegionPtr
|
||||||
|
glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||||
|
int srcx, int srcy, int width, int height, int dstx, int dsty);
|
||||||
|
|
||||||
|
RegionPtr
|
||||||
|
glamor_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||||
|
int srcx, int srcy, int width, int height, int dstx, int dsty,
|
||||||
|
unsigned long bitplane);
|
||||||
|
|
||||||
/* glamor_glyphblt.c */
|
/* glamor_glyphblt.c */
|
||||||
void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
|
void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
|
||||||
int x, int y, unsigned int nglyph,
|
int x, int y, unsigned int nglyph,
|
||||||
|
@ -996,17 +973,21 @@ void glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
|
||||||
void glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
|
void glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
|
||||||
DDXPointPtr ppt);
|
DDXPointPtr ppt);
|
||||||
|
|
||||||
void glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
|
|
||||||
xSegment *pSeg);
|
|
||||||
|
|
||||||
void glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
|
|
||||||
DDXPointPtr ppt);
|
|
||||||
|
|
||||||
void glamor_composite_rectangles(CARD8 op,
|
void glamor_composite_rectangles(CARD8 op,
|
||||||
PicturePtr dst,
|
PicturePtr dst,
|
||||||
xRenderColor *color,
|
xRenderColor *color,
|
||||||
int num_rects, xRectangle *rects);
|
int num_rects, xRectangle *rects);
|
||||||
|
|
||||||
|
/* glamor_util.c */
|
||||||
|
void
|
||||||
|
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||||
|
unsigned long fg_pixel);
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_solid_boxes(PixmapPtr pixmap,
|
||||||
|
BoxPtr box, int nbox, unsigned long fg_pixel);
|
||||||
|
|
||||||
|
|
||||||
/* glamor_xv */
|
/* glamor_xv */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t transform_index;
|
uint32_t transform_index;
|
||||||
|
@ -1028,8 +1009,34 @@ typedef struct {
|
||||||
int src_pix_w, src_pix_h;
|
int src_pix_w, src_pix_h;
|
||||||
} glamor_port_private;
|
} glamor_port_private;
|
||||||
|
|
||||||
void glamor_init_xv_shader(ScreenPtr screen);
|
extern XvAttributeRec glamor_xv_attributes[];
|
||||||
void glamor_fini_xv_shader(ScreenPtr screen);
|
extern int glamor_xv_num_attributes;
|
||||||
|
extern XvImageRec glamor_xv_images[];
|
||||||
|
extern int glamor_xv_num_images;
|
||||||
|
|
||||||
|
void glamor_xv_init_port(glamor_port_private *port_priv);
|
||||||
|
void glamor_xv_stop_video(glamor_port_private *port_priv);
|
||||||
|
int glamor_xv_set_port_attribute(glamor_port_private *port_priv,
|
||||||
|
Atom attribute, INT32 value);
|
||||||
|
int glamor_xv_get_port_attribute(glamor_port_private *port_priv,
|
||||||
|
Atom attribute, INT32 *value);
|
||||||
|
int glamor_xv_query_image_attributes(int id,
|
||||||
|
unsigned short *w, unsigned short *h,
|
||||||
|
int *pitches, int *offsets);
|
||||||
|
int glamor_xv_put_image(glamor_port_private *port_priv,
|
||||||
|
DrawablePtr pDrawable,
|
||||||
|
short src_x, short src_y,
|
||||||
|
short drw_x, short drw_y,
|
||||||
|
short src_w, short src_h,
|
||||||
|
short drw_w, short drw_h,
|
||||||
|
int id,
|
||||||
|
unsigned char *buf,
|
||||||
|
short width,
|
||||||
|
short height,
|
||||||
|
Bool sync,
|
||||||
|
RegionPtr clipBoxes);
|
||||||
|
void glamor_xv_core_init(ScreenPtr screen);
|
||||||
|
void glamor_xv_render(glamor_port_private *port_priv);
|
||||||
|
|
||||||
#include"glamor_utils.h"
|
#include"glamor_utils.h"
|
||||||
|
|
||||||
|
|
|
@ -51,42 +51,51 @@ static const glamor_facet glamor_fill_tile = {
|
||||||
.use = use_tile,
|
.use = use_tile,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
|
||||||
static Bool
|
static Bool
|
||||||
use_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog)
|
use_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
|
||||||
{
|
{
|
||||||
return glamor_set_stippled(pixmap, gc, prog->fg_uniform, prog->fill_offset_uniform, prog->fill_size_uniform);
|
return glamor_set_stippled(pixmap, gc, prog->fg_uniform,
|
||||||
|
prog->fill_offset_uniform,
|
||||||
|
prog->fill_size_uniform);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const glamor_facet glamor_fill_stipple = {
|
static const glamor_facet glamor_fill_stipple = {
|
||||||
.name = "stipple",
|
.name = "stipple",
|
||||||
.version = 130,
|
.vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
|
||||||
.vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n";
|
.fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n"
|
||||||
.fs_exec = (" if (texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0).x == 0)\n"
|
" if (a == 0.0)\n"
|
||||||
" discard;\n"
|
" discard;\n"
|
||||||
" gl_FragColor = fg;\n")
|
" gl_FragColor = fg;\n"),
|
||||||
.locations = glamor_program_location_fg | glamor_program_location_fill
|
.locations = glamor_program_location_fg | glamor_program_location_fill,
|
||||||
.use = use_stipple,
|
.use = use_stipple,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
use_opaque_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
|
||||||
|
{
|
||||||
|
if (!use_stipple(pixmap, gc, prog, arg))
|
||||||
|
return FALSE;
|
||||||
|
glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static const glamor_facet glamor_fill_opaque_stipple = {
|
static const glamor_facet glamor_fill_opaque_stipple = {
|
||||||
.name = "opaque_stipple",
|
.name = "opaque_stipple",
|
||||||
.version = 130,
|
.vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
|
||||||
.vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n";
|
.fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n"
|
||||||
.fs_exec = (" if (texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0).x == 0)\n"
|
" if (a == 0.0)\n"
|
||||||
" gl_FragColor = bg;\n"
|
" gl_FragColor = bg;\n"
|
||||||
" else\n"
|
" else\n"
|
||||||
" gl_FragColor = fg;\n"),
|
" gl_FragColor = fg;\n"),
|
||||||
.locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_fill
|
.locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_fill,
|
||||||
.use = use_opaque_stipple
|
.use = use_opaque_stipple
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
static const glamor_facet *glamor_facet_fill[4] = {
|
static const glamor_facet *glamor_facet_fill[4] = {
|
||||||
&glamor_fill_solid,
|
&glamor_fill_solid,
|
||||||
&glamor_fill_tile,
|
&glamor_fill_tile,
|
||||||
NULL,
|
&glamor_fill_stipple,
|
||||||
NULL,
|
&glamor_fill_opaque_stipple,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -117,6 +126,16 @@ static glamor_location_var location_vars[] = {
|
||||||
.location = glamor_program_location_font,
|
.location = glamor_program_location_font,
|
||||||
.fs_vars = "uniform usampler2D font;\n",
|
.fs_vars = "uniform usampler2D font;\n",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.location = glamor_program_location_bitplane,
|
||||||
|
.fs_vars = ("uniform uvec4 bitplane;\n"
|
||||||
|
"uniform vec4 bitmul;\n"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.location = glamor_program_location_dash,
|
||||||
|
.vs_vars = "uniform float dash_length;\n",
|
||||||
|
.fs_vars = "uniform sampler2D dash;\n",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_LOCATION_VARS (sizeof location_vars / sizeof location_vars[0])
|
#define NUM_LOCATION_VARS (sizeof location_vars / sizeof location_vars[0])
|
||||||
|
@ -196,6 +215,8 @@ static const glamor_facet facet_null_fill = {
|
||||||
.name = ""
|
.name = ""
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DBG 0
|
||||||
|
|
||||||
static GLint
|
static GLint
|
||||||
glamor_get_uniform(glamor_program *prog,
|
glamor_get_uniform(glamor_program *prog,
|
||||||
glamor_program_location location,
|
glamor_program_location location,
|
||||||
|
@ -281,7 +302,6 @@ glamor_build_program(ScreenPtr screen,
|
||||||
if (!vs_prog_string || !fs_prog_string)
|
if (!vs_prog_string || !fs_prog_string)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
#define DBG 0
|
|
||||||
#if DBG
|
#if DBG
|
||||||
ErrorF("\nPrograms for %s %s\nVertex shader:\n\n%s\n\nFragment Shader:\n\n%s",
|
ErrorF("\nPrograms for %s %s\nVertex shader:\n\n%s\n\nFragment Shader:\n\n%s",
|
||||||
prim->name, fill->name, vs_prog_string, fs_prog_string);
|
prim->name, fill->name, vs_prog_string, fs_prog_string);
|
||||||
|
@ -318,6 +338,10 @@ glamor_build_program(ScreenPtr screen,
|
||||||
prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_offset");
|
prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_offset");
|
||||||
prog->fill_size_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_size");
|
prog->fill_size_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_size");
|
||||||
prog->font_uniform = glamor_get_uniform(prog, glamor_program_location_font, "font");
|
prog->font_uniform = glamor_get_uniform(prog, glamor_program_location_font, "font");
|
||||||
|
prog->bitplane_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitplane");
|
||||||
|
prog->bitmul_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitmul");
|
||||||
|
prog->dash_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash");
|
||||||
|
prog->dash_length_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash_length");
|
||||||
|
|
||||||
if (glGetError() != GL_NO_ERROR)
|
if (glGetError() != GL_NO_ERROR)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
@ -29,6 +29,8 @@ typedef enum {
|
||||||
glamor_program_location_bg = 2,
|
glamor_program_location_bg = 2,
|
||||||
glamor_program_location_fill = 4,
|
glamor_program_location_fill = 4,
|
||||||
glamor_program_location_font = 8,
|
glamor_program_location_font = 8,
|
||||||
|
glamor_program_location_bitplane = 16,
|
||||||
|
glamor_program_location_dash = 32,
|
||||||
} glamor_program_location;
|
} glamor_program_location;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -61,6 +63,10 @@ struct _glamor_program {
|
||||||
GLint fill_size_uniform;
|
GLint fill_size_uniform;
|
||||||
GLint fill_offset_uniform;
|
GLint fill_offset_uniform;
|
||||||
GLint font_uniform;
|
GLint font_uniform;
|
||||||
|
GLint bitplane_uniform;
|
||||||
|
GLint bitmul_uniform;
|
||||||
|
GLint dash_uniform;
|
||||||
|
GLint dash_length_uniform;
|
||||||
glamor_program_location locations;
|
glamor_program_location locations;
|
||||||
glamor_program_flag flags;
|
glamor_program_flag flags;
|
||||||
glamor_use prim_use;
|
glamor_use prim_use;
|
||||||
|
|
|
@ -651,11 +651,12 @@ glamor_composite_with_copy(CARD8 op,
|
||||||
if (region->extents.y2 + y_source - y_dest > source->pDrawable->height)
|
if (region->extents.y2 + y_source - y_dest > source->pDrawable->height)
|
||||||
goto cleanup_region;
|
goto cleanup_region;
|
||||||
}
|
}
|
||||||
ret = glamor_copy_n_to_n_nf(source->pDrawable,
|
glamor_copy(source->pDrawable,
|
||||||
dest->pDrawable, NULL,
|
dest->pDrawable, NULL,
|
||||||
RegionRects(region), RegionNumRects(region),
|
RegionRects(region), RegionNumRects(region),
|
||||||
x_source - x_dest, y_source - y_dest,
|
x_source - x_dest, y_source - y_dest,
|
||||||
FALSE, FALSE, 0, NULL);
|
FALSE, FALSE, 0, NULL);
|
||||||
|
ret = TRUE;
|
||||||
cleanup_region:
|
cleanup_region:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -792,30 +793,29 @@ glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
|
||||||
float *matrix,
|
float *matrix,
|
||||||
float xscale, float yscale,
|
float xscale, float yscale,
|
||||||
int x1, int y1, int x2, int y2,
|
int x1, int y1, int x2, int y2,
|
||||||
int yInverted, float *texcoords,
|
float *texcoords,
|
||||||
int stride)
|
int stride)
|
||||||
{
|
{
|
||||||
if (!matrix && repeat_type == RepeatNone)
|
if (!matrix && repeat_type == RepeatNone)
|
||||||
glamor_set_normalize_tcoords_ext(priv, xscale, yscale,
|
glamor_set_normalize_tcoords_ext(priv, xscale, yscale,
|
||||||
x1, y1,
|
x1, y1,
|
||||||
x2, y2, yInverted, texcoords, stride);
|
x2, y2, texcoords, stride);
|
||||||
else if (matrix && repeat_type == RepeatNone)
|
else if (matrix && repeat_type == RepeatNone)
|
||||||
glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale,
|
glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale,
|
||||||
yscale, x1, y1,
|
yscale, x1, y1,
|
||||||
x2, y2,
|
x2, y2,
|
||||||
yInverted,
|
|
||||||
texcoords, stride);
|
texcoords, stride);
|
||||||
else if (!matrix && repeat_type != RepeatNone)
|
else if (!matrix && repeat_type != RepeatNone)
|
||||||
glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type,
|
glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type,
|
||||||
xscale, yscale,
|
xscale, yscale,
|
||||||
x1, y1,
|
x1, y1,
|
||||||
x2, y2,
|
x2, y2,
|
||||||
yInverted, texcoords, stride);
|
texcoords, stride);
|
||||||
else if (matrix && repeat_type != RepeatNone)
|
else if (matrix && repeat_type != RepeatNone)
|
||||||
glamor_set_repeat_transformed_normalize_tcoords_ext(priv, repeat_type,
|
glamor_set_repeat_transformed_normalize_tcoords_ext(priv, repeat_type,
|
||||||
matrix, xscale,
|
matrix, xscale,
|
||||||
yscale, x1, y1, x2,
|
yscale, x1, y1, x2,
|
||||||
y2, yInverted,
|
y2,
|
||||||
texcoords, stride);
|
texcoords, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1265,7 +1265,7 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale,
|
glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale,
|
||||||
dst_yscale, x_dest, y_dest,
|
dst_yscale, x_dest, y_dest,
|
||||||
x_dest + width, y_dest + height,
|
x_dest + width, y_dest + height,
|
||||||
glamor_priv->yInverted, vertices,
|
vertices,
|
||||||
vb_stride);
|
vb_stride);
|
||||||
vertices += 2;
|
vertices += 2;
|
||||||
if (key.source != SHADER_SOURCE_SOLID) {
|
if (key.source != SHADER_SOURCE_SOLID) {
|
||||||
|
@ -1275,7 +1275,6 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
src_yscale, x_source,
|
src_yscale, x_source,
|
||||||
y_source, x_source + width,
|
y_source, x_source + width,
|
||||||
y_source + height,
|
y_source + height,
|
||||||
glamor_priv->yInverted,
|
|
||||||
vertices, vb_stride);
|
vertices, vb_stride);
|
||||||
vertices += 2;
|
vertices += 2;
|
||||||
}
|
}
|
||||||
|
@ -1287,7 +1286,6 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
mask_yscale, x_mask,
|
mask_yscale, x_mask,
|
||||||
y_mask, x_mask + width,
|
y_mask, x_mask + width,
|
||||||
y_mask + height,
|
y_mask + height,
|
||||||
glamor_priv->yInverted,
|
|
||||||
vertices, vb_stride);
|
vertices, vb_stride);
|
||||||
vertices += 2;
|
vertices += 2;
|
||||||
}
|
}
|
||||||
|
@ -1315,8 +1313,6 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
|
glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
DEBUGF("finish rendering.\n");
|
DEBUGF("finish rendering.\n");
|
||||||
glamor_priv->state = RENDER_STATE;
|
|
||||||
glamor_priv->render_idle_cnt = 0;
|
|
||||||
if (saved_source_format)
|
if (saved_source_format)
|
||||||
source->format = saved_source_format;
|
source->format = saved_source_format;
|
||||||
|
|
||||||
|
@ -1586,15 +1582,6 @@ _glamor_composite(CARD8 op,
|
||||||
RegionRec region;
|
RegionRec region;
|
||||||
BoxPtr extent;
|
BoxPtr extent;
|
||||||
int nbox, ok = FALSE;
|
int nbox, ok = FALSE;
|
||||||
PixmapPtr sub_dest_pixmap = NULL;
|
|
||||||
PixmapPtr sub_source_pixmap = NULL;
|
|
||||||
PixmapPtr sub_mask_pixmap = NULL;
|
|
||||||
int dest_x_off, dest_y_off, saved_dest_x, saved_dest_y;
|
|
||||||
int source_x_off, source_y_off, saved_source_x, saved_source_y;
|
|
||||||
int mask_x_off, mask_y_off, saved_mask_x, saved_mask_y;
|
|
||||||
DrawablePtr saved_dest_drawable;
|
|
||||||
DrawablePtr saved_source_drawable;
|
|
||||||
DrawablePtr saved_mask_drawable;
|
|
||||||
int force_clip = 0;
|
int force_clip = 0;
|
||||||
|
|
||||||
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
|
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
|
||||||
|
@ -1737,34 +1724,13 @@ _glamor_composite(CARD8 op,
|
||||||
dest->pDrawable->width, dest->pDrawable->height,
|
dest->pDrawable->width, dest->pDrawable->height,
|
||||||
glamor_get_picture_location(dest));
|
glamor_get_picture_location(dest));
|
||||||
|
|
||||||
#define GET_SUB_PICTURE(p, access) do { \
|
if (glamor_prepare_access_picture_box(dest, GLAMOR_ACCESS_RW,
|
||||||
glamor_get_drawable_deltas(p->pDrawable, p ##_pixmap, \
|
x_dest, y_dest, width, height) &&
|
||||||
& p ##_x_off, & p ##_y_off); \
|
glamor_prepare_access_picture_box(source, GLAMOR_ACCESS_RO,
|
||||||
sub_ ##p ##_pixmap = glamor_get_sub_pixmap(p ##_pixmap, \
|
x_source, y_source, width, height) &&
|
||||||
x_ ##p + p ##_x_off + p->pDrawable->x, \
|
glamor_prepare_access_picture_box(mask, GLAMOR_ACCESS_RO,
|
||||||
y_ ##p + p ##_y_off + p->pDrawable->y, \
|
x_mask, y_mask, width, height))
|
||||||
width, height, access); \
|
{
|
||||||
if (sub_ ##p ##_pixmap != NULL) { \
|
|
||||||
saved_ ##p ##_drawable = p->pDrawable; \
|
|
||||||
saved_ ##p ##_x = x_ ##p; \
|
|
||||||
saved_ ##p ##_y = y_ ##p; \
|
|
||||||
if (p->pCompositeClip) \
|
|
||||||
pixman_region_translate (p->pCompositeClip, \
|
|
||||||
-p->pDrawable->x - x_ ##p, \
|
|
||||||
-p->pDrawable->y - y_ ##p); \
|
|
||||||
p->pDrawable = &sub_ ##p ##_pixmap->drawable; \
|
|
||||||
x_ ##p = 0; \
|
|
||||||
y_ ##p = 0; \
|
|
||||||
} } while(0)
|
|
||||||
GET_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
|
|
||||||
if (source->pDrawable && !source->transform)
|
|
||||||
GET_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
|
|
||||||
if (mask && mask->pDrawable && !mask->transform)
|
|
||||||
GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
|
|
||||||
|
|
||||||
if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW) &&
|
|
||||||
glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO) &&
|
|
||||||
glamor_prepare_access_picture(mask, GLAMOR_ACCESS_RO)) {
|
|
||||||
fbComposite(op,
|
fbComposite(op,
|
||||||
source, mask, dest,
|
source, mask, dest,
|
||||||
x_source, y_source,
|
x_source, y_source,
|
||||||
|
@ -1774,25 +1740,6 @@ _glamor_composite(CARD8 op,
|
||||||
glamor_finish_access_picture(source);
|
glamor_finish_access_picture(source);
|
||||||
glamor_finish_access_picture(dest);
|
glamor_finish_access_picture(dest);
|
||||||
|
|
||||||
#define PUT_SUB_PICTURE(p, access) do { \
|
|
||||||
if (sub_ ##p ##_pixmap != NULL) { \
|
|
||||||
x_ ##p = saved_ ##p ##_x; \
|
|
||||||
y_ ##p = saved_ ##p ##_y; \
|
|
||||||
p->pDrawable = saved_ ##p ##_drawable; \
|
|
||||||
if (p->pCompositeClip) \
|
|
||||||
pixman_region_translate (p->pCompositeClip, \
|
|
||||||
p->pDrawable->x + x_ ##p, \
|
|
||||||
p->pDrawable->y + y_ ##p); \
|
|
||||||
glamor_put_sub_pixmap(sub_ ##p ##_pixmap, p ##_pixmap, \
|
|
||||||
x_ ##p + p ##_x_off + p->pDrawable->x, \
|
|
||||||
y_ ##p + p ##_y_off + p->pDrawable->y, \
|
|
||||||
width, height, access); \
|
|
||||||
}} while(0)
|
|
||||||
if (mask && mask->pDrawable)
|
|
||||||
PUT_SUB_PICTURE(mask, GLAMOR_ACCESS_RO);
|
|
||||||
if (source->pDrawable)
|
|
||||||
PUT_SUB_PICTURE(source, GLAMOR_ACCESS_RO);
|
|
||||||
PUT_SUB_PICTURE(dest, GLAMOR_ACCESS_RW);
|
|
||||||
done:
|
done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
188
glamor/glamor_segs.c
Normal file
188
glamor/glamor_segs.c
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
* 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_program.h"
|
||||||
|
#include "glamor_transform.h"
|
||||||
|
#include "glamor_prepare.h"
|
||||||
|
|
||||||
|
static const glamor_facet glamor_facet_poly_segment = {
|
||||||
|
.name = "poly_segment",
|
||||||
|
.vs_vars = "attribute vec2 primitive;\n",
|
||||||
|
.vs_exec = (" vec2 pos = vec2(0.0,0.0);\n"
|
||||||
|
GLAMOR_POS(gl_Position, primitive.xy)),
|
||||||
|
};
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int nseg, xSegment *segs)
|
||||||
|
{
|
||||||
|
ScreenPtr screen = drawable->pScreen;
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||||
|
glamor_pixmap_private *pixmap_priv;
|
||||||
|
glamor_program *prog;
|
||||||
|
int off_x, off_y;
|
||||||
|
xSegment *v;
|
||||||
|
char *vbo_offset;
|
||||||
|
int box_x, box_y;
|
||||||
|
int add_last;
|
||||||
|
|
||||||
|
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
add_last = 0;
|
||||||
|
if (gc->capStyle != CapNotLast)
|
||||||
|
add_last = 1;
|
||||||
|
|
||||||
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
|
prog = glamor_use_program_fill(pixmap, gc,
|
||||||
|
&glamor_priv->poly_segment_program,
|
||||||
|
&glamor_facet_poly_segment);
|
||||||
|
|
||||||
|
if (!prog)
|
||||||
|
goto bail_ctx;
|
||||||
|
|
||||||
|
/* Set up the vertex buffers for the points */
|
||||||
|
|
||||||
|
v = glamor_get_vbo_space(drawable->pScreen,
|
||||||
|
(nseg << add_last) * sizeof (xSegment),
|
||||||
|
&vbo_offset);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
|
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
|
||||||
|
sizeof(DDXPointRec), vbo_offset);
|
||||||
|
|
||||||
|
if (add_last) {
|
||||||
|
int i, j;
|
||||||
|
for (i = 0, j=0; i < nseg; i++) {
|
||||||
|
v[j++] = segs[i];
|
||||||
|
v[j].x1 = segs[i].x2;
|
||||||
|
v[j].y1 = segs[i].y2;
|
||||||
|
v[j].x2 = segs[i].x2+1;
|
||||||
|
v[j].y2 = segs[i].y2;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
memcpy(v, segs, nseg * sizeof (xSegment));
|
||||||
|
|
||||||
|
glamor_put_vbo_space(screen);
|
||||||
|
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
|
||||||
|
int nbox = RegionNumRects(gc->pCompositeClip);
|
||||||
|
BoxPtr box = RegionRects(gc->pCompositeClip);
|
||||||
|
|
||||||
|
glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE,
|
||||||
|
prog->matrix_uniform, &off_x, &off_y);
|
||||||
|
|
||||||
|
while (nbox--) {
|
||||||
|
glScissor(box->x1 + off_x,
|
||||||
|
box->y1 + off_y,
|
||||||
|
box->x2 - box->x1,
|
||||||
|
box->y2 - box->y1);
|
||||||
|
box++;
|
||||||
|
glDrawArrays(GL_LINES, 0, nseg << (1 + add_last));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
|
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
bail_ctx:
|
||||||
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
|
bail:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
glamor_poly_segment_gl(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int nseg, xSegment *segs)
|
||||||
|
{
|
||||||
|
if (gc->lineWidth != 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (gc->lineStyle) {
|
||||||
|
case LineSolid:
|
||||||
|
return glamor_poly_segment_solid_gl(drawable, gc, nseg, segs);
|
||||||
|
case LineOnOffDash:
|
||||||
|
return glamor_poly_segment_dash_gl(drawable, gc, nseg, segs);
|
||||||
|
case LineDoubleDash:
|
||||||
|
if (gc->fillStyle == FillTiled)
|
||||||
|
return glamor_poly_segment_solid_gl(drawable, gc, nseg, segs);
|
||||||
|
else
|
||||||
|
return glamor_poly_segment_dash_gl(drawable, gc, nseg, segs);
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
glamor_poly_segment_bail(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int nseg, xSegment *segs)
|
||||||
|
{
|
||||||
|
glamor_fallback("to %p (%c)\n", drawable,
|
||||||
|
glamor_get_drawable_location(drawable));
|
||||||
|
|
||||||
|
if (gc->lineWidth == 0) {
|
||||||
|
if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
|
||||||
|
glamor_prepare_access_gc(gc)) {
|
||||||
|
fbPolySegment(drawable, gc, nseg, segs);
|
||||||
|
}
|
||||||
|
glamor_finish_access_gc(gc);
|
||||||
|
glamor_finish_access(drawable);
|
||||||
|
} else
|
||||||
|
miPolySegment(drawable, gc, nseg, segs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_poly_segment(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int nseg, xSegment *segs)
|
||||||
|
{
|
||||||
|
if (glamor_poly_segment_gl(drawable, gc, nseg, segs))
|
||||||
|
return;
|
||||||
|
|
||||||
|
glamor_poly_segment_bail(drawable, gc, nseg, segs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
glamor_poly_segment_nf(DrawablePtr drawable, GCPtr gc,
|
||||||
|
int nseg, xSegment *segs)
|
||||||
|
{
|
||||||
|
if (glamor_poly_segment_gl(drawable, gc, nseg, segs))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (glamor_ddx_fallback_check_pixmap(drawable) &&
|
||||||
|
glamor_ddx_fallback_check_gc(gc))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
glamor_poly_segment_bail(drawable, gc, nseg, segs);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -326,9 +326,6 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
|
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||||
|
|
||||||
glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
|
glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
|
||||||
|
|
|
@ -293,9 +293,6 @@ glamor_poly_text(DrawablePtr drawable, GCPtr gc,
|
||||||
|
|
||||||
glDisable(GL_COLOR_LOGIC_OP);
|
glDisable(GL_COLOR_LOGIC_OP);
|
||||||
|
|
||||||
glamor_priv->state = RENDER_STATE;
|
|
||||||
glamor_priv->render_idle_cnt = 0;
|
|
||||||
|
|
||||||
*final_pos = x;
|
*final_pos = x;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -493,9 +490,6 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
|
||||||
(void) glamor_text(drawable, gc, glamor_font, prog,
|
(void) glamor_text(drawable, gc, glamor_font, prog,
|
||||||
x, y, count, chars, charinfo, sixteen);
|
x, y, count, chars, charinfo, sixteen);
|
||||||
|
|
||||||
glamor_priv->state = RENDER_STATE;
|
|
||||||
glamor_priv->render_idle_cnt = 0;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
|
|
|
@ -1,293 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright © 2009 Intel Corporation
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the next
|
|
||||||
* paragraph) shall be included in all copies or substantial portions of the
|
|
||||||
* Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
* IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Eric Anholt <eric@anholt.net>
|
|
||||||
* Zhigang Gong <zhigang.gong@linux.intel.com>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "glamor_priv.h"
|
|
||||||
|
|
||||||
/** @file glamor_tile.c
|
|
||||||
*
|
|
||||||
* Implements the basic fill-with-a-tile support used by multiple GC ops.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
glamor_init_tile_shader(ScreenPtr screen)
|
|
||||||
{
|
|
||||||
glamor_screen_private *glamor_priv;
|
|
||||||
const char *tile_vs =
|
|
||||||
"attribute vec4 v_position;\n"
|
|
||||||
"attribute vec4 v_texcoord0;\n"
|
|
||||||
"varying vec2 tile_texture;\n"
|
|
||||||
"void main()\n"
|
|
||||||
"{\n"
|
|
||||||
" gl_Position = v_position;\n"
|
|
||||||
" tile_texture = v_texcoord0.xy;\n"
|
|
||||||
"}\n";
|
|
||||||
const char *tile_fs =
|
|
||||||
GLAMOR_DEFAULT_PRECISION
|
|
||||||
"varying vec2 tile_texture;\n"
|
|
||||||
"uniform sampler2D sampler;\n"
|
|
||||||
"uniform vec2 wh;"
|
|
||||||
"void main()\n"
|
|
||||||
"{\n"
|
|
||||||
" vec2 rel_tex;"
|
|
||||||
" rel_tex = tile_texture * wh; \n"
|
|
||||||
" rel_tex = floor(rel_tex) + (fract(rel_tex) / wh); \n"
|
|
||||||
" gl_FragColor = texture2D(sampler, rel_tex);\n"
|
|
||||||
"}\n";
|
|
||||||
GLint fs_prog, vs_prog;
|
|
||||||
GLint sampler_uniform_location;
|
|
||||||
|
|
||||||
glamor_priv = glamor_get_screen_private(screen);
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
glamor_priv->tile_prog = glCreateProgram();
|
|
||||||
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, tile_vs);
|
|
||||||
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs);
|
|
||||||
glAttachShader(glamor_priv->tile_prog, vs_prog);
|
|
||||||
glAttachShader(glamor_priv->tile_prog, fs_prog);
|
|
||||||
|
|
||||||
glBindAttribLocation(glamor_priv->tile_prog,
|
|
||||||
GLAMOR_VERTEX_POS, "v_position");
|
|
||||||
glBindAttribLocation(glamor_priv->tile_prog,
|
|
||||||
GLAMOR_VERTEX_SOURCE, "v_texcoord0");
|
|
||||||
glamor_link_glsl_prog(screen, glamor_priv->tile_prog, "tile");
|
|
||||||
|
|
||||||
sampler_uniform_location =
|
|
||||||
glGetUniformLocation(glamor_priv->tile_prog, "sampler");
|
|
||||||
glUseProgram(glamor_priv->tile_prog);
|
|
||||||
glUniform1i(sampler_uniform_location, 0);
|
|
||||||
|
|
||||||
glamor_priv->tile_wh =
|
|
||||||
glGetUniformLocation(glamor_priv->tile_prog, "wh");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
glamor_fini_tile_shader(ScreenPtr screen)
|
|
||||||
{
|
|
||||||
glamor_screen_private *glamor_priv;
|
|
||||||
|
|
||||||
glamor_priv = glamor_get_screen_private(screen);
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
glDeleteProgram(glamor_priv->tile_prog);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
|
|
||||||
int x, int y, int width, int height, int tile_x, int tile_y)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
int tile_x1 = tile_x;
|
|
||||||
int tile_x2 = tile_x + width;
|
|
||||||
int tile_y1 = tile_y;
|
|
||||||
int tile_y2 = tile_y + height;
|
|
||||||
float vertices[8];
|
|
||||||
float source_texcoords[8];
|
|
||||||
GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
|
|
||||||
glamor_pixmap_private *src_pixmap_priv;
|
|
||||||
glamor_pixmap_private *dst_pixmap_priv;
|
|
||||||
float wh[4];
|
|
||||||
|
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(tile);
|
|
||||||
dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
|
|
||||||
|
|
||||||
glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
|
|
||||||
pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
|
|
||||||
pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
glUseProgram(glamor_priv->tile_prog);
|
|
||||||
|
|
||||||
glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv);
|
|
||||||
glUniform2fv(glamor_priv->tile_wh, 1, wh);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
||||||
glamor_set_repeat_normalize_tcoords
|
|
||||||
(src_pixmap_priv, RepeatNormal,
|
|
||||||
src_xscale, src_yscale,
|
|
||||||
tile_x1, tile_y1,
|
|
||||||
tile_x2, tile_y2, glamor_priv->yInverted, source_texcoords);
|
|
||||||
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
|
|
||||||
2 * sizeof(float), source_texcoords);
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
|
||||||
|
|
||||||
glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale, dst_yscale,
|
|
||||||
x1, y1,
|
|
||||||
x2, y2, glamor_priv->yInverted, vertices);
|
|
||||||
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
|
|
||||||
2 * sizeof(float), vertices);
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
||||||
|
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
|
||||||
|
|
||||||
glamor_priv->state = RENDER_STATE;
|
|
||||||
glamor_priv->render_idle_cnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bool
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
|
||||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
|
||||||
glamor_pixmap_private *dst_pixmap_priv;
|
|
||||||
glamor_pixmap_private *src_pixmap_priv;
|
|
||||||
|
|
||||||
dst_pixmap_priv = glamor_get_pixmap_private(pixmap);
|
|
||||||
src_pixmap_priv = glamor_get_pixmap_private(tile);
|
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (glamor_priv->tile_prog == 0) {
|
|
||||||
glamor_fallback("Tiling unsupported\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)) {
|
|
||||||
/* XXX dynamic uploading candidate. */
|
|
||||||
glamor_fallback("Non-texture tile pixmap\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!glamor_set_planemask(pixmap, planemask)) {
|
|
||||||
glamor_fallback("unsupported planemask %lx\n", planemask);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
|
||||||
if (!glamor_set_alu(screen, alu)) {
|
|
||||||
glamor_fallback("unsupported alu %x\n", alu);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
|
|
||||||
|| src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
|
||||||
glamor_pixmap_clipped_regions *clipped_dst_regions;
|
|
||||||
int n_dst_region, i, j, k;
|
|
||||||
BoxRec box;
|
|
||||||
RegionRec region;
|
|
||||||
|
|
||||||
box.x1 = x;
|
|
||||||
box.y1 = y;
|
|
||||||
box.x2 = x + width;
|
|
||||||
box.y2 = y + height;
|
|
||||||
RegionInitBoxes(®ion, &box, 1);
|
|
||||||
clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
|
|
||||||
®ion,
|
|
||||||
&n_dst_region, 0,
|
|
||||||
0, 0);
|
|
||||||
for (i = 0; i < n_dst_region; i++) {
|
|
||||||
int n_src_region;
|
|
||||||
glamor_pixmap_clipped_regions *clipped_src_regions;
|
|
||||||
BoxPtr current_boxes;
|
|
||||||
int n_current_boxes;
|
|
||||||
|
|
||||||
SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv,
|
|
||||||
clipped_dst_regions[i].block_idx);
|
|
||||||
|
|
||||||
if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
|
||||||
RegionTranslate(clipped_dst_regions[i].region,
|
|
||||||
tile_x - x, tile_y - y);
|
|
||||||
DEBUGF("tiled a large src pixmap. %dx%d \n",
|
|
||||||
tile->drawable.width, tile->drawable.height);
|
|
||||||
clipped_src_regions =
|
|
||||||
glamor_compute_clipped_regions(src_pixmap_priv,
|
|
||||||
clipped_dst_regions[i].
|
|
||||||
region, &n_src_region, 1, 0,
|
|
||||||
0);
|
|
||||||
DEBUGF("got %d src regions %d \n", n_src_region);
|
|
||||||
for (j = 0; j < n_src_region; j++) {
|
|
||||||
|
|
||||||
SET_PIXMAP_FBO_CURRENT(src_pixmap_priv,
|
|
||||||
clipped_src_regions[j].block_idx);
|
|
||||||
|
|
||||||
RegionTranslate(clipped_src_regions[j].region,
|
|
||||||
x - tile_x, y - tile_y);
|
|
||||||
current_boxes = RegionRects(clipped_src_regions[j].region);
|
|
||||||
n_current_boxes =
|
|
||||||
RegionNumRects(clipped_src_regions[j].region);
|
|
||||||
for (k = 0; k < n_current_boxes; k++) {
|
|
||||||
DEBUGF
|
|
||||||
("Tile on %d %d %d %d dst block id %d tile block id %d tilex %d tiley %d\n",
|
|
||||||
current_boxes[k].x1, current_boxes[k].y1,
|
|
||||||
current_boxes[k].x2 - current_boxes[k].x1,
|
|
||||||
current_boxes[k].y2 - current_boxes[k].y1,
|
|
||||||
clipped_dst_regions[i].block_idx,
|
|
||||||
clipped_src_regions[j].block_idx,
|
|
||||||
(tile_x + (current_boxes[k].x1 - x)),
|
|
||||||
tile_y + (current_boxes[k].y1 - y));
|
|
||||||
|
|
||||||
_glamor_tile(pixmap, tile,
|
|
||||||
current_boxes[k].x1, current_boxes[k].y1,
|
|
||||||
current_boxes[k].x2 - current_boxes[k].x1,
|
|
||||||
current_boxes[k].y2 - current_boxes[k].y1,
|
|
||||||
(tile_x + (current_boxes[k].x1 - x)),
|
|
||||||
(tile_y + (current_boxes[k].y1 - y)));
|
|
||||||
}
|
|
||||||
|
|
||||||
RegionDestroy(clipped_src_regions[j].region);
|
|
||||||
}
|
|
||||||
free(clipped_src_regions);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
current_boxes = RegionRects(clipped_dst_regions[i].region);
|
|
||||||
n_current_boxes = RegionNumRects(clipped_dst_regions[i].region);
|
|
||||||
for (k = 0; k < n_current_boxes; k++) {
|
|
||||||
_glamor_tile(pixmap, tile,
|
|
||||||
current_boxes[k].x1, current_boxes[k].y1,
|
|
||||||
current_boxes[k].x2 - current_boxes[k].x1,
|
|
||||||
current_boxes[k].y2 - current_boxes[k].y1,
|
|
||||||
(tile_x + (current_boxes[k].x1 - x)),
|
|
||||||
(tile_y + (current_boxes[k].y1 - y)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RegionDestroy(clipped_dst_regions[i].region);
|
|
||||||
}
|
|
||||||
free(clipped_dst_regions);
|
|
||||||
RegionUninit(®ion);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y);
|
|
||||||
|
|
||||||
glamor_set_alu(screen, GXcopy);
|
|
||||||
return TRUE;
|
|
||||||
fail:
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
}
|
|
|
@ -72,9 +72,6 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
|
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
|
||||||
|
|
||||||
|
@ -90,27 +87,14 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
||||||
while (nbox--) {
|
while (nbox--) {
|
||||||
|
|
||||||
/* compute drawable coordinates */
|
/* compute drawable coordinates */
|
||||||
int x1 = boxes->x1 + dx_dst;
|
int x1 = MAX(boxes->x1 + dx_dst, box->x1);
|
||||||
int x2 = boxes->x2 + dx_dst;
|
int x2 = MIN(boxes->x2 + dx_dst, box->x2);
|
||||||
int y1 = boxes->y1 + dy_dst;
|
int y1 = MAX(boxes->y1 + dy_dst, box->y1);
|
||||||
int y2 = boxes->y2 + dy_dst;
|
int y2 = MIN(boxes->y2 + dy_dst, box->y2);
|
||||||
|
|
||||||
boxes++;
|
boxes++;
|
||||||
|
|
||||||
if (x1 < box->x1)
|
if (x2 <= x1 || y2 <= y1)
|
||||||
x1 = box->x1;
|
|
||||||
if (box->x2 < x2)
|
|
||||||
x2 = box->x2;
|
|
||||||
|
|
||||||
if (x2 <= x1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (y1 < box->y1)
|
|
||||||
y1 = box->y1;
|
|
||||||
if (box->y2 < y2)
|
|
||||||
y2 = box->y2;
|
|
||||||
|
|
||||||
if (y2 <= y1)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, y1 - dy_dst + dy_src);
|
glPixelStorei(GL_UNPACK_SKIP_ROWS, y1 - dy_dst + dy_src);
|
||||||
|
@ -195,26 +179,14 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
||||||
while (nbox--) {
|
while (nbox--) {
|
||||||
|
|
||||||
/* compute drawable coordinates */
|
/* compute drawable coordinates */
|
||||||
int x1 = boxes->x1 + dx_src;
|
int x1 = MAX(boxes->x1 + dx_src, box->x1);
|
||||||
int x2 = boxes->x2 + dx_src;
|
int x2 = MIN(boxes->x2 + dx_src, box->x2);
|
||||||
int y1 = boxes->y1 + dy_src;
|
int y1 = MAX(boxes->y1 + dy_src, box->y1);
|
||||||
int y2 = boxes->y2 + dy_src;
|
int y2 = MIN(boxes->y2 + dy_src, box->y2);
|
||||||
|
|
||||||
boxes++;
|
boxes++;
|
||||||
|
|
||||||
if (x1 < box->x1)
|
if (x2 <= x1 || y2 <= y1)
|
||||||
x1 = box->x1;
|
|
||||||
if (box->x2 < x2)
|
|
||||||
x2 = box->x2;
|
|
||||||
|
|
||||||
if (y1 < box->y1)
|
|
||||||
y1 = box->y1;
|
|
||||||
if (box->y2 < y2)
|
|
||||||
y2 = box->y2;
|
|
||||||
|
|
||||||
if (x2 <= x1)
|
|
||||||
continue;
|
|
||||||
if (y2 <= y1)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
glPixelStorei(GL_PACK_SKIP_PIXELS, x1 - dx_src + dx_dst);
|
glPixelStorei(GL_PACK_SKIP_PIXELS, x1 - dx_src + dx_dst);
|
||||||
|
|
|
@ -198,6 +198,64 @@ glamor_set_tiled(PixmapPtr pixmap,
|
||||||
size_uniform);
|
size_uniform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PixmapPtr
|
||||||
|
glamor_get_stipple_pixmap(GCPtr gc)
|
||||||
|
{
|
||||||
|
glamor_gc_private *gc_priv = glamor_get_gc_private(gc);
|
||||||
|
ScreenPtr screen = gc->pScreen;
|
||||||
|
PixmapPtr bitmap;
|
||||||
|
PixmapPtr pixmap;
|
||||||
|
GCPtr scratch_gc;
|
||||||
|
ChangeGCVal changes[2];
|
||||||
|
|
||||||
|
if (gc_priv->stipple)
|
||||||
|
return gc_priv->stipple;
|
||||||
|
|
||||||
|
bitmap = gc->stipple;
|
||||||
|
if (!bitmap)
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
pixmap = glamor_create_pixmap(screen,
|
||||||
|
bitmap->drawable.width,
|
||||||
|
bitmap->drawable.height,
|
||||||
|
8, GLAMOR_CREATE_NO_LARGE);
|
||||||
|
if (!pixmap)
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
scratch_gc = GetScratchGC(8, screen);
|
||||||
|
if (!scratch_gc)
|
||||||
|
goto bail_pixmap;
|
||||||
|
|
||||||
|
changes[0].val = 0xff;
|
||||||
|
changes[1].val = 0x00;
|
||||||
|
if (ChangeGC(NullClient, scratch_gc,
|
||||||
|
GCForeground|GCBackground, changes) != Success)
|
||||||
|
goto bail_gc;
|
||||||
|
ValidateGC(&pixmap->drawable, scratch_gc);
|
||||||
|
|
||||||
|
(*scratch_gc->ops->CopyPlane)(&bitmap->drawable,
|
||||||
|
&pixmap->drawable,
|
||||||
|
scratch_gc,
|
||||||
|
0, 0,
|
||||||
|
bitmap->drawable.width,
|
||||||
|
bitmap->drawable.height,
|
||||||
|
0, 0, 0x1);
|
||||||
|
|
||||||
|
FreeScratchGC(scratch_gc);
|
||||||
|
gc_priv->stipple = pixmap;
|
||||||
|
|
||||||
|
glamor_track_stipple(gc);
|
||||||
|
|
||||||
|
return pixmap;
|
||||||
|
|
||||||
|
bail_gc:
|
||||||
|
FreeScratchGC(scratch_gc);
|
||||||
|
bail_pixmap:
|
||||||
|
glamor_destroy_pixmap(pixmap);
|
||||||
|
bail:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
glamor_set_stippled(PixmapPtr pixmap,
|
glamor_set_stippled(PixmapPtr pixmap,
|
||||||
GCPtr gc,
|
GCPtr gc,
|
||||||
|
@ -205,11 +263,19 @@ glamor_set_stippled(PixmapPtr pixmap,
|
||||||
GLint offset_uniform,
|
GLint offset_uniform,
|
||||||
GLint size_uniform)
|
GLint size_uniform)
|
||||||
{
|
{
|
||||||
|
PixmapPtr stipple;
|
||||||
|
|
||||||
|
stipple = glamor_get_stipple_pixmap(gc);
|
||||||
|
if (!stipple)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform))
|
if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!glamor_set_texture(pixmap, gc->stipple, gc->patOrg.x, gc->patOrg.y, offset_uniform, size_uniform))
|
return glamor_set_texture(pixmap,
|
||||||
return FALSE;
|
stipple,
|
||||||
|
-gc->patOrg.x,
|
||||||
return TRUE;
|
-gc->patOrg.y,
|
||||||
|
offset_uniform,
|
||||||
|
size_uniform);
|
||||||
}
|
}
|
||||||
|
|
|
@ -908,7 +908,6 @@ _glamor_trapezoids_with_shader(CARD8 op,
|
||||||
clipped_vtx_tmp[5] = clipped_vtx[(i + 2) * 2 + 1];
|
clipped_vtx_tmp[5] = clipped_vtx[(i + 2) * 2 + 1];
|
||||||
glamor_set_normalize_tri_vcoords(dst_xscale, dst_yscale,
|
glamor_set_normalize_tri_vcoords(dst_xscale, dst_yscale,
|
||||||
clipped_vtx_tmp,
|
clipped_vtx_tmp,
|
||||||
glamor_priv->yInverted,
|
|
||||||
vertices);
|
vertices);
|
||||||
DEBUGF("vertices of triangle: (%f X %f), (%f X %f), "
|
DEBUGF("vertices of triangle: (%f X %f), (%f X %f), "
|
||||||
"(%f X %f)\n", vertices[0], vertices[1],
|
"(%f X %f)\n", vertices[0], vertices[1],
|
||||||
|
@ -920,14 +919,12 @@ _glamor_trapezoids_with_shader(CARD8 op,
|
||||||
glamor_set_transformed_normalize_tri_tcoords
|
glamor_set_transformed_normalize_tri_tcoords
|
||||||
(source_pixmap_priv, src_matrix, src_xscale,
|
(source_pixmap_priv, src_matrix, src_xscale,
|
||||||
src_yscale, clipped_vtx_tmp,
|
src_yscale, clipped_vtx_tmp,
|
||||||
glamor_priv->yInverted, source_texcoords);
|
source_texcoords);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
glamor_set_normalize_tri_tcoords(src_xscale,
|
glamor_set_normalize_tri_tcoords(src_xscale,
|
||||||
src_yscale,
|
src_yscale,
|
||||||
clipped_vtx_tmp,
|
clipped_vtx_tmp,
|
||||||
glamor_priv->
|
|
||||||
yInverted,
|
|
||||||
source_texcoords);
|
source_texcoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1392,12 +1389,8 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First, clear all to zero */
|
/* First, clear all to zero */
|
||||||
if (!glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width,
|
glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width,
|
||||||
pixmap_priv->base.pixmap->drawable.height,
|
pixmap_priv->base.pixmap->drawable.height, 0);
|
||||||
GXclear, 0xFFFFFFFF, 0)) {
|
|
||||||
DEBUGF("glamor_solid failed, fallback\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
|
@ -1443,11 +1436,9 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
|
||||||
miTrapezoidBounds(1, ptrap, &one_trap_bound);
|
miTrapezoidBounds(1, ptrap, &one_trap_bound);
|
||||||
|
|
||||||
vertices += 2;
|
vertices += 2;
|
||||||
glamor_set_tcoords_ext((pixmap_priv->base.pixmap->drawable.width),
|
glamor_set_tcoords_ext((one_trap_bound.x1), (one_trap_bound.y1),
|
||||||
(pixmap_priv->base.pixmap->drawable.height),
|
|
||||||
(one_trap_bound.x1), (one_trap_bound.y1),
|
|
||||||
(one_trap_bound.x2), (one_trap_bound.y2),
|
(one_trap_bound.x2), (one_trap_bound.y2),
|
||||||
glamor_priv->yInverted, vertices, stride);
|
vertices, stride);
|
||||||
DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
|
DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
|
||||||
"rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0],
|
"rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0],
|
||||||
vertices[1], vertices[1 * stride], vertices[1 * stride + 1],
|
vertices[1], vertices[1 * stride], vertices[1 * stride + 1],
|
||||||
|
@ -1467,8 +1458,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
|
||||||
one_trap_bound.y1,
|
one_trap_bound.y1,
|
||||||
one_trap_bound.x2,
|
one_trap_bound.x2,
|
||||||
one_trap_bound.y2,
|
one_trap_bound.y2,
|
||||||
glamor_priv->yInverted, vertices,
|
vertices, stride);
|
||||||
stride);
|
|
||||||
DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
|
DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
|
||||||
"rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0],
|
"rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0],
|
||||||
vertices[1], vertices[1 * stride], vertices[1 * stride + 1],
|
vertices[1], vertices[1 * stride], vertices[1 * stride + 1],
|
||||||
|
|
79
glamor/glamor_utils.c
Normal file
79
glamor/glamor_utils.c
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_solid_boxes(PixmapPtr pixmap,
|
||||||
|
BoxPtr box, int nbox, unsigned long fg_pixel)
|
||||||
|
{
|
||||||
|
DrawablePtr drawable = &pixmap->drawable;
|
||||||
|
GCPtr gc;
|
||||||
|
xRectangle *rect;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
rect = malloc(nbox * sizeof (xRectangle));
|
||||||
|
if (!rect)
|
||||||
|
return;
|
||||||
|
for (n = 0; n < nbox; n++) {
|
||||||
|
rect[n].x = box[n].x1;
|
||||||
|
rect[n].y = box[n].y1;
|
||||||
|
rect[n].width = box[n].x2 - box[n].x1;
|
||||||
|
rect[n].height = box[n].y2 - box[n].y1;
|
||||||
|
}
|
||||||
|
|
||||||
|
gc = GetScratchGC(drawable->depth, drawable->pScreen);
|
||||||
|
if (gc) {
|
||||||
|
ChangeGCVal vals[1];
|
||||||
|
|
||||||
|
vals[0].val = fg_pixel;
|
||||||
|
ChangeGC(NullClient, gc, GCForeground, vals);
|
||||||
|
ValidateGC(drawable, gc);
|
||||||
|
gc->ops->PolyFillRect(drawable, gc, nbox, rect);
|
||||||
|
FreeScratchGC(gc);
|
||||||
|
}
|
||||||
|
free(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
||||||
|
unsigned long fg_pixel)
|
||||||
|
{
|
||||||
|
DrawablePtr drawable = &pixmap->drawable;
|
||||||
|
GCPtr gc;
|
||||||
|
ChangeGCVal vals[1];
|
||||||
|
xRectangle rect;
|
||||||
|
|
||||||
|
vals[0].val = fg_pixel;
|
||||||
|
gc = GetScratchGC(drawable->depth, drawable->pScreen);
|
||||||
|
if (!gc)
|
||||||
|
return;
|
||||||
|
ChangeGC(NullClient, gc, GCForeground, vals);
|
||||||
|
ValidateGC(drawable, gc);
|
||||||
|
rect.x = x;
|
||||||
|
rect.y = y;
|
||||||
|
rect.width = width;
|
||||||
|
rect.height = height;
|
||||||
|
gc->ops->PolyFillRect(drawable, gc, 1, &rect);
|
||||||
|
FreeScratchGC(gc);
|
||||||
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#ifndef __GLAMOR_UTILS_H__
|
#ifndef __GLAMOR_UTILS_H__
|
||||||
#define __GLAMOR_UTILS_H__
|
#define __GLAMOR_UTILS_H__
|
||||||
|
|
||||||
|
#include "glamor_prepare.h"
|
||||||
|
|
||||||
#define v_from_x_coord_x(_xscale_, _x_) ( 2 * (_x_) * (_xscale_) - 1.0)
|
#define v_from_x_coord_x(_xscale_, _x_) ( 2 * (_x_) * (_xscale_) - 1.0)
|
||||||
#define v_from_x_coord_y(_yscale_, _y_) (-2 * (_y_) * (_yscale_) + 1.0)
|
#define v_from_x_coord_y(_yscale_, _y_) (-2 * (_y_) * (_yscale_) + 1.0)
|
||||||
#define v_from_x_coord_y_inverted(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0)
|
#define v_from_x_coord_y_inverted(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0)
|
||||||
|
@ -311,21 +313,17 @@
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define _glamor_set_normalize_tpoint(xscale, yscale, _tx_, _ty_, \
|
#define _glamor_set_normalize_tpoint(xscale, yscale, _tx_, _ty_, \
|
||||||
texcoord, yInverted) \
|
texcoord) \
|
||||||
do { \
|
do { \
|
||||||
(texcoord)[0] = t_from_x_coord_x(xscale, _tx_); \
|
(texcoord)[0] = t_from_x_coord_x(xscale, _tx_); \
|
||||||
if (_X_LIKELY(yInverted)) \
|
(texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_); \
|
||||||
(texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_);\
|
|
||||||
else \
|
|
||||||
(texcoord)[1] = t_from_x_coord_y(yscale, _ty_); \
|
|
||||||
DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0], \
|
DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0], \
|
||||||
(texcoord)[1]); \
|
(texcoord)[1]); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_transformed_point(priv, matrix, xscale, \
|
#define glamor_set_transformed_point(priv, matrix, xscale, \
|
||||||
yscale, texcoord, \
|
yscale, texcoord, \
|
||||||
x, y, \
|
x, y) \
|
||||||
yInverted) \
|
|
||||||
do { \
|
do { \
|
||||||
float tx, ty; \
|
float tx, ty; \
|
||||||
int fbo_x_off, fbo_y_off; \
|
int fbo_x_off, fbo_y_off; \
|
||||||
|
@ -337,10 +335,7 @@
|
||||||
tx += fbo_x_off; \
|
tx += fbo_x_off; \
|
||||||
ty += fbo_y_off; \
|
ty += fbo_y_off; \
|
||||||
(texcoord)[0] = t_from_x_coord_x(xscale, tx); \
|
(texcoord)[0] = t_from_x_coord_x(xscale, tx); \
|
||||||
if (_X_LIKELY(yInverted)) \
|
(texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \
|
||||||
(texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \
|
|
||||||
else \
|
|
||||||
(texcoord)[1] = t_from_x_coord_y(yscale, ty); \
|
|
||||||
DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]); \
|
DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
@ -349,18 +344,14 @@
|
||||||
xscale, \
|
xscale, \
|
||||||
yscale, \
|
yscale, \
|
||||||
vtx, \
|
vtx, \
|
||||||
yInverted, \
|
|
||||||
texcoords) \
|
texcoords) \
|
||||||
do { \
|
do { \
|
||||||
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
||||||
texcoords, (vtx)[0], (vtx)[1], \
|
texcoords, (vtx)[0], (vtx)[1]); \
|
||||||
yInverted); \
|
|
||||||
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
||||||
texcoords+2, (vtx)[2], (vtx)[3], \
|
texcoords+2, (vtx)[2], (vtx)[3]); \
|
||||||
yInverted); \
|
|
||||||
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
||||||
texcoords+4, (vtx)[4], (vtx)[5], \
|
texcoords+4, (vtx)[4], (vtx)[5]); \
|
||||||
yInverted); \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define glamor_set_transformed_normalize_tcoords_ext( priv, \
|
#define glamor_set_transformed_normalize_tcoords_ext( priv, \
|
||||||
|
@ -368,21 +359,17 @@
|
||||||
xscale, \
|
xscale, \
|
||||||
yscale, \
|
yscale, \
|
||||||
tx1, ty1, tx2, ty2, \
|
tx1, ty1, tx2, ty2, \
|
||||||
yInverted, texcoords, \
|
texcoords, \
|
||||||
stride) \
|
stride) \
|
||||||
do { \
|
do { \
|
||||||
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
||||||
texcoords, tx1, ty1, \
|
texcoords, tx1, ty1); \
|
||||||
yInverted); \
|
|
||||||
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
||||||
texcoords + 1 * stride, tx2, ty1, \
|
texcoords + 1 * stride, tx2, ty1); \
|
||||||
yInverted); \
|
|
||||||
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
||||||
texcoords + 2 * stride, tx2, ty2, \
|
texcoords + 2 * stride, tx2, ty2); \
|
||||||
yInverted); \
|
|
||||||
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
||||||
texcoords + 3 * stride, tx1, ty2, \
|
texcoords + 3 * stride, tx1, ty2); \
|
||||||
yInverted); \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define glamor_set_transformed_normalize_tcoords( priv, \
|
#define glamor_set_transformed_normalize_tcoords( priv, \
|
||||||
|
@ -390,35 +377,31 @@
|
||||||
xscale, \
|
xscale, \
|
||||||
yscale, \
|
yscale, \
|
||||||
tx1, ty1, tx2, ty2, \
|
tx1, ty1, tx2, ty2, \
|
||||||
yInverted, texcoords) \
|
texcoords) \
|
||||||
do { \
|
do { \
|
||||||
glamor_set_transformed_normalize_tcoords_ext( priv, \
|
glamor_set_transformed_normalize_tcoords_ext( priv, \
|
||||||
matrix, \
|
matrix, \
|
||||||
xscale, \
|
xscale, \
|
||||||
yscale, \
|
yscale, \
|
||||||
tx1, ty1, tx2, ty2, \
|
tx1, ty1, tx2, ty2, \
|
||||||
yInverted, texcoords, \
|
texcoords, \
|
||||||
2); \
|
2); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define glamor_set_normalize_tri_tcoords(xscale, \
|
#define glamor_set_normalize_tri_tcoords(xscale, \
|
||||||
yscale, \
|
yscale, \
|
||||||
vtx, \
|
vtx, \
|
||||||
yInverted, \
|
|
||||||
texcoords) \
|
texcoords) \
|
||||||
do { \
|
do { \
|
||||||
_glamor_set_normalize_tpoint(xscale, yscale, \
|
_glamor_set_normalize_tpoint(xscale, yscale, \
|
||||||
(vtx)[0], (vtx)[1], \
|
(vtx)[0], (vtx)[1], \
|
||||||
texcoords, \
|
texcoords); \
|
||||||
yInverted); \
|
|
||||||
_glamor_set_normalize_tpoint(xscale, yscale, \
|
_glamor_set_normalize_tpoint(xscale, yscale, \
|
||||||
(vtx)[2], (vtx)[3], \
|
(vtx)[2], (vtx)[3], \
|
||||||
texcoords+2, \
|
texcoords+2); \
|
||||||
yInverted); \
|
|
||||||
_glamor_set_normalize_tpoint(xscale, yscale, \
|
_glamor_set_normalize_tpoint(xscale, yscale, \
|
||||||
(vtx)[4], (vtx)[5], \
|
(vtx)[4], (vtx)[5], \
|
||||||
texcoords+4, \
|
texcoords+4); \
|
||||||
yInverted); \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \
|
#define glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \
|
||||||
|
@ -428,14 +411,13 @@
|
||||||
yscale, \
|
yscale, \
|
||||||
_x1_, _y1_, \
|
_x1_, _y1_, \
|
||||||
_x2_, _y2_, \
|
_x2_, _y2_, \
|
||||||
yInverted, \
|
|
||||||
texcoords, \
|
texcoords, \
|
||||||
stride) \
|
stride) \
|
||||||
do { \
|
do { \
|
||||||
if (_X_LIKELY(priv->type != GLAMOR_TEXTURE_LARGE)) { \
|
if (_X_LIKELY(priv->type != GLAMOR_TEXTURE_LARGE)) { \
|
||||||
glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, \
|
glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, \
|
||||||
yscale, _x1_, _y1_, \
|
yscale, _x1_, _y1_, \
|
||||||
_x2_, _y2_, yInverted, \
|
_x2_, _y2_, \
|
||||||
texcoords, stride); \
|
texcoords, stride); \
|
||||||
} else { \
|
} else { \
|
||||||
float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4; \
|
float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4; \
|
||||||
|
@ -462,13 +444,13 @@
|
||||||
DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, \
|
DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, \
|
||||||
ttx2, tty2, ttx3, tty3, ttx4, tty4); \
|
ttx2, tty2, ttx3, tty3, ttx4, tty4); \
|
||||||
_glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1, \
|
_glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1, \
|
||||||
texcoords, yInverted); \
|
texcoords); \
|
||||||
_glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2, \
|
_glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2, \
|
||||||
texcoords + 1 * stride, yInverted); \
|
texcoords + 1 * stride); \
|
||||||
_glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3, \
|
_glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3, \
|
||||||
texcoords + 2 * stride, yInverted); \
|
texcoords + 2 * stride); \
|
||||||
_glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4, \
|
_glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4, \
|
||||||
texcoords + 3 * stride, yInverted); \
|
texcoords + 3 * stride); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -479,7 +461,6 @@
|
||||||
yscale, \
|
yscale, \
|
||||||
_x1_, _y1_, \
|
_x1_, _y1_, \
|
||||||
_x2_, _y2_, \
|
_x2_, _y2_, \
|
||||||
yInverted, \
|
|
||||||
texcoords) \
|
texcoords) \
|
||||||
do { \
|
do { \
|
||||||
glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \
|
glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \
|
||||||
|
@ -489,14 +470,13 @@
|
||||||
yscale, \
|
yscale, \
|
||||||
_x1_, _y1_, \
|
_x1_, _y1_, \
|
||||||
_x2_, _y2_, \
|
_x2_, _y2_, \
|
||||||
yInverted, \
|
|
||||||
texcoords, \
|
texcoords, \
|
||||||
2); \
|
2); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define _glamor_set_normalize_tcoords(xscale, yscale, tx1, \
|
#define _glamor_set_normalize_tcoords(xscale, yscale, tx1, \
|
||||||
ty1, tx2, ty2, \
|
ty1, tx2, ty2, \
|
||||||
yInverted, vertices, stride) \
|
vertices, stride) \
|
||||||
do { \
|
do { \
|
||||||
/* vertices may be write-only, so we use following \
|
/* vertices may be write-only, so we use following \
|
||||||
* temporary variable. */ \
|
* temporary variable. */ \
|
||||||
|
@ -505,21 +485,15 @@
|
||||||
(vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2); \
|
(vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2); \
|
||||||
(vertices)[2 * stride] = _t2_; \
|
(vertices)[2 * stride] = _t2_; \
|
||||||
(vertices)[3 * stride] = _t0_; \
|
(vertices)[3 * stride] = _t0_; \
|
||||||
if (_X_LIKELY(yInverted)) { \
|
(vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1); \
|
||||||
(vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1); \
|
(vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2); \
|
||||||
(vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2);\
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
(vertices)[1] = _t1_ = t_from_x_coord_y(yscale, ty1); \
|
|
||||||
(vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y(yscale, ty2);\
|
|
||||||
} \
|
|
||||||
(vertices)[1 * stride + 1] = _t1_; \
|
(vertices)[1 * stride + 1] = _t1_; \
|
||||||
(vertices)[3 * stride + 1] = _t5_; \
|
(vertices)[3 * stride + 1] = _t5_; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \
|
#define glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \
|
||||||
x1, y1, x2, y2, \
|
x1, y1, x2, y2, \
|
||||||
yInverted, vertices, stride) \
|
vertices, stride) \
|
||||||
do { \
|
do { \
|
||||||
if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \
|
if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \
|
||||||
float tx1, tx2, ty1, ty2; \
|
float tx1, tx2, ty1, ty2; \
|
||||||
|
@ -530,26 +504,26 @@
|
||||||
ty1 = y1 + fbo_y_off; \
|
ty1 = y1 + fbo_y_off; \
|
||||||
ty2 = y2 + fbo_y_off; \
|
ty2 = y2 + fbo_y_off; \
|
||||||
_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \
|
_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \
|
||||||
tx2, ty2, yInverted, vertices, \
|
tx2, ty2, vertices, \
|
||||||
stride); \
|
stride); \
|
||||||
} else \
|
} else \
|
||||||
_glamor_set_normalize_tcoords(xscale, yscale, x1, y1, \
|
_glamor_set_normalize_tcoords(xscale, yscale, x1, y1, \
|
||||||
x2, y2, yInverted, vertices, stride);\
|
x2, y2, vertices, stride); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_normalize_tcoords(priv, xscale, yscale, \
|
#define glamor_set_normalize_tcoords(priv, xscale, yscale, \
|
||||||
x1, y1, x2, y2, \
|
x1, y1, x2, y2, \
|
||||||
yInverted, vertices) \
|
vertices) \
|
||||||
do { \
|
do { \
|
||||||
glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \
|
glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \
|
||||||
x1, y1, x2, y2, \
|
x1, y1, x2, y2, \
|
||||||
yInverted, vertices, 2); \
|
vertices, 2); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \
|
#define glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \
|
||||||
xscale, yscale, \
|
xscale, yscale, \
|
||||||
_x1_, _y1_, _x2_, _y2_, \
|
_x1_, _y1_, _x2_, _y2_, \
|
||||||
yInverted, vertices, stride)\
|
vertices, stride) \
|
||||||
do { \
|
do { \
|
||||||
if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \
|
if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \
|
||||||
float tx1, tx2, ty1, ty2; \
|
float tx1, tx2, ty1, ty2; \
|
||||||
|
@ -564,130 +538,99 @@
|
||||||
_x1_, _y1_, _x2_, _y2_); \
|
_x1_, _y1_, _x2_, _y2_); \
|
||||||
} \
|
} \
|
||||||
_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \
|
_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \
|
||||||
tx2, ty2, yInverted, vertices, \
|
tx2, ty2, vertices, \
|
||||||
stride); \
|
stride); \
|
||||||
} else \
|
} else \
|
||||||
_glamor_set_normalize_tcoords(xscale, yscale, _x1_, _y1_, \
|
_glamor_set_normalize_tcoords(xscale, yscale, _x1_, _y1_, \
|
||||||
_x2_, _y2_, yInverted, vertices, \
|
_x2_, _y2_, vertices, \
|
||||||
stride); \
|
stride); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_repeat_normalize_tcoords(priv, repeat_type, \
|
#define glamor_set_repeat_normalize_tcoords(priv, repeat_type, \
|
||||||
xscale, yscale, \
|
xscale, yscale, \
|
||||||
_x1_, _y1_, _x2_, _y2_, \
|
_x1_, _y1_, _x2_, _y2_, \
|
||||||
yInverted, vertices) \
|
vertices) \
|
||||||
do { \
|
do { \
|
||||||
glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \
|
glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \
|
||||||
xscale, yscale, \
|
xscale, yscale, \
|
||||||
_x1_, _y1_, _x2_, _y2_, \
|
_x1_, _y1_, _x2_, _y2_, \
|
||||||
yInverted, vertices, 2); \
|
vertices, 2); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_normalize_tcoords_tri_stripe(xscale, yscale, \
|
#define glamor_set_normalize_tcoords_tri_stripe(xscale, yscale, \
|
||||||
x1, y1, x2, y2, \
|
x1, y1, x2, y2, \
|
||||||
yInverted, vertices) \
|
vertices) \
|
||||||
do { \
|
do { \
|
||||||
(vertices)[0] = t_from_x_coord_x(xscale, x1); \
|
(vertices)[0] = t_from_x_coord_x(xscale, x1); \
|
||||||
(vertices)[2] = t_from_x_coord_x(xscale, x2); \
|
(vertices)[2] = t_from_x_coord_x(xscale, x2); \
|
||||||
(vertices)[6] = (vertices)[2]; \
|
(vertices)[6] = (vertices)[2]; \
|
||||||
(vertices)[4] = (vertices)[0]; \
|
(vertices)[4] = (vertices)[0]; \
|
||||||
if (_X_LIKELY(yInverted)) { \
|
(vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \
|
||||||
(vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \
|
(vertices)[7] = t_from_x_coord_y_inverted(yscale, y2); \
|
||||||
(vertices)[7] = t_from_x_coord_y_inverted(yscale, y2); \
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
(vertices)[1] = t_from_x_coord_y(yscale, y1); \
|
|
||||||
(vertices)[7] = t_from_x_coord_y(yscale, y2); \
|
|
||||||
} \
|
|
||||||
(vertices)[3] = (vertices)[1]; \
|
(vertices)[3] = (vertices)[1]; \
|
||||||
(vertices)[5] = (vertices)[7]; \
|
(vertices)[5] = (vertices)[7]; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_tcoords(width, height, x1, y1, x2, y2, \
|
#define glamor_set_tcoords(x1, y1, x2, y2, vertices) \
|
||||||
yInverted, vertices) \
|
|
||||||
do { \
|
do { \
|
||||||
(vertices)[0] = (x1); \
|
(vertices)[0] = (x1); \
|
||||||
(vertices)[2] = (x2); \
|
(vertices)[2] = (x2); \
|
||||||
(vertices)[4] = (vertices)[2]; \
|
(vertices)[4] = (vertices)[2]; \
|
||||||
(vertices)[6] = (vertices)[0]; \
|
(vertices)[6] = (vertices)[0]; \
|
||||||
if (_X_LIKELY(yInverted)) { \
|
(vertices)[1] = (y1); \
|
||||||
(vertices)[1] = (y1); \
|
(vertices)[5] = (y2); \
|
||||||
(vertices)[5] = (y2); \
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
(vertices)[1] = height - (y2); \
|
|
||||||
(vertices)[5] = height - (y1); \
|
|
||||||
} \
|
|
||||||
(vertices)[3] = (vertices)[1]; \
|
(vertices)[3] = (vertices)[1]; \
|
||||||
(vertices)[7] = (vertices)[5]; \
|
(vertices)[7] = (vertices)[5]; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_tcoords_ext(width, height, x1, y1, x2, y2, \
|
#define glamor_set_tcoords_ext(x1, y1, x2, y2, vertices, stride) \
|
||||||
yInverted, vertices, stride) \
|
|
||||||
do { \
|
do { \
|
||||||
(vertices)[0] = (x1); \
|
(vertices)[0] = (x1); \
|
||||||
(vertices)[1*stride] = (x2); \
|
(vertices)[1*stride] = (x2); \
|
||||||
(vertices)[2*stride] = (vertices)[1*stride]; \
|
(vertices)[2*stride] = (vertices)[1*stride]; \
|
||||||
(vertices)[3*stride] = (vertices)[0]; \
|
(vertices)[3*stride] = (vertices)[0]; \
|
||||||
if (_X_LIKELY(yInverted)) { \
|
(vertices)[1] = (y1); \
|
||||||
(vertices)[1] = (y1); \
|
(vertices)[2*stride + 1] = (y2); \
|
||||||
(vertices)[2*stride + 1] = (y2); \
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
(vertices)[1] = height - (y2); \
|
|
||||||
(vertices)[2*stride + 1] = height - (y1); \
|
|
||||||
} \
|
|
||||||
(vertices)[1*stride + 1] = (vertices)[1]; \
|
(vertices)[1*stride + 1] = (vertices)[1]; \
|
||||||
(vertices)[3*stride + 1] = (vertices)[2*stride + 1]; \
|
(vertices)[3*stride + 1] = (vertices)[2*stride + 1]; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_normalize_one_vcoord(xscale, yscale, x, y, \
|
#define glamor_set_normalize_one_vcoord(xscale, yscale, x, y, \
|
||||||
yInverted, vertices) \
|
vertices) \
|
||||||
do { \
|
do { \
|
||||||
(vertices)[0] = v_from_x_coord_x(xscale, x); \
|
(vertices)[0] = v_from_x_coord_x(xscale, x); \
|
||||||
if (_X_LIKELY(yInverted)) { \
|
(vertices)[1] = v_from_x_coord_y_inverted(yscale, y); \
|
||||||
(vertices)[1] = v_from_x_coord_y_inverted(yscale, y); \
|
|
||||||
} else { \
|
|
||||||
(vertices)[1] = v_from_x_coord_y(yscale, y); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_normalize_tri_vcoords(xscale, yscale, vtx, \
|
#define glamor_set_normalize_tri_vcoords(xscale, yscale, vtx, \
|
||||||
yInverted, vertices) \
|
vertices) \
|
||||||
do { \
|
do { \
|
||||||
glamor_set_normalize_one_vcoord(xscale, yscale, \
|
glamor_set_normalize_one_vcoord(xscale, yscale, \
|
||||||
(vtx)[0], (vtx)[1], \
|
(vtx)[0], (vtx)[1], \
|
||||||
yInverted, vertices); \
|
vertices); \
|
||||||
glamor_set_normalize_one_vcoord(xscale, yscale, \
|
glamor_set_normalize_one_vcoord(xscale, yscale, \
|
||||||
(vtx)[2], (vtx)[3], \
|
(vtx)[2], (vtx)[3], \
|
||||||
yInverted, vertices+2); \
|
vertices+2); \
|
||||||
glamor_set_normalize_one_vcoord(xscale, yscale, \
|
glamor_set_normalize_one_vcoord(xscale, yscale, \
|
||||||
(vtx)[4], (vtx)[5], \
|
(vtx)[4], (vtx)[5], \
|
||||||
yInverted, vertices+4); \
|
vertices+4); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_tcoords_tri_strip(width, height, x1, y1, x2, y2, \
|
#define glamor_set_tcoords_tri_strip(x1, y1, x2, y2, vertices) \
|
||||||
yInverted, vertices) \
|
|
||||||
do { \
|
do { \
|
||||||
(vertices)[0] = (x1); \
|
(vertices)[0] = (x1); \
|
||||||
(vertices)[2] = (x2); \
|
(vertices)[2] = (x2); \
|
||||||
(vertices)[6] = (vertices)[2]; \
|
(vertices)[6] = (vertices)[2]; \
|
||||||
(vertices)[4] = (vertices)[0]; \
|
(vertices)[4] = (vertices)[0]; \
|
||||||
if (_X_LIKELY(yInverted)) { \
|
(vertices)[1] = (y1); \
|
||||||
(vertices)[1] = (y1); \
|
(vertices)[7] = (y2); \
|
||||||
(vertices)[7] = (y2); \
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
(vertices)[1] = height - (y2); \
|
|
||||||
(vertices)[7] = height - (y1); \
|
|
||||||
} \
|
|
||||||
(vertices)[3] = (vertices)[1]; \
|
(vertices)[3] = (vertices)[1]; \
|
||||||
(vertices)[5] = (vertices)[7]; \
|
(vertices)[5] = (vertices)[7]; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \
|
#define glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \
|
||||||
x1, y1, x2, y2, \
|
x1, y1, x2, y2, \
|
||||||
yInverted, vertices, stride) \
|
vertices, stride) \
|
||||||
do { \
|
do { \
|
||||||
int fbo_x_off, fbo_y_off; \
|
int fbo_x_off, fbo_y_off; \
|
||||||
/* vertices may be write-only, so we use following \
|
/* vertices may be write-only, so we use following \
|
||||||
|
@ -699,29 +642,22 @@
|
||||||
x2 + fbo_x_off); \
|
x2 + fbo_x_off); \
|
||||||
(vertices)[2 * stride] = _t2_; \
|
(vertices)[2 * stride] = _t2_; \
|
||||||
(vertices)[3 * stride] = _t0_; \
|
(vertices)[3 * stride] = _t0_; \
|
||||||
if (_X_LIKELY(yInverted)) { \
|
(vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale, \
|
||||||
(vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale, \
|
y1 + fbo_y_off); \
|
||||||
y1 + fbo_y_off); \
|
(vertices)[2 * stride + 1] = _t5_ = \
|
||||||
(vertices)[2 * stride + 1] = _t5_ = \
|
v_from_x_coord_y_inverted(yscale, \
|
||||||
v_from_x_coord_y_inverted(yscale, \
|
y2 + fbo_y_off); \
|
||||||
y2 + fbo_y_off); \
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
(vertices)[1] = _t1_ = v_from_x_coord_y(yscale, y1 + fbo_y_off); \
|
|
||||||
(vertices)[2 * stride + 1] = _t5_ = v_from_x_coord_y(yscale, \
|
|
||||||
y2 + fbo_y_off); \
|
|
||||||
} \
|
|
||||||
(vertices)[1 * stride + 1] = _t1_; \
|
(vertices)[1 * stride + 1] = _t1_; \
|
||||||
(vertices)[3 * stride + 1] = _t5_; \
|
(vertices)[3 * stride + 1] = _t5_; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_normalize_vcoords(priv, xscale, yscale, \
|
#define glamor_set_normalize_vcoords(priv, xscale, yscale, \
|
||||||
x1, y1, x2, y2, \
|
x1, y1, x2, y2, \
|
||||||
yInverted, vertices) \
|
vertices) \
|
||||||
do { \
|
do { \
|
||||||
glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \
|
glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \
|
||||||
x1, y1, x2, y2, \
|
x1, y1, x2, y2, \
|
||||||
yInverted, vertices, 2); \
|
vertices, 2); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_const_ext(params, nparam, vertices, nverts, stride) \
|
#define glamor_set_const_ext(params, nparam, vertices, nverts, stride) \
|
||||||
|
@ -736,44 +672,30 @@
|
||||||
|
|
||||||
#define glamor_set_normalize_vcoords_tri_strip(xscale, yscale, \
|
#define glamor_set_normalize_vcoords_tri_strip(xscale, yscale, \
|
||||||
x1, y1, x2, y2, \
|
x1, y1, x2, y2, \
|
||||||
yInverted, vertices) \
|
vertices) \
|
||||||
do { \
|
do { \
|
||||||
(vertices)[0] = v_from_x_coord_x(xscale, x1); \
|
(vertices)[0] = v_from_x_coord_x(xscale, x1); \
|
||||||
(vertices)[2] = v_from_x_coord_x(xscale, x2); \
|
(vertices)[2] = v_from_x_coord_x(xscale, x2); \
|
||||||
(vertices)[6] = (vertices)[2]; \
|
(vertices)[6] = (vertices)[2]; \
|
||||||
(vertices)[4] = (vertices)[0]; \
|
(vertices)[4] = (vertices)[0]; \
|
||||||
if (_X_LIKELY(yInverted)) { \
|
(vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \
|
||||||
(vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \
|
(vertices)[7] = v_from_x_coord_y_inverted(yscale, y2); \
|
||||||
(vertices)[7] = v_from_x_coord_y_inverted(yscale, y2); \
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
(vertices)[1] = v_from_x_coord_y(yscale, y1); \
|
|
||||||
(vertices)[7] = v_from_x_coord_y(yscale, y2); \
|
|
||||||
} \
|
|
||||||
(vertices)[3] = (vertices)[1]; \
|
(vertices)[3] = (vertices)[1]; \
|
||||||
(vertices)[5] = (vertices)[7]; \
|
(vertices)[5] = (vertices)[7]; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_normalize_pt(xscale, yscale, x, y, \
|
#define glamor_set_normalize_pt(xscale, yscale, x, y, \
|
||||||
yInverted, pt) \
|
pt) \
|
||||||
do { \
|
do { \
|
||||||
(pt)[0] = t_from_x_coord_x(xscale, x); \
|
(pt)[0] = t_from_x_coord_x(xscale, x); \
|
||||||
if (_X_LIKELY(yInverted)) { \
|
(pt)[1] = t_from_x_coord_y_inverted(yscale, y); \
|
||||||
(pt)[1] = t_from_x_coord_y_inverted(yscale, y); \
|
|
||||||
} else { \
|
|
||||||
(pt)[1] = t_from_x_coord_y(yscale, y); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define glamor_set_circle_centre(width, height, x, y, \
|
#define glamor_set_circle_centre(width, height, x, y, \
|
||||||
yInverted, c) \
|
c) \
|
||||||
do { \
|
do { \
|
||||||
(c)[0] = (float)x; \
|
(c)[0] = (float)x; \
|
||||||
if (_X_LIKELY(yInverted)) { \
|
(c)[1] = (float)y; \
|
||||||
(c)[1] = (float)y; \
|
|
||||||
} else { \
|
|
||||||
(c)[1] = (float)height - (float)y; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
inline static void
|
inline static void
|
||||||
|
|
|
@ -36,12 +36,10 @@
|
||||||
#include <dix-config.h>
|
#include <dix-config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "xf86xv.h"
|
|
||||||
#define GLAMOR_FOR_XORG
|
|
||||||
#include "glamor_priv.h"
|
#include "glamor_priv.h"
|
||||||
|
|
||||||
#include <X11/extensions/Xv.h>
|
#include <X11/extensions/Xv.h>
|
||||||
#include "fourcc.h"
|
#include "../hw/xfree86/common/fourcc.h"
|
||||||
/* Reference color space transform data */
|
/* Reference color space transform data */
|
||||||
typedef struct tagREF_TRANSFORM {
|
typedef struct tagREF_TRANSFORM {
|
||||||
float RefLuma;
|
float RefLuma;
|
||||||
|
@ -90,7 +88,28 @@ static const char *xv_ps = GLAMOR_DEFAULT_PRECISION
|
||||||
"gl_FragColor = temp1;\n"
|
"gl_FragColor = temp1;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
void
|
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
|
||||||
|
|
||||||
|
XvAttributeRec glamor_xv_attributes[] = {
|
||||||
|
{XvSettable | XvGettable, -1000, 1000, (char *)"XV_BRIGHTNESS"},
|
||||||
|
{XvSettable | XvGettable, -1000, 1000, (char *)"XV_CONTRAST"},
|
||||||
|
{XvSettable | XvGettable, -1000, 1000, (char *)"XV_SATURATION"},
|
||||||
|
{XvSettable | XvGettable, -1000, 1000, (char *)"XV_HUE"},
|
||||||
|
{XvSettable | XvGettable, 0, 1, (char *)"XV_COLORSPACE"},
|
||||||
|
{0, 0, 0, NULL}
|
||||||
|
};
|
||||||
|
int glamor_xv_num_attributes = ARRAY_SIZE(glamor_xv_attributes) - 1;
|
||||||
|
|
||||||
|
Atom glamorBrightness, glamorContrast, glamorSaturation, glamorHue,
|
||||||
|
glamorColorspace, glamorGamma;
|
||||||
|
|
||||||
|
XvImageRec glamor_xv_images[] = {
|
||||||
|
XVIMAGE_YV12,
|
||||||
|
XVIMAGE_I420,
|
||||||
|
};
|
||||||
|
int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
|
||||||
|
|
||||||
|
static void
|
||||||
glamor_init_xv_shader(ScreenPtr screen)
|
glamor_init_xv_shader(ScreenPtr screen)
|
||||||
{
|
{
|
||||||
glamor_screen_private *glamor_priv;
|
glamor_screen_private *glamor_priv;
|
||||||
|
@ -113,43 +132,12 @@ glamor_init_xv_shader(ScreenPtr screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v))
|
#define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v))
|
||||||
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
|
|
||||||
|
|
||||||
static Atom xvBrightness, xvContrast, xvSaturation, xvHue, xvColorspace,
|
void
|
||||||
xvGamma;
|
glamor_xv_stop_video(glamor_port_private *port_priv)
|
||||||
|
|
||||||
#define NUM_ATTRIBUTES 5
|
|
||||||
static XF86AttributeRec Attributes_glamor[NUM_ATTRIBUTES + 1] = {
|
|
||||||
{XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
|
|
||||||
{XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
|
|
||||||
{XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
|
|
||||||
{XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
|
|
||||||
{XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"},
|
|
||||||
{0, 0, 0, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NUM_FORMATS 3
|
|
||||||
|
|
||||||
static XF86VideoFormatRec Formats[NUM_FORMATS] = {
|
|
||||||
{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NUM_IMAGES 2
|
|
||||||
|
|
||||||
static XF86ImageRec Images[NUM_IMAGES] = {
|
|
||||||
XVIMAGE_YV12,
|
|
||||||
XVIMAGE_I420,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
glamor_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup)
|
|
||||||
{
|
{
|
||||||
glamor_port_private *port_priv = (glamor_port_private *) data;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!cleanup)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
if (port_priv->src_pix[i]) {
|
if (port_priv->src_pix[i]) {
|
||||||
glamor_destroy_pixmap(port_priv->src_pix[i]);
|
glamor_destroy_pixmap(port_priv->src_pix[i]);
|
||||||
|
@ -158,46 +146,42 @@ glamor_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
glamor_xv_set_port_attribute(ScrnInfoPtr pScrn,
|
glamor_xv_set_port_attribute(glamor_port_private *port_priv,
|
||||||
Atom attribute, INT32 value, void *data)
|
Atom attribute, INT32 value)
|
||||||
{
|
{
|
||||||
glamor_port_private *port_priv = (glamor_port_private *) data;
|
if (attribute == glamorBrightness)
|
||||||
|
|
||||||
if (attribute == xvBrightness)
|
|
||||||
port_priv->brightness = ClipValue(value, -1000, 1000);
|
port_priv->brightness = ClipValue(value, -1000, 1000);
|
||||||
else if (attribute == xvHue)
|
else if (attribute == glamorHue)
|
||||||
port_priv->hue = ClipValue(value, -1000, 1000);
|
port_priv->hue = ClipValue(value, -1000, 1000);
|
||||||
else if (attribute == xvContrast)
|
else if (attribute == glamorContrast)
|
||||||
port_priv->contrast = ClipValue(value, -1000, 1000);
|
port_priv->contrast = ClipValue(value, -1000, 1000);
|
||||||
else if (attribute == xvSaturation)
|
else if (attribute == glamorSaturation)
|
||||||
port_priv->saturation = ClipValue(value, -1000, 1000);
|
port_priv->saturation = ClipValue(value, -1000, 1000);
|
||||||
else if (attribute == xvGamma)
|
else if (attribute == glamorGamma)
|
||||||
port_priv->gamma = ClipValue(value, 100, 10000);
|
port_priv->gamma = ClipValue(value, 100, 10000);
|
||||||
else if (attribute == xvColorspace)
|
else if (attribute == glamorColorspace)
|
||||||
port_priv->transform_index = ClipValue(value, 0, 1);
|
port_priv->transform_index = ClipValue(value, 0, 1);
|
||||||
else
|
else
|
||||||
return BadMatch;
|
return BadMatch;
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
glamor_xv_get_port_attribute(ScrnInfoPtr pScrn,
|
glamor_xv_get_port_attribute(glamor_port_private *port_priv,
|
||||||
Atom attribute, INT32 *value, void *data)
|
Atom attribute, INT32 *value)
|
||||||
{
|
{
|
||||||
glamor_port_private *port_priv = (glamor_port_private *) data;
|
if (attribute == glamorBrightness)
|
||||||
|
|
||||||
if (attribute == xvBrightness)
|
|
||||||
*value = port_priv->brightness;
|
*value = port_priv->brightness;
|
||||||
else if (attribute == xvHue)
|
else if (attribute == glamorHue)
|
||||||
*value = port_priv->hue;
|
*value = port_priv->hue;
|
||||||
else if (attribute == xvContrast)
|
else if (attribute == glamorContrast)
|
||||||
*value = port_priv->contrast;
|
*value = port_priv->contrast;
|
||||||
else if (attribute == xvSaturation)
|
else if (attribute == glamorSaturation)
|
||||||
*value = port_priv->saturation;
|
*value = port_priv->saturation;
|
||||||
else if (attribute == xvGamma)
|
else if (attribute == glamorGamma)
|
||||||
*value = port_priv->gamma;
|
*value = port_priv->gamma;
|
||||||
else if (attribute == xvColorspace)
|
else if (attribute == glamorColorspace)
|
||||||
*value = port_priv->transform_index;
|
*value = port_priv->transform_index;
|
||||||
else
|
else
|
||||||
return BadMatch;
|
return BadMatch;
|
||||||
|
@ -205,20 +189,8 @@ glamor_xv_get_port_attribute(ScrnInfoPtr pScrn,
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
int
|
||||||
glamor_xv_query_best_size(ScrnInfoPtr pScrn,
|
glamor_xv_query_image_attributes(int id,
|
||||||
Bool motion,
|
|
||||||
short vid_w, short vid_h,
|
|
||||||
short drw_w, short drw_h,
|
|
||||||
unsigned int *p_w, unsigned int *p_h, void *data)
|
|
||||||
{
|
|
||||||
*p_w = drw_w;
|
|
||||||
*p_h = drw_h;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
glamor_xv_query_image_attributes(ScrnInfoPtr pScrn,
|
|
||||||
int id,
|
|
||||||
unsigned short *w, unsigned short *h,
|
unsigned short *w, unsigned short *h,
|
||||||
int *pitches, int *offsets)
|
int *pitches, int *offsets)
|
||||||
{
|
{
|
||||||
|
@ -258,8 +230,8 @@ static REF_TRANSFORM trans[2] = {
|
||||||
{1.1643, 0.0, 1.7927, -0.2132, -0.5329, 2.1124, 0.0} /* BT.709 */
|
{1.1643, 0.0, 1.7927, -0.2132, -0.5329, 2.1124, 0.0} /* BT.709 */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
void
|
||||||
glamor_display_textured_video(glamor_port_private *port_priv)
|
glamor_xv_render(glamor_port_private *port_priv)
|
||||||
{
|
{
|
||||||
ScreenPtr screen = port_priv->pPixmap->drawable.pScreen;
|
ScreenPtr screen = port_priv->pPixmap->drawable.pScreen;
|
||||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
@ -282,6 +254,9 @@ glamor_display_textured_video(glamor_port_private *port_priv)
|
||||||
int ref = port_priv->transform_index;
|
int ref = port_priv->transform_index;
|
||||||
GLint uloc, sampler_loc;
|
GLint uloc, sampler_loc;
|
||||||
|
|
||||||
|
if (!glamor_priv->xv_prog)
|
||||||
|
glamor_init_xv_shader(screen);
|
||||||
|
|
||||||
cont = RTFContrast(port_priv->contrast);
|
cont = RTFContrast(port_priv->contrast);
|
||||||
bright = RTFBrightness(port_priv->brightness);
|
bright = RTFBrightness(port_priv->brightness);
|
||||||
gamma = (float) port_priv->gamma / 1000.0;
|
gamma = (float) port_priv->gamma / 1000.0;
|
||||||
|
@ -385,7 +360,7 @@ glamor_display_textured_video(glamor_port_private *port_priv)
|
||||||
dsty,
|
dsty,
|
||||||
dstx + dstw,
|
dstx + dstw,
|
||||||
dsty + dsth,
|
dsty + dsth,
|
||||||
glamor_priv->yInverted, vertices);
|
vertices);
|
||||||
|
|
||||||
glamor_set_normalize_tcoords(src_pixmap_priv[0],
|
glamor_set_normalize_tcoords(src_pixmap_priv[0],
|
||||||
src_xscale[0],
|
src_xscale[0],
|
||||||
|
@ -394,7 +369,7 @@ glamor_display_textured_video(glamor_port_private *port_priv)
|
||||||
srcy,
|
srcy,
|
||||||
srcx + srcw,
|
srcx + srcw,
|
||||||
srcy + srch,
|
srcy + srch,
|
||||||
glamor_priv->yInverted, texcoords);
|
texcoords);
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
}
|
}
|
||||||
|
@ -405,8 +380,9 @@ glamor_display_textured_video(glamor_port_private *port_priv)
|
||||||
DamageDamageRegion(port_priv->pDraw, &port_priv->clip);
|
DamageDamageRegion(port_priv->pDraw, &port_priv->clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
glamor_xv_put_image(ScrnInfoPtr pScrn,
|
glamor_xv_put_image(glamor_port_private *port_priv,
|
||||||
|
DrawablePtr pDrawable,
|
||||||
short src_x, short src_y,
|
short src_x, short src_y,
|
||||||
short drw_x, short drw_y,
|
short drw_x, short drw_y,
|
||||||
short src_w, short src_h,
|
short src_w, short src_h,
|
||||||
|
@ -416,35 +392,15 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
|
||||||
short width,
|
short width,
|
||||||
short height,
|
short height,
|
||||||
Bool sync,
|
Bool sync,
|
||||||
RegionPtr clipBoxes, void *data, DrawablePtr pDrawable)
|
RegionPtr clipBoxes)
|
||||||
{
|
{
|
||||||
ScreenPtr screen = pDrawable->pScreen;
|
ScreenPtr pScreen = pDrawable->pScreen;
|
||||||
glamor_port_private *port_priv = (glamor_port_private *) data;
|
|
||||||
INT32 x1, x2, y1, y2;
|
|
||||||
int srcPitch, srcPitch2;
|
int srcPitch, srcPitch2;
|
||||||
BoxRec dstBox;
|
|
||||||
int top, nlines;
|
int top, nlines;
|
||||||
int s2offset, s3offset, tmp;
|
int s2offset, s3offset, tmp;
|
||||||
|
|
||||||
s2offset = s3offset = srcPitch2 = 0;
|
s2offset = s3offset = srcPitch2 = 0;
|
||||||
|
|
||||||
/* Clip */
|
|
||||||
x1 = src_x;
|
|
||||||
x2 = src_x + src_w;
|
|
||||||
y1 = src_y;
|
|
||||||
y2 = src_y + src_h;
|
|
||||||
|
|
||||||
dstBox.x1 = drw_x;
|
|
||||||
dstBox.x2 = drw_x + drw_w;
|
|
||||||
dstBox.y1 = drw_y;
|
|
||||||
dstBox.y2 = drw_y + drw_h;
|
|
||||||
if (!xf86XVClipVideoHelper
|
|
||||||
(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height))
|
|
||||||
return Success;
|
|
||||||
|
|
||||||
if ((x1 >= x2) || (y1 >= y2))
|
|
||||||
return Success;
|
|
||||||
|
|
||||||
srcPitch = width;
|
srcPitch = width;
|
||||||
srcPitch2 = width >> 1;
|
srcPitch2 = width >> 1;
|
||||||
|
|
||||||
|
@ -457,11 +413,11 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
|
||||||
glamor_destroy_pixmap(port_priv->src_pix[i]);
|
glamor_destroy_pixmap(port_priv->src_pix[i]);
|
||||||
|
|
||||||
port_priv->src_pix[0] =
|
port_priv->src_pix[0] =
|
||||||
glamor_create_pixmap(screen, width, height, 8, 0);
|
glamor_create_pixmap(pScreen, width, height, 8, 0);
|
||||||
port_priv->src_pix[1] =
|
port_priv->src_pix[1] =
|
||||||
glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0);
|
glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, 0);
|
||||||
port_priv->src_pix[2] =
|
port_priv->src_pix[2] =
|
||||||
glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0);
|
glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, 0);
|
||||||
port_priv->src_pix_w = width;
|
port_priv->src_pix_w = width;
|
||||||
port_priv->src_pix_h = height;
|
port_priv->src_pix_h = height;
|
||||||
|
|
||||||
|
@ -470,8 +426,8 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
top = (y1 >> 16) & ~1;
|
top = (src_y) & ~1;
|
||||||
nlines = ((y2 + 0xffff) >> 16) - top;
|
nlines = (src_y + height) - top;
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case FOURCC_YV12:
|
case FOURCC_YV12:
|
||||||
|
@ -505,7 +461,7 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDrawable->type == DRAWABLE_WINDOW)
|
if (pDrawable->type == DRAWABLE_WINDOW)
|
||||||
port_priv->pPixmap = (*screen->GetWindowPixmap) ((WindowPtr) pDrawable);
|
port_priv->pPixmap = pScreen->GetWindowPixmap((WindowPtr) pDrawable);
|
||||||
else
|
else
|
||||||
port_priv->pPixmap = (PixmapPtr) pDrawable;
|
port_priv->pPixmap = (PixmapPtr) pDrawable;
|
||||||
|
|
||||||
|
@ -524,83 +480,30 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
|
||||||
port_priv->w = width;
|
port_priv->w = width;
|
||||||
port_priv->h = height;
|
port_priv->h = height;
|
||||||
port_priv->pDraw = pDrawable;
|
port_priv->pDraw = pDrawable;
|
||||||
glamor_display_textured_video(port_priv);
|
glamor_xv_render(port_priv);
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static XF86VideoEncodingRec DummyEncodingGLAMOR[1] = {
|
void
|
||||||
{
|
glamor_xv_init_port(glamor_port_private *port_priv)
|
||||||
0,
|
|
||||||
"XV_IMAGE",
|
|
||||||
8192, 8192,
|
|
||||||
{1, 1}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
XF86VideoAdaptorPtr
|
|
||||||
glamor_xv_init(ScreenPtr screen, int num_texture_ports)
|
|
||||||
{
|
{
|
||||||
glamor_port_private *port_priv;
|
port_priv->brightness = 0;
|
||||||
XF86VideoAdaptorPtr adapt;
|
port_priv->contrast = 0;
|
||||||
int i;
|
port_priv->saturation = 0;
|
||||||
|
port_priv->hue = 0;
|
||||||
|
port_priv->gamma = 1000;
|
||||||
|
port_priv->transform_index = 0;
|
||||||
|
|
||||||
glamor_init_xv_shader(screen);
|
REGION_NULL(pScreen, &port_priv->clip);
|
||||||
|
}
|
||||||
adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports *
|
|
||||||
(sizeof(glamor_port_private) + sizeof(DevUnion)));
|
void
|
||||||
if (adapt == NULL)
|
glamor_xv_core_init(ScreenPtr screen)
|
||||||
return NULL;
|
{
|
||||||
|
glamorBrightness = MAKE_ATOM("XV_BRIGHTNESS");
|
||||||
xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
|
glamorContrast = MAKE_ATOM("XV_CONTRAST");
|
||||||
xvContrast = MAKE_ATOM("XV_CONTRAST");
|
glamorSaturation = MAKE_ATOM("XV_SATURATION");
|
||||||
xvSaturation = MAKE_ATOM("XV_SATURATION");
|
glamorHue = MAKE_ATOM("XV_HUE");
|
||||||
xvHue = MAKE_ATOM("XV_HUE");
|
glamorGamma = MAKE_ATOM("XV_GAMMA");
|
||||||
xvGamma = MAKE_ATOM("XV_GAMMA");
|
glamorColorspace = MAKE_ATOM("XV_COLORSPACE");
|
||||||
xvColorspace = MAKE_ATOM("XV_COLORSPACE");
|
|
||||||
|
|
||||||
adapt->type = XvWindowMask | XvInputMask | XvImageMask;
|
|
||||||
adapt->flags = 0;
|
|
||||||
adapt->name = "GLAMOR Textured Video";
|
|
||||||
adapt->nEncodings = 1;
|
|
||||||
adapt->pEncodings = DummyEncodingGLAMOR;
|
|
||||||
|
|
||||||
adapt->nFormats = NUM_FORMATS;
|
|
||||||
adapt->pFormats = Formats;
|
|
||||||
adapt->nPorts = num_texture_ports;
|
|
||||||
adapt->pPortPrivates = (DevUnion *) (&adapt[1]);
|
|
||||||
|
|
||||||
adapt->pAttributes = Attributes_glamor;
|
|
||||||
adapt->nAttributes = NUM_ATTRIBUTES;
|
|
||||||
|
|
||||||
port_priv =
|
|
||||||
(glamor_port_private *) (&adapt->pPortPrivates[num_texture_ports]);
|
|
||||||
adapt->pImages = Images;
|
|
||||||
adapt->nImages = NUM_IMAGES;
|
|
||||||
adapt->PutVideo = NULL;
|
|
||||||
adapt->PutStill = NULL;
|
|
||||||
adapt->GetVideo = NULL;
|
|
||||||
adapt->GetStill = NULL;
|
|
||||||
adapt->StopVideo = glamor_xv_stop_video;
|
|
||||||
adapt->SetPortAttribute = glamor_xv_set_port_attribute;
|
|
||||||
adapt->GetPortAttribute = glamor_xv_get_port_attribute;
|
|
||||||
adapt->QueryBestSize = glamor_xv_query_best_size;
|
|
||||||
adapt->PutImage = glamor_xv_put_image;
|
|
||||||
adapt->ReputImage = NULL;
|
|
||||||
adapt->QueryImageAttributes = glamor_xv_query_image_attributes;
|
|
||||||
|
|
||||||
for (i = 0; i < num_texture_ports; i++) {
|
|
||||||
glamor_port_private *pPriv = &port_priv[i];
|
|
||||||
|
|
||||||
pPriv->brightness = 0;
|
|
||||||
pPriv->contrast = 0;
|
|
||||||
pPriv->saturation = 0;
|
|
||||||
pPriv->hue = 0;
|
|
||||||
pPriv->gamma = 1000;
|
|
||||||
pPriv->transform_index = 0;
|
|
||||||
|
|
||||||
REGION_NULL(pScreen, &pPriv->clip);
|
|
||||||
|
|
||||||
adapt->pPortPrivates[i].ptr = (void *) (pPriv);
|
|
||||||
}
|
|
||||||
return adapt;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,14 @@ XV_SRCS = ephyrvideo.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if GLAMOR
|
if GLAMOR
|
||||||
|
if XV
|
||||||
|
GLAMOR_XV_SRCS = ephyr_glamor_xv.c
|
||||||
|
endif
|
||||||
|
|
||||||
GLAMOR_SRCS = \
|
GLAMOR_SRCS = \
|
||||||
ephyr_glamor_glx.c \
|
ephyr_glamor_glx.c \
|
||||||
ephyr_glamor_glx.h \
|
ephyr_glamor_glx.h \
|
||||||
|
$(GLAMOR_XV_SRCS) \
|
||||||
$()
|
$()
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -650,7 +650,9 @@ ephyrInitScreen(ScreenPtr pScreen)
|
||||||
|
|
||||||
#ifdef XV
|
#ifdef XV
|
||||||
if (!ephyrNoXV) {
|
if (!ephyrNoXV) {
|
||||||
if (!ephyrInitVideo(pScreen)) {
|
if (ephyr_glamor)
|
||||||
|
ephyr_glamor_xv_init(pScreen);
|
||||||
|
else if (!ephyrInitVideo(pScreen)) {
|
||||||
EPHYR_LOG_ERROR("failed to initialize xvideo\n");
|
EPHYR_LOG_ERROR("failed to initialize xvideo\n");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -224,4 +224,14 @@ void ephyr_glamor_host_paint_rect(ScreenPtr pScreen);
|
||||||
|
|
||||||
Bool ephyrInitVideo(ScreenPtr pScreen);
|
Bool ephyrInitVideo(ScreenPtr pScreen);
|
||||||
|
|
||||||
|
/* ephyr_glamor_xv.c */
|
||||||
|
#ifdef GLAMOR
|
||||||
|
void ephyr_glamor_xv_init(ScreenPtr screen);
|
||||||
|
#else /* !GLAMOR */
|
||||||
|
static inline void
|
||||||
|
ephyr_glamor_xv_init(ScreenPtr screen)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif /* !GLAMOR */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
static Display *dpy;
|
static Display *dpy;
|
||||||
static XVisualInfo *visual_info;
|
static XVisualInfo *visual_info;
|
||||||
static GLXFBConfig fb_config;
|
static GLXFBConfig fb_config;
|
||||||
|
Bool ephyr_glamor_gles2;
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -145,6 +146,10 @@ ephyr_glamor_setup_texturing_shader(struct ephyr_glamor *glamor)
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
const char *fs_source =
|
const char *fs_source =
|
||||||
|
"#ifdef GL_ES\n"
|
||||||
|
"precision mediump float;\n"
|
||||||
|
"#endif\n"
|
||||||
|
"\n"
|
||||||
"varying vec2 t;\n"
|
"varying vec2 t;\n"
|
||||||
"uniform sampler2D s; /* initially 0 */\n"
|
"uniform sampler2D s; /* initially 0 */\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -276,7 +281,24 @@ ephyr_glamor_glx_screen_init(xcb_window_t win)
|
||||||
|
|
||||||
glx_win = glXCreateWindow(dpy, fb_config, win, NULL);
|
glx_win = glXCreateWindow(dpy, fb_config, win, NULL);
|
||||||
|
|
||||||
ctx = glXCreateContext(dpy, visual_info, NULL, True);
|
if (ephyr_glamor_gles2) {
|
||||||
|
static const int context_attribs[] = {
|
||||||
|
GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
|
||||||
|
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
|
||||||
|
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES_PROFILE_BIT_EXT,
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
if (epoxy_has_glx_extension(dpy, DefaultScreen(dpy),
|
||||||
|
"GLX_EXT_create_context_es2_profile")) {
|
||||||
|
ctx = glXCreateContextAttribsARB(dpy, fb_config, NULL, True,
|
||||||
|
context_attribs);
|
||||||
|
} else {
|
||||||
|
FatalError("Xephyr -glamor_gles2 rquires "
|
||||||
|
"GLX_EXT_create_context_es2_profile\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx = glXCreateContext(dpy, visual_info, NULL, True);
|
||||||
|
}
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
FatalError("glXCreateContext failed\n");
|
FatalError("glXCreateContext failed\n");
|
||||||
|
|
||||||
|
|
161
hw/kdrive/ephyr/ephyr_glamor_xv.c
Normal file
161
hw/kdrive/ephyr/ephyr_glamor_xv.c
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2014 Intel Corporation
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <kdrive-config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "kdrive.h"
|
||||||
|
#include "kxv.h"
|
||||||
|
#include "ephyr.h"
|
||||||
|
#include "glamor_priv.h"
|
||||||
|
|
||||||
|
#include <X11/extensions/Xv.h>
|
||||||
|
#include "fourcc.h"
|
||||||
|
|
||||||
|
#define NUM_FORMATS 3
|
||||||
|
|
||||||
|
static KdVideoFormatRec Formats[NUM_FORMATS] = {
|
||||||
|
{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
ephyr_glamor_xv_stop_video(KdScreenInfo *screen, void *data, Bool cleanup)
|
||||||
|
{
|
||||||
|
if (!cleanup)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glamor_xv_stop_video(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ephyr_glamor_xv_set_port_attribute(KdScreenInfo *screen,
|
||||||
|
Atom attribute, INT32 value, void *data)
|
||||||
|
{
|
||||||
|
return glamor_xv_set_port_attribute(data, attribute, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ephyr_glamor_xv_get_port_attribute(KdScreenInfo *screen,
|
||||||
|
Atom attribute, INT32 *value, void *data)
|
||||||
|
{
|
||||||
|
return glamor_xv_get_port_attribute(data, attribute, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ephyr_glamor_xv_query_best_size(KdScreenInfo *screen,
|
||||||
|
Bool motion,
|
||||||
|
short vid_w, short vid_h,
|
||||||
|
short drw_w, short drw_h,
|
||||||
|
unsigned int *p_w, unsigned int *p_h,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
*p_w = drw_w;
|
||||||
|
*p_h = drw_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ephyr_glamor_xv_query_image_attributes(KdScreenInfo *screen,
|
||||||
|
int id,
|
||||||
|
unsigned short *w, unsigned short *h,
|
||||||
|
int *pitches, int *offsets)
|
||||||
|
{
|
||||||
|
return glamor_xv_query_image_attributes(id, w, h, pitches, offsets);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ephyr_glamor_xv_put_image(KdScreenInfo *screen,
|
||||||
|
DrawablePtr pDrawable,
|
||||||
|
short src_x, short src_y,
|
||||||
|
short drw_x, short drw_y,
|
||||||
|
short src_w, short src_h,
|
||||||
|
short drw_w, short drw_h,
|
||||||
|
int id,
|
||||||
|
unsigned char *buf,
|
||||||
|
short width,
|
||||||
|
short height,
|
||||||
|
Bool sync,
|
||||||
|
RegionPtr clipBoxes, void *data)
|
||||||
|
{
|
||||||
|
return glamor_xv_put_image(data, pDrawable,
|
||||||
|
src_x, src_y,
|
||||||
|
drw_x, drw_y,
|
||||||
|
src_w, src_h,
|
||||||
|
drw_w, drw_h,
|
||||||
|
id, buf, width, height, sync, clipBoxes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ephyr_glamor_xv_init(ScreenPtr screen)
|
||||||
|
{
|
||||||
|
KdVideoAdaptorRec *adaptor;
|
||||||
|
glamor_port_private *port_privates;
|
||||||
|
KdVideoEncodingRec encoding = {
|
||||||
|
0,
|
||||||
|
"XV_IMAGE",
|
||||||
|
/* These sizes should probably be GL_MAX_TEXTURE_SIZE instead
|
||||||
|
* of 2048, but our context isn't set up yet.
|
||||||
|
*/
|
||||||
|
2048, 2048,
|
||||||
|
{1, 1}
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
glamor_xv_core_init(screen);
|
||||||
|
|
||||||
|
adaptor = xnfcalloc(1, sizeof(*adaptor));
|
||||||
|
|
||||||
|
adaptor->name = "glamor textured video";
|
||||||
|
adaptor->type = XvWindowMask | XvInputMask | XvImageMask;
|
||||||
|
adaptor->flags = 0;
|
||||||
|
adaptor->nEncodings = 1;
|
||||||
|
adaptor->pEncodings = &encoding;
|
||||||
|
|
||||||
|
adaptor->pFormats = Formats;
|
||||||
|
adaptor->nFormats = NUM_FORMATS;
|
||||||
|
|
||||||
|
adaptor->nPorts = 16; /* Some absurd number */
|
||||||
|
port_privates = xnfcalloc(adaptor->nPorts,
|
||||||
|
sizeof(glamor_port_private));
|
||||||
|
adaptor->pPortPrivates = xnfcalloc(adaptor->nPorts,
|
||||||
|
sizeof(glamor_port_private *));
|
||||||
|
for (i = 0; i < adaptor->nPorts; i++) {
|
||||||
|
adaptor->pPortPrivates[i].ptr = &port_privates[i];
|
||||||
|
glamor_xv_init_port(&port_privates[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
adaptor->pAttributes = glamor_xv_attributes;
|
||||||
|
adaptor->nAttributes = glamor_xv_num_attributes;
|
||||||
|
|
||||||
|
adaptor->pImages = glamor_xv_images;
|
||||||
|
adaptor->nImages = glamor_xv_num_images;
|
||||||
|
|
||||||
|
adaptor->StopVideo = ephyr_glamor_xv_stop_video;
|
||||||
|
adaptor->SetPortAttribute = ephyr_glamor_xv_set_port_attribute;
|
||||||
|
adaptor->GetPortAttribute = ephyr_glamor_xv_get_port_attribute;
|
||||||
|
adaptor->QueryBestSize = ephyr_glamor_xv_query_best_size;
|
||||||
|
adaptor->PutImage = ephyr_glamor_xv_put_image;
|
||||||
|
adaptor->QueryImageAttributes = ephyr_glamor_xv_query_image_attributes;
|
||||||
|
|
||||||
|
KdXVScreenInit(screen, adaptor, 1);
|
||||||
|
}
|
|
@ -35,7 +35,7 @@ extern Bool EphyrWantGrayScale;
|
||||||
extern Bool EphyrWantResize;
|
extern Bool EphyrWantResize;
|
||||||
extern Bool kdHasPointer;
|
extern Bool kdHasPointer;
|
||||||
extern Bool kdHasKbd;
|
extern Bool kdHasKbd;
|
||||||
extern Bool ephyr_glamor;
|
extern Bool ephyr_glamor, ephyr_glamor_gles2;
|
||||||
|
|
||||||
#ifdef GLXEXT
|
#ifdef GLXEXT
|
||||||
extern Bool ephyrNoDRI;
|
extern Bool ephyrNoDRI;
|
||||||
|
@ -138,6 +138,7 @@ ddxUseMsg(void)
|
||||||
ErrorF("-resizeable Make Xephyr windows resizeable\n");
|
ErrorF("-resizeable Make Xephyr windows resizeable\n");
|
||||||
#ifdef GLAMOR
|
#ifdef GLAMOR
|
||||||
ErrorF("-glamor Enable 2D acceleration using glamor\n");
|
ErrorF("-glamor Enable 2D acceleration using glamor\n");
|
||||||
|
ErrorF("-glamor_gles2 Enable 2D acceleration using glamor (with GLES2 only)\n");
|
||||||
#endif
|
#endif
|
||||||
ErrorF
|
ErrorF
|
||||||
("-fakexa Simulate acceleration using software rendering\n");
|
("-fakexa Simulate acceleration using software rendering\n");
|
||||||
|
@ -251,6 +252,15 @@ ddxProcessArgument(int argc, char **argv, int i)
|
||||||
ephyrFuncs.finiAccel = ephyr_glamor_fini;
|
ephyrFuncs.finiAccel = ephyr_glamor_fini;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp (argv[i], "-glamor_gles2")) {
|
||||||
|
ephyr_glamor = TRUE;
|
||||||
|
ephyr_glamor_gles2 = TRUE;
|
||||||
|
ephyrFuncs.initAccel = ephyr_glamor_init;
|
||||||
|
ephyrFuncs.enableAccel = ephyr_glamor_enable;
|
||||||
|
ephyrFuncs.disableAccel = ephyr_glamor_disable;
|
||||||
|
ephyrFuncs.finiAccel = ephyr_glamor_fini;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (!strcmp(argv[i], "-fakexa")) {
|
else if (!strcmp(argv[i], "-fakexa")) {
|
||||||
ephyrFuncs.initAccel = ephyrDrawInit;
|
ephyrFuncs.initAccel = ephyrDrawInit;
|
||||||
|
|
|
@ -69,7 +69,7 @@ static Bool ephyrXVPrivSetAdaptorsHooks(EphyrXVPriv * a_this);
|
||||||
static Bool ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this,
|
static Bool ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this,
|
||||||
ScreenPtr a_screen);
|
ScreenPtr a_screen);
|
||||||
|
|
||||||
static Bool ephyrXVPrivIsAttrValueValid(KdAttributePtr a_attrs,
|
static Bool ephyrXVPrivIsAttrValueValid(XvAttributePtr a_attrs,
|
||||||
int a_attrs_len,
|
int a_attrs_len,
|
||||||
const char *a_attr_name,
|
const char *a_attr_name,
|
||||||
int a_attr_value, Bool *a_is_valid);
|
int a_attr_value, Bool *a_is_valid);
|
||||||
|
@ -363,7 +363,7 @@ translate_xv_attributes(KdVideoAdaptorPtr adaptor,
|
||||||
|
|
||||||
it = xcb_xv_query_port_attributes_attributes_iterator(reply);
|
it = xcb_xv_query_port_attributes_attributes_iterator(reply);
|
||||||
for (i = 0; i < reply->num_attributes; i++) {
|
for (i = 0; i < reply->num_attributes; i++) {
|
||||||
KdAttributePtr attribute = &adaptor->pAttributes[i];
|
XvAttributePtr attribute = &adaptor->pAttributes[i];
|
||||||
|
|
||||||
attribute->flags = it.data->flags;
|
attribute->flags = it.data->flags;
|
||||||
attribute->min_value = it.data->min;
|
attribute->min_value = it.data->min;
|
||||||
|
@ -397,7 +397,7 @@ translate_xv_image_formats(KdVideoAdaptorPtr adaptor,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
adaptor->nImages = reply->num_formats;
|
adaptor->nImages = reply->num_formats;
|
||||||
adaptor->pImages = calloc(reply->num_formats, sizeof(KdImageRec));
|
adaptor->pImages = calloc(reply->num_formats, sizeof(XvImageRec));
|
||||||
if (!adaptor->pImages) {
|
if (!adaptor->pImages) {
|
||||||
free(reply);
|
free(reply);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -405,7 +405,7 @@ translate_xv_image_formats(KdVideoAdaptorPtr adaptor,
|
||||||
|
|
||||||
formats = xcb_xv_list_image_formats_format(reply);
|
formats = xcb_xv_list_image_formats_format(reply);
|
||||||
for (i = 0; i < reply->num_formats; i++) {
|
for (i = 0; i < reply->num_formats; i++) {
|
||||||
KdImagePtr image = &adaptor->pImages[i];
|
XvImagePtr image = &adaptor->pImages[i];
|
||||||
|
|
||||||
image->id = formats[i].id;
|
image->id = formats[i].id;
|
||||||
image->type = formats[i].type;
|
image->type = formats[i].type;
|
||||||
|
@ -612,11 +612,7 @@ ephyrXVPrivSetAdaptorsHooks(EphyrXVPriv * a_this)
|
||||||
static Bool
|
static Bool
|
||||||
ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this, ScreenPtr a_screen)
|
ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this, ScreenPtr a_screen)
|
||||||
{
|
{
|
||||||
KdScreenPriv(a_screen);
|
|
||||||
KdScreenInfo *screen = pScreenPriv->screen;
|
|
||||||
Bool is_ok = FALSE;
|
Bool is_ok = FALSE;
|
||||||
KdVideoAdaptorPtr *adaptors = NULL, *registered_adaptors = NULL;
|
|
||||||
int num_registered_adaptors = 0, i = 0, num_adaptors = 0;
|
|
||||||
|
|
||||||
EPHYR_RETURN_VAL_IF_FAIL(a_this && a_screen, FALSE);
|
EPHYR_RETURN_VAL_IF_FAIL(a_this && a_screen, FALSE);
|
||||||
|
|
||||||
|
@ -624,38 +620,22 @@ ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this, ScreenPtr a_screen)
|
||||||
|
|
||||||
if (!a_this->num_adaptors)
|
if (!a_this->num_adaptors)
|
||||||
goto out;
|
goto out;
|
||||||
num_registered_adaptors =
|
|
||||||
KdXVListGenericAdaptors(screen, ®istered_adaptors);
|
|
||||||
|
|
||||||
num_adaptors = num_registered_adaptors + a_this->num_adaptors;
|
if (!KdXVScreenInit(a_screen, a_this->adaptors, a_this->num_adaptors)) {
|
||||||
adaptors = calloc(num_adaptors, sizeof(KdVideoAdaptorPtr));
|
|
||||||
if (!adaptors) {
|
|
||||||
EPHYR_LOG_ERROR("failed to allocate adaptors tab\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
memmove(adaptors, registered_adaptors, num_registered_adaptors);
|
|
||||||
for (i = 0; i < a_this->num_adaptors; i++) {
|
|
||||||
*(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i];
|
|
||||||
}
|
|
||||||
if (!KdXVScreenInit(a_screen, adaptors, num_adaptors)) {
|
|
||||||
EPHYR_LOG_ERROR("failed to register adaptors\n");
|
EPHYR_LOG_ERROR("failed to register adaptors\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
EPHYR_LOG("there are %d registered adaptors\n", num_adaptors);
|
EPHYR_LOG("there are %d registered adaptors\n", a_this->num_adaptors);
|
||||||
is_ok = TRUE;
|
is_ok = TRUE;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(registered_adaptors);
|
|
||||||
registered_adaptors = NULL;
|
|
||||||
free(adaptors);
|
|
||||||
adaptors = NULL;
|
|
||||||
|
|
||||||
EPHYR_LOG("leave\n");
|
EPHYR_LOG("leave\n");
|
||||||
return is_ok;
|
return is_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
ephyrXVPrivIsAttrValueValid(KdAttributePtr a_attrs,
|
ephyrXVPrivIsAttrValueValid(XvAttributePtr a_attrs,
|
||||||
int a_attrs_len,
|
int a_attrs_len,
|
||||||
const char *a_attr_name,
|
const char *a_attr_name,
|
||||||
int a_attr_value, Bool *a_is_valid)
|
int a_attr_value, Bool *a_is_valid)
|
||||||
|
|
|
@ -287,7 +287,8 @@ hostx_set_title(char *title)
|
||||||
int
|
int
|
||||||
hostx_init(void)
|
hostx_init(void)
|
||||||
{
|
{
|
||||||
uint32_t attr;
|
uint32_t attrs[2];
|
||||||
|
uint32_t attr_mask = 0;
|
||||||
xcb_cursor_t empty_cursor;
|
xcb_cursor_t empty_cursor;
|
||||||
xcb_pixmap_t cursor_pxm;
|
xcb_pixmap_t cursor_pxm;
|
||||||
uint16_t red, green, blue;
|
uint16_t red, green, blue;
|
||||||
|
@ -299,7 +300,7 @@ hostx_init(void)
|
||||||
const xcb_query_extension_reply_t *shm_rep;
|
const xcb_query_extension_reply_t *shm_rep;
|
||||||
xcb_screen_t *xscreen;
|
xcb_screen_t *xscreen;
|
||||||
|
|
||||||
attr =
|
attrs[0] =
|
||||||
XCB_EVENT_MASK_BUTTON_PRESS
|
XCB_EVENT_MASK_BUTTON_PRESS
|
||||||
| XCB_EVENT_MASK_BUTTON_RELEASE
|
| XCB_EVENT_MASK_BUTTON_RELEASE
|
||||||
| XCB_EVENT_MASK_POINTER_MOTION
|
| XCB_EVENT_MASK_POINTER_MOTION
|
||||||
|
@ -307,6 +308,7 @@ hostx_init(void)
|
||||||
| XCB_EVENT_MASK_KEY_RELEASE
|
| XCB_EVENT_MASK_KEY_RELEASE
|
||||||
| XCB_EVENT_MASK_EXPOSURE
|
| XCB_EVENT_MASK_EXPOSURE
|
||||||
| XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
| XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
||||||
|
attr_mask |= XCB_CW_EVENT_MASK;
|
||||||
|
|
||||||
EPHYR_DBG("mark");
|
EPHYR_DBG("mark");
|
||||||
#ifdef GLAMOR
|
#ifdef GLAMOR
|
||||||
|
@ -325,9 +327,18 @@ hostx_init(void)
|
||||||
HostX.gc = xcb_generate_id(HostX.conn);
|
HostX.gc = xcb_generate_id(HostX.conn);
|
||||||
HostX.depth = xscreen->root_depth;
|
HostX.depth = xscreen->root_depth;
|
||||||
#ifdef GLAMOR
|
#ifdef GLAMOR
|
||||||
if (ephyr_glamor)
|
if (ephyr_glamor) {
|
||||||
HostX.visual = ephyr_glamor_get_visual();
|
HostX.visual = ephyr_glamor_get_visual();
|
||||||
else
|
if (HostX.visual->visual_id != xscreen->root_visual) {
|
||||||
|
attrs[1] = xcb_generate_id(HostX.conn);
|
||||||
|
attr_mask |= XCB_CW_COLORMAP;
|
||||||
|
xcb_create_colormap(HostX.conn,
|
||||||
|
XCB_COLORMAP_ALLOC_NONE,
|
||||||
|
attrs[1],
|
||||||
|
HostX.winroot,
|
||||||
|
HostX.visual->visual_id);
|
||||||
|
}
|
||||||
|
} else
|
||||||
#endif
|
#endif
|
||||||
HostX.visual = xcb_aux_find_visual_by_id(xscreen,xscreen->root_visual);
|
HostX.visual = xcb_aux_find_visual_by_id(xscreen,xscreen->root_visual);
|
||||||
|
|
||||||
|
@ -379,9 +390,9 @@ hostx_init(void)
|
||||||
scrpriv->win_height,
|
scrpriv->win_height,
|
||||||
0,
|
0,
|
||||||
XCB_WINDOW_CLASS_COPY_FROM_PARENT,
|
XCB_WINDOW_CLASS_COPY_FROM_PARENT,
|
||||||
XCB_COPY_FROM_PARENT,
|
HostX.visual->visual_id,
|
||||||
XCB_CW_EVENT_MASK,
|
attr_mask,
|
||||||
&attr);
|
attrs);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
xcb_create_window(HostX.conn,
|
xcb_create_window(HostX.conn,
|
||||||
|
@ -391,9 +402,9 @@ hostx_init(void)
|
||||||
0,0,100,100, /* will resize */
|
0,0,100,100, /* will resize */
|
||||||
0,
|
0,
|
||||||
XCB_WINDOW_CLASS_COPY_FROM_PARENT,
|
XCB_WINDOW_CLASS_COPY_FROM_PARENT,
|
||||||
XCB_COPY_FROM_PARENT,
|
HostX.visual->visual_id,
|
||||||
XCB_CW_EVENT_MASK,
|
attr_mask,
|
||||||
&attr);
|
attrs);
|
||||||
|
|
||||||
hostx_set_win_title(screen,
|
hostx_set_win_title(screen,
|
||||||
"(ctrl+shift grabs mouse and keyboard)");
|
"(ctrl+shift grabs mouse and keyboard)");
|
||||||
|
@ -1234,8 +1245,7 @@ ephyr_glamor_init(ScreenPtr screen)
|
||||||
|
|
||||||
glamor_init(screen,
|
glamor_init(screen,
|
||||||
GLAMOR_USE_SCREEN |
|
GLAMOR_USE_SCREEN |
|
||||||
GLAMOR_USE_PICTURE_SCREEN |
|
GLAMOR_USE_PICTURE_SCREEN);
|
||||||
GLAMOR_INVERTED_Y_AXIS);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ static void KdXVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2);
|
||||||
static void KdXVClipNotify(WindowPtr pWin, int dx, int dy);
|
static void KdXVClipNotify(WindowPtr pWin, int dx, int dy);
|
||||||
|
|
||||||
/* misc */
|
/* misc */
|
||||||
static Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr *, int);
|
static Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr, int);
|
||||||
|
|
||||||
static DevPrivateKeyRec KdXVWindowKeyRec;
|
static DevPrivateKeyRec KdXVWindowKeyRec;
|
||||||
|
|
||||||
|
@ -116,49 +116,6 @@ static unsigned long PortResource = 0;
|
||||||
#define GET_KDXV_WINDOW(pWin) ((KdXVWindowPtr) \
|
#define GET_KDXV_WINDOW(pWin) ((KdXVWindowPtr) \
|
||||||
dixLookupPrivate(&(pWin)->devPrivates, KdXVWindowKey))
|
dixLookupPrivate(&(pWin)->devPrivates, KdXVWindowKey))
|
||||||
|
|
||||||
static KdXVInitGenericAdaptorPtr *GenDrivers = NULL;
|
|
||||||
static int NumGenDrivers = 0;
|
|
||||||
|
|
||||||
int
|
|
||||||
KdXVRegisterGenericAdaptorDriver(KdXVInitGenericAdaptorPtr InitFunc)
|
|
||||||
{
|
|
||||||
KdXVInitGenericAdaptorPtr *newdrivers;
|
|
||||||
|
|
||||||
/* fprintf(stderr,"KdXVRegisterGenericAdaptorDriver\n"); */
|
|
||||||
|
|
||||||
newdrivers = realloc(GenDrivers, sizeof(KdXVInitGenericAdaptorPtr) *
|
|
||||||
(1 + NumGenDrivers));
|
|
||||||
if (!newdrivers)
|
|
||||||
return 0;
|
|
||||||
GenDrivers = newdrivers;
|
|
||||||
|
|
||||||
GenDrivers[NumGenDrivers++] = InitFunc;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
KdXVListGenericAdaptors(KdScreenInfo * screen, KdVideoAdaptorPtr ** adaptors)
|
|
||||||
{
|
|
||||||
int i, j, n, num;
|
|
||||||
KdVideoAdaptorPtr *DrivAdap, *new;
|
|
||||||
|
|
||||||
num = 0;
|
|
||||||
*adaptors = NULL;
|
|
||||||
for (i = 0; i < NumGenDrivers; i++) {
|
|
||||||
n = GenDrivers[i] (screen, &DrivAdap);
|
|
||||||
if (0 == n)
|
|
||||||
continue;
|
|
||||||
new = realloc(*adaptors, sizeof(KdVideoAdaptorPtr) * (num + n));
|
|
||||||
if (NULL == new)
|
|
||||||
continue;
|
|
||||||
*adaptors = new;
|
|
||||||
for (j = 0; j < n; j++, num++)
|
|
||||||
(*adaptors)[num] = DrivAdap[j];
|
|
||||||
}
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
KdVideoAdaptorPtr
|
KdVideoAdaptorPtr
|
||||||
KdXVAllocateVideoAdaptorRec(KdScreenInfo * screen)
|
KdXVAllocateVideoAdaptorRec(KdScreenInfo * screen)
|
||||||
{
|
{
|
||||||
|
@ -172,7 +129,7 @@ KdXVFreeVideoAdaptorRec(KdVideoAdaptorPtr ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr * adaptors, int num)
|
KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr adaptors, int num)
|
||||||
{
|
{
|
||||||
KdXVScreenPtr ScreenPriv;
|
KdXVScreenPtr ScreenPriv;
|
||||||
XvScreenPtr pxvs;
|
XvScreenPtr pxvs;
|
||||||
|
@ -282,7 +239,7 @@ KdXVFreeAdaptor(XvAdaptorPtr pAdaptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number)
|
KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr infoPtr, int number)
|
||||||
{
|
{
|
||||||
KdScreenPriv(pScreen);
|
KdScreenPriv(pScreen);
|
||||||
KdScreenInfo *screen = pScreenPriv->screen;
|
KdScreenInfo *screen = pScreenPriv->screen;
|
||||||
|
@ -295,15 +252,11 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number)
|
||||||
XvPortRecPrivatePtr portPriv;
|
XvPortRecPrivatePtr portPriv;
|
||||||
XvPortPtr pPort, pp;
|
XvPortPtr pPort, pp;
|
||||||
int numPort;
|
int numPort;
|
||||||
KdAttributePtr attributePtr;
|
|
||||||
XvAttributePtr pAttribute, pat;
|
|
||||||
KdVideoFormatPtr formatPtr;
|
KdVideoFormatPtr formatPtr;
|
||||||
XvFormatPtr pFormat, pf;
|
XvFormatPtr pFormat, pf;
|
||||||
int numFormat, totFormat;
|
int numFormat, totFormat;
|
||||||
KdVideoEncodingPtr encodingPtr;
|
KdVideoEncodingPtr encodingPtr;
|
||||||
XvEncodingPtr pEncode, pe;
|
XvEncodingPtr pEncode, pe;
|
||||||
KdImagePtr imagePtr;
|
|
||||||
XvImagePtr pImage, pi;
|
|
||||||
int numVisuals;
|
int numVisuals;
|
||||||
VisualPtr pVisual;
|
VisualPtr pVisual;
|
||||||
int i;
|
int i;
|
||||||
|
@ -315,7 +268,7 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
for (pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
|
for (pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
|
||||||
adaptorPtr = infoPtr[na];
|
adaptorPtr = &infoPtr[na];
|
||||||
|
|
||||||
if (!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
|
if (!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
|
||||||
!adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
|
!adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
|
||||||
|
@ -381,26 +334,24 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adaptorPtr->nImages &&
|
if (adaptorPtr->nImages &&
|
||||||
(pImage = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
|
(pa->pImages = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
|
||||||
|
memcpy(pa->pImages, adaptorPtr->pImages,
|
||||||
for (i = 0, pi = pImage, imagePtr = adaptorPtr->pImages;
|
adaptorPtr->nImages * sizeof(XvImageRec));
|
||||||
i < adaptorPtr->nImages; i++, pi++, imagePtr++) {
|
|
||||||
memcpy(pi, imagePtr, sizeof(*pi));
|
|
||||||
}
|
|
||||||
pa->nImages = adaptorPtr->nImages;
|
pa->nImages = adaptorPtr->nImages;
|
||||||
pa->pImages = pImage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adaptorPtr->nAttributes &&
|
if (adaptorPtr->nAttributes &&
|
||||||
(pAttribute =
|
(pa->pAttributes = calloc(adaptorPtr->nAttributes,
|
||||||
calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec)))) {
|
sizeof(XvAttributeRec)))) {
|
||||||
for (pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i =
|
memcpy(pa->pAttributes, adaptorPtr->pAttributes,
|
||||||
0; i < adaptorPtr->nAttributes; pat++, i++, attributePtr++) {
|
adaptorPtr->nAttributes * sizeof(XvAttributeRec));
|
||||||
memcpy(pat, attributePtr, sizeof(*pat));
|
|
||||||
pat->name = strdup(attributePtr->name);
|
for (i = 0; i < adaptorPtr->nAttributes; i++) {
|
||||||
|
pa->pAttributes[i].name =
|
||||||
|
strdup(adaptorPtr->pAttributes[i].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
pa->nAttributes = adaptorPtr->nAttributes;
|
pa->nAttributes = adaptorPtr->nAttributes;
|
||||||
pa->pAttributes = pAttribute;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
totFormat = adaptorPtr->nFormats;
|
totFormat = adaptorPtr->nFormats;
|
||||||
|
|
|
@ -56,8 +56,6 @@ of the copyright holder.
|
||||||
#define VIDEO_OVERLAID_STILLS 0x00000008
|
#define VIDEO_OVERLAID_STILLS 0x00000008
|
||||||
#define VIDEO_CLIP_TO_VIEWPORT 0x00000010
|
#define VIDEO_CLIP_TO_VIEWPORT 0x00000010
|
||||||
|
|
||||||
typedef XvImageRec KdImageRec, *KdImagePtr;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
KdScreenInfo *screen;
|
KdScreenInfo *screen;
|
||||||
int id;
|
int id;
|
||||||
|
@ -121,7 +119,7 @@ typedef enum {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int id;
|
int id;
|
||||||
char *name;
|
const char *name;
|
||||||
unsigned short width, height;
|
unsigned short width, height;
|
||||||
XvRationalRec rate;
|
XvRationalRec rate;
|
||||||
} KdVideoEncodingRec, *KdVideoEncodingPtr;
|
} KdVideoEncodingRec, *KdVideoEncodingPtr;
|
||||||
|
@ -131,12 +129,10 @@ typedef struct {
|
||||||
short class;
|
short class;
|
||||||
} KdVideoFormatRec, *KdVideoFormatPtr;
|
} KdVideoFormatRec, *KdVideoFormatPtr;
|
||||||
|
|
||||||
typedef XvAttributeRec KdAttributeRec, *KdAttributePtr;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
int flags;
|
int flags;
|
||||||
char *name;
|
const char *name;
|
||||||
int nEncodings;
|
int nEncodings;
|
||||||
KdVideoEncodingPtr pEncodings;
|
KdVideoEncodingPtr pEncodings;
|
||||||
int nFormats;
|
int nFormats;
|
||||||
|
@ -144,9 +140,9 @@ typedef struct {
|
||||||
int nPorts;
|
int nPorts;
|
||||||
DevUnion *pPortPrivates;
|
DevUnion *pPortPrivates;
|
||||||
int nAttributes;
|
int nAttributes;
|
||||||
KdAttributePtr pAttributes;
|
XvAttributePtr pAttributes;
|
||||||
int nImages;
|
int nImages;
|
||||||
KdImagePtr pImages;
|
XvImagePtr pImages;
|
||||||
PutVideoFuncPtr PutVideo;
|
PutVideoFuncPtr PutVideo;
|
||||||
PutStillFuncPtr PutStill;
|
PutStillFuncPtr PutStill;
|
||||||
GetVideoFuncPtr GetVideo;
|
GetVideoFuncPtr GetVideo;
|
||||||
|
@ -161,16 +157,7 @@ typedef struct {
|
||||||
} KdVideoAdaptorRec, *KdVideoAdaptorPtr;
|
} KdVideoAdaptorRec, *KdVideoAdaptorPtr;
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr * Adaptors, int num);
|
KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr Adaptors, int num);
|
||||||
|
|
||||||
typedef int (*KdXVInitGenericAdaptorPtr) (KdScreenInfo * screen,
|
|
||||||
KdVideoAdaptorPtr ** Adaptors);
|
|
||||||
|
|
||||||
int
|
|
||||||
KdXVRegisterGenericAdaptorDriver(KdXVInitGenericAdaptorPtr InitFunc);
|
|
||||||
|
|
||||||
int
|
|
||||||
KdXVListGenericAdaptors(KdScreenInfo * screen, KdVideoAdaptorPtr ** Adaptors);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
||||||
|
|
|
@ -359,15 +359,11 @@ xf86XVInitAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr * infoPtr, int number)
|
||||||
XvPortRecPrivatePtr portPriv;
|
XvPortRecPrivatePtr portPriv;
|
||||||
XvPortPtr pPort, pp;
|
XvPortPtr pPort, pp;
|
||||||
int numPort;
|
int numPort;
|
||||||
XF86AttributePtr attributePtr;
|
|
||||||
XvAttributePtr pAttribute, pat;
|
|
||||||
XF86VideoFormatPtr formatPtr;
|
XF86VideoFormatPtr formatPtr;
|
||||||
XvFormatPtr pFormat, pf;
|
XvFormatPtr pFormat, pf;
|
||||||
int numFormat, totFormat;
|
int numFormat, totFormat;
|
||||||
XF86VideoEncodingPtr encodingPtr;
|
XF86VideoEncodingPtr encodingPtr;
|
||||||
XvEncodingPtr pEncode, pe;
|
XvEncodingPtr pEncode, pe;
|
||||||
XF86ImagePtr imagePtr;
|
|
||||||
XvImagePtr pImage, pi;
|
|
||||||
int numVisuals;
|
int numVisuals;
|
||||||
VisualPtr pVisual;
|
VisualPtr pVisual;
|
||||||
int i;
|
int i;
|
||||||
|
@ -445,49 +441,24 @@ xf86XVInitAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr * infoPtr, int number)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adaptorPtr->nImages &&
|
if (adaptorPtr->nImages &&
|
||||||
(pImage = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
|
(pa->pImages = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
|
||||||
|
memcpy(pa->pImages, adaptorPtr->pImages,
|
||||||
for (i = 0, pi = pImage, imagePtr = adaptorPtr->pImages;
|
adaptorPtr->nImages * sizeof(XvImageRec));
|
||||||
i < adaptorPtr->nImages; i++, pi++, imagePtr++) {
|
|
||||||
pi->id = imagePtr->id;
|
|
||||||
pi->type = imagePtr->type;
|
|
||||||
pi->byte_order = imagePtr->byte_order;
|
|
||||||
memcpy(pi->guid, imagePtr->guid, 16);
|
|
||||||
pi->bits_per_pixel = imagePtr->bits_per_pixel;
|
|
||||||
pi->format = imagePtr->format;
|
|
||||||
pi->num_planes = imagePtr->num_planes;
|
|
||||||
pi->depth = imagePtr->depth;
|
|
||||||
pi->red_mask = imagePtr->red_mask;
|
|
||||||
pi->green_mask = imagePtr->green_mask;
|
|
||||||
pi->blue_mask = imagePtr->blue_mask;
|
|
||||||
pi->y_sample_bits = imagePtr->y_sample_bits;
|
|
||||||
pi->u_sample_bits = imagePtr->u_sample_bits;
|
|
||||||
pi->v_sample_bits = imagePtr->v_sample_bits;
|
|
||||||
pi->horz_y_period = imagePtr->horz_y_period;
|
|
||||||
pi->horz_u_period = imagePtr->horz_u_period;
|
|
||||||
pi->horz_v_period = imagePtr->horz_v_period;
|
|
||||||
pi->vert_y_period = imagePtr->vert_y_period;
|
|
||||||
pi->vert_u_period = imagePtr->vert_u_period;
|
|
||||||
pi->vert_v_period = imagePtr->vert_v_period;
|
|
||||||
memcpy(pi->component_order, imagePtr->component_order, 32);
|
|
||||||
pi->scanline_order = imagePtr->scanline_order;
|
|
||||||
}
|
|
||||||
pa->nImages = adaptorPtr->nImages;
|
pa->nImages = adaptorPtr->nImages;
|
||||||
pa->pImages = pImage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adaptorPtr->nAttributes &&
|
if (adaptorPtr->nAttributes &&
|
||||||
(pAttribute =
|
(pa->pAttributes = calloc(adaptorPtr->nAttributes,
|
||||||
calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec)))) {
|
sizeof(XvAttributeRec)))) {
|
||||||
for (pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i =
|
memcpy(pa->pAttributes, adaptorPtr->pAttributes,
|
||||||
0; i < adaptorPtr->nAttributes; pat++, i++, attributePtr++) {
|
adaptorPtr->nAttributes * sizeof(XvAttributeRec));
|
||||||
pat->flags = attributePtr->flags;
|
|
||||||
pat->min_value = attributePtr->min_value;
|
for (i = 0; i < adaptorPtr->nAttributes; i++) {
|
||||||
pat->max_value = attributePtr->max_value;
|
pa->pAttributes[i].name =
|
||||||
pat->name = strdup(attributePtr->name);
|
strdup(adaptorPtr->pAttributes[i].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
pa->nAttributes = adaptorPtr->nAttributes;
|
pa->nAttributes = adaptorPtr->nAttributes;
|
||||||
pa->pAttributes = pAttribute;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
totFormat = adaptorPtr->nFormats;
|
totFormat = adaptorPtr->nFormats;
|
||||||
|
|
|
@ -42,34 +42,7 @@
|
||||||
*/
|
*/
|
||||||
#define VIDEO_CLIP_TO_VIEWPORT 0x00000010
|
#define VIDEO_CLIP_TO_VIEWPORT 0x00000010
|
||||||
|
|
||||||
typedef struct {
|
typedef XvImageRec XF86ImageRec, *XF86ImagePtr;
|
||||||
int id;
|
|
||||||
int type;
|
|
||||||
int byte_order;
|
|
||||||
unsigned char guid[16];
|
|
||||||
int bits_per_pixel;
|
|
||||||
int format;
|
|
||||||
int num_planes;
|
|
||||||
|
|
||||||
/* for RGB formats only */
|
|
||||||
int depth;
|
|
||||||
unsigned int red_mask;
|
|
||||||
unsigned int green_mask;
|
|
||||||
unsigned int blue_mask;
|
|
||||||
|
|
||||||
/* for YUV formats only */
|
|
||||||
unsigned int y_sample_bits;
|
|
||||||
unsigned int u_sample_bits;
|
|
||||||
unsigned int v_sample_bits;
|
|
||||||
unsigned int horz_y_period;
|
|
||||||
unsigned int horz_u_period;
|
|
||||||
unsigned int horz_v_period;
|
|
||||||
unsigned int vert_y_period;
|
|
||||||
unsigned int vert_u_period;
|
|
||||||
unsigned int vert_v_period;
|
|
||||||
char component_order[32];
|
|
||||||
int scanline_order;
|
|
||||||
} XF86ImageRec, *XF86ImagePtr;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ScrnInfoPtr pScrn;
|
ScrnInfoPtr pScrn;
|
||||||
|
@ -147,12 +120,7 @@ typedef struct {
|
||||||
short class;
|
short class;
|
||||||
} XF86VideoFormatRec, *XF86VideoFormatPtr;
|
} XF86VideoFormatRec, *XF86VideoFormatPtr;
|
||||||
|
|
||||||
typedef struct {
|
typedef XvAttributeRec XF86AttributeRec, *XF86AttributePtr;
|
||||||
int flags;
|
|
||||||
int min_value;
|
|
||||||
int max_value;
|
|
||||||
const char *name;
|
|
||||||
} XF86AttributeRec, *XF86AttributePtr;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
|
|
|
@ -24,7 +24,7 @@ module_LTLIBRARIES = libglamoregl.la
|
||||||
libglamoregl_la_SOURCES = \
|
libglamoregl_la_SOURCES = \
|
||||||
$(top_srcdir)/glamor/glamor_egl.c \
|
$(top_srcdir)/glamor/glamor_egl.c \
|
||||||
$(top_srcdir)/glamor/glamor_eglmodule.c \
|
$(top_srcdir)/glamor/glamor_eglmodule.c \
|
||||||
$(top_srcdir)/glamor/glamor_xv.c \
|
glamor_xf86_xv.c \
|
||||||
$()
|
$()
|
||||||
|
|
||||||
libglamoregl_la_LDFLAGS = \
|
libglamoregl_la_LDFLAGS = \
|
||||||
|
@ -38,6 +38,7 @@ libglamoregl_la_LIBADD = \
|
||||||
|
|
||||||
AM_CPPFLAGS = $(XORG_INCS) \
|
AM_CPPFLAGS = $(XORG_INCS) \
|
||||||
-I$(top_srcdir)/dri3 \
|
-I$(top_srcdir)/dri3 \
|
||||||
|
-I$(top_srcdir)/glamor \
|
||||||
$()
|
$()
|
||||||
|
|
||||||
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_CFLAGS) $(GBM_CFLAGS)
|
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_CFLAGS) $(GBM_CFLAGS)
|
||||||
|
|
185
hw/xfree86/glamor_egl/glamor_xf86_xv.c
Normal file
185
hw/xfree86/glamor_egl/glamor_xf86_xv.c
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2013 Red Hat
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Dave Airlie <airlied@redhat.com>
|
||||||
|
*
|
||||||
|
* some code is derived from the xf86-video-ati radeon driver, mainly
|
||||||
|
* the calculations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file glamor_xf86_xv.c
|
||||||
|
*
|
||||||
|
* This implements the XF86 XV interface, and calls into glamor core
|
||||||
|
* for its support of the suspiciously similar XF86 and Kdrive
|
||||||
|
* device-dependent XV interfaces.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_DIX_CONFIG_H
|
||||||
|
#include <dix-config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GLAMOR_FOR_XORG
|
||||||
|
#include "glamor_priv.h"
|
||||||
|
|
||||||
|
#include <X11/extensions/Xv.h>
|
||||||
|
#include "fourcc.h"
|
||||||
|
|
||||||
|
#define NUM_FORMATS 3
|
||||||
|
|
||||||
|
static XF86VideoFormatRec Formats[NUM_FORMATS] = {
|
||||||
|
{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
glamor_xf86_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup)
|
||||||
|
{
|
||||||
|
if (!cleanup)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glamor_xv_stop_video(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
glamor_xf86_xv_set_port_attribute(ScrnInfoPtr pScrn,
|
||||||
|
Atom attribute, INT32 value, void *data)
|
||||||
|
{
|
||||||
|
return glamor_xv_set_port_attribute(data, attribute, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
glamor_xf86_xv_get_port_attribute(ScrnInfoPtr pScrn,
|
||||||
|
Atom attribute, INT32 *value, void *data)
|
||||||
|
{
|
||||||
|
return glamor_xv_get_port_attribute(data, attribute, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
glamor_xf86_xv_query_best_size(ScrnInfoPtr pScrn,
|
||||||
|
Bool motion,
|
||||||
|
short vid_w, short vid_h,
|
||||||
|
short drw_w, short drw_h,
|
||||||
|
unsigned int *p_w, unsigned int *p_h, void *data)
|
||||||
|
{
|
||||||
|
*p_w = drw_w;
|
||||||
|
*p_h = drw_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
glamor_xf86_xv_query_image_attributes(ScrnInfoPtr pScrn,
|
||||||
|
int id,
|
||||||
|
unsigned short *w, unsigned short *h,
|
||||||
|
int *pitches, int *offsets)
|
||||||
|
{
|
||||||
|
return glamor_xv_query_image_attributes(id, w, h, pitches, offsets);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
glamor_xf86_xv_put_image(ScrnInfoPtr pScrn,
|
||||||
|
short src_x, short src_y,
|
||||||
|
short drw_x, short drw_y,
|
||||||
|
short src_w, short src_h,
|
||||||
|
short drw_w, short drw_h,
|
||||||
|
int id,
|
||||||
|
unsigned char *buf,
|
||||||
|
short width,
|
||||||
|
short height,
|
||||||
|
Bool sync,
|
||||||
|
RegionPtr clipBoxes, void *data, DrawablePtr pDrawable)
|
||||||
|
{
|
||||||
|
return glamor_xv_put_image(data, pDrawable,
|
||||||
|
src_x, src_y,
|
||||||
|
drw_x, drw_y,
|
||||||
|
src_w, src_h,
|
||||||
|
drw_w, drw_h,
|
||||||
|
id, buf, width, height, sync, clipBoxes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static XF86VideoEncodingRec DummyEncodingGLAMOR[1] = {
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
"XV_IMAGE",
|
||||||
|
8192, 8192,
|
||||||
|
{1, 1}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
XF86VideoAdaptorPtr
|
||||||
|
glamor_xv_init(ScreenPtr screen, int num_texture_ports)
|
||||||
|
{
|
||||||
|
glamor_port_private *port_priv;
|
||||||
|
XF86VideoAdaptorPtr adapt;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
glamor_xv_core_init(screen);
|
||||||
|
|
||||||
|
adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports *
|
||||||
|
(sizeof(glamor_port_private) + sizeof(DevUnion)));
|
||||||
|
if (adapt == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
adapt->type = XvWindowMask | XvInputMask | XvImageMask;
|
||||||
|
adapt->flags = 0;
|
||||||
|
adapt->name = "GLAMOR Textured Video";
|
||||||
|
adapt->nEncodings = 1;
|
||||||
|
adapt->pEncodings = DummyEncodingGLAMOR;
|
||||||
|
|
||||||
|
adapt->nFormats = NUM_FORMATS;
|
||||||
|
adapt->pFormats = Formats;
|
||||||
|
adapt->nPorts = num_texture_ports;
|
||||||
|
adapt->pPortPrivates = (DevUnion *) (&adapt[1]);
|
||||||
|
|
||||||
|
adapt->pAttributes = glamor_xv_attributes;
|
||||||
|
adapt->nAttributes = glamor_xv_num_attributes;
|
||||||
|
|
||||||
|
port_priv =
|
||||||
|
(glamor_port_private *) (&adapt->pPortPrivates[num_texture_ports]);
|
||||||
|
adapt->pImages = glamor_xv_images;
|
||||||
|
adapt->nImages = glamor_xv_num_images;
|
||||||
|
adapt->PutVideo = NULL;
|
||||||
|
adapt->PutStill = NULL;
|
||||||
|
adapt->GetVideo = NULL;
|
||||||
|
adapt->GetStill = NULL;
|
||||||
|
adapt->StopVideo = glamor_xf86_xv_stop_video;
|
||||||
|
adapt->SetPortAttribute = glamor_xf86_xv_set_port_attribute;
|
||||||
|
adapt->GetPortAttribute = glamor_xf86_xv_get_port_attribute;
|
||||||
|
adapt->QueryBestSize = glamor_xf86_xv_query_best_size;
|
||||||
|
adapt->PutImage = glamor_xf86_xv_put_image;
|
||||||
|
adapt->ReputImage = NULL;
|
||||||
|
adapt->QueryImageAttributes = glamor_xf86_xv_query_image_attributes;
|
||||||
|
|
||||||
|
for (i = 0; i < num_texture_ports; i++) {
|
||||||
|
glamor_port_private *pPriv = &port_priv[i];
|
||||||
|
|
||||||
|
pPriv->brightness = 0;
|
||||||
|
pPriv->contrast = 0;
|
||||||
|
pPriv->saturation = 0;
|
||||||
|
pPriv->hue = 0;
|
||||||
|
pPriv->gamma = 1000;
|
||||||
|
pPriv->transform_index = 0;
|
||||||
|
|
||||||
|
REGION_NULL(pScreen, &pPriv->clip);
|
||||||
|
|
||||||
|
adapt->pPortPrivates[i].ptr = (void *) (pPriv);
|
||||||
|
}
|
||||||
|
return adapt;
|
||||||
|
}
|
11
mi/mi.h
11
mi/mi.h
|
@ -67,6 +67,11 @@ typedef struct _miDash *miDashPtr;
|
||||||
|
|
||||||
/* miarc.c */
|
/* miarc.c */
|
||||||
|
|
||||||
|
extern _X_EXPORT void miWideArc(DrawablePtr pDraw,
|
||||||
|
GCPtr pGC,
|
||||||
|
int narcs,
|
||||||
|
xArc * parcs);
|
||||||
|
|
||||||
extern _X_EXPORT void miPolyArc(DrawablePtr /*pDraw */ ,
|
extern _X_EXPORT void miPolyArc(DrawablePtr /*pDraw */ ,
|
||||||
GCPtr /*pGC */ ,
|
GCPtr /*pGC */ ,
|
||||||
int /*narcs */ ,
|
int /*narcs */ ,
|
||||||
|
@ -452,6 +457,12 @@ extern _X_EXPORT void miWideDash(DrawablePtr /*pDrawable */ ,
|
||||||
DDXPointPtr /*pPts */
|
DDXPointPtr /*pPts */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
extern _X_EXPORT void miPolylines(DrawablePtr pDrawable,
|
||||||
|
GCPtr pGC,
|
||||||
|
int mode,
|
||||||
|
int npt,
|
||||||
|
DDXPointPtr pPts);
|
||||||
|
|
||||||
/* miwindow.c */
|
/* miwindow.c */
|
||||||
|
|
||||||
extern _X_EXPORT void miClearToBackground(WindowPtr /*pWin */ ,
|
extern _X_EXPORT void miClearToBackground(WindowPtr /*pWin */ ,
|
||||||
|
|
11
mi/miarc.c
11
mi/miarc.c
|
@ -886,7 +886,7 @@ miFillWideEllipse(DrawablePtr pDraw, GCPtr pGC, xArc * parc)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
miPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
|
miWideArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
xArc *parc;
|
xArc *parc;
|
||||||
|
@ -3396,3 +3396,12 @@ drawQuadrant(struct arc_def *def,
|
||||||
y--;
|
y--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
miPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
|
||||||
|
{
|
||||||
|
if (pGC->lineWidth == 0)
|
||||||
|
miZeroPolyArc(pDraw, pGC, narcs, parcs);
|
||||||
|
else
|
||||||
|
miWideArc(pDraw, pGC, narcs, parcs);
|
||||||
|
}
|
||||||
|
|
144
mi/mifillarc.c
144
mi/mifillarc.c
|
@ -476,26 +476,16 @@ miFillArcSliceSetup(xArc * arc, miArcSliceRec * slice, GCPtr pGC)
|
||||||
*wids++ = slw; \
|
*wids++ = slw; \
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
|
||||||
{
|
{
|
||||||
int x, y, e;
|
int x, y, e;
|
||||||
int yk, xk, ym, xm, dx, dy, xorg, yorg;
|
int yk, xk, ym, xm, dx, dy, xorg, yorg;
|
||||||
int slw;
|
int slw;
|
||||||
miFillArcRec info;
|
miFillArcRec info;
|
||||||
DDXPointPtr points;
|
|
||||||
DDXPointPtr pts;
|
DDXPointPtr pts;
|
||||||
int *widths;
|
|
||||||
int *wids;
|
int *wids;
|
||||||
|
|
||||||
points = malloc(sizeof(DDXPointRec) * arc->height);
|
|
||||||
if (!points)
|
|
||||||
return;
|
|
||||||
widths = malloc(sizeof(int) * arc->height);
|
|
||||||
if (!widths) {
|
|
||||||
free(points);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
miFillArcSetup(arc, &info);
|
miFillArcSetup(arc, &info);
|
||||||
MIFILLARCSETUP();
|
MIFILLARCSETUP();
|
||||||
if (pGC->miTranslate) {
|
if (pGC->miTranslate) {
|
||||||
|
@ -508,31 +498,19 @@ miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
||||||
MIFILLARCSTEP(slw);
|
MIFILLARCSTEP(slw);
|
||||||
ADDSPANS();
|
ADDSPANS();
|
||||||
}
|
}
|
||||||
(*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE);
|
return pts - points;
|
||||||
free(widths);
|
|
||||||
free(points);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
int xorg, yorg, dx, dy, slw;
|
int xorg, yorg, dx, dy, slw;
|
||||||
double e, yk, xk, ym, xm;
|
double e, yk, xk, ym, xm;
|
||||||
miFillArcDRec info;
|
miFillArcDRec info;
|
||||||
DDXPointPtr points;
|
|
||||||
DDXPointPtr pts;
|
DDXPointPtr pts;
|
||||||
int *widths;
|
|
||||||
int *wids;
|
int *wids;
|
||||||
|
|
||||||
points = malloc(sizeof(DDXPointRec) * arc->height);
|
|
||||||
if (!points)
|
|
||||||
return;
|
|
||||||
widths = malloc(sizeof(int) * arc->height);
|
|
||||||
if (!widths) {
|
|
||||||
free(points);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
miFillArcDSetup(arc, &info);
|
miFillArcDSetup(arc, &info);
|
||||||
MIFILLARCSETUP();
|
MIFILLARCSETUP();
|
||||||
if (pGC->miTranslate) {
|
if (pGC->miTranslate) {
|
||||||
|
@ -545,9 +523,7 @@ miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
||||||
MIFILLARCSTEP(slw);
|
MIFILLARCSTEP(slw);
|
||||||
ADDSPANS();
|
ADDSPANS();
|
||||||
}
|
}
|
||||||
(*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE);
|
return pts - points;
|
||||||
free(widths);
|
|
||||||
free(points);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ADDSPAN(l,r) \
|
#define ADDSPAN(l,r) \
|
||||||
|
@ -572,17 +548,15 @@ miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
||||||
ADDSPAN(xl, xc); \
|
ADDSPAN(xl, xc); \
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
|
||||||
{
|
{
|
||||||
int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
|
int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
|
||||||
int x, y, e;
|
int x, y, e;
|
||||||
miFillArcRec info;
|
miFillArcRec info;
|
||||||
miArcSliceRec slice;
|
miArcSliceRec slice;
|
||||||
int ya, xl, xr, xc;
|
int ya, xl, xr, xc;
|
||||||
DDXPointPtr points;
|
|
||||||
DDXPointPtr pts;
|
DDXPointPtr pts;
|
||||||
int *widths;
|
|
||||||
int *wids;
|
int *wids;
|
||||||
|
|
||||||
miFillArcSetup(arc, &info);
|
miFillArcSetup(arc, &info);
|
||||||
|
@ -591,14 +565,6 @@ miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
||||||
slw = arc->height;
|
slw = arc->height;
|
||||||
if (slice.flip_top || slice.flip_bot)
|
if (slice.flip_top || slice.flip_bot)
|
||||||
slw += (arc->height >> 1) + 1;
|
slw += (arc->height >> 1) + 1;
|
||||||
points = malloc(sizeof(DDXPointRec) * slw);
|
|
||||||
if (!points)
|
|
||||||
return;
|
|
||||||
widths = malloc(sizeof(int) * slw);
|
|
||||||
if (!widths) {
|
|
||||||
free(points);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (pGC->miTranslate) {
|
if (pGC->miTranslate) {
|
||||||
xorg += pDraw->x;
|
xorg += pDraw->x;
|
||||||
yorg += pDraw->y;
|
yorg += pDraw->y;
|
||||||
|
@ -622,13 +588,11 @@ miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
||||||
ADDSLICESPANS(slice.flip_bot);
|
ADDSLICESPANS(slice.flip_bot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE);
|
return pts - points;
|
||||||
free(widths);
|
|
||||||
free(points);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
int dx, dy, xorg, yorg, slw;
|
int dx, dy, xorg, yorg, slw;
|
||||||
|
@ -636,9 +600,7 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
||||||
miFillArcDRec info;
|
miFillArcDRec info;
|
||||||
miArcSliceRec slice;
|
miArcSliceRec slice;
|
||||||
int ya, xl, xr, xc;
|
int ya, xl, xr, xc;
|
||||||
DDXPointPtr points;
|
|
||||||
DDXPointPtr pts;
|
DDXPointPtr pts;
|
||||||
int *widths;
|
|
||||||
int *wids;
|
int *wids;
|
||||||
|
|
||||||
miFillArcDSetup(arc, &info);
|
miFillArcDSetup(arc, &info);
|
||||||
|
@ -647,14 +609,6 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
||||||
slw = arc->height;
|
slw = arc->height;
|
||||||
if (slice.flip_top || slice.flip_bot)
|
if (slice.flip_top || slice.flip_bot)
|
||||||
slw += (arc->height >> 1) + 1;
|
slw += (arc->height >> 1) + 1;
|
||||||
points = malloc(sizeof(DDXPointRec) * slw);
|
|
||||||
if (!points)
|
|
||||||
return;
|
|
||||||
widths = malloc(sizeof(int) * slw);
|
|
||||||
if (!widths) {
|
|
||||||
free(points);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (pGC->miTranslate) {
|
if (pGC->miTranslate) {
|
||||||
xorg += pDraw->x;
|
xorg += pDraw->x;
|
||||||
yorg += pDraw->y;
|
yorg += pDraw->y;
|
||||||
|
@ -678,35 +632,69 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
|
||||||
ADDSLICESPANS(slice.flip_bot);
|
ADDSLICESPANS(slice.flip_bot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE);
|
return pts - points;
|
||||||
free(widths);
|
|
||||||
free(points);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MIPOLYFILLARC -- The public entry for the PolyFillArc request.
|
/* MIPOLYFILLARC -- The public entry for the PolyFillArc request.
|
||||||
* Since we don't have to worry about overlapping segments, we can just
|
* Since we don't have to worry about overlapping segments, we can just
|
||||||
* fill each arc as it comes.
|
* fill each arc as it comes.
|
||||||
*/
|
*/
|
||||||
void
|
|
||||||
miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
xArc *arc;
|
|
||||||
|
|
||||||
for (i = narcs, arc = parcs; --i >= 0; arc++) {
|
/* Limit the number of spans in a single draw request to avoid integer
|
||||||
if (miFillArcEmpty(arc))
|
* overflow in the computation of the span buffer size.
|
||||||
continue;
|
*/
|
||||||
if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE)) {
|
#define MAX_SPANS_PER_LOOP (4 * 1024 * 1024)
|
||||||
if (miCanFillArc(arc))
|
|
||||||
miFillEllipseI(pDraw, pGC, arc);
|
void
|
||||||
else
|
miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs_all, xArc * parcs)
|
||||||
miFillEllipseD(pDraw, pGC, arc);
|
{
|
||||||
|
while (narcs_all > 0) {
|
||||||
|
int narcs;
|
||||||
|
int i;
|
||||||
|
xArc *arc;
|
||||||
|
int nspans = 0;
|
||||||
|
DDXPointPtr pts, points;
|
||||||
|
int *wids, *widths;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (narcs = 0, arc = parcs; narcs < narcs_all; narcs++, arc++) {
|
||||||
|
if (narcs && nspans + arc->height > MAX_SPANS_PER_LOOP)
|
||||||
|
break;
|
||||||
|
nspans += arc->height;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (miCanFillArc(arc))
|
pts = points = malloc (sizeof (DDXPointRec) * nspans +
|
||||||
miFillArcSliceI(pDraw, pGC, arc);
|
sizeof(int) * nspans);
|
||||||
else
|
if (points) {
|
||||||
miFillArcSliceD(pDraw, pGC, arc);
|
wids = widths = (int *) (points + nspans);
|
||||||
|
|
||||||
|
for (i = 0, arc = parcs; i < narcs; arc++, i++) {
|
||||||
|
if (miFillArcEmpty(arc))
|
||||||
|
continue;
|
||||||
|
if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE))
|
||||||
|
{
|
||||||
|
if (miCanFillArc(arc))
|
||||||
|
n = miFillEllipseI(pDraw, pGC, arc, pts, wids);
|
||||||
|
else
|
||||||
|
n = miFillEllipseD(pDraw, pGC, arc, pts, wids);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (miCanFillArc(arc))
|
||||||
|
n = miFillArcSliceI(pDraw, pGC, arc, pts, wids);
|
||||||
|
else
|
||||||
|
n = miFillArcSliceD(pDraw, pGC, arc, pts, wids);
|
||||||
|
}
|
||||||
|
pts += n;
|
||||||
|
wids += n;
|
||||||
|
}
|
||||||
|
nspans = pts - points;
|
||||||
|
if (nspans)
|
||||||
|
(*pGC->ops->FillSpans) (pDraw, pGC, nspans, points,
|
||||||
|
widths, FALSE);
|
||||||
|
free (points);
|
||||||
}
|
}
|
||||||
|
parcs += narcs;
|
||||||
|
narcs_all -= narcs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1979,3 +1979,23 @@ miWideDash(DrawablePtr pDrawable, GCPtr pGC,
|
||||||
if (spanData)
|
if (spanData)
|
||||||
miCleanupSpanData(pDrawable, pGC, spanData);
|
miCleanupSpanData(pDrawable, pGC, spanData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
miPolylines(DrawablePtr drawable,
|
||||||
|
GCPtr gc,
|
||||||
|
int mode,
|
||||||
|
int n,
|
||||||
|
DDXPointPtr points)
|
||||||
|
{
|
||||||
|
if (gc->lineWidth == 0) {
|
||||||
|
if (gc->lineStyle == LineSolid)
|
||||||
|
miZeroLine(drawable, gc, mode, n, points);
|
||||||
|
else
|
||||||
|
miZeroDashLine(drawable, gc, mode, n, points);
|
||||||
|
} else {
|
||||||
|
if (gc->lineStyle == LineSolid)
|
||||||
|
miWideLine(drawable, gc, mode, n, points);
|
||||||
|
else
|
||||||
|
miWideDash(drawable, gc, mode, n, points);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -656,7 +656,7 @@ miZeroPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
|
||||||
|
|
||||||
for (arc = parcs, i = narcs; --i >= 0; arc++) {
|
for (arc = parcs, i = narcs; --i >= 0; arc++) {
|
||||||
if (!miCanZeroArc(arc))
|
if (!miCanZeroArc(arc))
|
||||||
miPolyArc(pDraw, pGC, 1, arc);
|
miWideArc(pDraw, pGC, 1, arc);
|
||||||
else {
|
else {
|
||||||
if (arc->width > arc->height)
|
if (arc->width > arc->height)
|
||||||
n = arc->width + (arc->height >> 1);
|
n = arc->width + (arc->height >> 1);
|
||||||
|
|
|
@ -179,14 +179,6 @@ miZeroLine(DrawablePtr pDraw, GCPtr pGC, int mode, /* Origin or Previous */
|
||||||
MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom);
|
MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom);
|
||||||
|
|
||||||
while (--npt > 0) {
|
while (--npt > 0) {
|
||||||
if (Nspans > 0)
|
|
||||||
(*pGC->ops->FillSpans) (pDraw, pGC, Nspans, pspanInit,
|
|
||||||
pwidthInit, FALSE);
|
|
||||||
Nspans = 0;
|
|
||||||
new_span = TRUE;
|
|
||||||
spans = pspanInit - 1;
|
|
||||||
widths = pwidthInit - 1;
|
|
||||||
|
|
||||||
x1 = x2;
|
x1 = x2;
|
||||||
y1 = y2;
|
y1 = y2;
|
||||||
oc1 = oc2;
|
oc1 = oc2;
|
||||||
|
@ -208,6 +200,14 @@ miZeroLine(DrawablePtr pDraw, GCPtr pGC, int mode, /* Origin or Previous */
|
||||||
|
|
||||||
CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
|
CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
|
||||||
|
|
||||||
|
if (ady + 1 > (list_len - Nspans)) {
|
||||||
|
(*pGC->ops->FillSpans) (pDraw, pGC, Nspans, pspanInit,
|
||||||
|
pwidthInit, FALSE);
|
||||||
|
Nspans = 0;
|
||||||
|
spans = pspanInit - 1;
|
||||||
|
widths = pwidthInit - 1;
|
||||||
|
}
|
||||||
|
new_span = TRUE;
|
||||||
if (adx > ady) {
|
if (adx > ady) {
|
||||||
e1 = ady << 1;
|
e1 = ady << 1;
|
||||||
e2 = e1 - (adx << 1);
|
e2 = e1 - (adx << 1);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user