summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2014-07-17 20:06:21 -0700
committerKeith Packard <keithp@keithp.com>2014-07-17 20:06:21 -0700
commit5c2e9fa3d6c4bdf626fededce866056ba8eca502 (patch)
tree738f445f5b19a1749321979ef23b1b1f44843515
parente678b4971b666e65a99c141e0a5f33969aa701b7 (diff)
parent6d4954884908ea9894fcfe9836db1ba7bb45be61 (diff)
Merge remote-tracking branch 'anholt/glamor-next'
-rw-r--r--glamor/Makefile.am15
-rw-r--r--glamor/glamor.c49
-rw-r--r--glamor/glamor.h23
-rw-r--r--glamor/glamor_copy.c693
-rw-r--r--glamor/glamor_copyarea.c626
-rw-r--r--glamor/glamor_copyplane.c75
-rw-r--r--glamor/glamor_copywindow.c56
-rw-r--r--glamor/glamor_core.c202
-rw-r--r--glamor/glamor_dash.c370
-rw-r--r--glamor/glamor_fill.c356
-rw-r--r--glamor/glamor_glyphblt.c154
-rw-r--r--glamor/glamor_glyphs.c10
-rw-r--r--glamor/glamor_gradient.c19
-rw-r--r--glamor/glamor_largepixmap.c13
-rw-r--r--glamor/glamor_lines.c187
-rw-r--r--glamor/glamor_picture.c18
-rw-r--r--glamor/glamor_pixmap.c509
-rw-r--r--glamor/glamor_points.c3
-rw-r--r--glamor/glamor_polylines.c136
-rw-r--r--glamor/glamor_prepare.c274
-rw-r--r--glamor/glamor_prepare.h (renamed from glamor/glamor_segment.c)40
-rw-r--r--glamor/glamor_priv.h251
-rw-r--r--glamor/glamor_program.c56
-rw-r--r--glamor/glamor_program.h6
-rw-r--r--glamor/glamor_render.c89
-rw-r--r--glamor/glamor_segs.c188
-rw-r--r--glamor/glamor_spans.c3
-rw-r--r--glamor/glamor_text.c6
-rw-r--r--glamor/glamor_tile.c293
-rw-r--r--glamor/glamor_transfer.c48
-rw-r--r--glamor/glamor_transform.c72
-rw-r--r--glamor/glamor_trapezoid.c22
-rw-r--r--glamor/glamor_utils.c79
-rw-r--r--glamor/glamor_utils.h218
-rw-r--r--glamor/glamor_xv.c265
-rw-r--r--hw/kdrive/ephyr/Makefile.am5
-rw-r--r--hw/kdrive/ephyr/ephyr.c4
-rw-r--r--hw/kdrive/ephyr/ephyr.h10
-rw-r--r--hw/kdrive/ephyr/ephyr_glamor_glx.c24
-rw-r--r--hw/kdrive/ephyr/ephyr_glamor_xv.c161
-rw-r--r--hw/kdrive/ephyr/ephyrinit.c12
-rw-r--r--hw/kdrive/ephyr/ephyrvideo.c34
-rw-r--r--hw/kdrive/ephyr/hostx.c34
-rw-r--r--hw/kdrive/src/kxv.c81
-rw-r--r--hw/kdrive/src/kxv.h23
-rw-r--r--hw/xfree86/common/xf86xv.c53
-rw-r--r--hw/xfree86/common/xf86xv.h36
-rw-r--r--hw/xfree86/glamor_egl/Makefile.am3
-rw-r--r--hw/xfree86/glamor_egl/glamor_xf86_xv.c185
-rw-r--r--mi/mi.h11
-rw-r--r--mi/miarc.c11
-rw-r--r--mi/mifillarc.c146
-rw-r--r--mi/miwideline.c20
-rw-r--r--mi/mizerarc.c2
-rw-r--r--mi/mizerline.c16
55 files changed, 3053 insertions, 3242 deletions
diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index bde58b632..334d8fc20 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -7,20 +7,21 @@ AM_CFLAGS = $(CWARNFLAGS) $(DIX_CFLAGS) $(GLAMOR_CFLAGS)
libglamor_la_SOURCES = \
glamor.c \
glamor_context.h \
- glamor_copyarea.c \
- glamor_copywindow.c \
+ glamor_copy.c \
glamor_core.c \
+ glamor_dash.c \
glamor_debug.h \
- glamor_fill.c \
glamor_font.c \
glamor_font.h \
glamor_glx.c \
glamor_glyphs.c \
- glamor_polylines.c \
- glamor_segment.c \
glamor_image.c \
+ glamor_lines.c \
+ glamor_segs.c \
glamor_render.c \
glamor_gradient.c \
+ glamor_prepare.c \
+ glamor_prepare.h \
glamor_program.c \
glamor_program.h \
glamor_rects.c \
@@ -31,10 +32,8 @@ libglamor_la_SOURCES = \
glamor_transform.c \
glamor_transform.h \
glamor_trapezoid.c \
- glamor_tile.c \
glamor_triangles.c\
glamor_addtraps.c\
- glamor_copyplane.c\
glamor_glyphblt.c\
glamor_points.c\
glamor_priv.h\
@@ -45,7 +44,9 @@ libglamor_la_SOURCES = \
glamor_window.c\
glamor_fbo.c\
glamor_compositerects.c\
+ glamor_utils.c\
glamor_utils.h\
+ glamor_xv.c \
glamor.h
libglamor_egl_stubs_la_SOURCES = glamor_egl_stubs.c
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 358890375..d7b8b09a9 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -35,10 +35,9 @@
#include "glamor_priv.h"
-static DevPrivateKeyRec glamor_screen_private_key_index;
-DevPrivateKey glamor_screen_private_key = &glamor_screen_private_key_index;
-static DevPrivateKeyRec glamor_pixmap_private_key_index;
-DevPrivateKey glamor_pixmap_private_key = &glamor_pixmap_private_key_index;
+DevPrivateKeyRec glamor_screen_private_key;
+DevPrivateKeyRec glamor_pixmap_private_key;
+DevPrivateKeyRec glamor_gc_private_key;
/**
* 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);
pixmap_priv = dixLookupPrivate(&pixmap->devPrivates,
- glamor_pixmap_private_key);
+ &glamor_pixmap_private_key);
if (pixmap_priv == NULL) {
pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
glamor_set_pixmap_private(pixmap, pixmap_priv);
@@ -251,11 +250,6 @@ glamor_block_handler(ScreenPtr screen)
glamor_priv->tick++;
glFlush();
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
@@ -330,13 +324,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
return FALSE;
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,
"glamor%d: Failed to allocate screen private\n",
screen->myNum);
@@ -345,11 +334,19 @@ glamor_init(ScreenPtr screen, unsigned int flags)
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,
"glamor%d: Failed to allocate pixmap private\n",
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())
@@ -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_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");
glamor_priv->has_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_VIEWPORT_DIMS, max_viewport_size);
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_pixmap_fbo(screen);
- glamor_init_solid_shader(screen);
- glamor_init_tile_shader(screen);
#ifdef GLAMOR_TRAPEZOID_SHADER
glamor_init_trapezoid_shader(screen);
#endif
@@ -538,8 +541,6 @@ glamor_release_screen_priv(ScreenPtr screen)
#endif
glamor_fini_vbo(screen);
glamor_fini_pixmap_fbo(screen);
- glamor_fini_solid_shader(screen);
- glamor_fini_tile_shader(screen);
#ifdef GLAMOR_TRAPEZOID_SHADER
glamor_fini_trapezoid_shader(screen);
#endif
@@ -559,7 +560,7 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
glamor_pixmap_private *old_priv;
glamor_pixmap_fbo *fbo;
- old_priv = dixGetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
+ old_priv = dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
if (priv) {
assert(old_priv == NULL);
@@ -572,7 +573,7 @@ glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
free(old_priv);
}
- dixSetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key, priv);
+ dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key, priv);
}
Bool
diff --git a/glamor/glamor.h b/glamor/glamor.h
index b0f2212d9..405dbe8ed 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -63,7 +63,7 @@ typedef enum glamor_pixmap_type {
} glamor_pixmap_type_t;
#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_PICTURE_SCREEN (1 << 2)
#define GLAMOR_USE_EGL_SCREEN (1 << 3)
@@ -79,12 +79,6 @@ typedef enum glamor_pixmap_type {
* @screen: Current screen pointer.
* @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:
* If running in an pre-existing X environment, and the
* 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,
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 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,
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,
PicturePtr source,
PicturePtr mask,
diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
new file mode 100644
index 000000000..bfcde43db
--- /dev/null
+++ b/glamor/glamor_copy.c
@@ -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;
+}
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
deleted file mode 100644
index e1988225f..000000000
--- a/glamor/glamor_copyarea.c
+++ /dev/null
@@ -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(&region, box, nbox);
- extent = RegionExtents(&region);
-
- 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(&region, dst_x_off, dst_y_off);
- if (!force_clip)
- clipped_dst_regions =
- glamor_compute_clipped_regions(dst_pixmap_priv, &region,
- &n_dst_region, 0, reverse,
- upsidedown);
- else
- clipped_dst_regions =
- glamor_compute_clipped_regions_ext(dst_pixmap_priv, &region,
- &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(&region);
- 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);
-}
diff --git a/glamor/glamor_copyplane.c b/glamor/glamor_copyplane.c
deleted file mode 100644
index 2bd2de30d..000000000
--- a/glamor/glamor_copyplane.c
+++ /dev/null
@@ -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);
-}
diff --git a/glamor/glamor_copywindow.c b/glamor/glamor_copywindow.c
deleted file mode 100644
index 1ced4b336..000000000
--- a/glamor/glamor_copywindow.c
+++ /dev/null
@@ -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);
-}
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index b34943761..737b2744b 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -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,
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]);
}
-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 = {
.FillSpans = glamor_fill_spans,
.SetSpans = glamor_set_spans,
@@ -432,6 +315,58 @@ GCOps glamor_gc_ops = {
.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
* 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;
}
+ if (changes & GCStipple)
+ glamor_invalidate_stipple(gc);
+
if (changes & GCStipple && gc->stipple) {
/* We can't inline stipple handling like we do for GCTile because
* it sets fbgc privates.
@@ -515,14 +453,38 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr 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;
}
+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 = {
glamor_validate_gc,
miChangeGC,
miCopyGC,
- miDestroyGC,
+ glamor_destroy_gc,
miChangeClip,
miDestroyClip,
miCopyClip
@@ -535,6 +497,10 @@ static GCFuncs glamor_gc_funcs = {
int
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))
return FALSE;
diff --git a/glamor/glamor_dash.c b/glamor/glamor_dash.c
new file mode 100644
index 000000000..e8f60fa10
--- /dev/null
+++ b/glamor/glamor_dash.c
@@ -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;
+}
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
deleted file mode 100644
index 073904d2a..000000000
--- a/glamor/glamor_fill.c
+++ /dev/null
@@ -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(&region, box, nbox);
- clipped_regions =
- glamor_compute_clipped_regions(pixmap_priv, &region, &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(&region);
- }
- 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;
-}
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index 1c511ff2b..73b1df51e 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -56,7 +56,8 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
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);
if (!prog)
goto bail_ctx;
@@ -74,7 +75,8 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
int off_x, off_y;
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;
num_points = 0;
@@ -105,10 +107,12 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
if (!num_points) {
points = glamor_get_vbo_space(screen,
- max_points * (2 * sizeof (INT16)),
+ max_points *
+ (2 * sizeof (INT16)),
&vbo_offset);
- glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT,
+ glVertexAttribPointer(GLAMOR_VERTEX_POS,
+ 2, GL_SHORT,
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,
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;
miPolyGlyphBlt(drawable, gc, start_x, y, nglyph,
ppci, pglyph_base);
@@ -160,10 +165,13 @@ glamor_poly_glyph_blt_nf(DrawablePtr drawable, GCPtr gc,
int start_x, int y, unsigned int nglyph,
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;
- 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;
+ }
miPolyGlyphBlt(drawable, gc, start_x, y, nglyph,
ppci, pglyph_base);
return TRUE;
@@ -179,8 +187,8 @@ glamor_image_glyph_blt_nf(DrawablePtr drawable, GCPtr gc,
}
static Bool
-glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap,
- DrawablePtr drawable, int w, int h, int x, int y)
+glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
+ DrawablePtr drawable, int w, int h, int x, int y)
{
ScreenPtr screen = drawable->pScreen;
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;
uint8_t *bitmap_data = bitmap->devPrivate.ptr;
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;
- GLfloat xscale, yscale;
- float color[4];
- unsigned long fg_pixel = gc->fgPixel;
- float *points, *next_point;
- int num_points = 0;
+ int num_points;
+ INT16 *points = NULL;
char *vbo_offset;
- RegionPtr clip;
if (w * h > MAXINT / (2 * sizeof(float)))
- return FALSE;
-
- if (gc->fillStyle != FillSolid) {
- glamor_fallback("gc fillstyle not solid\n");
- return FALSE;
- }
+ goto bail;
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
- return FALSE;
+ goto bail;
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)) {
- glamor_fallback("Failed to set planemask in %s.\n", __FUNCTION__);
- return FALSE;
- }
-
- glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
-
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
- pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
- glUseProgram(glamor_priv->solid_prog);
+ prog = glamor_use_program_fill(pixmap, gc,
+ &glamor_priv->poly_glyph_blt_progs,
+ &glamor_facet_poly_glyph_blt);
+ if (!prog)
+ goto bail_ctx;
- 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);
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
- points = glamor_get_vbo_space(screen, w * h * sizeof(float) * 2,
+ points = glamor_get_vbo_space(screen, w * h * sizeof(INT16) * 2,
&vbo_offset);
- next_point = points;
-
- clip = fbGetCompositeClip(gc);
+ num_points = 0;
/* Note that because fb sets miTranslate in the GC, our incoming X
* and Y are in screen coordinate space (same for spans, but not
* other operations).
*/
+
for (yy = 0; yy < h; yy++) {
uint8_t *bitmap_row = bitmap_data + yy * bitmap_stride;
for (xx = 0; xx < w; xx++) {
@@ -255,63 +238,58 @@ glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap,
x + xx,
y + yy,
NULL)) {
- next_point[0] = v_from_x_coord_x(xscale, x + xx + off_x + 0.5);
- if (glamor_priv->yInverted)
- 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;
+ *points++ = x + xx;
+ *points++ = y + yy;
num_points++;
}
}
}
- glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
- GL_FALSE, 2 * sizeof(float),
- vbo_offset);
- glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT,
+ GL_FALSE, 0, vbo_offset);
glamor_put_vbo_space(screen);
- glDrawArrays(GL_POINTS, 0, num_points);
-
- glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-
- 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;
+ 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);
- 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;
+ glDrawArrays(GL_POINTS, 0, num_points);
}
- miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
+ glDisable(GL_COLOR_LOGIC_OP);
+ glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
return TRUE;
+
+bail_ctx:
+ glDisable(GL_COLOR_LOGIC_OP);
+bail:
+ return FALSE;
}
void
glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
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
-glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap,
- DrawablePtr pDrawable, int w, int h, int x, int y)
+glamor_push_pixels_nf(GCPtr gc, PixmapPtr bitmap,
+ 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;
}
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index 42f5f65f6..f570d7519 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -168,7 +168,7 @@ clear_mask_cache(struct glamor_glyph_mask_cache *maskcache)
struct glamor_glyph_mask_cache_entry *mce;
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];
while (cnt--) {
mce->width = 0;
@@ -448,9 +448,9 @@ glamor_glyph_cache_upload_glyph(ScreenPtr screen,
box.y1 = y;
box.x2 = x + glyph->info.width;
box.y2 = y + glyph->info.height;
- glamor_copy_n_to_n_nf(&scratch->drawable,
- &pCachePixmap->drawable, NULL,
- &box, 1, -x, -y, FALSE, FALSE, 0, NULL);
+ glamor_copy(&scratch->drawable,
+ &pCachePixmap->drawable, NULL,
+ &box, 1, -x, -y, FALSE, FALSE, 0, NULL);
if (scratch != pGlyphPixmap)
screen->DestroyPixmap(scratch);
@@ -1433,7 +1433,7 @@ glamor_glyphs_via_mask(CARD8 op,
glamor_destroy_pixmap(mask_pixmap);
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);
mask = CreatePicture(0, &mask_pixmap->drawable,
mask_format, CPComponentAlpha,
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index 28d66917f..4ded89dcd 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -699,7 +699,7 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
width),
(INT16) (dst_picture->pDrawable->
height),
- glamor_priv->yInverted, vertices);
+ vertices);
if (tex_normalize) {
glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale,
@@ -710,17 +710,14 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
(INT16) (dst_picture->
pDrawable->height +
y_source),
- glamor_priv->yInverted,
tex_vertices);
}
else {
- glamor_set_tcoords_tri_strip((INT16) (dst_picture->pDrawable->width),
- (INT16) (dst_picture->pDrawable->height),
- x_source, y_source,
+ glamor_set_tcoords_tri_strip(x_source, y_source,
(INT16) (dst_picture->pDrawable->width) +
x_source,
(INT16) (dst_picture->pDrawable->height) +
- y_source, glamor_priv->yInverted,
+ y_source,
tex_vertices);
}
@@ -1084,13 +1081,11 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
r2 = (float) pixman_fixed_to_double(src_picture->pSourcePict->radial.c2.
radius);
- glamor_set_circle_centre(width, height, c1x, c1y, glamor_priv->yInverted,
- cxy);
+ glamor_set_circle_centre(width, height, c1x, c1y, cxy);
glUniform2fv(c1_uniform_location, 1, cxy);
glUniform1f(r1_uniform_location, r1);
- glamor_set_circle_centre(width, height, c2x, c2y, glamor_priv->yInverted,
- cxy);
+ glamor_set_circle_centre(width, height, c2x, c2y, cxy);
glUniform2fv(c2_uniform_location, 1, cxy);
glUniform1f(r2_uniform_location, r2);
@@ -1322,7 +1317,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
linear.p1.x),
pixman_fixed_to_double(src_picture->pSourcePict->
linear.p1.y),
- glamor_priv->yInverted, pt1);
+ pt1);
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.y),
@@ -1333,7 +1328,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
linear.p2.x),
pixman_fixed_to_double(src_picture->pSourcePict->
linear.p2.y),
- glamor_priv->yInverted, pt2);
+ pt2);
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.y),
diff --git a/glamor/glamor_largepixmap.c b/glamor/glamor_largepixmap.c
index b3a8d5d20..5a4bec571 100644
--- a/glamor/glamor_largepixmap.c
+++ b/glamor/glamor_largepixmap.c
@@ -797,9 +797,9 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
copy_box.y2 = temp_extent->y2 - temp_extent->y1;
dx = temp_extent->x1;
dy = temp_extent->y1;
- glamor_copy_n_to_n(&priv->base.pixmap->drawable,
- &temp_pixmap->drawable,
- NULL, &copy_box, 1, dx, dy, 0, 0, 0, NULL);
+ glamor_copy(&priv->base.pixmap->drawable,
+ &temp_pixmap->drawable,
+ NULL, &copy_box, 1, dx, dy, 0, 0, 0, NULL);
// glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width,
// 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.y2, dx, dy);
- glamor_copy_n_to_n(&priv->base.pixmap->drawable,
- &temp_pixmap->drawable,
- NULL, &copy_box, 1, dx, dy, 0, 0, 0, NULL);
+ glamor_copy(&priv->base.pixmap->drawable,
+ &temp_pixmap->drawable,
+ NULL, &copy_box, 1, dx, dy, 0, 0, 0, NULL);
+
box++;
}
}
diff --git a/glamor/glamor_lines.c b/glamor/glamor_lines.c
new file mode 100644
index 000000000..e9a619505
--- /dev/null
+++ b/glamor/glamor_lines.c
@@ -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;
+}
+
diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c
index 5fdc5f9b0..cbbc19406 100644
--- a/glamor/glamor_picture.c
+++ b/glamor/glamor_picture.c
@@ -45,24 +45,6 @@ glamor_upload_picture_to_texture(PicturePtr picture)
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.
* Then set the attached pixmap to is_picture format, and set
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 789d3772e..ccb49f3c6 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -747,11 +747,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
glamor_get_screen_private(pixmap->drawable.pScreen);
static float vertices[8];
- static float texcoords[8] = { 0, 1,
- 1, 1,
- 1, 0,
- 0, 0
- };
static float texcoords_inv[8] = { 0, 0,
1, 0,
1, 1,
@@ -760,11 +755,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
float *ptexcoords;
float dst_xscale, dst_yscale;
GLuint tex = 0;
- int need_flip;
int need_free_bits = 0;
- need_flip = !glamor_priv->yInverted;
-
if (bits == NULL)
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
* to the fbo directly. */
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
&& pixmap_priv->type != GLAMOR_TEXTURE_LARGE
#endif
@@ -818,17 +810,14 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
return TRUE;
}
- if (need_flip)
- ptexcoords = texcoords;
- else
- ptexcoords = texcoords_inv;
+ ptexcoords = texcoords_inv;
pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
dst_yscale,
x, y,
x + w, y + h,
- glamor_priv->yInverted, vertices);
+ vertices);
/* Slow path, we need to flip y or wire alpha to 1. */
glamor_make_current(glamor_priv);
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.
* 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
glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
int revert, int swap_rb)
@@ -896,8 +882,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
return 0;
if (!(no_alpha || (revert == REVERT_NORMAL)
- || (swap_rb != SWAP_NONE_UPLOADING)
- || !glamor_priv->yInverted)) {
+ || (swap_rb != SWAP_NONE_UPLOADING))) {
/* We don't need a fbo, a simple texture uploading should work. */
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
glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
int h, int stride, void *bits, int pbo)
@@ -1100,13 +1065,6 @@ glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
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
* 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,
temp_xscale, temp_yscale, 0, 0, w, h,
- glamor_priv->yInverted, vertices);
+ vertices);
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
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,
x, y,
x + w, y + h,
- glamor_priv->yInverted, texcoords);
+ texcoords);
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
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;
}
-/*
- * 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(&region, &box, 1);
-
- if (!force_clip)
- clipped_regions =
- glamor_compute_clipped_regions(pixmap_priv, &region, &n_region,
- 0, 0, 0);
- else
- clipped_regions =
- glamor_compute_clipped_regions_ext(pixmap_priv, &region,
- &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(&region);
- 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(&region);
- 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. */
/* XXX LARGE pixmap? */
Bool
@@ -1558,132 +1192,3 @@ glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
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);
-}
diff --git a/glamor/glamor_points.c b/glamor/glamor_points.c
index d4525e294..84383d254 100644
--- a/glamor/glamor_points.c
+++ b/glamor/glamor_points.c
@@ -105,9 +105,6 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
glDisable(GL_COLOR_LOGIC_OP);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- glamor_priv->state = RENDER_STATE;
- glamor_priv->render_idle_cnt = 0;
-
return TRUE;
bail_ctx:
diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c
deleted file mode 100644
index 1adf45ddc..000000000
--- a/glamor/glamor_polylines.c
+++ /dev/null
@@ -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);
-}
diff --git a/glamor/glamor_prepare.c b/glamor/glamor_prepare.c
new file mode 100644
index 000000000..561c55d19
--- /dev/null
+++ b/glamor/glamor_prepare.c
@@ -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(&region, 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(&region, &region, &priv->base.prepare_region);
+ if (!RegionNotEmpty(&region))
+ 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(&region), RegionNumRects(&region),
+ 0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind);
+
+ RegionUninit(&region);
+
+ 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;
+ }
+}
diff --git a/glamor/glamor_segment.c b/glamor/glamor_prepare.h
index 53f7da0cb..85fa79574 100644
--- a/glamor/glamor_segment.c
+++ b/glamor/glamor_prepare.h
@@ -20,25 +20,33 @@
* OF THIS SOFTWARE.
*/
-#include "glamor_priv.h"
+#ifndef _GLAMOR_PREPARE_H_
+#define _GLAMOR_PREPARE_H_
Bool
-glamor_poly_segment_nf(DrawablePtr drawable, GCPtr gc, int nseg,
- xSegment *seg)
-{
- if (glamor_ddx_fallback_check_pixmap(drawable) &&
- glamor_ddx_fallback_check_gc(gc)) {
- return FALSE;
- }
+glamor_prepare_access(DrawablePtr drawable, glamor_access_t access);
- miPolySegment(drawable, gc, nseg, seg);
+Bool
+glamor_prepare_access_box(DrawablePtr drawable, glamor_access_t access,
+ int x, int y, int w, int h);
+
+void
+glamor_finish_access(DrawablePtr drawable);
- return TRUE;
-}
+Bool
+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_poly_segment(DrawablePtr drawable, GCPtr gc, int nseg,
- xSegment *seg)
-{
- miPolySegment(drawable, gc, nseg, seg);
-}
+glamor_finish_access_picture(PicturePtr picture);
+
+Bool
+glamor_prepare_access_gc(GCPtr gc);
+
+void
+glamor_finish_access_gc(GCPtr gc);
+
+#endif /* _GLAMOR_PREPARE_H_ */
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index c56c55973..2a9eccef4 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -31,6 +31,7 @@
#include <xorg-server.h>
#include "glamor.h"
+#include "xvdix.h"
#include <epoxy/gl.h>
#if GLAMOR_HAS_GBM
@@ -193,13 +194,7 @@ struct glamor_saved_procs {
#define GLAMOR_TICK_AFTER(t0, t1) \
(((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 {
- Bool yInverted;
unsigned int tick;
enum glamor_gl_flavor gl_flavor;
int glsl_version;
@@ -208,16 +203,14 @@ typedef struct glamor_screen_private {
int has_map_buffer_range;
int has_buffer_storage;
int has_khr_debug;
+ int has_nv_texture_barrier;
int max_fbo_size;
+ int has_rw_pbo;
struct xorg_list
fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
unsigned long fbo_cache_watermark;
- /* glamor_solid */
- GLint solid_prog;
- GLint solid_color_uniform_location;
-
/* glamor point shader */
glamor_program point_prog;
@@ -235,6 +228,20 @@ typedef struct glamor_screen_private {
glamor_program te_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 */
GLuint vbo, ebo;
/** 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_swap_rb[2];
- /* glamor_tile */
- GLint tile_prog;
- GLint tile_wh;
-
/* glamor gradient, 0 for small nstops, 1 for
large nstops and 2 for dynamic generate. */
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];
int delayed_fallback_pending;
int flags;
- int state;
- unsigned int render_idle_cnt;
ScreenPtr screen;
int dri3_enabled;
@@ -430,6 +431,9 @@ typedef struct glamor_pixmap_private_base {
int drm_stride;
glamor_screen_private *glamor_priv;
PicturePtr picture;
+ GLuint pbo;
+ RegionRec prepare_region;
+ Bool prepared;
#if GLAMOR_HAS_GBM
EGLImageKHR image;
#endif
@@ -528,7 +532,7 @@ glamor_pixmap_hcnt(glamor_pixmap_private *priv)
for (y = 0; y < glamor_pixmap_hcnt(priv); y++) \
for (x = 0; x < glamor_pixmap_wcnt(priv); x++)
-/*
+/*
* Pixmap dynamic status, used by dynamic upload feature.
*
* GLAMOR_NONE: initial status, don't need to do anything.
@@ -544,19 +548,29 @@ typedef enum glamor_pixmap_status {
GLAMOR_UPLOAD_FAILED
} glamor_pixmap_status_t;
-extern DevPrivateKey glamor_screen_private_key;
-extern DevPrivateKey glamor_pixmap_private_key;
+/* GC private structure. Currently holds only any computed dash pixmap */
+
+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 *
glamor_get_screen_private(ScreenPtr screen)
{
return (glamor_screen_private *)
- dixLookupPrivate(&screen->devPrivates, glamor_screen_private_key);
+ dixLookupPrivate(&screen->devPrivates, &glamor_screen_private_key);
}
static inline void
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 *
@@ -564,17 +578,23 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
{
glamor_pixmap_private *priv;
- priv = dixLookupPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
+ priv = dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
if (!priv) {
glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
priv = dixLookupPrivate(&pixmap->devPrivates,
- glamor_pixmap_private_key);
+ &glamor_pixmap_private_key);
}
return 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
* 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,
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 */
-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_fini_finish_access_shaders(ScreenPtr screen);
+
const Bool glamor_get_drawable_location(const DrawablePtr drawable);
void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
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);
void glamor_link_glsl_prog(ScreenPtr screen, GLint prog,
const char *format, ...) _X_ATTRIBUTE_PRINTF(3,4);
@@ -651,7 +652,7 @@ int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv);
void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *, int, int, int, int);
/* nc means no check. caller must ensure this pixmap has valid fbo.
- * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly.
+ * usually use the GLAMOR_PIXMAP_PRIV_HAS_FBO firstly.
* */
void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv);
@@ -665,17 +666,8 @@ Bool glamor_set_alu(ScreenPtr screen, unsigned char alu);
Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
-/* glamor_fill.c */
-Bool glamor_fill(DrawablePtr drawable,
- 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);
+void
+glamor_track_stipple(GCPtr gc);
/* glamor_glyphs.c */
Bool glamor_realize_glyph_caches(ScreenPtr screen);
@@ -687,10 +679,6 @@ void glamor_glyphs(CARD8 op,
INT16 xSrc,
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 */
Bool glamor_composite_clipped_region(CARD8 op,
PicturePtr source,
@@ -756,14 +744,6 @@ void glamor_trapezoids(CARD8 op,
PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
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 */
void glamor_init_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
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,
* 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 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_compute_clipped_regions(glamor_pixmap_private *priv,
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,
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);
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);
/* 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,
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 */
int glamor_poly_text8(DrawablePtr pDrawable, GCPtr pGC,
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,
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 */
void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
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,
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,
PicturePtr dst,
xRenderColor *color,
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 */
typedef struct {
uint32_t transform_index;
@@ -1028,15 +1009,41 @@ typedef struct {
int src_pix_w, src_pix_h;
} glamor_port_private;
-void glamor_init_xv_shader(ScreenPtr screen);
-void glamor_fini_xv_shader(ScreenPtr screen);
+extern XvAttributeRec glamor_xv_attributes[];
+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"
-/* Dynamic pixmap upload to texture if needed.
+/* Dynamic pixmap upload to texture if needed.
* Sometimes, the target is a gl texture pixmap/picture,
* but the source or mask is in cpu memory. In that case,
- * upload the source/mask to gl texture and then avoid
+ * upload the source/mask to gl texture and then avoid
* fallback the whole process to cpu. Most of the time,
* this will increase performance obviously. */
diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
index 0f4d0f06a..1d0328f2b 100644
--- a/glamor/glamor_program.c
+++ b/glamor/glamor_program.c
@@ -51,42 +51,51 @@ static const glamor_facet glamor_fill_tile = {
.use = use_tile,
};
-#if 0
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 = {
.name = "stipple",
- .version = 130,
- .vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n";
- .fs_exec = (" if (texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0).x == 0)\n"
+ .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
+ .fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n"
+ " if (a == 0.0)\n"
" discard;\n"
- " gl_FragColor = fg;\n")
- .locations = glamor_program_location_fg | glamor_program_location_fill
+ " gl_FragColor = fg;\n"),
+ .locations = glamor_program_location_fg | glamor_program_location_fill,
.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 = {
.name = "opaque_stipple",
- .version = 130,
- .vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n";
- .fs_exec = (" if (texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0).x == 0)\n"
+ .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
+ .fs_exec = (" float a = texture2D(sampler, fill_pos).w;\n"
+ " if (a == 0.0)\n"
" gl_FragColor = bg;\n"
" else\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
};
-#endif
static const glamor_facet *glamor_facet_fill[4] = {
&glamor_fill_solid,
&glamor_fill_tile,
- NULL,
- NULL,
+ &glamor_fill_stipple,
+ &glamor_fill_opaque_stipple,
};
typedef struct {
@@ -117,6 +126,16 @@ static glamor_location_var location_vars[] = {
.location = glamor_program_location_font,
.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])
@@ -196,6 +215,8 @@ static const glamor_facet facet_null_fill = {
.name = ""
};
+#define DBG 0
+
static GLint
glamor_get_uniform(glamor_program *prog,
glamor_program_location location,
@@ -281,7 +302,6 @@ glamor_build_program(ScreenPtr screen,
if (!vs_prog_string || !fs_prog_string)
goto fail;
-#define DBG 0
#if DBG
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);
@@ -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_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->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)
goto fail;
diff --git a/glamor/glamor_program.h b/glamor/glamor_program.h
index 88efc3593..56ba03aa8 100644
--- a/glamor/glamor_program.h
+++ b/glamor/glamor_program.h
@@ -29,6 +29,8 @@ typedef enum {
glamor_program_location_bg = 2,
glamor_program_location_fill = 4,
glamor_program_location_font = 8,
+ glamor_program_location_bitplane = 16,
+ glamor_program_location_dash = 32,
} glamor_program_location;
typedef enum {
@@ -61,6 +63,10 @@ struct _glamor_program {
GLint fill_size_uniform;
GLint fill_offset_uniform;
GLint font_uniform;
+ GLint bitplane_uniform;
+ GLint bitmul_uniform;
+ GLint dash_uniform;
+ GLint dash_length_uniform;
glamor_program_location locations;
glamor_program_flag flags;
glamor_use prim_use;
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index e5d5d2cb1..2386f2e2e 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -651,11 +651,12 @@ glamor_composite_with_copy(CARD8 op,
if (region->extents.y2 + y_source - y_dest > source->pDrawable->height)
goto cleanup_region;
}
- ret = glamor_copy_n_to_n_nf(source->pDrawable,
- dest->pDrawable, NULL,
- RegionRects(region), RegionNumRects(region),
- x_source - x_dest, y_source - y_dest,
- FALSE, FALSE, 0, NULL);
+ glamor_copy(source->pDrawable,
+ dest->pDrawable, NULL,
+ RegionRects(region), RegionNumRects(region),
+ x_source - x_dest, y_source - y_dest,
+ FALSE, FALSE, 0, NULL);
+ ret = TRUE;
cleanup_region:
return ret;
}
@@ -792,30 +793,29 @@ glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
float *matrix,
float xscale, float yscale,
int x1, int y1, int x2, int y2,
- int yInverted, float *texcoords,
+ float *texcoords,
int stride)
{
if (!matrix && repeat_type == RepeatNone)
glamor_set_normalize_tcoords_ext(priv, xscale, yscale,
x1, y1,
- x2, y2, yInverted, texcoords, stride);
+ x2, y2, texcoords, stride);
else if (matrix && repeat_type == RepeatNone)
glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale,
yscale, x1, y1,
x2, y2,
- yInverted,
texcoords, stride);
else if (!matrix && repeat_type != RepeatNone)
glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type,
xscale, yscale,
x1, y1,
x2, y2,
- yInverted, texcoords, stride);
+ texcoords, stride);
else if (matrix && repeat_type != RepeatNone)
glamor_set_repeat_transformed_normalize_tcoords_ext(priv, repeat_type,
matrix, xscale,
yscale, x1, y1, x2,
- y2, yInverted,
+ y2,
texcoords, stride);
}
@@ -1265,7 +1265,7 @@ glamor_composite_with_shader(CARD8 op,
glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale,
dst_yscale, x_dest, y_dest,
x_dest + width, y_dest + height,
- glamor_priv->yInverted, vertices,
+ vertices,
vb_stride);
vertices += 2;
if (key.source != SHADER_SOURCE_SOLID) {
@@ -1275,7 +1275,6 @@ glamor_composite_with_shader(CARD8 op,
src_yscale, x_source,
y_source, x_source + width,
y_source + height,
- glamor_priv->yInverted,
vertices, vb_stride);
vertices += 2;
}
@@ -1287,7 +1286,6 @@ glamor_composite_with_shader(CARD8 op,
mask_yscale, x_mask,
y_mask, x_mask + width,
y_mask + height,
- glamor_priv->yInverted,
vertices, vb_stride);
vertices += 2;
}
@@ -1315,8 +1313,6 @@ glamor_composite_with_shader(CARD8 op,
glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
glDisable(GL_BLEND);
DEBUGF("finish rendering.\n");
- glamor_priv->state = RENDER_STATE;
- glamor_priv->render_idle_cnt = 0;
if (saved_source_format)
source->format = saved_source_format;
@@ -1586,15 +1582,6 @@ _glamor_composite(CARD8 op,
RegionRec region;
BoxPtr extent;
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;
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
@@ -1737,34 +1724,13 @@ _glamor_composite(CARD8 op,
dest->pDrawable->width, dest->pDrawable->height,
glamor_get_picture_location(dest));
-#define GET_SUB_PICTURE(p, access) do { \
- glamor_get_drawable_deltas(p->pDrawable, p ##_pixmap, \
- & p ##_x_off, & p ##_y_off); \
- sub_ ##p ##_pixmap = glamor_get_sub_pixmap(p ##_pixmap, \
- x_ ##p + p ##_x_off + p->pDrawable->x, \
- y_ ##p + p ##_y_off + p->pDrawable->y, \
- 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)) {
+ if (glamor_prepare_access_picture_box(dest, GLAMOR_ACCESS_RW,
+ x_dest, y_dest, width, height) &&
+ glamor_prepare_access_picture_box(source, GLAMOR_ACCESS_RO,
+ x_source, y_source, width, height) &&
+ glamor_prepare_access_picture_box(mask, GLAMOR_ACCESS_RO,
+ x_mask, y_mask, width, height))
+ {
fbComposite(op,
source, mask, dest,
x_source, y_source,
@@ -1774,25 +1740,6 @@ _glamor_composite(CARD8 op,
glamor_finish_access_picture(source);
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:
return ret;
}
diff --git a/glamor/glamor_segs.c b/glamor/glamor_segs.c
new file mode 100644
index 000000000..ff0daef10
--- /dev/null
+++ b/glamor/glamor_segs.c
@@ -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;
+}
+
diff --git a/glamor/glamor_spans.c b/glamor/glamor_spans.c
index 46ba6c38f..582d11df3 100644
--- a/glamor/glamor_spans.c
+++ b/glamor/glamor_spans.c
@@ -326,9 +326,6 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
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);
glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c
index 6e02b9aa8..59cd0fdc8 100644
--- a/glamor/glamor_text.c
+++ b/glamor/glamor_text.c
@@ -293,9 +293,6 @@ glamor_poly_text(DrawablePtr drawable, GCPtr gc,
glDisable(GL_COLOR_LOGIC_OP);
- glamor_priv->state = RENDER_STATE;
- glamor_priv->render_idle_cnt = 0;
-
*final_pos = x;
return TRUE;
@@ -493,9 +490,6 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
(void) glamor_text(drawable, gc, glamor_font, prog,
x, y, count, chars, charinfo, sixteen);
- glamor_priv->state = RENDER_STATE;
- glamor_priv->render_idle_cnt = 0;
-
return TRUE;
bail:
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
deleted file mode 100644
index 4e479763e..000000000
--- a/glamor/glamor_tile.c
+++ /dev/null
@@ -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(&region, &box, 1);
- clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv,
- &region,
- &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(&region);
- }
- else
- _glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y);
-
- glamor_set_alu(screen, GXcopy);
- return TRUE;
- fail:
- return FALSE;
-
-}
diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c
index ad875c962..891415565 100644
--- a/glamor/glamor_transfer.c
+++ b/glamor/glamor_transfer.c
@@ -72,9 +72,6 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
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_ROW_LENGTH, byte_stride / bytes_per_pixel);
@@ -90,27 +87,14 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
while (nbox--) {
/* compute drawable coordinates */
- int x1 = boxes->x1 + dx_dst;
- int x2 = boxes->x2 + dx_dst;
- int y1 = boxes->y1 + dy_dst;
- int y2 = boxes->y2 + dy_dst;
+ int x1 = MAX(boxes->x1 + dx_dst, box->x1);
+ int x2 = MIN(boxes->x2 + dx_dst, box->x2);
+ int y1 = MAX(boxes->y1 + dy_dst, box->y1);
+ int y2 = MIN(boxes->y2 + dy_dst, box->y2);
boxes++;
- if (x1 < box->x1)
- 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)
+ if (x2 <= x1 || y2 <= y1)
continue;
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--) {
/* compute drawable coordinates */
- int x1 = boxes->x1 + dx_src;
- int x2 = boxes->x2 + dx_src;
- int y1 = boxes->y1 + dy_src;
- int y2 = boxes->y2 + dy_src;
+ int x1 = MAX(boxes->x1 + dx_src, box->x1);
+ int x2 = MIN(boxes->x2 + dx_src, box->x2);
+ int y1 = MAX(boxes->y1 + dy_src, box->y1);
+ int y2 = MIN(boxes->y2 + dy_src, box->y2);
boxes++;
- if (x1 < box->x1)
- 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)
+ if (x2 <= x1 || y2 <= y1)
continue;
glPixelStorei(GL_PACK_SKIP_PIXELS, x1 - dx_src + dx_dst);
diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
index d6ba56421..c1df56018 100644
--- a/glamor/glamor_transform.c
+++ b/glamor/glamor_transform.c
@@ -198,6 +198,64 @@ glamor_set_tiled(PixmapPtr pixmap,
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
glamor_set_stippled(PixmapPtr pixmap,
GCPtr gc,
@@ -205,11 +263,19 @@ glamor_set_stippled(PixmapPtr pixmap,
GLint offset_uniform,
GLint size_uniform)
{
- if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform))
+ PixmapPtr stipple;
+
+ stipple = glamor_get_stipple_pixmap(gc);
+ if (!stipple)
return FALSE;
- if (!glamor_set_texture(pixmap, gc->stipple, gc->patOrg.x, gc->patOrg.y, offset_uniform, size_uniform))
+ if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform))
return FALSE;
- return TRUE;
+ return glamor_set_texture(pixmap,
+ stipple,
+ -gc->patOrg.x,
+ -gc->patOrg.y,
+ offset_uniform,
+ size_uniform);
}
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index 4aba469af..d61d11f79 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -908,7 +908,6 @@ _glamor_trapezoids_with_shader(CARD8 op,
clipped_vtx_tmp[5] = clipped_vtx[(i + 2) * 2 + 1];
glamor_set_normalize_tri_vcoords(dst_xscale, dst_yscale,
clipped_vtx_tmp,
- glamor_priv->yInverted,
vertices);
DEBUGF("vertices of triangle: (%f X %f), (%f X %f), "
"(%f X %f)\n", vertices[0], vertices[1],
@@ -920,14 +919,12 @@ _glamor_trapezoids_with_shader(CARD8 op,
glamor_set_transformed_normalize_tri_tcoords
(source_pixmap_priv, src_matrix, src_xscale,
src_yscale, clipped_vtx_tmp,
- glamor_priv->yInverted, source_texcoords);
+ source_texcoords);
}
else {
glamor_set_normalize_tri_tcoords(src_xscale,
src_yscale,
clipped_vtx_tmp,
- glamor_priv->
- yInverted,
source_texcoords);
}
@@ -1392,12 +1389,8 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
}
/* First, clear all to zero */
- if (!glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width,
- pixmap_priv->base.pixmap->drawable.height,
- GXclear, 0xFFFFFFFF, 0)) {
- DEBUGF("glamor_solid failed, fallback\n");
- return FALSE;
- }
+ glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width,
+ pixmap_priv->base.pixmap->drawable.height, 0);
glamor_make_current(glamor_priv);
@@ -1443,11 +1436,9 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
miTrapezoidBounds(1, ptrap, &one_trap_bound);
vertices += 2;
- glamor_set_tcoords_ext((pixmap_priv->base.pixmap->drawable.width),
- (pixmap_priv->base.pixmap->drawable.height),
- (one_trap_bound.x1), (one_trap_bound.y1),
+ glamor_set_tcoords_ext((one_trap_bound.x1), (one_trap_bound.y1),
(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,"
"rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0],
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.x2,
one_trap_bound.y2,
- glamor_priv->yInverted, vertices,
- stride);
+ vertices, stride);
DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
"rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0],
vertices[1], vertices[1 * stride], vertices[1 * stride + 1],
diff --git a/glamor/glamor_utils.c b/glamor/glamor_utils.c
new file mode 100644
index 000000000..f06896096
--- /dev/null
+++ b/glamor/glamor_utils.c
@@ -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);
+}
+
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 4c1581ef5..c15d17ca3 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -32,6 +32,8 @@
#ifndef __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_y(_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)
#define _glamor_set_normalize_tpoint(xscale, yscale, _tx_, _ty_, \
- texcoord, yInverted) \
+ texcoord) \
do { \
(texcoord)[0] = t_from_x_coord_x(xscale, _tx_); \
- if (_X_LIKELY(yInverted)) \
- (texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_);\
- else \
- (texcoord)[1] = t_from_x_coord_y(yscale, _ty_); \
+ (texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_); \
DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0], \
(texcoord)[1]); \
} while(0)
#define glamor_set_transformed_point(priv, matrix, xscale, \
yscale, texcoord, \
- x, y, \
- yInverted) \
+ x, y) \
do { \
float tx, ty; \
int fbo_x_off, fbo_y_off; \
@@ -337,10 +335,7 @@
tx += fbo_x_off; \
ty += fbo_y_off; \
(texcoord)[0] = t_from_x_coord_x(xscale, tx); \
- if (_X_LIKELY(yInverted)) \
- (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \
- else \
- (texcoord)[1] = t_from_x_coord_y(yscale, ty); \
+ (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \
DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]); \
} while(0)
@@ -349,18 +344,14 @@
xscale, \
yscale, \
vtx, \
- yInverted, \
texcoords) \
do { \
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
- texcoords, (vtx)[0], (vtx)[1], \
- yInverted); \
+ texcoords, (vtx)[0], (vtx)[1]); \
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
- texcoords+2, (vtx)[2], (vtx)[3], \
- yInverted); \
+ texcoords+2, (vtx)[2], (vtx)[3]); \
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
- texcoords+4, (vtx)[4], (vtx)[5], \
- yInverted); \
+ texcoords+4, (vtx)[4], (vtx)[5]); \
} while (0)
#define glamor_set_transformed_normalize_tcoords_ext( priv, \
@@ -368,21 +359,17 @@
xscale, \
yscale, \
tx1, ty1, tx2, ty2, \
- yInverted, texcoords, \
+ texcoords, \
stride) \
do { \
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
- texcoords, tx1, ty1, \
- yInverted); \
+ texcoords, tx1, ty1); \
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
- texcoords + 1 * stride, tx2, ty1, \
- yInverted); \
+ texcoords + 1 * stride, tx2, ty1); \
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
- texcoords + 2 * stride, tx2, ty2, \
- yInverted); \
+ texcoords + 2 * stride, tx2, ty2); \
glamor_set_transformed_point(priv, matrix, xscale, yscale, \
- texcoords + 3 * stride, tx1, ty2, \
- yInverted); \
+ texcoords + 3 * stride, tx1, ty2); \
} while (0)
#define glamor_set_transformed_normalize_tcoords( priv, \
@@ -390,35 +377,31 @@
xscale, \
yscale, \
tx1, ty1, tx2, ty2, \
- yInverted, texcoords) \
+ texcoords) \
do { \
glamor_set_transformed_normalize_tcoords_ext( priv, \
matrix, \
xscale, \
yscale, \
tx1, ty1, tx2, ty2, \
- yInverted, texcoords, \
+ texcoords, \
2); \
} while (0)
#define glamor_set_normalize_tri_tcoords(xscale, \
yscale, \
vtx, \
- yInverted, \
texcoords) \
do { \
_glamor_set_normalize_tpoint(xscale, yscale, \
(vtx)[0], (vtx)[1], \
- texcoords, \
- yInverted); \
+ texcoords); \
_glamor_set_normalize_tpoint(xscale, yscale, \
(vtx)[2], (vtx)[3], \
- texcoords+2, \
- yInverted); \
+ texcoords+2); \
_glamor_set_normalize_tpoint(xscale, yscale, \
(vtx)[4], (vtx)[5], \
- texcoords+4, \
- yInverted); \
+ texcoords+4); \
} while (0)
#define glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \
@@ -428,14 +411,13 @@
yscale, \
_x1_, _y1_, \
_x2_, _y2_, \
- yInverted, \
texcoords, \
stride) \
do { \
if (_X_LIKELY(priv->type != GLAMOR_TEXTURE_LARGE)) { \
glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, \
yscale, _x1_, _y1_, \
- _x2_, _y2_, yInverted, \
+ _x2_, _y2_, \
texcoords, stride); \
} else { \
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, \
ttx2, tty2, ttx3, tty3, ttx4, tty4); \
_glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1, \
- texcoords, yInverted); \
+ texcoords); \
_glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2, \
- texcoords + 1 * stride, yInverted); \
+ texcoords + 1 * stride); \
_glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3, \
- texcoords + 2 * stride, yInverted); \
+ texcoords + 2 * stride); \
_glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4, \
- texcoords + 3 * stride, yInverted); \
+ texcoords + 3 * stride); \
} \
} while (0)
@@ -479,7 +461,6 @@
yscale, \
_x1_, _y1_, \
_x2_, _y2_, \
- yInverted, \
texcoords) \
do { \
glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \
@@ -489,14 +470,13 @@
yscale, \
_x1_, _y1_, \
_x2_, _y2_, \
- yInverted, \
texcoords, \
2); \
} while (0)
#define _glamor_set_normalize_tcoords(xscale, yscale, tx1, \
ty1, tx2, ty2, \
- yInverted, vertices, stride) \
+ vertices, stride) \
do { \
/* vertices may be write-only, so we use following \
* temporary variable. */ \
@@ -505,21 +485,15 @@
(vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2); \
(vertices)[2 * stride] = _t2_; \
(vertices)[3 * stride] = _t0_; \
- if (_X_LIKELY(yInverted)) { \
- (vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1); \
- (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] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1); \
+ (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2); \
(vertices)[1 * stride + 1] = _t1_; \
(vertices)[3 * stride + 1] = _t5_; \
} while(0)
#define glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \
x1, y1, x2, y2, \
- yInverted, vertices, stride) \
+ vertices, stride) \
do { \
if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \
float tx1, tx2, ty1, ty2; \
@@ -530,26 +504,26 @@
ty1 = y1 + fbo_y_off; \
ty2 = y2 + fbo_y_off; \
_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \
- tx2, ty2, yInverted, vertices, \
+ tx2, ty2, vertices, \
stride); \
} else \
_glamor_set_normalize_tcoords(xscale, yscale, x1, y1, \
- x2, y2, yInverted, vertices, stride);\
+ x2, y2, vertices, stride); \
} while(0)
#define glamor_set_normalize_tcoords(priv, xscale, yscale, \
x1, y1, x2, y2, \
- yInverted, vertices) \
+ vertices) \
do { \
glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \
x1, y1, x2, y2, \
- yInverted, vertices, 2); \
+ vertices, 2); \
} while(0)
#define glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \
xscale, yscale, \
_x1_, _y1_, _x2_, _y2_, \
- yInverted, vertices, stride)\
+ vertices, stride) \
do { \
if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \
float tx1, tx2, ty1, ty2; \
@@ -564,130 +538,99 @@
_x1_, _y1_, _x2_, _y2_); \
} \
_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \
- tx2, ty2, yInverted, vertices, \
+ tx2, ty2, vertices, \
stride); \
} else \
_glamor_set_normalize_tcoords(xscale, yscale, _x1_, _y1_, \
- _x2_, _y2_, yInverted, vertices, \
+ _x2_, _y2_, vertices, \
stride); \
} while(0)
#define glamor_set_repeat_normalize_tcoords(priv, repeat_type, \
xscale, yscale, \
_x1_, _y1_, _x2_, _y2_, \
- yInverted, vertices) \
+ vertices) \
do { \
glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \
xscale, yscale, \
_x1_, _y1_, _x2_, _y2_, \
- yInverted, vertices, 2); \
+ vertices, 2); \
} while(0)
#define glamor_set_normalize_tcoords_tri_stripe(xscale, yscale, \
x1, y1, x2, y2, \
- yInverted, vertices) \
+ vertices) \
do { \
(vertices)[0] = t_from_x_coord_x(xscale, x1); \
(vertices)[2] = t_from_x_coord_x(xscale, x2); \
(vertices)[6] = (vertices)[2]; \
(vertices)[4] = (vertices)[0]; \
- if (_X_LIKELY(yInverted)) { \
- (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \
- (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)[1] = t_from_x_coord_y_inverted(yscale, y1); \
+ (vertices)[7] = t_from_x_coord_y_inverted(yscale, y2); \
(vertices)[3] = (vertices)[1]; \
(vertices)[5] = (vertices)[7]; \
} while(0)
-#define glamor_set_tcoords(width, height, x1, y1, x2, y2, \
- yInverted, vertices) \
+#define glamor_set_tcoords(x1, y1, x2, y2, vertices) \
do { \
(vertices)[0] = (x1); \
(vertices)[2] = (x2); \
(vertices)[4] = (vertices)[2]; \
(vertices)[6] = (vertices)[0]; \
- if (_X_LIKELY(yInverted)) { \
- (vertices)[1] = (y1); \
- (vertices)[5] = (y2); \
- } \
- else { \
- (vertices)[1] = height - (y2); \
- (vertices)[5] = height - (y1); \
- } \
+ (vertices)[1] = (y1); \
+ (vertices)[5] = (y2); \
(vertices)[3] = (vertices)[1]; \
(vertices)[7] = (vertices)[5]; \
} while(0)
-#define glamor_set_tcoords_ext(width, height, x1, y1, x2, y2, \
- yInverted, vertices, stride) \
+#define glamor_set_tcoords_ext(x1, y1, x2, y2, vertices, stride) \
do { \
(vertices)[0] = (x1); \
(vertices)[1*stride] = (x2); \
(vertices)[2*stride] = (vertices)[1*stride]; \
(vertices)[3*stride] = (vertices)[0]; \
- if (_X_LIKELY(yInverted)) { \
- (vertices)[1] = (y1); \
- (vertices)[2*stride + 1] = (y2); \
- } \
- else { \
- (vertices)[1] = height - (y2); \
- (vertices)[2*stride + 1] = height - (y1); \
- } \
+ (vertices)[1] = (y1); \
+ (vertices)[2*stride + 1] = (y2); \
(vertices)[1*stride + 1] = (vertices)[1]; \
(vertices)[3*stride + 1] = (vertices)[2*stride + 1]; \
} while(0)
#define glamor_set_normalize_one_vcoord(xscale, yscale, x, y, \
- yInverted, vertices) \
+ vertices) \
do { \
(vertices)[0] = v_from_x_coord_x(xscale, x); \
- if (_X_LIKELY(yInverted)) { \
- (vertices)[1] = v_from_x_coord_y_inverted(yscale, y); \
- } else { \
- (vertices)[1] = v_from_x_coord_y(yscale, y); \
- } \
+ (vertices)[1] = v_from_x_coord_y_inverted(yscale, y); \
} while(0)
#define glamor_set_normalize_tri_vcoords(xscale, yscale, vtx, \
- yInverted, vertices) \
+ vertices) \
do { \
glamor_set_normalize_one_vcoord(xscale, yscale, \
(vtx)[0], (vtx)[1], \
- yInverted, vertices); \
+ vertices); \
glamor_set_normalize_one_vcoord(xscale, yscale, \
(vtx)[2], (vtx)[3], \
- yInverted, vertices+2); \
+ vertices+2); \
glamor_set_normalize_one_vcoord(xscale, yscale, \
(vtx)[4], (vtx)[5], \
- yInverted, vertices+4); \
+ vertices+4); \
} while(0)
-#define glamor_set_tcoords_tri_strip(width, height, x1, y1, x2, y2, \
- yInverted, vertices) \
+#define glamor_set_tcoords_tri_strip(x1, y1, x2, y2, vertices) \
do { \
(vertices)[0] = (x1); \
(vertices)[2] = (x2); \
(vertices)[6] = (vertices)[2]; \
(vertices)[4] = (vertices)[0]; \
- if (_X_LIKELY(yInverted)) { \
- (vertices)[1] = (y1); \
- (vertices)[7] = (y2); \
- } \
- else { \
- (vertices)[1] = height - (y2); \
- (vertices)[7] = height - (y1); \
- } \
+ (vertices)[1] = (y1); \
+ (vertices)[7] = (y2); \
(vertices)[3] = (vertices)[1]; \
(vertices)[5] = (vertices)[7]; \
} while(0)
#define glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \
x1, y1, x2, y2, \
- yInverted, vertices, stride) \
+ vertices, stride) \
do { \
int fbo_x_off, fbo_y_off; \
/* vertices may be write-only, so we use following \
@@ -699,29 +642,22 @@
x2 + fbo_x_off); \
(vertices)[2 * stride] = _t2_; \
(vertices)[3 * stride] = _t0_; \
- if (_X_LIKELY(yInverted)) { \
- (vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale, \
- y1 + fbo_y_off); \
- (vertices)[2 * stride + 1] = _t5_ = \
- v_from_x_coord_y_inverted(yscale, \
- 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] = _t1_ = v_from_x_coord_y_inverted(yscale, \
+ y1 + fbo_y_off); \
+ (vertices)[2 * stride + 1] = _t5_ = \
+ v_from_x_coord_y_inverted(yscale, \
+ y2 + fbo_y_off); \
(vertices)[1 * stride + 1] = _t1_; \
(vertices)[3 * stride + 1] = _t5_; \
} while(0)
#define glamor_set_normalize_vcoords(priv, xscale, yscale, \
x1, y1, x2, y2, \
- yInverted, vertices) \
+ vertices) \
do { \
glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \
x1, y1, x2, y2, \
- yInverted, vertices, 2); \
+ vertices, 2); \
} while(0)
#define glamor_set_const_ext(params, nparam, vertices, nverts, stride) \
@@ -736,44 +672,30 @@
#define glamor_set_normalize_vcoords_tri_strip(xscale, yscale, \
x1, y1, x2, y2, \
- yInverted, vertices) \
+ vertices) \
do { \
(vertices)[0] = v_from_x_coord_x(xscale, x1); \
(vertices)[2] = v_from_x_coord_x(xscale, x2); \
(vertices)[6] = (vertices)[2]; \
(vertices)[4] = (vertices)[0]; \
- if (_X_LIKELY(yInverted)) { \
- (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \
- (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)[1] = v_from_x_coord_y_inverted(yscale, y1); \
+ (vertices)[7] = v_from_x_coord_y_inverted(yscale, y2); \
(vertices)[3] = (vertices)[1]; \
(vertices)[5] = (vertices)[7]; \
} while(0)
#define glamor_set_normalize_pt(xscale, yscale, x, y, \
- yInverted, pt) \
+ pt) \
do { \
(pt)[0] = t_from_x_coord_x(xscale, x); \
- if (_X_LIKELY(yInverted)) { \
- (pt)[1] = t_from_x_coord_y_inverted(yscale, y); \
- } else { \
- (pt)[1] = t_from_x_coord_y(yscale, y); \
- } \
+ (pt)[1] = t_from_x_coord_y_inverted(yscale, y); \
} while(0)
#define glamor_set_circle_centre(width, height, x, y, \
- yInverted, c) \
+ c) \
do { \
(c)[0] = (float)x; \
- if (_X_LIKELY(yInverted)) { \
- (c)[1] = (float)y; \
- } else { \
- (c)[1] = (float)height - (float)y; \
- } \
+ (c)[1] = (float)y; \
} while(0)
inline static void
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 369b02b61..68a06a413 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -36,12 +36,10 @@
#include <dix-config.h>
#endif
-#include "xf86xv.h"
-#define GLAMOR_FOR_XORG
#include "glamor_priv.h"
#include <X11/extensions/Xv.h>
-#include "fourcc.h"
+#include "../hw/xfree86/common/fourcc.h"
/* Reference color space transform data */
typedef struct tagREF_TRANSFORM {
float RefLuma;
@@ -90,7 +88,28 @@ static const char *xv_ps = GLAMOR_DEFAULT_PRECISION
"gl_FragColor = temp1;\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_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 MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
-
-static Atom xvBrightness, xvContrast, xvSaturation, xvHue, xvColorspace,
- xvGamma;
-
-#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)
+void
+glamor_xv_stop_video(glamor_port_private *port_priv)
{
- glamor_port_private *port_priv = (glamor_port_private *) data;
int i;
- if (!cleanup)
- return;
-
for (i = 0; i < 3; i++) {
if (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
-glamor_xv_set_port_attribute(ScrnInfoPtr pScrn,
- Atom attribute, INT32 value, void *data)
+int
+glamor_xv_set_port_attribute(glamor_port_private *port_priv,
+ Atom attribute, INT32 value)
{
- glamor_port_private *port_priv = (glamor_port_private *) data;
-
- if (attribute == xvBrightness)
+ if (attribute == glamorBrightness)
port_priv->brightness = ClipValue(value, -1000, 1000);
- else if (attribute == xvHue)
+ else if (attribute == glamorHue)
port_priv->hue = ClipValue(value, -1000, 1000);
- else if (attribute == xvContrast)
+ else if (attribute == glamorContrast)
port_priv->contrast = ClipValue(value, -1000, 1000);
- else if (attribute == xvSaturation)
+ else if (attribute == glamorSaturation)
port_priv->saturation = ClipValue(value, -1000, 1000);
- else if (attribute == xvGamma)
+ else if (attribute == glamorGamma)
port_priv->gamma = ClipValue(value, 100, 10000);
- else if (attribute == xvColorspace)
+ else if (attribute == glamorColorspace)
port_priv->transform_index = ClipValue(value, 0, 1);
else
return BadMatch;
return Success;
}
-static int
-glamor_xv_get_port_attribute(ScrnInfoPtr pScrn,
- Atom attribute, INT32 *value, void *data)
+int
+glamor_xv_get_port_attribute(glamor_port_private *port_priv,
+ Atom attribute, INT32 *value)
{
- glamor_port_private *port_priv = (glamor_port_private *) data;
-
- if (attribute == xvBrightness)
+ if (attribute == glamorBrightness)
*value = port_priv->brightness;
- else if (attribute == xvHue)
+ else if (attribute == glamorHue)
*value = port_priv->hue;
- else if (attribute == xvContrast)
+ else if (attribute == glamorContrast)
*value = port_priv->contrast;
- else if (attribute == xvSaturation)
+ else if (attribute == glamorSaturation)
*value = port_priv->saturation;
- else if (attribute == xvGamma)
+ else if (attribute == glamorGamma)
*value = port_priv->gamma;
- else if (attribute == xvColorspace)
+ else if (attribute == glamorColorspace)
*value = port_priv->transform_index;
else
return BadMatch;
@@ -205,20 +189,8 @@ glamor_xv_get_port_attribute(ScrnInfoPtr pScrn,
return Success;
}
-static void
-glamor_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_xv_query_image_attributes(ScrnInfoPtr pScrn,
- int id,
+int
+glamor_xv_query_image_attributes(int id,
unsigned short *w, unsigned short *h,
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 */
};
-static void
-glamor_display_textured_video(glamor_port_private *port_priv)
+void
+glamor_xv_render(glamor_port_private *port_priv)
{
ScreenPtr screen = port_priv->pPixmap->drawable.pScreen;
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;
GLint uloc, sampler_loc;
+ if (!glamor_priv->xv_prog)
+ glamor_init_xv_shader(screen);
+
cont = RTFContrast(port_priv->contrast);
bright = RTFBrightness(port_priv->brightness);
gamma = (float) port_priv->gamma / 1000.0;
@@ -385,7 +360,7 @@ glamor_display_textured_video(glamor_port_private *port_priv)
dsty,
dstx + dstw,
dsty + dsth,
- glamor_priv->yInverted, vertices);
+ vertices);
glamor_set_normalize_tcoords(src_pixmap_priv[0],
src_xscale[0],
@@ -394,7 +369,7 @@ glamor_display_textured_video(glamor_port_private *port_priv)
srcy,
srcx + srcw,
srcy + srch,
- glamor_priv->yInverted, texcoords);
+ texcoords);
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);
}
-static int
-glamor_xv_put_image(ScrnInfoPtr pScrn,
+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,
@@ -416,35 +392,15 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
short width,
short height,
Bool sync,
- RegionPtr clipBoxes, void *data, DrawablePtr pDrawable)
+ RegionPtr clipBoxes)
{
- ScreenPtr screen = pDrawable->pScreen;
- glamor_port_private *port_priv = (glamor_port_private *) data;
- INT32 x1, x2, y1, y2;
+ ScreenPtr pScreen = pDrawable->pScreen;
int srcPitch, srcPitch2;
- BoxRec dstBox;
int top, nlines;
int s2offset, s3offset, tmp;
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;
srcPitch2 = width >> 1;
@@ -457,11 +413,11 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
glamor_destroy_pixmap(port_priv->src_pix[i]);
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] =
- 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] =
- 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_h = height;
@@ -470,8 +426,8 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
return BadAlloc;
}
- top = (y1 >> 16) & ~1;
- nlines = ((y2 + 0xffff) >> 16) - top;
+ top = (src_y) & ~1;
+ nlines = (src_y + height) - top;
switch (id) {
case FOURCC_YV12:
@@ -505,7 +461,7 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
}
if (pDrawable->type == DRAWABLE_WINDOW)
- port_priv->pPixmap = (*screen->GetWindowPixmap) ((WindowPtr) pDrawable);
+ port_priv->pPixmap = pScreen->GetWindowPixmap((WindowPtr) pDrawable);
else
port_priv->pPixmap = (PixmapPtr) pDrawable;
@@ -524,83 +480,30 @@ glamor_xv_put_image(ScrnInfoPtr pScrn,
port_priv->w = width;
port_priv->h = height;
port_priv->pDraw = pDrawable;
- glamor_display_textured_video(port_priv);
+ glamor_xv_render(port_priv);
return Success;
}
-static XF86VideoEncodingRec DummyEncodingGLAMOR[1] = {
- {
- 0,
- "XV_IMAGE",
- 8192, 8192,
- {1, 1}
- }
-};
-
-XF86VideoAdaptorPtr
-glamor_xv_init(ScreenPtr screen, int num_texture_ports)
+void
+glamor_xv_init_port(glamor_port_private *port_priv)
{
- glamor_port_private *port_priv;
- XF86VideoAdaptorPtr adapt;
- int i;
+ port_priv->brightness = 0;
+ port_priv->contrast = 0;
+ port_priv->saturation = 0;
+ port_priv->hue = 0;
+ port_priv->gamma = 1000;
+ port_priv->transform_index = 0;
+
+ REGION_NULL(pScreen, &port_priv->clip);
+}
- glamor_init_xv_shader(screen);
-
- adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports *
- (sizeof(glamor_port_private) + sizeof(DevUnion)));
- if (adapt == NULL)
- return NULL;
-
- xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
- xvContrast = MAKE_ATOM("XV_CONTRAST");
- xvSaturation = MAKE_ATOM("XV_SATURATION");
- xvHue = MAKE_ATOM("XV_HUE");
- xvGamma = MAKE_ATOM("XV_GAMMA");
- 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;
+void
+glamor_xv_core_init(ScreenPtr screen)
+{
+ glamorBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+ glamorContrast = MAKE_ATOM("XV_CONTRAST");
+ glamorSaturation = MAKE_ATOM("XV_SATURATION");
+ glamorHue = MAKE_ATOM("XV_HUE");
+ glamorGamma = MAKE_ATOM("XV_GAMMA");
+ glamorColorspace = MAKE_ATOM("XV_COLORSPACE");
}
diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index 00a53d0df..10c59174f 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -35,9 +35,14 @@ XV_SRCS = ephyrvideo.c
endif
if GLAMOR
+if XV
+GLAMOR_XV_SRCS = ephyr_glamor_xv.c
+endif
+
GLAMOR_SRCS = \
ephyr_glamor_glx.c \
ephyr_glamor_glx.h \
+ $(GLAMOR_XV_SRCS) \
$()
endif
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 49a4d2ded..d57e9f33c 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -650,7 +650,9 @@ ephyrInitScreen(ScreenPtr pScreen)
#ifdef XV
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");
}
else {
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index e69178082..dfd93c9bc 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -224,4 +224,14 @@ void ephyr_glamor_host_paint_rect(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
diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c
index eaf565496..8fe751693 100644
--- a/hw/kdrive/ephyr/ephyr_glamor_glx.c
+++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -52,6 +52,7 @@
static Display *dpy;
static XVisualInfo *visual_info;
static GLXFBConfig fb_config;
+Bool ephyr_glamor_gles2;
/** @} */
/**
@@ -145,6 +146,10 @@ ephyr_glamor_setup_texturing_shader(struct ephyr_glamor *glamor)
"}\n";
const char *fs_source =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "\n"
"varying vec2 t;\n"
"uniform sampler2D s; /* initially 0 */\n"
"\n"
@@ -276,7 +281,24 @@ ephyr_glamor_glx_screen_init(xcb_window_t win)
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)
FatalError("glXCreateContext failed\n");
diff --git a/hw/kdrive/ephyr/ephyr_glamor_xv.c b/hw/kdrive/ephyr/ephyr_glamor_xv.c
new file mode 100644
index 000000000..b9c3464d8
--- /dev/null
+++ b/hw/kdrive/ephyr/ephyr_glamor_xv.c
@@ -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);
+}
diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index 3f66e1c2f..fc0001012 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -35,7 +35,7 @@ extern Bool EphyrWantGrayScale;
extern Bool EphyrWantResize;
extern Bool kdHasPointer;
extern Bool kdHasKbd;
-extern Bool ephyr_glamor;
+extern Bool ephyr_glamor, ephyr_glamor_gles2;
#ifdef GLXEXT
extern Bool ephyrNoDRI;
@@ -138,6 +138,7 @@ ddxUseMsg(void)
ErrorF("-resizeable Make Xephyr windows resizeable\n");
#ifdef GLAMOR
ErrorF("-glamor Enable 2D acceleration using glamor\n");
+ ErrorF("-glamor_gles2 Enable 2D acceleration using glamor (with GLES2 only)\n");
#endif
ErrorF
("-fakexa Simulate acceleration using software rendering\n");
@@ -251,6 +252,15 @@ ddxProcessArgument(int argc, char **argv, int i)
ephyrFuncs.finiAccel = ephyr_glamor_fini;
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
else if (!strcmp(argv[i], "-fakexa")) {
ephyrFuncs.initAccel = ephyrDrawInit;
diff --git a/hw/kdrive/ephyr/ephyrvideo.c b/hw/kdrive/ephyr/ephyrvideo.c
index c6728351f..ab18c7afa 100644
--- a/hw/kdrive/ephyr/ephyrvideo.c
+++ b/hw/kdrive/ephyr/ephyrvideo.c
@@ -69,7 +69,7 @@ static Bool ephyrXVPrivSetAdaptorsHooks(EphyrXVPriv * a_this);
static Bool ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this,
ScreenPtr a_screen);
-static Bool ephyrXVPrivIsAttrValueValid(KdAttributePtr a_attrs,
+static Bool ephyrXVPrivIsAttrValueValid(XvAttributePtr a_attrs,
int a_attrs_len,
const char *a_attr_name,
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);
for (i = 0; i < reply->num_attributes; i++) {
- KdAttributePtr attribute = &adaptor->pAttributes[i];
+ XvAttributePtr attribute = &adaptor->pAttributes[i];
attribute->flags = it.data->flags;
attribute->min_value = it.data->min;
@@ -397,7 +397,7 @@ translate_xv_image_formats(KdVideoAdaptorPtr adaptor,
return FALSE;
adaptor->nImages = reply->num_formats;
- adaptor->pImages = calloc(reply->num_formats, sizeof(KdImageRec));
+ adaptor->pImages = calloc(reply->num_formats, sizeof(XvImageRec));
if (!adaptor->pImages) {
free(reply);
return FALSE;
@@ -405,7 +405,7 @@ translate_xv_image_formats(KdVideoAdaptorPtr adaptor,
formats = xcb_xv_list_image_formats_format(reply);
for (i = 0; i < reply->num_formats; i++) {
- KdImagePtr image = &adaptor->pImages[i];
+ XvImagePtr image = &adaptor->pImages[i];
image->id = formats[i].id;
image->type = formats[i].type;
@@ -612,11 +612,7 @@ ephyrXVPrivSetAdaptorsHooks(EphyrXVPriv * a_this)
static Bool
ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this, ScreenPtr a_screen)
{
- KdScreenPriv(a_screen);
- KdScreenInfo *screen = pScreenPriv->screen;
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);
@@ -624,38 +620,22 @@ ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this, ScreenPtr a_screen)
if (!a_this->num_adaptors)
goto out;
- num_registered_adaptors =
- KdXVListGenericAdaptors(screen, &registered_adaptors);
- num_adaptors = num_registered_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)) {
+ if (!KdXVScreenInit(a_screen, a_this->adaptors, a_this->num_adaptors)) {
EPHYR_LOG_ERROR("failed to register adaptors\n");
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;
out:
- free(registered_adaptors);
- registered_adaptors = NULL;
- free(adaptors);
- adaptors = NULL;
EPHYR_LOG("leave\n");
return is_ok;
}
static Bool
-ephyrXVPrivIsAttrValueValid(KdAttributePtr a_attrs,
+ephyrXVPrivIsAttrValueValid(XvAttributePtr a_attrs,
int a_attrs_len,
const char *a_attr_name,
int a_attr_value, Bool *a_is_valid)
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 435919e0a..1c759743d 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -287,7 +287,8 @@ hostx_set_title(char *title)
int
hostx_init(void)
{
- uint32_t attr;
+ uint32_t attrs[2];
+ uint32_t attr_mask = 0;
xcb_cursor_t empty_cursor;
xcb_pixmap_t cursor_pxm;
uint16_t red, green, blue;
@@ -299,7 +300,7 @@ hostx_init(void)
const xcb_query_extension_reply_t *shm_rep;
xcb_screen_t *xscreen;
- attr =
+ attrs[0] =
XCB_EVENT_MASK_BUTTON_PRESS
| XCB_EVENT_MASK_BUTTON_RELEASE
| XCB_EVENT_MASK_POINTER_MOTION
@@ -307,6 +308,7 @@ hostx_init(void)
| XCB_EVENT_MASK_KEY_RELEASE
| XCB_EVENT_MASK_EXPOSURE
| XCB_EVENT_MASK_STRUCTURE_NOTIFY;
+ attr_mask |= XCB_CW_EVENT_MASK;
EPHYR_DBG("mark");
#ifdef GLAMOR
@@ -325,9 +327,18 @@ hostx_init(void)
HostX.gc = xcb_generate_id(HostX.conn);
HostX.depth = xscreen->root_depth;
#ifdef GLAMOR
- if (ephyr_glamor)
+ if (ephyr_glamor) {
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
HostX.visual = xcb_aux_find_visual_by_id(xscreen,xscreen->root_visual);
@@ -379,9 +390,9 @@ hostx_init(void)
scrpriv->win_height,
0,
XCB_WINDOW_CLASS_COPY_FROM_PARENT,
- XCB_COPY_FROM_PARENT,
- XCB_CW_EVENT_MASK,
- &attr);
+ HostX.visual->visual_id,
+ attr_mask,
+ attrs);
}
else {
xcb_create_window(HostX.conn,
@@ -391,9 +402,9 @@ hostx_init(void)
0,0,100,100, /* will resize */
0,
XCB_WINDOW_CLASS_COPY_FROM_PARENT,
- XCB_COPY_FROM_PARENT,
- XCB_CW_EVENT_MASK,
- &attr);
+ HostX.visual->visual_id,
+ attr_mask,
+ attrs);
hostx_set_win_title(screen,
"(ctrl+shift grabs mouse and keyboard)");
@@ -1234,8 +1245,7 @@ ephyr_glamor_init(ScreenPtr screen)
glamor_init(screen,
GLAMOR_USE_SCREEN |
- GLAMOR_USE_PICTURE_SCREEN |
- GLAMOR_INVERTED_Y_AXIS);
+ GLAMOR_USE_PICTURE_SCREEN);
return TRUE;
}
diff --git a/hw/kdrive/src/kxv.c b/hw/kdrive/src/kxv.c
index 9cc0edd8a..60a83458c 100644
--- a/hw/kdrive/src/kxv.c
+++ b/hw/kdrive/src/kxv.c
@@ -98,7 +98,7 @@ static void KdXVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2);
static void KdXVClipNotify(WindowPtr pWin, int dx, int dy);
/* misc */
-static Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr *, int);
+static Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr, int);
static DevPrivateKeyRec KdXVWindowKeyRec;
@@ -116,49 +116,6 @@ static unsigned long PortResource = 0;
#define GET_KDXV_WINDOW(pWin) ((KdXVWindowPtr) \
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
KdXVAllocateVideoAdaptorRec(KdScreenInfo * screen)
{
@@ -172,7 +129,7 @@ KdXVFreeVideoAdaptorRec(KdVideoAdaptorPtr ptr)
}
Bool
-KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr * adaptors, int num)
+KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr adaptors, int num)
{
KdXVScreenPtr ScreenPriv;
XvScreenPtr pxvs;
@@ -282,7 +239,7 @@ KdXVFreeAdaptor(XvAdaptorPtr pAdaptor)
}
static Bool
-KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number)
+KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr infoPtr, int number)
{
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
@@ -295,15 +252,11 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number)
XvPortRecPrivatePtr portPriv;
XvPortPtr pPort, pp;
int numPort;
- KdAttributePtr attributePtr;
- XvAttributePtr pAttribute, pat;
KdVideoFormatPtr formatPtr;
XvFormatPtr pFormat, pf;
int numFormat, totFormat;
KdVideoEncodingPtr encodingPtr;
XvEncodingPtr pEncode, pe;
- KdImagePtr imagePtr;
- XvImagePtr pImage, pi;
int numVisuals;
VisualPtr pVisual;
int i;
@@ -315,7 +268,7 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number)
return FALSE;
for (pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
- adaptorPtr = infoPtr[na];
+ adaptorPtr = &infoPtr[na];
if (!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
!adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
@@ -381,26 +334,24 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr * infoPtr, int number)
}
if (adaptorPtr->nImages &&
- (pImage = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
-
- for (i = 0, pi = pImage, imagePtr = adaptorPtr->pImages;
- i < adaptorPtr->nImages; i++, pi++, imagePtr++) {
- memcpy(pi, imagePtr, sizeof(*pi));
- }
+ (pa->pImages = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
+ memcpy(pa->pImages, adaptorPtr->pImages,
+ adaptorPtr->nImages * sizeof(XvImageRec));
pa->nImages = adaptorPtr->nImages;
- pa->pImages = pImage;
}
if (adaptorPtr->nAttributes &&
- (pAttribute =
- calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec)))) {
- for (pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i =
- 0; i < adaptorPtr->nAttributes; pat++, i++, attributePtr++) {
- memcpy(pat, attributePtr, sizeof(*pat));
- pat->name = strdup(attributePtr->name);
+ (pa->pAttributes = calloc(adaptorPtr->nAttributes,
+ sizeof(XvAttributeRec)))) {
+ memcpy(pa->pAttributes, adaptorPtr->pAttributes,
+ adaptorPtr->nAttributes * sizeof(XvAttributeRec));
+
+ for (i = 0; i < adaptorPtr->nAttributes; i++) {
+ pa->pAttributes[i].name =
+ strdup(adaptorPtr->pAttributes[i].name);
}
+
pa->nAttributes = adaptorPtr->nAttributes;
- pa->pAttributes = pAttribute;
}
totFormat = adaptorPtr->nFormats;
diff --git a/hw/kdrive/src/kxv.h b/hw/kdrive/src/kxv.h
index 85a030ee9..3a49a659f 100644
--- a/hw/kdrive/src/kxv.h
+++ b/hw/kdrive/src/kxv.h
@@ -56,8 +56,6 @@ of the copyright holder.
#define VIDEO_OVERLAID_STILLS 0x00000008
#define VIDEO_CLIP_TO_VIEWPORT 0x00000010
-typedef XvImageRec KdImageRec, *KdImagePtr;
-
typedef struct {
KdScreenInfo *screen;
int id;
@@ -121,7 +119,7 @@ typedef enum {
typedef struct {
int id;
- char *name;
+ const char *name;
unsigned short width, height;
XvRationalRec rate;
} KdVideoEncodingRec, *KdVideoEncodingPtr;
@@ -131,12 +129,10 @@ typedef struct {
short class;
} KdVideoFormatRec, *KdVideoFormatPtr;
-typedef XvAttributeRec KdAttributeRec, *KdAttributePtr;
-
typedef struct {
unsigned int type;
int flags;
- char *name;
+ const char *name;
int nEncodings;
KdVideoEncodingPtr pEncodings;
int nFormats;
@@ -144,9 +140,9 @@ typedef struct {
int nPorts;
DevUnion *pPortPrivates;
int nAttributes;
- KdAttributePtr pAttributes;
+ XvAttributePtr pAttributes;
int nImages;
- KdImagePtr pImages;
+ XvImagePtr pImages;
PutVideoFuncPtr PutVideo;
PutStillFuncPtr PutStill;
GetVideoFuncPtr GetVideo;
@@ -161,16 +157,7 @@ typedef struct {
} KdVideoAdaptorRec, *KdVideoAdaptorPtr;
Bool
- KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr * Adaptors, int num);
-
-typedef int (*KdXVInitGenericAdaptorPtr) (KdScreenInfo * screen,
- KdVideoAdaptorPtr ** Adaptors);
-
-int
- KdXVRegisterGenericAdaptorDriver(KdXVInitGenericAdaptorPtr InitFunc);
-
-int
- KdXVListGenericAdaptors(KdScreenInfo * screen, KdVideoAdaptorPtr ** Adaptors);
+ KdXVScreenInit(ScreenPtr pScreen, KdVideoAdaptorPtr Adaptors, int num);
void
diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index b16cb5df3..e212a7387 100644
--- a/hw/xfree86/common/xf86xv.c
+++ b/hw/xfree86/common/xf86xv.c
@@ -359,15 +359,11 @@ xf86XVInitAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr * infoPtr, int number)
XvPortRecPrivatePtr portPriv;
XvPortPtr pPort, pp;
int numPort;
- XF86AttributePtr attributePtr;
- XvAttributePtr pAttribute, pat;
XF86VideoFormatPtr formatPtr;
XvFormatPtr pFormat, pf;
int numFormat, totFormat;
XF86VideoEncodingPtr encodingPtr;
XvEncodingPtr pEncode, pe;
- XF86ImagePtr imagePtr;
- XvImagePtr pImage, pi;
int numVisuals;
VisualPtr pVisual;
int i;
@@ -445,49 +441,24 @@ xf86XVInitAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr * infoPtr, int number)
}
if (adaptorPtr->nImages &&
- (pImage = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
-
- for (i = 0, pi = pImage, imagePtr = adaptorPtr->pImages;
- 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->pImages = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
+ memcpy(pa->pImages, adaptorPtr->pImages,
+ adaptorPtr->nImages * sizeof(XvImageRec));
pa->nImages = adaptorPtr->nImages;
- pa->pImages = pImage;
}
if (adaptorPtr->nAttributes &&
- (pAttribute =
- calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec)))) {
- for (pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i =
- 0; i < adaptorPtr->nAttributes; pat++, i++, attributePtr++) {
- pat->flags = attributePtr->flags;
- pat->min_value = attributePtr->min_value;
- pat->max_value = attributePtr->max_value;
- pat->name = strdup(attributePtr->name);
+ (pa->pAttributes = calloc(adaptorPtr->nAttributes,
+ sizeof(XvAttributeRec)))) {
+ memcpy(pa->pAttributes, adaptorPtr->pAttributes,
+ adaptorPtr->nAttributes * sizeof(XvAttributeRec));
+
+ for (i = 0; i < adaptorPtr->nAttributes; i++) {
+ pa->pAttributes[i].name =
+ strdup(adaptorPtr->pAttributes[i].name);
}
+
pa->nAttributes = adaptorPtr->nAttributes;
- pa->pAttributes = pAttribute;
}
totFormat = adaptorPtr->nFormats;
diff --git a/hw/xfree86/common/xf86xv.h b/hw/xfree86/common/xf86xv.h
index 8986e2e57..de17eb133 100644
--- a/hw/xfree86/common/xf86xv.h
+++ b/hw/xfree86/common/xf86xv.h
@@ -42,34 +42,7 @@
*/
#define VIDEO_CLIP_TO_VIEWPORT 0x00000010
-typedef struct {
- 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 XvImageRec XF86ImageRec, *XF86ImagePtr;
typedef struct {
ScrnInfoPtr pScrn;
@@ -147,12 +120,7 @@ typedef struct {
short class;
} XF86VideoFormatRec, *XF86VideoFormatPtr;
-typedef struct {
- int flags;
- int min_value;
- int max_value;
- const char *name;
-} XF86AttributeRec, *XF86AttributePtr;
+typedef XvAttributeRec XF86AttributeRec, *XF86AttributePtr;
typedef struct {
unsigned int type;
diff --git a/hw/xfree86/glamor_egl/Makefile.am b/hw/xfree86/glamor_egl/Makefile.am
index 85e1c0c06..e697c8296 100644
--- a/hw/xfree86/glamor_egl/Makefile.am
+++ b/hw/xfree86/glamor_egl/Makefile.am
@@ -24,7 +24,7 @@ module_LTLIBRARIES = libglamoregl.la
libglamoregl_la_SOURCES = \
$(top_srcdir)/glamor/glamor_egl.c \
$(top_srcdir)/glamor/glamor_eglmodule.c \
- $(top_srcdir)/glamor/glamor_xv.c \
+ glamor_xf86_xv.c \
$()
libglamoregl_la_LDFLAGS = \
@@ -38,6 +38,7 @@ libglamoregl_la_LIBADD = \
AM_CPPFLAGS = $(XORG_INCS) \
-I$(top_srcdir)/dri3 \
+ -I$(top_srcdir)/glamor \
$()
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_CFLAGS) $(GBM_CFLAGS)
diff --git a/hw/xfree86/glamor_egl/glamor_xf86_xv.c b/hw/xfree86/glamor_egl/glamor_xf86_xv.c
new file mode 100644
index 000000000..8535fa0c9
--- /dev/null
+++ b/hw/xfree86/glamor_egl/glamor_xf86_xv.c
@@ -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;
+}
diff --git a/mi/mi.h b/mi/mi.h
index 483fa3ebe..feba5cb0c 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -67,6 +67,11 @@ typedef struct _miDash *miDashPtr;
/* miarc.c */
+extern _X_EXPORT void miWideArc(DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc * parcs);
+
extern _X_EXPORT void miPolyArc(DrawablePtr /*pDraw */ ,
GCPtr /*pGC */ ,
int /*narcs */ ,
@@ -452,6 +457,12 @@ extern _X_EXPORT void miWideDash(DrawablePtr /*pDrawable */ ,
DDXPointPtr /*pPts */
);
+extern _X_EXPORT void miPolylines(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts);
+
/* miwindow.c */
extern _X_EXPORT void miClearToBackground(WindowPtr /*pWin */ ,
diff --git a/mi/miarc.c b/mi/miarc.c
index 0f56c7db3..e55108a44 100644
--- a/mi/miarc.c
+++ b/mi/miarc.c
@@ -886,7 +886,7 @@ miFillWideEllipse(DrawablePtr pDraw, GCPtr pGC, xArc * parc)
*/
void
-miPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
+miWideArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
{
int i;
xArc *parc;
@@ -3396,3 +3396,12 @@ drawQuadrant(struct arc_def *def,
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);
+}
diff --git a/mi/mifillarc.c b/mi/mifillarc.c
index 337343dd1..08484d703 100644
--- a/mi/mifillarc.c
+++ b/mi/mifillarc.c
@@ -476,26 +476,16 @@ miFillArcSliceSetup(xArc * arc, miArcSliceRec * slice, GCPtr pGC)
*wids++ = slw; \
}
-static void
-miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
+static int
+miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
{
int x, y, e;
int yk, xk, ym, xm, dx, dy, xorg, yorg;
int slw;
miFillArcRec info;
- DDXPointPtr points;
DDXPointPtr pts;
- int *widths;
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();
if (pGC->miTranslate) {
@@ -508,31 +498,19 @@ miFillEllipseI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
MIFILLARCSTEP(slw);
ADDSPANS();
}
- (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE);
- free(widths);
- free(points);
+ return pts - points;
}
-static void
-miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
+static int
+miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
{
int x, y;
int xorg, yorg, dx, dy, slw;
double e, yk, xk, ym, xm;
miFillArcDRec info;
- DDXPointPtr points;
DDXPointPtr pts;
- int *widths;
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);
MIFILLARCSETUP();
if (pGC->miTranslate) {
@@ -545,9 +523,7 @@ miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
MIFILLARCSTEP(slw);
ADDSPANS();
}
- (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE);
- free(widths);
- free(points);
+ return pts - points;
}
#define ADDSPAN(l,r) \
@@ -572,17 +548,15 @@ miFillEllipseD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
ADDSPAN(xl, xc); \
}
-static void
-miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
+static int
+miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
{
int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
int x, y, e;
miFillArcRec info;
miArcSliceRec slice;
int ya, xl, xr, xc;
- DDXPointPtr points;
DDXPointPtr pts;
- int *widths;
int *wids;
miFillArcSetup(arc, &info);
@@ -591,14 +565,6 @@ miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
slw = arc->height;
if (slice.flip_top || slice.flip_bot)
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) {
xorg += pDraw->x;
yorg += pDraw->y;
@@ -622,13 +588,11 @@ miFillArcSliceI(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
ADDSLICESPANS(slice.flip_bot);
}
}
- (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE);
- free(widths);
- free(points);
+ return pts - points;
}
-static void
-miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
+static int
+miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc, DDXPointPtr points, int *widths)
{
int x, y;
int dx, dy, xorg, yorg, slw;
@@ -636,9 +600,7 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
miFillArcDRec info;
miArcSliceRec slice;
int ya, xl, xr, xc;
- DDXPointPtr points;
DDXPointPtr pts;
- int *widths;
int *wids;
miFillArcDSetup(arc, &info);
@@ -647,14 +609,6 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
slw = arc->height;
if (slice.flip_top || slice.flip_bot)
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) {
xorg += pDraw->x;
yorg += pDraw->y;
@@ -678,35 +632,69 @@ miFillArcSliceD(DrawablePtr pDraw, GCPtr pGC, xArc * arc)
ADDSLICESPANS(slice.flip_bot);
}
}
- (*pGC->ops->FillSpans) (pDraw, pGC, pts - points, points, widths, FALSE);
- free(widths);
- free(points);
+ return pts - points;
}
/* MIPOLYFILLARC -- The public entry for the PolyFillArc request.
* Since we don't have to worry about overlapping segments, we can just
* fill each arc as it comes.
*/
+
+/* Limit the number of spans in a single draw request to avoid integer
+ * overflow in the computation of the span buffer size.
+ */
+#define MAX_SPANS_PER_LOOP (4 * 1024 * 1024)
+
void
-miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
+miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs_all, xArc * parcs)
{
- int i;
- xArc *arc;
-
- for (i = narcs, arc = parcs; --i >= 0; arc++) {
- if (miFillArcEmpty(arc))
- continue;
- if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE)) {
- if (miCanFillArc(arc))
- miFillEllipseI(pDraw, pGC, arc);
- else
- miFillEllipseD(pDraw, pGC, arc);
- }
- else {
- if (miCanFillArc(arc))
- miFillArcSliceI(pDraw, pGC, arc);
- else
- miFillArcSliceD(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;
+ }
+
+ pts = points = malloc (sizeof (DDXPointRec) * nspans +
+ sizeof(int) * nspans);
+ if (points) {
+ 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;
}
}
diff --git a/mi/miwideline.c b/mi/miwideline.c
index b76e7a818..29ba12c69 100644
--- a/mi/miwideline.c
+++ b/mi/miwideline.c
@@ -1979,3 +1979,23 @@ miWideDash(DrawablePtr pDrawable, GCPtr pGC,
if (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);
+ }
+}
diff --git a/mi/mizerarc.c b/mi/mizerarc.c
index 9dac180d1..b216cf43d 100644
--- a/mi/mizerarc.c
+++ b/mi/mizerarc.c
@@ -656,7 +656,7 @@ miZeroPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
for (arc = parcs, i = narcs; --i >= 0; arc++) {
if (!miCanZeroArc(arc))
- miPolyArc(pDraw, pGC, 1, arc);
+ miWideArc(pDraw, pGC, 1, arc);
else {
if (arc->width > arc->height)
n = arc->width + (arc->height >> 1);
diff --git a/mi/mizerline.c b/mi/mizerline.c
index 90798dbdf..f30e01239 100644
--- a/mi/mizerline.c
+++ b/mi/mizerline.c
@@ -179,14 +179,6 @@ miZeroLine(DrawablePtr pDraw, GCPtr pGC, int mode, /* Origin or Previous */
MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom);
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;
y1 = y2;
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);
+ 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) {
e1 = ady << 1;
e2 = e1 - (adx << 1);