summaryrefslogtreecommitdiff
path: root/xserver/glamor
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2016-05-29 12:02:41 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2016-05-29 12:02:41 +0000
commit4a991716ac65d28a68f9943d54c4b74ad0b58f65 (patch)
treec037c3fe64bb15ea67dbf03a96783a8b04085371 /xserver/glamor
parent549cb8bcb6bdd3a7d44f3b9fdc003df777b2b0d2 (diff)
Update to xserver 1.18.3. Tested by shadchin@ and naddy@.
Note that indirect GLX is now disbled by default.
Diffstat (limited to 'xserver/glamor')
-rw-r--r--xserver/glamor/Makefile.am8
-rw-r--r--xserver/glamor/Makefile.in109
-rw-r--r--xserver/glamor/glamor.c459
-rw-r--r--xserver/glamor/glamor.h218
-rw-r--r--xserver/glamor/glamor_addtraps.c29
-rw-r--r--xserver/glamor/glamor_composite_glyphs.c573
-rw-r--r--xserver/glamor/glamor_compositerects.c6
-rw-r--r--xserver/glamor/glamor_copy.c110
-rw-r--r--xserver/glamor/glamor_core.c66
-rw-r--r--xserver/glamor/glamor_dash.c23
-rw-r--r--xserver/glamor/glamor_egl.c316
-rw-r--r--xserver/glamor/glamor_egl_stubs.c6
-rw-r--r--xserver/glamor/glamor_fbo.c263
-rw-r--r--xserver/glamor/glamor_font.c35
-rw-r--r--xserver/glamor/glamor_font.h2
-rw-r--r--xserver/glamor/glamor_glyphblt.c66
-rw-r--r--xserver/glamor/glamor_glyphs.c1783
-rw-r--r--xserver/glamor/glamor_gradient.c74
-rw-r--r--xserver/glamor/glamor_image.c31
-rw-r--r--xserver/glamor/glamor_largepixmap.c215
-rw-r--r--xserver/glamor/glamor_lines.c29
-rw-r--r--xserver/glamor/glamor_picture.c925
-rw-r--r--xserver/glamor/glamor_pixmap.c1036
-rw-r--r--xserver/glamor/glamor_points.c34
-rw-r--r--xserver/glamor/glamor_prepare.c62
-rw-r--r--xserver/glamor/glamor_priv.h598
-rw-r--r--xserver/glamor/glamor_program.c324
-rw-r--r--xserver/glamor/glamor_program.h66
-rw-r--r--xserver/glamor/glamor_rects.c35
-rw-r--r--xserver/glamor/glamor_render.c949
-rw-r--r--xserver/glamor/glamor_segs.c26
-rw-r--r--xserver/glamor/glamor_spans.c84
-rw-r--r--xserver/glamor/glamor_text.c69
-rw-r--r--xserver/glamor/glamor_transfer.c20
-rw-r--r--xserver/glamor/glamor_transform.c69
-rw-r--r--xserver/glamor/glamor_transform.h21
-rw-r--r--xserver/glamor/glamor_trapezoid.c16
-rw-r--r--xserver/glamor/glamor_triangles.c42
-rw-r--r--xserver/glamor/glamor_utils.c2
-rw-r--r--xserver/glamor/glamor_utils.h352
-rw-r--r--xserver/glamor/glamor_vbo.c26
-rw-r--r--xserver/glamor/glamor_window.c32
-rw-r--r--xserver/glamor/glamor_xv.c273
43 files changed, 3789 insertions, 5693 deletions
diff --git a/xserver/glamor/Makefile.am b/xserver/glamor/Makefile.am
index db72cb11c..c631c530b 100644
--- a/xserver/glamor/Makefile.am
+++ b/xserver/glamor/Makefile.am
@@ -14,7 +14,7 @@ libglamor_la_SOURCES = \
glamor_font.c \
glamor_font.h \
glamor_glx.c \
- glamor_glyphs.c \
+ glamor_composite_glyphs.c \
glamor_image.c \
glamor_lines.c \
glamor_segs.c \
@@ -46,10 +46,14 @@ libglamor_la_SOURCES = \
glamor_compositerects.c\
glamor_utils.c\
glamor_utils.h\
- glamor_xv.c \
glamor_sync.c \
glamor.h
+if XV
+libglamor_la_SOURCES += \
+ glamor_xv.c
+endif
+
libglamor_egl_stubs_la_SOURCES = glamor_egl_stubs.c
sdk_HEADERS = glamor.h
diff --git a/xserver/glamor/Makefile.in b/xserver/glamor/Makefile.in
index 53a28429e..c277ec5ee 100644
--- a/xserver/glamor/Makefile.in
+++ b/xserver/glamor/Makefile.in
@@ -51,6 +51,9 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+@XV_TRUE@am__append_1 = \
+@XV_TRUE@ glamor_xv.c
+
subdir = glamor
DIST_COMMON = $(sdk_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(top_srcdir)/depcomp
@@ -58,8 +61,7 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
- $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/xorg-tls.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -76,17 +78,33 @@ CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
am__DEPENDENCIES_1 =
libglamor_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__libglamor_la_SOURCES_DIST = glamor.c glamor_context.h \
+ glamor_copy.c glamor_core.c glamor_dash.c glamor_debug.h \
+ glamor_font.c glamor_font.h glamor_glx.c \
+ glamor_composite_glyphs.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 glamor_spans.c glamor_text.c \
+ glamor_transfer.c glamor_transfer.h glamor_transform.c \
+ glamor_transform.h glamor_trapezoid.c glamor_triangles.c \
+ glamor_addtraps.c glamor_glyphblt.c glamor_points.c \
+ glamor_priv.h glamor_pixmap.c glamor_largepixmap.c \
+ glamor_picture.c glamor_vbo.c glamor_window.c glamor_fbo.c \
+ glamor_compositerects.c glamor_utils.c glamor_utils.h \
+ glamor_sync.c glamor.h glamor_xv.c
+@XV_TRUE@am__objects_1 = glamor_xv.lo
am_libglamor_la_OBJECTS = glamor.lo glamor_copy.lo glamor_core.lo \
- glamor_dash.lo glamor_font.lo glamor_glx.lo glamor_glyphs.lo \
- glamor_image.lo glamor_lines.lo glamor_segs.lo \
- glamor_render.lo glamor_gradient.lo glamor_prepare.lo \
- glamor_program.lo glamor_rects.lo glamor_spans.lo \
- glamor_text.lo glamor_transfer.lo glamor_transform.lo \
- glamor_trapezoid.lo glamor_triangles.lo glamor_addtraps.lo \
- glamor_glyphblt.lo glamor_points.lo glamor_pixmap.lo \
- glamor_largepixmap.lo glamor_picture.lo glamor_vbo.lo \
- glamor_window.lo glamor_fbo.lo glamor_compositerects.lo \
- glamor_utils.lo glamor_xv.lo glamor_sync.lo
+ glamor_dash.lo glamor_font.lo glamor_glx.lo \
+ glamor_composite_glyphs.lo glamor_image.lo glamor_lines.lo \
+ glamor_segs.lo glamor_render.lo glamor_gradient.lo \
+ glamor_prepare.lo glamor_program.lo glamor_rects.lo \
+ glamor_spans.lo glamor_text.lo glamor_transfer.lo \
+ glamor_transform.lo glamor_trapezoid.lo glamor_triangles.lo \
+ glamor_addtraps.lo glamor_glyphblt.lo glamor_points.lo \
+ glamor_pixmap.lo glamor_largepixmap.lo glamor_picture.lo \
+ glamor_vbo.lo glamor_window.lo glamor_fbo.lo \
+ glamor_compositerects.lo glamor_utils.lo glamor_sync.lo \
+ $(am__objects_1)
libglamor_la_OBJECTS = $(am_libglamor_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -130,7 +148,7 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libglamor_la_SOURCES) $(libglamor_egl_stubs_la_SOURCES)
-DIST_SOURCES = $(libglamor_la_SOURCES) \
+DIST_SOURCES = $(am__libglamor_la_SOURCES_DIST) \
$(libglamor_egl_stubs_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
@@ -260,7 +278,6 @@ GLAMOR_LIBS = @GLAMOR_LIBS@
GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@
GLX_DEFINES = @GLX_DEFINES@
GLX_SYS_LIBS = @GLX_SYS_LIBS@
-GLX_TLS = @GLX_TLS@
GL_CFLAGS = @GL_CFLAGS@
GL_LIBS = @GL_LIBS@
GREP = @GREP@
@@ -390,8 +407,6 @@ XEPHYR_INCS = @XEPHYR_INCS@
XEPHYR_LIBS = @XEPHYR_LIBS@
XF86CONFIGDIR = @XF86CONFIGDIR@
XF86CONFIGFILE = @XF86CONFIGFILE@
-XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@
-XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@
XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@
XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@
XKB_COMPILED_DIR = @XKB_COMPILED_DIR@
@@ -518,52 +533,20 @@ top_srcdir = @top_srcdir@
noinst_LTLIBRARIES = libglamor.la libglamor_egl_stubs.la
libglamor_la_LIBADD = $(GLAMOR_LIBS)
AM_CFLAGS = $(CWARNFLAGS) $(DIX_CFLAGS) $(GLAMOR_CFLAGS)
-libglamor_la_SOURCES = \
- glamor.c \
- glamor_context.h \
- glamor_copy.c \
- glamor_core.c \
- glamor_dash.c \
- glamor_debug.h \
- glamor_font.c \
- glamor_font.h \
- glamor_glx.c \
- glamor_glyphs.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 \
- glamor_spans.c \
- glamor_text.c \
- glamor_transfer.c \
- glamor_transfer.h \
- glamor_transform.c \
- glamor_transform.h \
- glamor_trapezoid.c \
- glamor_triangles.c\
- glamor_addtraps.c\
- glamor_glyphblt.c\
- glamor_points.c\
- glamor_priv.h\
- glamor_pixmap.c\
- glamor_largepixmap.c\
- glamor_picture.c\
- glamor_vbo.c \
- glamor_window.c\
- glamor_fbo.c\
- glamor_compositerects.c\
- glamor_utils.c\
- glamor_utils.h\
- glamor_xv.c \
- glamor_sync.c \
- glamor.h
-
+libglamor_la_SOURCES = glamor.c glamor_context.h glamor_copy.c \
+ glamor_core.c glamor_dash.c glamor_debug.h glamor_font.c \
+ glamor_font.h glamor_glx.c glamor_composite_glyphs.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 \
+ glamor_spans.c glamor_text.c glamor_transfer.c \
+ glamor_transfer.h glamor_transform.c glamor_transform.h \
+ glamor_trapezoid.c glamor_triangles.c glamor_addtraps.c \
+ glamor_glyphblt.c glamor_points.c glamor_priv.h \
+ glamor_pixmap.c glamor_largepixmap.c glamor_picture.c \
+ glamor_vbo.c glamor_window.c glamor_fbo.c \
+ glamor_compositerects.c glamor_utils.c glamor_utils.h \
+ glamor_sync.c glamor.h $(am__append_1)
libglamor_egl_stubs_la_SOURCES = glamor_egl_stubs.c
sdk_HEADERS = glamor.h
all: all-am
@@ -624,6 +607,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_addtraps.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_composite_glyphs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_compositerects.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_copy.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_core.Plo@am__quote@
@@ -633,7 +617,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_font.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_glx.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_glyphblt.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_glyphs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_gradient.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_image.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glamor_largepixmap.Plo@am__quote@
diff --git a/xserver/glamor/glamor.c b/xserver/glamor/glamor.c
index 50317b481..8b5eb5493 100644
--- a/xserver/glamor/glamor.c
+++ b/xserver/glamor/glamor.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2008 Intel Corporation
+ * Copyright © 2008,2011 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -23,7 +23,7 @@
* Authors:
* Eric Anholt <eric@anholt.net>
* Zhigang Gong <zhigang.gong@linux.intel.com>
- *
+ * Chad Versace <chad.versace@linux.intel.com>
*/
/** @file glamor.c
@@ -34,6 +34,7 @@
#include <stdlib.h>
#include "glamor_priv.h"
+#include "mipict.h"
DevPrivateKeyRec glamor_screen_private_key;
DevPrivateKeyRec glamor_pixmap_private_key;
@@ -59,26 +60,29 @@ glamor_get_drawable_pixmap(DrawablePtr drawable)
return (PixmapPtr) drawable;
}
+static void
+glamor_init_pixmap_private_small(PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv)
+{
+ pixmap_priv->box.x1 = 0;
+ pixmap_priv->box.x2 = pixmap->drawable.width;
+ pixmap_priv->box.y1 = 0;
+ pixmap_priv->box.y2 = pixmap->drawable.height;
+ pixmap_priv->block_w = pixmap->drawable.width;
+ pixmap_priv->block_h = pixmap->drawable.height;
+ pixmap_priv->block_hcnt = 1;
+ pixmap_priv->block_wcnt = 1;
+ pixmap_priv->box_array = &pixmap_priv->box;
+ pixmap_priv->fbo_array = &pixmap_priv->fbo;
+}
+
_X_EXPORT void
glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
{
glamor_pixmap_private *pixmap_priv;
- glamor_screen_private *glamor_priv =
- glamor_get_screen_private(pixmap->drawable.pScreen);
- pixmap_priv = dixLookupPrivate(&pixmap->devPrivates,
- &glamor_pixmap_private_key);
- if (pixmap_priv == NULL) {
- pixmap_priv = calloc(sizeof(*pixmap_priv), 1);
- glamor_set_pixmap_private(pixmap, pixmap_priv);
- pixmap_priv->base.pixmap = pixmap;
- pixmap_priv->base.glamor_priv = glamor_priv;
- }
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
pixmap_priv->type = type;
- pixmap_priv->base.box.x1 = 0;
- pixmap_priv->base.box.x2 = pixmap->drawable.width;
- pixmap_priv->base.box.y1 = 0;
- pixmap_priv->base.box.y2 = pixmap->drawable.height;
+ glamor_init_pixmap_private_small(pixmap, pixmap_priv);
}
_X_EXPORT void
@@ -93,9 +97,9 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
glamor_priv = glamor_get_screen_private(screen);
pixmap_priv = glamor_get_pixmap_private(pixmap);
- if (pixmap_priv->base.fbo) {
+ if (pixmap_priv->fbo) {
fbo = glamor_pixmap_detach_fbo(pixmap_priv);
- glamor_destroy_fbo(fbo);
+ glamor_destroy_fbo(glamor_priv, fbo);
}
format = gl_iformat_for_pixmap(pixmap);
@@ -119,10 +123,10 @@ glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap)
glamor_priv = glamor_get_screen_private(screen_pixmap->drawable.pScreen);
pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
- glamor_priv->screen_fbo = pixmap_priv->base.fbo->fb;
+ glamor_priv->screen_fbo = pixmap_priv->fbo->fb;
- pixmap_priv->base.fbo->width = screen_pixmap->drawable.width;
- pixmap_priv->base.fbo->height = screen_pixmap->drawable.height;
+ pixmap_priv->fbo->width = screen_pixmap->drawable.width;
+ pixmap_priv->fbo->height = screen_pixmap->drawable.height;
}
uint32_t
@@ -133,7 +137,7 @@ glamor_get_pixmap_texture(PixmapPtr pixmap)
if (pixmap_priv->type != GLAMOR_TEXTURE_ONLY)
return 0;
- return pixmap_priv->base.fbo->tex;
+ return pixmap_priv->fbo->tex;
}
PixmapPtr
@@ -141,7 +145,6 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
unsigned int usage)
{
PixmapPtr pixmap;
- glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY;
glamor_pixmap_private *pixmap_priv;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_pixmap_fbo *fbo = NULL;
@@ -152,7 +155,9 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
return NullPixmap;
if ((usage == GLAMOR_CREATE_PIXMAP_CPU
- || (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 64 && h <= 64)
+ || (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE &&
+ w <= glamor_priv->glyph_max_dim &&
+ h <= glamor_priv->glyph_max_dim)
|| (w == 0 && h == 0)
|| !glamor_check_pixmap_fbo_depth(depth))
|| (!GLAMOR_TEXTURED_LARGE_PIXMAP &&
@@ -161,46 +166,28 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
else
pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
- pixmap_priv = calloc(1, sizeof(*pixmap_priv));
-
- if (!pixmap_priv) {
- fbDestroyPixmap(pixmap);
- return fbCreatePixmap(screen, w, h, depth, usage);
- }
- glamor_set_pixmap_private(pixmap, pixmap_priv);
-
- if (usage == GLAMOR_CREATE_PIXMAP_MAP)
- type = GLAMOR_MEMORY_MAP;
-
- pixmap_priv->base.pixmap = pixmap;
- pixmap_priv->base.glamor_priv = glamor_priv;
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
format = gl_iformat_for_pixmap(pixmap);
pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
+ pixmap_priv->type = GLAMOR_TEXTURE_ONLY;
+
if (usage == GLAMOR_CREATE_PIXMAP_NO_TEXTURE) {
- pixmap_priv->type = GLAMOR_TEXTURE_ONLY;
- pixmap_priv->base.box.x1 = 0;
- pixmap_priv->base.box.y1 = 0;
- pixmap_priv->base.box.x2 = w;
- pixmap_priv->base.box.y2 = h;
+ glamor_init_pixmap_private_small(pixmap, pixmap_priv);
return pixmap;
}
- else if (type == GLAMOR_MEMORY_MAP || usage == GLAMOR_CREATE_NO_LARGE ||
+ else if (usage == GLAMOR_CREATE_NO_LARGE ||
glamor_check_fbo_size(glamor_priv, w, h))
{
- pixmap_priv->type = type;
- pixmap_priv->base.box.x1 = 0;
- pixmap_priv->base.box.y1 = 0;
- pixmap_priv->base.box.x2 = w;
- pixmap_priv->base.box.y2 = h;
+ glamor_init_pixmap_private_small(pixmap, pixmap_priv);
fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
} else {
int tile_size = glamor_priv->max_fbo_size;
- DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n", pixmap, w, h, tile_size);
- pixmap_priv->type = GLAMOR_TEXTURE_LARGE;
+ DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n",
+ pixmap, w, h, tile_size);
fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage,
tile_size, tile_size, pixmap_priv);
}
@@ -219,13 +206,10 @@ void
glamor_destroy_textured_pixmap(PixmapPtr pixmap)
{
if (pixmap->refcnt == 1) {
- glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
- if (pixmap_priv != NULL) {
#if GLAMOR_HAS_GBM
- glamor_egl_destroy_pixmap_image(pixmap);
+ glamor_egl_destroy_pixmap_image(pixmap);
#endif
- glamor_set_pixmap_private(pixmap, NULL);
- }
+ glamor_pixmap_destroy_fbo(pixmap);
}
}
@@ -275,6 +259,68 @@ glamor_set_debug_level(int *debug_level)
int glamor_debug_level;
+void
+glamor_gldrawarrays_quads_using_indices(glamor_screen_private *glamor_priv,
+ unsigned count)
+{
+ unsigned i;
+
+ /* For a single quad, don't bother with an index buffer. */
+ if (count == 1)
+ goto fallback;
+
+ if (glamor_priv->ib_size < count) {
+ /* Basic GLES2 doesn't have any way to map buffer objects for
+ * writing, but it's long past time for drivers to have
+ * MapBufferRange.
+ */
+ if (!glamor_priv->has_map_buffer_range)
+ goto fallback;
+
+ /* Lazy create the buffer name, and only bind it once since
+ * none of the glamor code binds it to anything else.
+ */
+ if (!glamor_priv->ib) {
+ glGenBuffers(1, &glamor_priv->ib);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ib);
+ }
+
+ /* For now, only support GL_UNSIGNED_SHORTs. */
+ if (count > ((1 << 16) - 1) / 4) {
+ goto fallback;
+ } else {
+ uint16_t *data;
+ size_t size = count * 6 * sizeof(GLushort);
+
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW);
+ data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER,
+ 0, size,
+ GL_MAP_WRITE_BIT |
+ GL_MAP_INVALIDATE_BUFFER_BIT);
+ for (i = 0; i < count; i++) {
+ data[i * 6 + 0] = i * 4 + 0;
+ data[i * 6 + 1] = i * 4 + 1;
+ data[i * 6 + 2] = i * 4 + 2;
+ data[i * 6 + 3] = i * 4 + 0;
+ data[i * 6 + 4] = i * 4 + 2;
+ data[i * 6 + 5] = i * 4 + 3;
+ }
+ glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+
+ glamor_priv->ib_size = count;
+ glamor_priv->ib_type = GL_UNSIGNED_SHORT;
+ }
+ }
+
+ glDrawElements(GL_TRIANGLES, count * 6, glamor_priv->ib_type, NULL);
+ return;
+
+fallback:
+ for (i = 0; i < count; i++)
+ glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
+}
+
+
/**
* Creates any pixmaps used internally by glamor, since those can't be
* allocated at ScreenInit time.
@@ -291,16 +337,6 @@ glamor_create_screen_resources(ScreenPtr screen)
ret = screen->CreateScreenResources(screen);
screen->CreateScreenResources = glamor_create_screen_resources;
- if (!glamor_glyphs_init(screen)) {
- ErrorF("Failed to initialize glyphs\n");
- ret = FALSE;
- }
-
- if (!glamor_realize_glyph_caches(screen)) {
- ErrorF("Failed to initialize glyph cache\n");
- ret = FALSE;
- }
-
return ret;
}
@@ -333,17 +369,68 @@ glamor_check_instruction_count(int gl_version)
return TRUE;
}
+static void GLAPIENTRY
+glamor_debug_output_callback(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *message,
+ const void *userParam)
+{
+ ScreenPtr screen = (void *)userParam;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ if (glamor_priv->suppress_gl_out_of_memory_logging &&
+ source == GL_DEBUG_SOURCE_API && type == GL_DEBUG_TYPE_ERROR) {
+ return;
+ }
+
+ LogMessageVerb(X_ERROR, 0, "glamor%d: GL error: %*s\n",
+ screen->myNum, length, message);
+}
+
+/**
+ * Configures GL_ARB_debug_output to give us immediate callbacks when
+ * GL errors occur, so that we can log them.
+ */
+static void
+glamor_setup_debug_output(ScreenPtr screen)
+{
+ if (!epoxy_has_gl_extension("GL_ARB_debug_output"))
+ return;
+
+ glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
+ /* Disable debugging messages other than GL API errors */
+ glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL,
+ GL_FALSE);
+ glDebugMessageControl(GL_DEBUG_SOURCE_API,
+ GL_DEBUG_TYPE_ERROR,
+ GL_DONT_CARE,
+ 0, NULL, GL_TRUE);
+ glDebugMessageCallback(glamor_debug_output_callback,
+ screen);
+
+ /* If KHR_debug is present, all debug output is disabled by
+ * default on non-debug contexts.
+ */
+ if (epoxy_has_gl_extension("GL_KHR_debug"))
+ glEnable(GL_DEBUG_OUTPUT);
+}
+
/** Set up glamor for an already-configured GL context. */
Bool
glamor_init(ScreenPtr screen, unsigned int flags)
{
glamor_screen_private *glamor_priv;
int gl_version;
+ int glsl_major, glsl_minor;
int max_viewport_size[2];
+ const char *shading_version_string;
+ int shading_version_offset;
-#ifdef RENDER
PictureScreenPtr ps = GetPictureScreenIfSet(screen);
-#endif
+
if (flags & ~GLAMOR_VALID_FLAGS) {
ErrorF("glamor_init: Invalid flags %x\n", flags);
return FALSE;
@@ -363,7 +450,8 @@ 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,
+ sizeof(struct glamor_pixmap_private))) {
LogMessage(X_WARNING,
"glamor%d: Failed to allocate pixmap private\n",
screen->myNum);
@@ -399,14 +487,40 @@ glamor_init(ScreenPtr screen, unsigned int flags)
gl_version = epoxy_gl_version();
- /* Would be nice to have a cleaner test for GLSL 1.30 support,
- * but for now this should suffice
- */
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && gl_version >= 30)
- glamor_priv->glsl_version = 130;
- else
- glamor_priv->glsl_version = 120;
+ shading_version_string = (char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
+
+ if (!shading_version_string) {
+ LogMessage(X_WARNING,
+ "glamor%d: Failed to get GLSL version\n",
+ screen->myNum);
+ goto fail;
+ }
+ shading_version_offset = 0;
+ if (strncmp("OpenGL ES GLSL ES ", shading_version_string, 18) == 0)
+ shading_version_offset = 18;
+
+ if (sscanf(shading_version_string + shading_version_offset,
+ "%i.%i",
+ &glsl_major,
+ &glsl_minor) != 2) {
+ LogMessage(X_WARNING,
+ "glamor%d: Failed to parse GLSL version string %s\n",
+ screen->myNum, shading_version_string);
+ goto fail;
+ }
+ glamor_priv->glsl_version = glsl_major * 100 + glsl_minor;
+
+ if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
+ /* Force us back to the base version of our programs on an ES
+ * context, anyway. Basically glamor only uses desktop 1.20
+ * or 1.30 currently. 1.30's new features are also present in
+ * ES 3.0, but our glamor_program.c constructions use a lot of
+ * compatibility features (to reduce the diff between 1.20 and
+ * 1.30 programs).
+ */
+ glamor_priv->glsl_version = 120;
+ }
/* We'd like to require GL_ARB_map_buffer_range or
* GL_OES_map_buffer_range, since it offers more information to
@@ -451,7 +565,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
glamor_priv->has_fbo_blit =
epoxy_has_gl_extension("GL_EXT_framebuffer_blit");
glamor_priv->has_map_buffer_range =
- epoxy_has_gl_extension("GL_ARB_map_buffer_range");
+ epoxy_has_gl_extension("GL_ARB_map_buffer_range") ||
+ epoxy_has_gl_extension("GL_EXT_map_buffer_range");
glamor_priv->has_buffer_storage =
epoxy_has_gl_extension("GL_ARB_buffer_storage");
glamor_priv->has_nv_texture_barrier =
@@ -464,6 +579,27 @@ glamor_init(ScreenPtr screen, unsigned int flags)
glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP ||
epoxy_gl_version() >= 30 ||
epoxy_has_gl_extension("GL_NV_pack_subimage");
+ glamor_priv->has_vertex_array_object =
+ epoxy_has_gl_extension("GL_ARB_vertex_array_object");
+ glamor_priv->has_dual_blend =
+ epoxy_has_gl_extension("GL_ARB_blend_func_extended");
+
+ /* assume a core profile if we are GL 3.1 and don't have ARB_compatibility */
+ glamor_priv->is_core_profile =
+ gl_version >= 31 && !epoxy_has_gl_extension("GL_ARB_compatibility");
+
+ glamor_setup_debug_output(screen);
+
+ glamor_priv->use_quads = (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) &&
+ !glamor_priv->is_core_profile;
+
+ /* Driver-specific hack: Avoid using GL_QUADS on VC4, where
+ * they'll be emulated more expensively than we can with our
+ * cached IB.
+ */
+ if (strstr((char *)glGetString(GL_VENDOR), "Broadcom") &&
+ strstr((char *)glGetString(GL_RENDERER), "VC4"))
+ glamor_priv->use_quads = FALSE;
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glamor_priv->max_fbo_size);
@@ -474,6 +610,10 @@ glamor_init(ScreenPtr screen, unsigned int flags)
glamor_priv->max_fbo_size = MAX_FBO_SIZE;
#endif
+ glamor_priv->one_channel_format = GL_ALPHA;
+ if (epoxy_has_gl_extension("GL_ARB_texture_rg") && epoxy_has_gl_extension("GL_ARB_texture_swizzle"))
+ glamor_priv->one_channel_format = GL_RED;
+
glamor_set_debug_level(&glamor_debug_level);
glamor_priv->saved_procs.create_screen_resources =
@@ -483,74 +623,61 @@ glamor_init(ScreenPtr screen, unsigned int flags)
if (!glamor_font_init(screen))
goto fail;
- if (flags & GLAMOR_USE_SCREEN) {
+ glamor_priv->saved_procs.block_handler = screen->BlockHandler;
+ screen->BlockHandler = _glamor_block_handler;
- glamor_priv->saved_procs.block_handler = screen->BlockHandler;
- screen->BlockHandler = _glamor_block_handler;
+ if (!glamor_composite_glyphs_init(screen)) {
+ ErrorF("Failed to initialize composite masks\n");
+ goto fail;
+ }
- glamor_priv->saved_procs.create_gc = screen->CreateGC;
- screen->CreateGC = glamor_create_gc;
+ glamor_priv->saved_procs.create_gc = screen->CreateGC;
+ screen->CreateGC = glamor_create_gc;
- glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap;
- screen->CreatePixmap = glamor_create_pixmap;
+ glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap;
+ screen->CreatePixmap = glamor_create_pixmap;
- glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap;
- screen->DestroyPixmap = glamor_destroy_pixmap;
+ glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap;
+ screen->DestroyPixmap = glamor_destroy_pixmap;
- glamor_priv->saved_procs.get_spans = screen->GetSpans;
- screen->GetSpans = glamor_get_spans;
+ glamor_priv->saved_procs.get_spans = screen->GetSpans;
+ screen->GetSpans = glamor_get_spans;
- glamor_priv->saved_procs.get_image = screen->GetImage;
- screen->GetImage = glamor_get_image;
+ glamor_priv->saved_procs.get_image = screen->GetImage;
+ screen->GetImage = glamor_get_image;
- glamor_priv->saved_procs.change_window_attributes =
- screen->ChangeWindowAttributes;
- screen->ChangeWindowAttributes = glamor_change_window_attributes;
+ glamor_priv->saved_procs.change_window_attributes =
+ screen->ChangeWindowAttributes;
+ screen->ChangeWindowAttributes = glamor_change_window_attributes;
- glamor_priv->saved_procs.copy_window = screen->CopyWindow;
- screen->CopyWindow = glamor_copy_window;
+ glamor_priv->saved_procs.copy_window = screen->CopyWindow;
+ screen->CopyWindow = glamor_copy_window;
- glamor_priv->saved_procs.bitmap_to_region = screen->BitmapToRegion;
- screen->BitmapToRegion = glamor_bitmap_to_region;
- }
-#ifdef RENDER
- if (flags & GLAMOR_USE_PICTURE_SCREEN) {
- glamor_priv->saved_procs.composite = ps->Composite;
- ps->Composite = glamor_composite;
+ glamor_priv->saved_procs.bitmap_to_region = screen->BitmapToRegion;
+ screen->BitmapToRegion = glamor_bitmap_to_region;
- glamor_priv->saved_procs.trapezoids = ps->Trapezoids;
- ps->Trapezoids = glamor_trapezoids;
+ glamor_priv->saved_procs.composite = ps->Composite;
+ ps->Composite = glamor_composite;
- glamor_priv->saved_procs.triangles = ps->Triangles;
- ps->Triangles = glamor_triangles;
+ glamor_priv->saved_procs.trapezoids = ps->Trapezoids;
+ ps->Trapezoids = glamor_trapezoids;
- glamor_priv->saved_procs.addtraps = ps->AddTraps;
- ps->AddTraps = glamor_add_traps;
+ glamor_priv->saved_procs.triangles = ps->Triangles;
+ ps->Triangles = glamor_triangles;
- }
+ glamor_priv->saved_procs.addtraps = ps->AddTraps;
+ ps->AddTraps = glamor_add_traps;
glamor_priv->saved_procs.composite_rects = ps->CompositeRects;
ps->CompositeRects = glamor_composite_rectangles;
glamor_priv->saved_procs.glyphs = ps->Glyphs;
- ps->Glyphs = glamor_glyphs;
-
- glamor_priv->saved_procs.unrealize_glyph = ps->UnrealizeGlyph;
- ps->UnrealizeGlyph = glamor_glyph_unrealize;
-
- glamor_priv->saved_procs.create_picture = ps->CreatePicture;
- ps->CreatePicture = glamor_create_picture;
-
- glamor_priv->saved_procs.destroy_picture = ps->DestroyPicture;
- ps->DestroyPicture = glamor_destroy_picture;
- glamor_init_composite_shaders(screen);
-#endif
- glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap;
- screen->SetWindowPixmap = glamor_set_window_pixmap;
+ ps->Glyphs = glamor_composite_glyphs;
glamor_init_vbo(screen);
glamor_init_pixmap_fbo(screen);
glamor_init_finish_access_shaders(screen);
+
#ifdef GLAMOR_GRADIENT_SHADER
glamor_init_gradient_shader(screen);
#endif
@@ -573,86 +700,46 @@ glamor_release_screen_priv(ScreenPtr screen)
glamor_screen_private *glamor_priv;
glamor_priv = glamor_get_screen_private(screen);
-#ifdef RENDER
- glamor_fini_composite_shaders(screen);
-#endif
glamor_fini_vbo(screen);
glamor_fini_pixmap_fbo(screen);
- glamor_fini_finish_access_shaders(screen);
-#ifdef GLAMOR_GRADIENT_SHADER
- glamor_fini_gradient_shader(screen);
-#endif
glamor_pixmap_fini(screen);
free(glamor_priv);
glamor_set_screen_private(screen, NULL);
}
-_X_EXPORT void
-glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
-{
- glamor_pixmap_private *old_priv;
-
- old_priv = dixGetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
-
- if (priv) {
- assert(old_priv == NULL);
- }
- else {
- if (old_priv == NULL)
- return;
-
- glamor_pixmap_destroy_fbo(old_priv);
- free(old_priv);
- }
-
- dixSetPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key, priv);
-}
-
Bool
glamor_close_screen(ScreenPtr screen)
{
glamor_screen_private *glamor_priv;
PixmapPtr screen_pixmap;
- int flags;
-
-#ifdef RENDER
PictureScreenPtr ps = GetPictureScreenIfSet(screen);
-#endif
+
glamor_priv = glamor_get_screen_private(screen);
- flags = glamor_priv->flags;
glamor_sync_close(screen);
- glamor_glyphs_fini(screen);
+ glamor_composite_glyphs_fini(screen);
screen->CloseScreen = glamor_priv->saved_procs.close_screen;
screen->CreateScreenResources =
glamor_priv->saved_procs.create_screen_resources;
- if (flags & GLAMOR_USE_SCREEN) {
-
- screen->CreateGC = glamor_priv->saved_procs.create_gc;
- screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
- screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
- screen->GetSpans = glamor_priv->saved_procs.get_spans;
- screen->ChangeWindowAttributes =
- glamor_priv->saved_procs.change_window_attributes;
- screen->CopyWindow = glamor_priv->saved_procs.copy_window;
- screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
- screen->BlockHandler = glamor_priv->saved_procs.block_handler;
- }
-#ifdef RENDER
- if (ps && (flags & GLAMOR_USE_PICTURE_SCREEN)) {
- ps->Composite = glamor_priv->saved_procs.composite;
- ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
- ps->Triangles = glamor_priv->saved_procs.triangles;
- ps->CreatePicture = glamor_priv->saved_procs.create_picture;
- }
+ screen->CreateGC = glamor_priv->saved_procs.create_gc;
+ screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
+ screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
+ screen->GetSpans = glamor_priv->saved_procs.get_spans;
+ screen->ChangeWindowAttributes =
+ glamor_priv->saved_procs.change_window_attributes;
+ screen->CopyWindow = glamor_priv->saved_procs.copy_window;
+ screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
+ screen->BlockHandler = glamor_priv->saved_procs.block_handler;
+
+ ps->Composite = glamor_priv->saved_procs.composite;
+ ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
+ ps->Triangles = glamor_priv->saved_procs.triangles;
ps->CompositeRects = glamor_priv->saved_procs.composite_rects;
ps->Glyphs = glamor_priv->saved_procs.glyphs;
- ps->UnrealizeGlyph = glamor_priv->saved_procs.unrealize_glyph;
- screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
-#endif
+
screen_pixmap = screen->GetScreenPixmap(screen);
- glamor_set_pixmap_private(screen_pixmap, NULL);
+ glamor_pixmap_destroy_fbo(screen_pixmap);
glamor_release_screen_priv(screen);
@@ -685,12 +772,11 @@ _X_EXPORT int
glamor_fd_from_pixmap(ScreenPtr screen,
PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
{
- glamor_pixmap_private *pixmap_priv;
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
- pixmap_priv = glamor_get_pixmap_private(pixmap);
- if (pixmap_priv == NULL || !glamor_priv->dri3_enabled)
+ if (!glamor_priv->dri3_enabled)
return -1;
switch (pixmap_priv->type) {
case GLAMOR_TEXTURE_DRM:
@@ -699,7 +785,7 @@ glamor_fd_from_pixmap(ScreenPtr screen,
return -1;
return glamor_egl_dri3_fd_name_from_tex(screen,
pixmap,
- pixmap_priv->base.fbo->tex,
+ pixmap_priv->fbo->tex,
FALSE, stride, size);
default:
break;
@@ -710,13 +796,10 @@ glamor_fd_from_pixmap(ScreenPtr screen,
int
glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
{
- glamor_pixmap_private *pixmap_priv;
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
- pixmap_priv = glamor_get_pixmap_private(pixmap);
- if (pixmap_priv == NULL)
- return -1;
switch (pixmap_priv->type) {
case GLAMOR_TEXTURE_DRM:
case GLAMOR_TEXTURE_ONLY:
@@ -724,7 +807,7 @@ glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
return -1;
return glamor_egl_dri3_fd_name_from_tex(pixmap->drawable.pScreen,
pixmap,
- pixmap_priv->base.fbo->tex,
+ pixmap_priv->fbo->tex,
TRUE, stride, size);
default:
break;
diff --git a/xserver/glamor/glamor.h b/xserver/glamor/glamor.h
index 206158c02..0aa6d5604 100644
--- a/xserver/glamor/glamor.h
+++ b/xserver/glamor/glamor.h
@@ -52,50 +52,34 @@ struct glamor_context;
* @TEXTURE_ONLY: pixmap is in an internal texture.
*/
typedef enum glamor_pixmap_type {
- GLAMOR_MEMORY,
- GLAMOR_MEMORY_MAP,
+ GLAMOR_MEMORY = 0, /* Newly calloc()ed pixmaps are memory. */
GLAMOR_TEXTURE_DRM,
- GLAMOR_SEPARATE_TEXTURE,
GLAMOR_DRM_ONLY,
GLAMOR_TEXTURE_ONLY,
- GLAMOR_TEXTURE_LARGE,
- GLAMOR_TEXTURE_PACK
} glamor_pixmap_type_t;
#define GLAMOR_EGL_EXTERNAL_BUFFER 3
-#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)
-#define GLAMOR_NO_DRI3 (1 << 4)
-#define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS \
- | GLAMOR_USE_SCREEN \
- | GLAMOR_USE_PICTURE_SCREEN \
- | GLAMOR_USE_EGL_SCREEN \
+#define GLAMOR_USE_EGL_SCREEN (1 << 0)
+#define GLAMOR_NO_DRI3 (1 << 1)
+#define GLAMOR_VALID_FLAGS (GLAMOR_USE_EGL_SCREEN \
| GLAMOR_NO_DRI3)
+/* until we need geometry shaders GL3.1 should suffice. */
+#define GLAMOR_GL_CORE_VER_MAJOR 3
+#define GLAMOR_GL_CORE_VER_MINOR 1
+
/* @glamor_init: Initialize glamor internal data structure.
*
* @screen: Current screen pointer.
* @flags: Please refer the flags description above.
*
- * @GLAMOR_USE_SCREEN:
- * If running in an pre-existing X environment, and the
- * gl context is GLX, then you should set this bit and
- * let the glamor to handle all the screen related
- * functions such as GC ops and CreatePixmap/DestroyPixmap.
- *
- * @GLAMOR_USE_PICTURE_SCREEN:
- * If don't use any other underlying DDX driver to handle
- * the picture related rendering functions, please set this
- * bit on. Otherwise, clear this bit. And then it is the DDX
- * driver's responsibility to determine how/when to jump to
- * glamor's picture compositing path.
- *
* @GLAMOR_USE_EGL_SCREEN:
* If you are using EGL layer, then please set this bit
* on, otherwise, clear it.
*
+ * @GLAMOR_NO_DRI3
+ * Disable the built-in DRI3 support
+ *
* This function initializes necessary internal data structure
* for glamor. And before calling into this function, the OpenGL
* environment should be ready. Should be called before any real
@@ -125,8 +109,6 @@ extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap,
extern _X_EXPORT uint32_t glamor_get_pixmap_texture(PixmapPtr pixmap);
-extern _X_EXPORT Bool glamor_glyphs_init(ScreenPtr pScreen);
-
extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap,
unsigned int tex);
@@ -142,7 +124,6 @@ extern _X_EXPORT Bool glamor_destroy_pixmap(PixmapPtr pixmap);
#define GLAMOR_CREATE_PIXMAP_CPU 0x100
#define GLAMOR_CREATE_PIXMAP_FIXUP 0x101
#define GLAMOR_CREATE_FBO_NO_FBO 0x103
-#define GLAMOR_CREATE_PIXMAP_MAP 0x104
#define GLAMOR_CREATE_NO_LARGE 0x105
#define GLAMOR_CREATE_PIXMAP_NO_TEXTURE 0x106
@@ -165,7 +146,8 @@ extern _X_EXPORT void glamor_enable_dri3(ScreenPtr screen);
extern _X_EXPORT unsigned int glamor_egl_create_argb8888_based_texture(ScreenPtr
screen,
int w,
- int h);
+ int h,
+ Bool linear);
extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr,
unsigned int, Bool,
CARD16 *, CARD32 *);
@@ -220,6 +202,21 @@ extern _X_EXPORT int glamor_fd_from_pixmap(ScreenPtr screen,
extern _X_EXPORT int glamor_name_from_pixmap(PixmapPtr pixmap,
CARD16 *stride, CARD32 *size);
+/* @glamor_gbm_bo_from_pixmap: Get a GBM bo from a pixmap.
+ *
+ * @screen: Current screen pointer.
+ * @pixmap: The pixmap from which we want the fd.
+ * @stride, @size: Pointers to fill the stride and size of the
+ * buffer associated to the fd.
+ *
+ * the pixmap and the buffer represented by the gbm_bo will share the same
+ * content.
+ *
+ * Returns the gbm_bo on success, NULL on error.
+ * */
+extern _X_EXPORT void *glamor_gbm_bo_from_pixmap(ScreenPtr screen,
+ PixmapPtr pixmap);
+
/* @glamor_pixmap_from_fd: Creates a pixmap to wrap a dma-buf fd.
*
* @screen: Current screen pointer.
@@ -240,6 +237,25 @@ extern _X_EXPORT PixmapPtr glamor_pixmap_from_fd(ScreenPtr screen,
CARD8 depth,
CARD8 bpp);
+/* @glamor_back_pixmap_from_fd: Backs an existing pixmap with a dma-buf fd.
+ *
+ * @pixmap: Pixmap to change backing for
+ * @fd: The dma-buf fd to import.
+ * @width: The width of the buffer.
+ * @height: The height of the buffer.
+ * @stride: The stride of the buffer.
+ * @depth: The depth of the buffer.
+ * @bpp: The number of bpp of the buffer.
+ *
+ * Returns TRUE if successful, FALSE on failure.
+ * */
+extern _X_EXPORT Bool glamor_back_pixmap_from_fd(PixmapPtr pixmap,
+ int fd,
+ CARD16 width,
+ CARD16 height,
+ CARD16 stride,
+ CARD8 depth,
+ CARD8 bpp);
#ifdef GLAMOR_FOR_XORG
#define GLAMOR_EGL_MODULE_NAME "glamoregl"
@@ -326,146 +342,6 @@ extern _X_EXPORT void glamor_destroy_gc(GCPtr gc);
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);
-/* Glamor rendering/drawing functions with XXX_nf.
- * nf means no fallback within glamor internal if possible. If glamor
- * fail to accelerate the operation, glamor will return a false, and the
- * caller need to implement fallback method. Return a true means the
- * rendering request get done successfully. */
-extern _X_EXPORT Bool glamor_fill_spans_nf(DrawablePtr drawable,
- GCPtr gc,
- int n, DDXPointPtr points,
- int *widths, int sorted);
-
-extern _X_EXPORT Bool glamor_poly_fill_rect_nf(DrawablePtr drawable,
- GCPtr gc,
- int nrect, xRectangle *prect);
-
-extern _X_EXPORT Bool glamor_put_image_nf(DrawablePtr drawable,
- GCPtr gc, int depth, int x, int y,
- int w, int h, int left_pad,
- int image_format, char *bits);
-
-extern _X_EXPORT 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);
-
-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,
- PicturePtr dest,
- INT16 x_source,
- INT16 y_source,
- INT16 x_mask,
- INT16 y_mask,
- INT16 x_dest, INT16 y_dest,
- CARD16 width, CARD16 height);
-
-extern _X_EXPORT Bool glamor_trapezoids_nf(CARD8 op,
- PicturePtr src, PicturePtr dst,
- PictFormatPtr mask_format,
- INT16 x_src, INT16 y_src,
- int ntrap, xTrapezoid *traps);
-
-extern _X_EXPORT Bool glamor_glyphs_nf(CARD8 op,
- PicturePtr src,
- PicturePtr dst,
- PictFormatPtr mask_format,
- INT16 x_src,
- INT16 y_src, int nlist,
- GlyphListPtr list, GlyphPtr *glyphs);
-
-extern _X_EXPORT Bool glamor_triangles_nf(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc, INT16 ySrc,
- int ntris, xTriangle *tris);
-
-extern _X_EXPORT void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
-
-extern _X_EXPORT Bool glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc,
- char *src, DDXPointPtr points,
- int *widths, int n, int sorted);
-
-extern _X_EXPORT Bool glamor_get_spans_nf(DrawablePtr drawable, int wmax,
- DDXPointPtr points, int *widths,
- int count, char *dst);
-
-extern _X_EXPORT Bool glamor_composite_rects_nf(CARD8 op,
- PicturePtr pDst,
- xRenderColor *color,
- int nRect, xRectangle *rects);
-
-extern _X_EXPORT Bool glamor_get_image_nf(DrawablePtr pDrawable, int x, int y,
- int w, int h, unsigned int format,
- unsigned long planeMask, char *d);
-
-extern _X_EXPORT Bool glamor_add_traps_nf(PicturePtr pPicture,
- INT16 x_off,
- INT16 y_off, int ntrap,
- xTrap *traps);
-
-extern _X_EXPORT 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);
-
-extern _X_EXPORT Bool glamor_image_glyph_blt_nf(DrawablePtr pDrawable,
- GCPtr pGC, int x, int y,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- void *pglyphBase);
-
-extern _X_EXPORT Bool glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- void *pglyphBase);
-
-extern _X_EXPORT Bool glamor_push_pixels_nf(GCPtr pGC, PixmapPtr pBitmap,
- DrawablePtr pDrawable, int w, int h,
- int x, int y);
-
-extern _X_EXPORT Bool glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC,
- int mode, int npt, DDXPointPtr ppt);
-
-extern _X_EXPORT Bool glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC,
- int nseg, xSegment *pSeg);
-
-extern _X_EXPORT Bool glamor_poly_lines_nf(DrawablePtr drawable, GCPtr gc,
- int mode, int n, DDXPointPtr points);
-
-extern _X_EXPORT Bool glamor_poly_text8_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, char *chars, int *final_pos);
-
-extern _X_EXPORT Bool glamor_poly_text16_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, unsigned short *chars, int *final_pos);
-
-extern _X_EXPORT Bool glamor_image_text8_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, char *chars);
-
-extern _X_EXPORT Bool glamor_image_text16_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, unsigned short *chars);
-
#define HAS_GLAMOR_TEXT 1
#ifdef GLAMOR_FOR_XORG
diff --git a/xserver/glamor/glamor_addtraps.c b/xserver/glamor/glamor_addtraps.c
index fdc0f4232..7ad9f3000 100644
--- a/xserver/glamor/glamor_addtraps.c
+++ b/xserver/glamor/glamor_addtraps.c
@@ -28,34 +28,13 @@
#include "glamor_priv.h"
-static Bool
-_glamor_add_traps(PicturePtr pPicture,
- INT16 x_off,
- INT16 y_off, int ntrap, xTrap *traps, Bool fallback)
+void
+glamor_add_traps(PicturePtr pPicture,
+ INT16 x_off,
+ INT16 y_off, int ntrap, xTrap *traps)
{
- if (!fallback
- && (!pPicture->pDrawable
- || glamor_ddx_fallback_check_pixmap(pPicture->pDrawable)))
- return FALSE;
-
if (glamor_prepare_access_picture(pPicture, GLAMOR_ACCESS_RW)) {
fbAddTraps(pPicture, x_off, y_off, ntrap, traps);
}
glamor_finish_access_picture(pPicture);
-
- return TRUE;
-}
-
-void
-glamor_add_traps(PicturePtr pPicture,
- INT16 x_off, INT16 y_off, int ntrap, xTrap *traps)
-{
- _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, TRUE);
-}
-
-Bool
-glamor_add_traps_nf(PicturePtr pPicture,
- INT16 x_off, INT16 y_off, int ntrap, xTrap *traps)
-{
- return _glamor_add_traps(pPicture, x_off, y_off, ntrap, traps, FALSE);
}
diff --git a/xserver/glamor/glamor_composite_glyphs.c b/xserver/glamor/glamor_composite_glyphs.c
new file mode 100644
index 000000000..f51ff6dad
--- /dev/null
+++ b/xserver/glamor/glamor_composite_glyphs.c
@@ -0,0 +1,573 @@
+/*
+ * 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 <stdlib.h>
+#include "Xprintf.h"
+
+#include "glamor_priv.h"
+#include "glamor_transform.h"
+#include "glamor_transfer.h"
+
+#include <mipict.h>
+
+#define DEFAULT_ATLAS_DIM 1024
+
+static DevPrivateKeyRec glamor_glyph_private_key;
+
+struct glamor_glyph_private {
+ int16_t x;
+ int16_t y;
+ uint32_t serial;
+};
+
+struct glamor_glyph_atlas {
+ PixmapPtr atlas;
+ PictFormatPtr format;
+ int x, y;
+ int row_height;
+ int nglyph;
+ uint32_t serial;
+};
+
+static inline struct glamor_glyph_private *glamor_get_glyph_private(PixmapPtr pixmap) {
+ return dixLookupPrivate(&pixmap->devPrivates, &glamor_glyph_private_key);
+}
+
+static inline void
+glamor_copy_glyph(PixmapPtr glyph_pixmap,
+ DrawablePtr atlas_draw,
+ int16_t x,
+ int16_t y)
+{
+ DrawablePtr glyph_draw = &glyph_pixmap->drawable;
+ BoxRec box = {
+ .x1 = 0,
+ .y1 = 0,
+ .x2 = glyph_draw->width,
+ .y2 = glyph_draw->height,
+ };
+ PixmapPtr upload_pixmap = glyph_pixmap;
+
+ if (glyph_pixmap->drawable.bitsPerPixel != atlas_draw->bitsPerPixel) {
+
+ /* If we're dealing with 1-bit glyphs, we copy them to a
+ * temporary 8-bit pixmap and upload them from there, since
+ * that's what GL can handle.
+ */
+ ScreenPtr screen = atlas_draw->pScreen;
+ GCPtr scratch_gc;
+ ChangeGCVal changes[2];
+
+ upload_pixmap = glamor_create_pixmap(screen,
+ glyph_draw->width,
+ glyph_draw->height,
+ atlas_draw->depth,
+ GLAMOR_CREATE_PIXMAP_CPU);
+ if (!upload_pixmap)
+ return;
+
+ scratch_gc = GetScratchGC(upload_pixmap->drawable.depth, screen);
+ if (!scratch_gc) {
+ glamor_destroy_pixmap(upload_pixmap);
+ return;
+ }
+ changes[0].val = 0xff;
+ changes[1].val = 0x00;
+ if (ChangeGC(NullClient, scratch_gc,
+ GCForeground|GCBackground, changes) != Success) {
+ glamor_destroy_pixmap(upload_pixmap);
+ FreeScratchGC(scratch_gc);
+ return;
+ }
+ ValidateGC(&upload_pixmap->drawable, scratch_gc);
+
+ (*scratch_gc->ops->CopyPlane)(glyph_draw,
+ &upload_pixmap->drawable,
+ scratch_gc,
+ 0, 0,
+ glyph_draw->width,
+ glyph_draw->height,
+ 0, 0, 0x1);
+ }
+ glamor_upload_boxes((PixmapPtr) atlas_draw,
+ &box, 1,
+ 0, 0,
+ x, y,
+ upload_pixmap->devPrivate.ptr,
+ upload_pixmap->devKind);
+
+ if (upload_pixmap != glyph_pixmap)
+ glamor_destroy_pixmap(upload_pixmap);
+}
+
+static Bool
+glamor_glyph_atlas_init(ScreenPtr screen, struct glamor_glyph_atlas *atlas)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ PictFormatPtr format = atlas->format;
+
+ atlas->atlas = glamor_create_pixmap(screen, glamor_priv->glyph_atlas_dim,
+ glamor_priv->glyph_atlas_dim, format->depth,
+ GLAMOR_CREATE_FBO_NO_FBO);
+ if (!glamor_pixmap_has_fbo(atlas->atlas)) {
+ glamor_destroy_pixmap(atlas->atlas);
+ atlas->atlas = NULL;
+ }
+ atlas->x = 0;
+ atlas->y = 0;
+ atlas->row_height = 0;
+ atlas->serial++;
+ atlas->nglyph = 0;
+ return TRUE;
+}
+
+static Bool
+glamor_glyph_can_add(struct glamor_glyph_atlas *atlas, int dim, DrawablePtr glyph_draw)
+{
+ /* Step down */
+ if (atlas->x + glyph_draw->width > dim) {
+ atlas->x = 0;
+ atlas->y += atlas->row_height;
+ atlas->row_height = 0;
+ }
+
+ /* Check for overfull */
+ if (atlas->y + glyph_draw->height > dim)
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+glamor_glyph_add(struct glamor_glyph_atlas *atlas, DrawablePtr glyph_draw)
+{
+ PixmapPtr glyph_pixmap = (PixmapPtr) glyph_draw;
+ struct glamor_glyph_private *glyph_priv = glamor_get_glyph_private(glyph_pixmap);
+
+ glamor_copy_glyph(glyph_pixmap, &atlas->atlas->drawable, atlas->x, atlas->y);
+
+ glyph_priv->x = atlas->x;
+ glyph_priv->y = atlas->y;
+ glyph_priv->serial = atlas->serial;
+
+ atlas->x += glyph_draw->width;
+ if (atlas->row_height < glyph_draw->height)
+ atlas->row_height = glyph_draw->height;
+
+ atlas->nglyph++;
+
+ return TRUE;
+}
+
+static const glamor_facet glamor_facet_composite_glyphs_130 = {
+ .name = "composite_glyphs",
+ .version = 130,
+ .vs_vars = ("attribute vec4 primitive;\n"
+ "attribute vec2 source;\n"
+ "varying vec2 glyph_pos;\n"),
+ .vs_exec = (" vec2 pos = primitive.zw * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n"
+ GLAMOR_POS(gl_Position, (primitive.xy + pos))
+ " glyph_pos = (source + pos) * ATLAS_DIM_INV;\n"),
+ .fs_vars = ("varying vec2 glyph_pos;\n"
+ "out vec4 color0;\n"
+ "out vec4 color1;\n"),
+ .fs_exec = (" vec4 mask = texture2D(atlas, glyph_pos);\n"),
+ .source_name = "source",
+ .locations = glamor_program_location_atlas,
+};
+
+static const glamor_facet glamor_facet_composite_glyphs_120 = {
+ .name = "composite_glyphs",
+ .vs_vars = ("attribute vec2 primitive;\n"
+ "attribute vec2 source;\n"
+ "varying vec2 glyph_pos;\n"),
+ .vs_exec = (GLAMOR_POS(gl_Position, primitive)
+ " glyph_pos = source.xy * ATLAS_DIM_INV;\n"),
+ .fs_vars = ("varying vec2 glyph_pos;\n"),
+ .fs_exec = (" vec4 mask = texture2D(atlas, glyph_pos);\n"),
+ .source_name = "source",
+ .locations = glamor_program_location_atlas,
+};
+
+static inline Bool
+glamor_glyph_use_130(glamor_screen_private *glamor_priv) {
+ return glamor_priv->glsl_version >= 130;
+}
+
+static Bool
+glamor_glyphs_init_facet(ScreenPtr screen)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ return asprintf(&glamor_priv->glyph_defines, "#define ATLAS_DIM_INV %20.18f\n", 1.0/glamor_priv->glyph_atlas_dim) > 0;
+}
+
+static void
+glamor_glyphs_fini_facet(ScreenPtr screen)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ free(glamor_priv->glyph_defines);
+}
+
+static void
+glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst,
+ glamor_program *prog,
+ struct glamor_glyph_atlas *atlas, int nglyph)
+{
+ DrawablePtr drawable = dst->pDrawable;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen);
+ PixmapPtr atlas_pixmap = atlas->atlas;
+ glamor_pixmap_private *atlas_priv = glamor_get_pixmap_private(atlas_pixmap);
+ glamor_pixmap_fbo *atlas_fbo = glamor_pixmap_fbo_at(atlas_priv, 0);
+ PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+ int box_index;
+ int off_x, off_y;
+
+ glamor_put_vbo_space(drawable->pScreen);
+
+ glEnable(GL_SCISSOR_TEST);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, atlas_fbo->tex);
+
+ for (;;) {
+ if (!glamor_use_program_render(prog, op, src, dst))
+ break;
+
+ glUniform1i(prog->atlas_uniform, 1);
+
+ glamor_pixmap_loop(pixmap_priv, box_index) {
+ BoxPtr box = RegionRects(dst->pCompositeClip);
+ int nbox = RegionNumRects(dst->pCompositeClip);
+
+ glamor_set_destination_drawable(drawable, box_index, TRUE, FALSE,
+ prog->matrix_uniform,
+ &off_x, &off_y);
+
+ /* Run over the clip list, drawing the glyphs
+ * in each box
+ */
+
+ while (nbox--) {
+ glScissor(box->x1 + off_x,
+ box->y1 + off_y,
+ box->x2 - box->x1,
+ box->y2 - box->y1);
+ box++;
+
+ if (glamor_glyph_use_130(glamor_priv))
+ glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nglyph);
+ else
+ glamor_glDrawArrays_GL_QUADS(glamor_priv, nglyph);
+ }
+ }
+ if (prog->alpha != glamor_program_alpha_ca_first)
+ break;
+ prog++;
+ }
+
+ glDisable(GL_SCISSOR_TEST);
+
+ if (glamor_glyph_use_130(glamor_priv)) {
+ glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 0);
+ glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
+ }
+ glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+ glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glDisable(GL_BLEND);
+}
+
+static GLshort *
+glamor_glyph_start(ScreenPtr screen, int count)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ GLshort *v;
+ char *vbo_offset;
+
+ /* Set up the vertex buffers for the font and destination */
+
+ if (glamor_glyph_use_130(glamor_priv)) {
+ v = glamor_get_vbo_space(screen, count * (6 * sizeof (GLshort)), &vbo_offset);
+
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1);
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 4, GL_SHORT, GL_FALSE,
+ 6 * sizeof (GLshort), vbo_offset);
+
+ glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+ glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 1);
+ glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_SHORT, GL_FALSE,
+ 6 * sizeof (GLshort), vbo_offset + 4 * sizeof (GLshort));
+ } else {
+ v = glamor_get_vbo_space(screen, count * (16 * sizeof (GLshort)), &vbo_offset);
+
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE,
+ 4 * sizeof (GLshort), vbo_offset);
+
+ glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+ glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_SHORT, GL_FALSE,
+ 4 * sizeof (GLshort), vbo_offset + 2 * sizeof (GLshort));
+ }
+ return v;
+}
+
+static inline struct glamor_glyph_atlas *
+glamor_atlas_for_glyph(glamor_screen_private *glamor_priv, DrawablePtr drawable)
+{
+ if (drawable->depth == 32)
+ return glamor_priv->glyph_atlas_argb;
+ else
+ return glamor_priv->glyph_atlas_a;
+}
+
+void
+glamor_composite_glyphs(CARD8 op,
+ PicturePtr src,
+ PicturePtr dst,
+ PictFormatPtr glyph_format,
+ INT16 x_src,
+ INT16 y_src, int nlist, GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ int glyphs_queued;
+ GLshort *v = NULL;
+ DrawablePtr drawable = dst->pDrawable;
+ ScreenPtr screen = drawable->pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ glamor_program *prog = NULL;
+ glamor_program_render *glyphs_program = &glamor_priv->glyphs_program;
+ struct glamor_glyph_atlas *glyph_atlas = NULL;
+ int x = 0, y = 0;
+ int n;
+ int glyph_atlas_dim = glamor_priv->glyph_atlas_dim;
+ int glyph_max_dim = glamor_priv->glyph_max_dim;
+ int nglyph = 0;
+ int screen_num = screen->myNum;
+
+ for (n = 0; n < nlist; n++)
+ nglyph += list[n].len;
+
+ glamor_make_current(glamor_priv);
+
+ glyphs_queued = 0;
+
+ while (nlist--) {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+ list++;
+ while (n--) {
+ GlyphPtr glyph = *glyphs++;
+
+ /* Glyph not empty?
+ */
+ if (glyph->info.width && glyph->info.height) {
+ PicturePtr glyph_pict = GlyphPicture(glyph)[screen_num];
+ DrawablePtr glyph_draw = glyph_pict->pDrawable;
+
+ /* Need to draw with slow path?
+ */
+ if (_X_UNLIKELY(glyph_draw->width > glyph_max_dim ||
+ glyph_draw->height > glyph_max_dim ||
+ !glamor_pixmap_is_memory((PixmapPtr)glyph_draw)))
+ {
+ if (glyphs_queued) {
+ glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued);
+ glyphs_queued = 0;
+ }
+ bail_one:
+ glamor_composite(op, src, glyph_pict, dst,
+ x_src + (x - glyph->info.x), (y - glyph->info.y),
+ 0, 0,
+ x - glyph->info.x, y - glyph->info.y,
+ glyph_draw->width, glyph_draw->height);
+ } else {
+ struct glamor_glyph_private *glyph_priv = glamor_get_glyph_private((PixmapPtr)(glyph_draw));
+ struct glamor_glyph_atlas *next_atlas = glamor_atlas_for_glyph(glamor_priv, glyph_draw);
+
+ /* Switching source glyph format?
+ */
+ if (_X_UNLIKELY(next_atlas != glyph_atlas)) {
+ if (glyphs_queued) {
+ glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued);
+ glyphs_queued = 0;
+ }
+ glyph_atlas = next_atlas;
+ }
+
+ /* Glyph not cached in current atlas?
+ */
+ if (_X_UNLIKELY(glyph_priv->serial != glyph_atlas->serial)) {
+ if (!glamor_glyph_can_add(glyph_atlas, glyph_atlas_dim, glyph_draw)) {
+ if (glyphs_queued) {
+ glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued);
+ glyphs_queued = 0;
+ }
+ if (glyph_atlas->atlas) {
+ (*screen->DestroyPixmap)(glyph_atlas->atlas);
+ glyph_atlas->atlas = NULL;
+ }
+ }
+ if (!glyph_atlas->atlas) {
+ glamor_glyph_atlas_init(screen, glyph_atlas);
+ if (!glyph_atlas->atlas)
+ goto bail_one;
+ }
+ glamor_glyph_add(glyph_atlas, glyph_draw);
+ }
+
+ /* First glyph in the current atlas?
+ */
+ if (_X_UNLIKELY(glyphs_queued == 0)) {
+ if (glamor_glyph_use_130(glamor_priv))
+ prog = glamor_setup_program_render(op, src, glyph_pict, dst,
+ glyphs_program,
+ &glamor_facet_composite_glyphs_130,
+ glamor_priv->glyph_defines);
+ else
+ prog = glamor_setup_program_render(op, src, glyph_pict, dst,
+ glyphs_program,
+ &glamor_facet_composite_glyphs_120,
+ glamor_priv->glyph_defines);
+ if (!prog)
+ goto bail_one;
+ v = glamor_glyph_start(screen, nglyph);
+ }
+
+ /* Add the glyph
+ */
+
+ glyphs_queued++;
+ if (_X_LIKELY(glamor_glyph_use_130(glamor_priv))) {
+ v[0] = x - glyph->info.x;
+ v[1] = y - glyph->info.y;
+ v[2] = glyph_draw->width;
+ v[3] = glyph_draw->height;
+ v[4] = glyph_priv->x;
+ v[5] = glyph_priv->y;
+ v += 6;
+ } else {
+ v[0] = x - glyph->info.x;
+ v[1] = y - glyph->info.y;
+ v[2] = glyph_priv->x;
+ v[3] = glyph_priv->y;
+ v += 4;
+
+ v[0] = x - glyph->info.x + glyph_draw->width;
+ v[1] = y - glyph->info.y;
+ v[2] = glyph_priv->x + glyph_draw->width;
+ v[3] = glyph_priv->y;
+ v += 4;
+
+ v[0] = x - glyph->info.x + glyph_draw->width;
+ v[1] = y - glyph->info.y + glyph_draw->height;
+ v[2] = glyph_priv->x + glyph_draw->width;
+ v[3] = glyph_priv->y + glyph_draw->height;
+ v += 4;
+
+ v[0] = x - glyph->info.x;
+ v[1] = y - glyph->info.y + glyph_draw->height;
+ v[2] = glyph_priv->x;
+ v[3] = glyph_priv->y + glyph_draw->height;
+ v += 4;
+ }
+ }
+ }
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ nglyph--;
+ }
+ }
+
+ if (glyphs_queued)
+ glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued);
+
+ return;
+}
+
+static struct glamor_glyph_atlas *
+glamor_alloc_glyph_atlas(ScreenPtr screen, int depth, CARD32 f)
+{
+ PictFormatPtr format;
+ struct glamor_glyph_atlas *glyph_atlas;
+
+ format = PictureMatchFormat(screen, depth, f);
+ if (!format)
+ return NULL;
+ glyph_atlas = calloc (1, sizeof (struct glamor_glyph_atlas));
+ if (!glyph_atlas)
+ return NULL;
+ glyph_atlas->format = format;
+ glyph_atlas->serial = 1;
+
+ return glyph_atlas;
+}
+
+Bool
+glamor_composite_glyphs_init(ScreenPtr screen)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ if (!dixRegisterPrivateKey(&glamor_glyph_private_key, PRIVATE_PIXMAP, sizeof (struct glamor_glyph_private)))
+ return FALSE;
+
+ /* Make glyph atlases of a reasonable size, but no larger than the maximum
+ * supported by the hardware
+ */
+ glamor_priv->glyph_atlas_dim = MIN(DEFAULT_ATLAS_DIM, glamor_priv->max_fbo_size);
+
+ /* Don't stick huge glyphs in the atlases */
+ glamor_priv->glyph_max_dim = glamor_priv->glyph_atlas_dim / 8;
+
+ glamor_priv->glyph_atlas_a = glamor_alloc_glyph_atlas(screen, 8, PICT_a8);
+ if (!glamor_priv->glyph_atlas_a)
+ return FALSE;
+ glamor_priv->glyph_atlas_argb = glamor_alloc_glyph_atlas(screen, 32, PICT_a8r8g8b8);
+ if (!glamor_priv->glyph_atlas_argb) {
+ free (glamor_priv->glyph_atlas_a);
+ return FALSE;
+ }
+ if (!glamor_glyphs_init_facet(screen))
+ return FALSE;
+ return TRUE;
+}
+
+static void
+glamor_free_glyph_atlas(struct glamor_glyph_atlas *atlas)
+{
+ if (!atlas)
+ return;
+ if (atlas->atlas)
+ FreePicture(atlas->atlas, 0);
+ free (atlas);
+}
+
+void
+glamor_composite_glyphs_fini(ScreenPtr screen)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ glamor_glyphs_fini_facet(screen);
+ glamor_free_glyph_atlas(glamor_priv->glyph_atlas_a);
+ glamor_free_glyph_atlas(glamor_priv->glyph_atlas_argb);
+}
diff --git a/xserver/glamor/glamor_compositerects.c b/xserver/glamor/glamor_compositerects.c
index 3b6b2ed07..885a6c065 100644
--- a/xserver/glamor/glamor_compositerects.c
+++ b/xserver/glamor/glamor_compositerects.c
@@ -57,7 +57,7 @@ _pixman_region_init_clipped_rectangles(pixman_region16_t * region,
unsigned int i, j;
if (num_rects > ARRAY_SIZE(stack_boxes)) {
- boxes = malloc(sizeof(pixman_box16_t) * num_rects);
+ boxes = xallocarray(num_rects, sizeof(pixman_box16_t));
if (boxes == NULL)
return FALSE;
}
@@ -246,7 +246,7 @@ glamor_composite_rectangles(CARD8 op,
goto done;
}
else {
- if (_X_LIKELY(priv->type != GLAMOR_TEXTURE_LARGE)) {
+ if (_X_LIKELY(glamor_pixmap_priv_is_small(priv))) {
int error;
source = CreateSolidPicture(0, color, &error);
@@ -254,7 +254,7 @@ glamor_composite_rectangles(CARD8 op,
goto done;
if (glamor_composite_clipped_region(op, source,
NULL, dst,
- NULL, NULL, priv,
+ NULL, NULL, pixmap,
&region, 0, 0, 0, 0, 0, 0))
goto done;
}
diff --git a/xserver/glamor/glamor_copy.c b/xserver/glamor/glamor_copy.c
index 3320935f0..5fed89f0c 100644
--- a/xserver/glamor/glamor_copy.c
+++ b/xserver/glamor/glamor_copy.c
@@ -42,7 +42,7 @@ use_copyarea(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
glBindTexture(GL_TEXTURE_2D, src->tex);
glUniform2f(prog->fill_offset_uniform, args->dx, args->dy);
- glUniform2f(prog->fill_size_uniform, src->width, src->height);
+ glUniform2f(prog->fill_size_inv_uniform, 1.0f/src->width, 1.0f/src->height);
return TRUE;
}
@@ -51,9 +51,9 @@ 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"),
+ " fill_pos = (fill_offset + primitive.xy) * fill_size_inv;\n"),
.fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n",
- .locations = glamor_program_location_fill,
+ .locations = glamor_program_location_fillsamp | glamor_program_location_fillpos,
.use = use_copyarea,
};
@@ -71,7 +71,7 @@ use_copyplane(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
glBindTexture(GL_TEXTURE_2D, src->tex);
glUniform2f(prog->fill_offset_uniform, args->dx, args->dy);
- glUniform2f(prog->fill_size_uniform, src->width, src->height);
+ glUniform2f(prog->fill_size_inv_uniform, 1.0f/src->width, 1.0f/src->height);
glamor_set_color(dst, gc->fgPixel, prog->fg_uniform);
glamor_set_color(dst, gc->bgPixel, prog->bg_uniform);
@@ -134,13 +134,13 @@ static const glamor_facet glamor_facet_copyplane = {
.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"),
+ " fill_pos = (fill_offset + primitive.xy) * fill_size_inv;\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,
+ .locations = glamor_program_location_fillsamp|glamor_program_location_fillpos|glamor_program_location_fg|glamor_program_location_bg|glamor_program_location_bitplane,
.use = use_copyplane,
};
@@ -212,7 +212,7 @@ glamor_copy_cpu_fbo(DrawablePtr src,
if (gc && gc->alu != GXcopy)
goto bail;
- if (gc && !glamor_pm_is_solid(dst, gc->planemask))
+ if (gc && !glamor_pm_is_solid(gc->depth, gc->planemask))
goto bail;
glamor_make_current(glamor_priv);
@@ -262,7 +262,7 @@ glamor_copy_fbo_cpu(DrawablePtr src,
if (gc && gc->alu != GXcopy)
goto bail;
- if (gc && !glamor_pm_is_solid(dst, gc->planemask))
+ if (gc && !glamor_pm_is_solid(gc->depth, gc->planemask))
goto bail;
glamor_make_current(glamor_priv);
@@ -307,7 +307,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr 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 src_box_index, dst_box_index;
int dst_off_x, dst_off_y;
int src_off_x, src_off_y;
GLshort *v;
@@ -315,12 +315,11 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
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))
+ if (gc && !glamor_set_planemask(gc->depth, gc->planemask))
goto bail_ctx;
if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy))
@@ -339,7 +338,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
if (!prog->prog) {
if (!glamor_build_program(screen, prog,
- copy_facet, NULL))
+ copy_facet, NULL, NULL, NULL))
goto bail_ctx;
}
@@ -367,48 +366,37 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
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);
+ 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);
+ glamor_pixmap_loop(src_priv, src_box_index) {
+ BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_index);
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);
+ args.src = glamor_pixmap_fbo_at(src_priv, src_box_index);
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);
- }
+ glamor_pixmap_loop(dst_priv, dst_box_index) {
+ glamor_set_destination_drawable(dst, dst_box_index, FALSE, FALSE,
+ prog->matrix_uniform,
+ &dst_off_x, &dst_off_y);
+
+ glScissor(dst_off_x - args.dx,
+ dst_off_y - args.dy,
+ src_box->x2 - src_box->x1,
+ src_box->y2 - src_box->y1);
+
+ glamor_glDrawArrays_GL_QUADS(glamor_priv, nbox);
}
}
- if (set_scissor)
- glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_SCISSOR_TEST);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- glDisable(GL_COLOR_LOGIC_OP);
return TRUE;
bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
return FALSE;
}
@@ -432,7 +420,6 @@ glamor_copy_fbo_fbo_temp(DrawablePtr src,
{
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;
@@ -447,12 +434,11 @@ glamor_copy_fbo_fbo_temp(DrawablePtr src,
*/
glamor_make_current(glamor_priv);
- if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask))
+ if (gc && !glamor_set_planemask(gc->depth, 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
*/
@@ -521,7 +507,6 @@ bail:
return FALSE;
bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
return FALSE;
}
@@ -656,6 +641,9 @@ glamor_copy(DrawablePtr src,
Pixel bitplane,
void *closure)
{
+ if (nbox == 0)
+ return;
+
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);
@@ -709,39 +697,3 @@ glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_regio
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/xserver/glamor/glamor_core.c b/xserver/glamor/glamor_core.c
index 235a4baed..b9948b569 100644
--- a/xserver/glamor/glamor_core.c
+++ b/xserver/glamor/glamor_core.c
@@ -42,10 +42,9 @@ glamor_get_drawable_location(const DrawablePtr drawable)
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_screen_private *glamor_priv =
glamor_get_screen_private(drawable->pScreen);
- if (pixmap_priv == NULL ||
- pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED)
+ if (pixmap_priv->gl_fbo == GLAMOR_FBO_UNATTACHED)
return 'm';
- if (pixmap_priv->base.fbo->fb == glamor_priv->screen_fbo)
+ if (pixmap_priv->fbo->fb == glamor_priv->screen_fbo)
return 's';
else
return 'f';
@@ -88,6 +87,17 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...)
GLint ok;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ if (glamor_priv->has_khr_debug) {
+ char *label;
+ va_list va;
+
+ va_start(va, format);
+ XNFvasprintf(&label, format, va);
+ glObjectLabel(GL_PROGRAM, prog, -1, label);
+ free(label);
+ va_end(va);
+ }
+
glLinkProgram(prog);
glGetProgramiv(prog, GL_LINK_STATUS, &ok);
if (!ok) {
@@ -101,17 +111,6 @@ glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...)
ErrorF("Failed to link: %s\n", info);
FatalError("GLSL link failure\n");
}
-
- if (glamor_priv->has_khr_debug) {
- char *label;
- va_list va;
-
- va_start(va, format);
- XNFvasprintf(&label, format, va);
- glObjectLabel(GL_PROGRAM, prog, -1, label);
- free(label);
- va_end(va);
- }
}
/*
@@ -173,46 +172,48 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
const char *fs_source =
"void main()\n"
"{\n"
+ " vec4 color = texture2D(sampler, source_texture);\n"
" if (revert == REVERT_NONE) \n"
" { \n"
" if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING)) \n"
- " gl_FragColor = texture2D(sampler, source_texture).bgra;\n"
+ " gl_FragColor = color.bgra;\n"
" else \n"
- " gl_FragColor = texture2D(sampler, source_texture).rgba;\n"
+ " gl_FragColor = color.rgba;\n"
" } \n"
" else \n"
" { \n"
" if (swap_rb == SWAP_DOWNLOADING) \n"
- " gl_FragColor = texture2D(sampler, source_texture).argb;\n"
+ " gl_FragColor = color.argb;\n"
" else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
- " gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
+ " gl_FragColor = color.abgr;\n"
" else if (swap_rb == SWAP_UPLOADING)\n"
- " gl_FragColor = texture2D(sampler, source_texture).gbar;\n"
+ " gl_FragColor = color.gbar;\n"
" else if (swap_rb == SWAP_NONE_UPLOADING)\n"
- " gl_FragColor = texture2D(sampler, source_texture).abgr;\n"
+ " gl_FragColor = color.abgr;\n"
" } \n"
"}\n";
const char *set_alpha_source =
"void main()\n"
"{\n"
+ " vec4 color = texture2D(sampler, source_texture);\n"
" if (revert == REVERT_NONE) \n"
" { \n"
" if ((swap_rb != SWAP_NONE_DOWNLOADING) && (swap_rb != SWAP_NONE_UPLOADING)) \n"
- " gl_FragColor = vec4(texture2D(sampler, source_texture).bgr, 1);\n"
+ " gl_FragColor = vec4(color.bgr, 1);\n"
" else \n"
- " gl_FragColor = vec4(texture2D(sampler, source_texture).rgb, 1);\n"
+ " gl_FragColor = vec4(color.rgb, 1);\n"
" } \n"
" else \n"
" { \n"
" if (swap_rb == SWAP_DOWNLOADING) \n"
- " gl_FragColor = vec4(1, texture2D(sampler, source_texture).rgb);\n"
+ " gl_FragColor = vec4(1, color.rgb);\n"
" else if (swap_rb == SWAP_NONE_DOWNLOADING)\n"
- " gl_FragColor = vec4(1, texture2D(sampler, source_texture).bgr);\n"
+ " gl_FragColor = vec4(1, color.bgr);\n"
" else if (swap_rb == SWAP_UPLOADING)\n"
- " gl_FragColor = vec4(texture2D(sampler, source_texture).gba, 1);\n"
+ " gl_FragColor = vec4(color.gba, 1);\n"
" else if (swap_rb == SWAP_NONE_UPLOADING)\n"
- " gl_FragColor = vec4(texture2D(sampler, source_texture).abg, 1);\n"
+ " gl_FragColor = vec4(color.abg, 1);\n"
" } \n"
"}\n";
GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
@@ -281,18 +282,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
}
-void
-glamor_fini_finish_access_shaders(ScreenPtr screen)
-{
- glamor_screen_private *glamor_priv;
-
- glamor_priv = glamor_get_screen_private(screen);
- glamor_make_current(glamor_priv);
- glDeleteProgram(glamor_priv->finish_access_prog[0]);
- glDeleteProgram(glamor_priv->finish_access_prog[1]);
-}
-
-GCOps glamor_gc_ops = {
+static GCOps glamor_gc_ops = {
.FillSpans = glamor_fill_spans,
.SetSpans = glamor_set_spans,
.PutImage = glamor_put_image,
diff --git a/xserver/glamor/glamor_dash.c b/xserver/glamor/glamor_dash.c
index e8f60fa10..a6a11c1a2 100644
--- a/xserver/glamor/glamor_dash.c
+++ b/xserver/glamor/glamor_dash.c
@@ -159,44 +159,42 @@ glamor_dash_setup(DrawablePtr drawable, GCPtr gc)
&glamor_priv->on_off_dash_line_progs,
&glamor_facet_on_off_dash_lines);
if (!prog)
- goto bail_ctx;
+ goto bail;
break;
case LineDoubleDash:
if (gc->fillStyle != FillSolid)
- goto bail_ctx;
+ goto bail;
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;
+ NULL, NULL, NULL))
+ goto bail;
}
if (!glamor_use_program(pixmap, gc, prog, NULL))
- goto bail_ctx;
+ goto bail;
glamor_set_color(pixmap, gc->fgPixel, prog->fg_uniform);
glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform);
break;
default:
- goto bail_ctx;
+ goto bail;
}
/* Set the dash pattern as texture 1 */
glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, dash_priv->base.fbo->tex);
+ glBindTexture(GL_TEXTURE_2D, dash_priv->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;
}
@@ -207,16 +205,16 @@ glamor_dash_loop(DrawablePtr drawable, GCPtr gc, glamor_program *prog,
{
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
- int box_x, box_y;
+ int box_index;
int off_x, off_y;
glEnable(GL_SCISSOR_TEST);
- glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ glamor_pixmap_loop(pixmap_priv, box_index) {
int nbox = RegionNumRects(gc->pCompositeClip);
BoxPtr box = RegionRects(gc->pCompositeClip);
- glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE,
+ glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE,
prog->matrix_uniform, &off_x, &off_y);
while (nbox--) {
@@ -230,7 +228,6 @@ glamor_dash_loop(DrawablePtr drawable, GCPtr gc, glamor_program *prog,
}
glDisable(GL_SCISSOR_TEST);
- glDisable(GL_COLOR_LOGIC_OP);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
}
diff --git a/xserver/glamor/glamor_egl.c b/xserver/glamor/glamor_egl.c
index 6160032f0..80a97f7a1 100644
--- a/xserver/glamor/glamor_egl.c
+++ b/xserver/glamor/glamor_egl.c
@@ -187,7 +187,7 @@ glamor_egl_get_gbm_device(ScreenPtr screen)
}
unsigned int
-glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
+glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h, Bool linear)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct glamor_egl_screen_private *glamor_egl;
@@ -200,6 +200,9 @@ glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
glamor_egl = glamor_egl_get_screen_private(scrn);
bo = gbm_bo_create(glamor_egl->gbm, w, h, GBM_FORMAT_ARGB8888,
+#ifdef GLAMOR_HAS_GBM_LINEAR
+ (linear ? GBM_BO_USE_LINEAR : 0) |
+#endif
GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
if (!bo)
return 0;
@@ -239,7 +242,6 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
"Failed to create textured screen.");
return FALSE;
}
-
glamor_set_screen_pixmap(screen_pixmap, NULL);
return TRUE;
}
@@ -272,7 +274,7 @@ glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image)
glamor_get_pixmap_private(pixmap);
EGLImageKHR old;
- old = pixmap_priv->base.image;
+ old = pixmap_priv->image;
if (old) {
ScreenPtr screen = pixmap->drawable.pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
@@ -280,7 +282,7 @@ glamor_egl_set_pixmap_image(PixmapPtr pixmap, EGLImageKHR image)
eglDestroyImageKHR(glamor_egl->display, old);
}
- pixmap_priv->base.image = image;
+ pixmap_priv->image = image;
}
Bool
@@ -393,48 +395,108 @@ glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name)
}
#endif
-int
-glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
- PixmapPtr pixmap,
- unsigned int tex,
- Bool want_name, CARD16 *stride, CARD32 *size)
+static Bool
+glamor_make_pixmap_exportable(PixmapPtr pixmap)
{
#ifdef GLAMOR_HAS_GBM
+ ScreenPtr screen = pixmap->drawable.pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ struct glamor_egl_screen_private *glamor_egl =
+ glamor_egl_get_screen_private(scrn);
struct glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
- struct glamor_screen_private *glamor_priv =
- glamor_get_screen_private(screen);
- struct glamor_egl_screen_private *glamor_egl;
- EGLImageKHR image;
+ unsigned width = pixmap->drawable.width;
+ unsigned height = pixmap->drawable.height;
struct gbm_bo *bo;
- int fd = -1;
+ PixmapPtr exported;
+ GCPtr scratch_gc;
- EGLint attribs[] = {
- EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
- EGL_GL_TEXTURE_LEVEL_KHR, 0,
- EGL_NONE
- };
+ if (pixmap_priv->image)
+ return TRUE;
- glamor_egl = glamor_egl_get_screen_private(scrn);
+ if (pixmap->drawable.bitsPerPixel != 32) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Failed to make %dbpp pixmap exportable\n",
+ pixmap->drawable.bitsPerPixel);
+ return FALSE;
+ }
- glamor_make_current(glamor_priv);
+ bo = gbm_bo_create(glamor_egl->gbm, width, height,
+ GBM_FORMAT_ARGB8888,
+#ifdef GLAMOR_HAS_GBM_LINEAR
+ (pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED ?
+ GBM_BO_USE_LINEAR : 0) |
+#endif
+ GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
+ if (!bo) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Failed to make %dx%dx%dbpp GBM bo\n",
+ width, height, pixmap->drawable.bitsPerPixel);
+ return FALSE;
+ }
- image = pixmap_priv->base.image;
- if (!image) {
- image = eglCreateImageKHR(glamor_egl->display,
- glamor_egl->context,
- EGL_GL_TEXTURE_2D_KHR,
- (EGLClientBuffer) (uintptr_t)
- tex, attribs);
- if (image == EGL_NO_IMAGE_KHR)
- goto failure;
-
- glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
- glamor_egl_set_pixmap_image(pixmap, image);
+ exported = screen->CreatePixmap(screen, 0, 0, pixmap->drawable.depth, 0);
+ screen->ModifyPixmapHeader(exported, width, height, 0, 0,
+ gbm_bo_get_stride(bo), NULL);
+ if (!glamor_egl_create_textured_pixmap_from_gbm_bo(exported, bo)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Failed to make %dx%dx%dbpp pixmap from GBM bo\n",
+ width, height, pixmap->drawable.bitsPerPixel);
+ screen->DestroyPixmap(exported);
+ gbm_bo_destroy(bo);
+ return FALSE;
}
+ gbm_bo_destroy(bo);
+
+ scratch_gc = GetScratchGC(pixmap->drawable.depth, screen);
+ ValidateGC(&pixmap->drawable, scratch_gc);
+ scratch_gc->ops->CopyArea(&pixmap->drawable, &exported->drawable,
+ scratch_gc,
+ 0, 0, width, height, 0, 0);
+ FreeScratchGC(scratch_gc);
+
+ /* Now, swap the tex/gbm/EGLImage/etc. of the exported pixmap into
+ * the original pixmap struct.
+ */
+ glamor_egl_exchange_buffers(pixmap, exported);
+
+ screen->DestroyPixmap(exported);
+
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+void *
+glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap)
+{
+ struct glamor_egl_screen_private *glamor_egl =
+ glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
+ struct glamor_pixmap_private *pixmap_priv =
+ glamor_get_pixmap_private(pixmap);
+
+ if (!glamor_make_pixmap_exportable(pixmap))
+ return NULL;
+
+ return gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE,
+ pixmap_priv->image, 0);
+}
- bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
+int
+glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
+ PixmapPtr pixmap,
+ unsigned int tex,
+ Bool want_name, CARD16 *stride, CARD32 *size)
+{
+#ifdef GLAMOR_HAS_GBM
+ struct glamor_egl_screen_private *glamor_egl;
+ struct gbm_bo *bo;
+ int fd = -1;
+
+ glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
+
+ bo = glamor_gbm_bo_from_pixmap(screen, pixmap);
if (!bo)
goto failure;
@@ -459,72 +521,67 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
#endif
}
-_X_EXPORT PixmapPtr
-glamor_pixmap_from_fd(ScreenPtr screen,
- int fd,
- CARD16 width,
- CARD16 height,
- CARD16 stride, CARD8 depth, CARD8 bpp)
+_X_EXPORT Bool
+glamor_back_pixmap_from_fd(PixmapPtr pixmap,
+ int fd,
+ CARD16 width,
+ CARD16 height,
+ CARD16 stride, CARD8 depth, CARD8 bpp)
{
#ifdef GLAMOR_HAS_GBM
+ ScreenPtr screen = pixmap->drawable.pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct glamor_egl_screen_private *glamor_egl;
struct gbm_bo *bo;
- EGLImageKHR image;
- PixmapPtr pixmap;
- Bool ret = FALSE;
-
- EGLint attribs[] = {
- EGL_WIDTH, 0,
- EGL_HEIGHT, 0,
- EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
- EGL_DMA_BUF_PLANE0_FD_EXT, 0,
- EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
- EGL_DMA_BUF_PLANE0_PITCH_EXT, 0,
- EGL_NONE
- };
+ struct gbm_import_fd_data import_data = { 0 };
+ Bool ret;
glamor_egl = glamor_egl_get_screen_private(scrn);
if (!glamor_egl->dri3_capable)
- return NULL;
+ return FALSE;
if (bpp != 32 || !(depth == 24 || depth == 32) || width == 0 || height == 0)
- return NULL;
-
- attribs[1] = width;
- attribs[3] = height;
- attribs[7] = fd;
- attribs[11] = stride;
- image = eglCreateImageKHR(glamor_egl->display,
- EGL_NO_CONTEXT,
- EGL_LINUX_DMA_BUF_EXT,
- NULL, attribs);
-
- if (image == EGL_NO_IMAGE_KHR)
- return NULL;
-
- /* EGL_EXT_image_dma_buf_import can impose restrictions on the
- * usage of the image. Use gbm_bo to bypass the limitations. */
-
- bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
- eglDestroyImageKHR(glamor_egl->display, image);
+ return FALSE;
+ import_data.fd = fd;
+ import_data.width = width;
+ import_data.height = height;
+ import_data.stride = stride;
+ import_data.format = GBM_FORMAT_ARGB8888;
+ bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_FD, &import_data, 0);
if (!bo)
- return NULL;
+ return FALSE;
- pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0);
screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL);
ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo);
gbm_bo_destroy(bo);
+ return ret;
+#else
+ return FALSE;
+#endif
+}
- if (ret)
- return pixmap;
- else {
+_X_EXPORT PixmapPtr
+glamor_pixmap_from_fd(ScreenPtr screen,
+ int fd,
+ CARD16 width,
+ CARD16 height,
+ CARD16 stride, CARD8 depth, CARD8 bpp)
+{
+#ifdef GLAMOR_HAS_GBM
+ PixmapPtr pixmap;
+ Bool ret;
+
+ pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0);
+ ret = glamor_back_pixmap_from_fd(pixmap, fd, width, height,
+ stride, depth, bpp);
+ if (ret == FALSE) {
screen->DestroyPixmap(pixmap);
return NULL;
}
+ return pixmap;
#else
return NULL;
#endif
@@ -536,17 +593,13 @@ glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
struct glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
- if (pixmap_priv && pixmap_priv->base.image) {
+ if (pixmap_priv->image) {
ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
struct glamor_egl_screen_private *glamor_egl =
glamor_egl_get_screen_private(scrn);
- /* Before destroy an image which was attached to
- * a texture. we must call glFlush to make sure the
- * operation on that texture has been done.*/
- glamor_block_handler(pixmap->drawable.pScreen);
- eglDestroyImageKHR(glamor_egl->display, pixmap_priv->base.image);
- pixmap_priv->base.image = NULL;
+ eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
+ pixmap_priv->image = NULL;
}
}
@@ -561,13 +614,12 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
glamor_pixmap_exchange_fbos(front, back);
- temp = back_priv->base.image;
- back_priv->base.image = front_priv->base.image;
- front_priv->base.image = temp;
+ temp = back_priv->image;
+ back_priv->image = front_priv->image;
+ front_priv->image = temp;
glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM);
glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
-
}
void
@@ -589,8 +641,8 @@ glamor_egl_close_screen(ScreenPtr screen)
screen_pixmap = screen->GetScreenPixmap(screen);
pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
- eglDestroyImageKHR(glamor_egl->display, pixmap_priv->base.image);
- pixmap_priv->base.image = NULL;
+ eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
+ pixmap_priv->image = NULL;
screen->CloseScreen = glamor_egl->saved_close_screen;
@@ -699,6 +751,21 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
#endif
}
+static void glamor_egl_cleanup(struct glamor_egl_screen_private *glamor_egl)
+{
+ if (glamor_egl->display != EGL_NO_DISPLAY) {
+ eglMakeCurrent(glamor_egl->display,
+ EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglTerminate(glamor_egl->display);
+ }
+#ifdef GLAMOR_HAS_GBM
+ if (glamor_egl->gbm)
+ gbm_device_destroy(glamor_egl->gbm);
+#endif
+ free(glamor_egl->device_path);
+ free(glamor_egl);
+}
+
static void
glamor_egl_free_screen(ScrnInfoPtr scrn)
{
@@ -706,17 +773,8 @@ glamor_egl_free_screen(ScrnInfoPtr scrn)
glamor_egl = glamor_egl_get_screen_private(scrn);
if (glamor_egl != NULL) {
-
- eglMakeCurrent(glamor_egl->display,
- EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-#ifdef GLAMOR_HAS_GBM
- if (glamor_egl->gbm)
- gbm_device_destroy(glamor_egl->gbm);
-#endif
- free(glamor_egl->device_path);
-
scrn->FreeScreen = glamor_egl->saved_free_screen;
- free(glamor_egl);
+ glamor_egl_cleanup(glamor_egl);
scrn->FreeScreen(scrn);
}
}
@@ -733,6 +791,15 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
#endif
EGL_NONE
};
+ static const EGLint config_attribs_core[] = {
+ EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR,
+ EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,
+ EGL_CONTEXT_MAJOR_VERSION_KHR,
+ GLAMOR_GL_CORE_VER_MAJOR,
+ EGL_CONTEXT_MINOR_VERSION_KHR,
+ GLAMOR_GL_CORE_VER_MINOR,
+ EGL_NONE
+ };
glamor_identify(0);
glamor_egl = calloc(sizeof(*glamor_egl), 1);
@@ -747,7 +814,7 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
glamor_egl->gbm = gbm_create_device(glamor_egl->fd);
if (glamor_egl->gbm == NULL) {
ErrorF("couldn't get display device\n");
- return FALSE;
+ goto error;
}
glamor_egl->display = eglGetDisplay(glamor_egl->gbm);
#else
@@ -764,7 +831,8 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
if (!eglInitialize
(glamor_egl->display, &glamor_egl->major, &glamor_egl->minor)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR, "eglInitialize() failed\n");
- return FALSE;
+ glamor_egl->display = EGL_NO_DISPLAY;
+ goto error;
}
version = eglQueryString(glamor_egl->display, EGL_VERSION);
@@ -773,14 +841,14 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
#define GLAMOR_CHECK_EGL_EXTENSION(EXT) \
if (!epoxy_has_egl_extension(glamor_egl->display, "EGL_" #EXT)) { \
ErrorF("EGL_" #EXT " required.\n"); \
- return FALSE; \
+ goto error; \
}
#define GLAMOR_CHECK_EGL_EXTENSIONS(EXT1, EXT2) \
if (!epoxy_has_egl_extension(glamor_egl->display, "EGL_" #EXT1) && \
!epoxy_has_egl_extension(glamor_egl->display, "EGL_" #EXT2)) { \
ErrorF("EGL_" #EXT1 " or EGL_" #EXT2 " required.\n"); \
- return FALSE; \
+ goto error; \
}
GLAMOR_CHECK_EGL_EXTENSION(MESA_drm_image);
@@ -792,28 +860,36 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
KHR_surfaceless_opengl);
#endif
-#ifdef GLAMOR_HAS_GBM
- if (epoxy_has_egl_extension(glamor_egl->display,
- "EGL_KHR_gl_texture_2D_image") &&
- epoxy_has_egl_extension(glamor_egl->display,
- "EGL_EXT_image_dma_buf_import"))
- glamor_egl->dri3_capable = TRUE;
-#endif
-
+#ifndef GLAMOR_GLES2
glamor_egl->context = eglCreateContext(glamor_egl->display,
NULL, EGL_NO_CONTEXT,
- config_attribs);
- if (glamor_egl->context == EGL_NO_CONTEXT) {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create EGL context\n");
- return FALSE;
+ config_attribs_core);
+#else
+ glamor_egl->context = NULL;
+#endif
+ if (!glamor_egl->context) {
+ glamor_egl->context = eglCreateContext(glamor_egl->display,
+ NULL, EGL_NO_CONTEXT,
+ config_attribs);
+ if (glamor_egl->context == EGL_NO_CONTEXT) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to create EGL context\n");
+ goto error;
+ }
}
if (!eglMakeCurrent(glamor_egl->display,
EGL_NO_SURFACE, EGL_NO_SURFACE, glamor_egl->context)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to make EGL context current\n");
- return FALSE;
+ goto error;
}
+#ifdef GLAMOR_HAS_GBM
+ if (epoxy_has_egl_extension(glamor_egl->display,
+ "EGL_KHR_gl_texture_2D_image") &&
+ epoxy_has_gl_extension("GL_OES_EGL_image"))
+ glamor_egl->dri3_capable = TRUE;
+#endif
+
glamor_egl->saved_free_screen = scrn->FreeScreen;
scrn->FreeScreen = glamor_egl_free_screen;
#ifdef GLAMOR_GLES2
@@ -823,6 +899,10 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
"Indirect GLX may not work correctly.\n");
#endif
return TRUE;
+
+error:
+ glamor_egl_cleanup(glamor_egl);
+ return FALSE;
}
/** Stub to retain compatibility with pre-server-1.16 ABI. */
diff --git a/xserver/glamor/glamor_egl_stubs.c b/xserver/glamor/glamor_egl_stubs.c
index a93f62dcb..5dbbfe4b2 100644
--- a/xserver/glamor/glamor_egl_stubs.c
+++ b/xserver/glamor/glamor_egl_stubs.c
@@ -48,9 +48,3 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
{
return 0;
}
-
-unsigned int
-glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
-{
- return 0;
-}
diff --git a/xserver/glamor/glamor_fbo.c b/xserver/glamor/glamor_fbo.c
index 802d665a9..c6ba095c0 100644
--- a/xserver/glamor/glamor_fbo.c
+++ b/xserver/glamor/glamor_fbo.c
@@ -70,9 +70,26 @@ cache_hbucket(int size)
return order;
}
+static int
+cache_format(GLenum format)
+{
+ switch (format) {
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_RED:
+ return 2;
+ case GL_RGB:
+ return 1;
+ case GL_RGBA:
+ return 0;
+ default:
+ return -1;
+ }
+}
+
static glamor_pixmap_fbo *
glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
- int w, int h, GLenum format, int flag)
+ int w, int h, GLenum format)
{
struct xorg_list *cache;
glamor_pixmap_fbo *fbo_entry, *ret_fbo = NULL;
@@ -87,33 +104,18 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
cache = &glamor_priv->fbo_cache[n_format]
[cache_wbucket(w)]
[cache_hbucket(h)];
- if (!(flag & GLAMOR_CACHE_EXACT_SIZE)) {
- xorg_list_for_each_entry(fbo_entry, cache, list) {
- if (fbo_entry->width >= w && fbo_entry->height >= h) {
-
- DEBUGF("Request w %d h %d format %x \n", w, h, format);
- DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
- fbo_entry, fbo_entry->width, fbo_entry->height,
- fbo_entry->fb, fbo_entry->tex);
- xorg_list_del(&fbo_entry->list);
- ret_fbo = fbo_entry;
- break;
- }
- }
- }
- else {
- xorg_list_for_each_entry(fbo_entry, cache, list) {
- if (fbo_entry->width == w && fbo_entry->height == h) {
-
- DEBUGF("Request w %d h %d format %x \n", w, h, format);
- DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
- fbo_entry, fbo_entry->width, fbo_entry->height,
- fbo_entry->fb, fbo_entry->tex, fbo_entry->format);
- assert(format == fbo_entry->format);
- xorg_list_del(&fbo_entry->list);
- ret_fbo = fbo_entry;
- break;
- }
+
+ xorg_list_for_each_entry(fbo_entry, cache, list) {
+ if (fbo_entry->width == w && fbo_entry->height == h) {
+
+ DEBUGF("Request w %d h %d format %x \n", w, h, format);
+ DEBUGF("got cache entry %p w %d h %d fbo %d tex %d format %x\n",
+ fbo_entry, fbo_entry->width, fbo_entry->height,
+ fbo_entry->fb, fbo_entry->tex, fbo_entry->format);
+ assert(format == fbo_entry->format);
+ xorg_list_del(&fbo_entry->list);
+ ret_fbo = fbo_entry;
+ break;
}
}
@@ -127,22 +129,22 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
}
static void
-glamor_purge_fbo(glamor_pixmap_fbo *fbo)
+glamor_purge_fbo(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *fbo)
{
- glamor_make_current(fbo->glamor_priv);
+ glamor_make_current(glamor_priv);
if (fbo->fb)
glDeleteFramebuffers(1, &fbo->fb);
if (fbo->tex)
glDeleteTextures(1, &fbo->tex);
- if (fbo->pbo)
- glDeleteBuffers(1, &fbo->pbo);
free(fbo);
}
static void
-glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
+glamor_pixmap_fbo_cache_put(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *fbo)
{
struct xorg_list *cache;
int n_format;
@@ -154,32 +156,33 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
n_format = cache_format(fbo->format);
if (fbo->fb == 0 || fbo->external || n_format == -1
- || fbo->glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) {
- fbo->glamor_priv->tick += GLAMOR_CACHE_EXPIRE_MAX;
- glamor_fbo_expire(fbo->glamor_priv);
- glamor_purge_fbo(fbo);
+ || glamor_priv->fbo_cache_watermark >= FBO_CACHE_THRESHOLD) {
+ glamor_priv->tick += GLAMOR_CACHE_EXPIRE_MAX;
+ glamor_fbo_expire(glamor_priv);
+ glamor_purge_fbo(glamor_priv, fbo);
return;
}
- cache = &fbo->glamor_priv->fbo_cache[n_format]
+ cache = &glamor_priv->fbo_cache[n_format]
[cache_wbucket(fbo->width)]
[cache_hbucket(fbo->height)];
DEBUGF
("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n",
fbo, cache, fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
- fbo->glamor_priv->fbo_cache_watermark += fbo->width * fbo->height;
+ glamor_priv->fbo_cache_watermark += fbo->width * fbo->height;
xorg_list_add(&fbo->list, cache);
- fbo->expire = fbo->glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
+ fbo->expire = glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
#endif
}
static int
-glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
+glamor_pixmap_ensure_fb(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *fbo)
{
int status, err = 0;
- glamor_make_current(fbo->glamor_priv);
+ glamor_make_current(glamor_priv);
if (fbo->fb == 0)
glGenFramebuffers(1, &fbo->fb);
@@ -239,22 +242,17 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
fbo->height = h;
fbo->external = FALSE;
fbo->format = format;
- fbo->glamor_priv = glamor_priv;
- if (flag == GLAMOR_CREATE_PIXMAP_MAP) {
- glamor_make_current(glamor_priv);
- glGenBuffers(1, &fbo->pbo);
- goto done;
- }
+ if (flag == CREATE_PIXMAP_USAGE_SHARED)
+ fbo->external = TRUE;
if (flag != GLAMOR_CREATE_FBO_NO_FBO) {
- if (glamor_pixmap_ensure_fb(fbo) != 0) {
- glamor_purge_fbo(fbo);
+ if (glamor_pixmap_ensure_fb(glamor_priv, fbo) != 0) {
+ glamor_purge_fbo(glamor_priv, fbo);
fbo = NULL;
}
}
- done:
return fbo;
}
@@ -280,7 +278,7 @@ glamor_fbo_expire(glamor_screen_private *glamor_priv)
xorg_list_del(&fbo_entry->list);
DEBUGF("cache %p fbo %p expired %d current %d \n", cache,
fbo_entry, fbo_entry->expire, glamor_priv->tick);
- glamor_purge_fbo(fbo_entry);
+ glamor_purge_fbo(glamor_priv, fbo_entry);
}
}
@@ -317,16 +315,17 @@ glamor_fini_pixmap_fbo(ScreenPtr screen)
xorg_list_for_each_entry_safe_reverse(fbo_entry, tmp, cache,
list) {
xorg_list_del(&fbo_entry->list);
- glamor_purge_fbo(fbo_entry);
+ glamor_purge_fbo(glamor_priv, fbo_entry);
}
}
}
void
-glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
+glamor_destroy_fbo(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *fbo)
{
xorg_list_del(&fbo->list);
- glamor_pixmap_fbo_cache_put(fbo);
+ glamor_pixmap_fbo_cache_put(glamor_priv, fbo);
}
@@ -334,25 +333,34 @@ static int
_glamor_create_tex(glamor_screen_private *glamor_priv,
int w, int h, GLenum format)
{
- unsigned int tex = 0;
-
- /* With dri3, we want to allocate ARGB8888 pixmaps only.
- * Depending on the implementation, GL_RGBA might not
- * give us ARGB8888. We ask glamor_egl to use get
- * an ARGB8888 based texture for us. */
- if (format == GL_RGBA) {
- tex = glamor_egl_create_argb8888_based_texture(glamor_priv->screen,
- w, h);
+ unsigned int tex;
+
+ glamor_make_current(glamor_priv);
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ if (format == glamor_priv->one_channel_format && format == GL_RED) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ZERO);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
}
- if (!tex) {
- glamor_make_current(glamor_priv);
- glGenTextures(1, &tex);
- glBindTexture(GL_TEXTURE_2D, tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
- format, GL_UNSIGNED_BYTE, NULL);
+ glamor_priv->suppress_gl_out_of_memory_logging = true;
+ glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
+ format, GL_UNSIGNED_BYTE, NULL);
+ glamor_priv->suppress_gl_out_of_memory_logging = false;
+
+ if (glGetError() == GL_OUT_OF_MEMORY) {
+ if (!glamor_priv->logged_any_fbo_allocation_failure) {
+ LogMessageVerb(X_WARNING, 0, "glamor: Failed to allocate %dx%d "
+ "FBO due to GL_OUT_OF_MEMORY.\n", w, h);
+ LogMessageVerb(X_WARNING, 0,
+ "glamor: Expect reduced performance.\n");
+ glamor_priv->logged_any_fbo_allocation_failure = true;
+ }
+ glDeleteTextures(1, &tex);
+ return 0;
}
+
return tex;
}
@@ -362,45 +370,40 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
{
glamor_pixmap_fbo *fbo;
GLint tex = 0;
- int cache_flag;
- if (flag == GLAMOR_CREATE_FBO_NO_FBO)
+ if (flag == GLAMOR_CREATE_FBO_NO_FBO || flag == CREATE_PIXMAP_USAGE_SHARED)
goto new_fbo;
- if (flag == GLAMOR_CREATE_PIXMAP_MAP)
- goto no_tex;
-
- /* Tiling from textures requires exact pixmap sizes. As we don't
- * know which pixmaps will be used as tiles, just allocate
- * everything at the requested size
- */
- cache_flag = GLAMOR_CACHE_EXACT_SIZE;
-
- fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h, format, cache_flag);
+ fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h, format);
if (fbo)
return fbo;
new_fbo:
tex = _glamor_create_tex(glamor_priv, w, h, format);
- no_tex:
+ if (!tex)
+ return NULL;
fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag);
return fbo;
}
-static glamor_pixmap_fbo *
-_glamor_create_fbo_array(glamor_screen_private *glamor_priv,
+/**
+ * Create storage for the w * h region, using FBOs of the GL's maximum
+ * supported size.
+ */
+glamor_pixmap_fbo *
+glamor_create_fbo_array(glamor_screen_private *glamor_priv,
int w, int h, GLenum format, int flag,
int block_w, int block_h,
- glamor_pixmap_private *pixmap_priv, int has_fbo)
+ glamor_pixmap_private *priv)
{
int block_wcnt;
int block_hcnt;
glamor_pixmap_fbo **fbo_array;
BoxPtr box_array;
int i, j;
- glamor_pixmap_private_large_t *priv;
- priv = &pixmap_priv->large;
+ priv->block_w = block_w;
+ priv->block_h = block_h;
block_wcnt = (w + block_w - 1) / block_w;
block_hcnt = (h + block_h - 1) / block_h;
@@ -431,13 +434,10 @@ _glamor_create_fbo_array(glamor_screen_private *glamor_priv,
fbo_w =
box_array[i * block_wcnt + j].x2 - box_array[i * block_wcnt +
j].x1;
- if (!has_fbo)
- fbo_array[i * block_wcnt + j] = glamor_create_fbo(glamor_priv,
- fbo_w, fbo_h,
- format,
- GLAMOR_CREATE_PIXMAP_FIXUP);
- else
- fbo_array[i * block_wcnt + j] = priv->base.fbo;
+ fbo_array[i * block_wcnt + j] = glamor_create_fbo(glamor_priv,
+ fbo_w, fbo_h,
+ format,
+ GLAMOR_CREATE_PIXMAP_FIXUP);
if (fbo_array[i * block_wcnt + j] == NULL)
goto cleanup;
}
@@ -452,27 +452,13 @@ _glamor_create_fbo_array(glamor_screen_private *glamor_priv,
cleanup:
for (i = 0; i < block_wcnt * block_hcnt; i++)
- if ((fbo_array)[i])
- glamor_destroy_fbo((fbo_array)[i]);
+ if (fbo_array[i])
+ glamor_destroy_fbo(glamor_priv, fbo_array[i]);
free(box_array);
free(fbo_array);
return NULL;
}
-/* Create a fbo array to cover the w*h region, by using block_w*block_h
- * block.*/
-glamor_pixmap_fbo *
-glamor_create_fbo_array(glamor_screen_private *glamor_priv,
- int w, int h, GLenum format, int flag,
- int block_w, int block_h,
- glamor_pixmap_private *pixmap_priv)
-{
- pixmap_priv->large.block_w = block_w;
- pixmap_priv->large.block_h = block_h;
- return _glamor_create_fbo_array(glamor_priv, w, h, format, flag,
- block_w, block_h, pixmap_priv, 0);
-}
-
glamor_pixmap_fbo *
glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv)
{
@@ -481,11 +467,11 @@ glamor_pixmap_detach_fbo(glamor_pixmap_private *pixmap_priv)
if (pixmap_priv == NULL)
return NULL;
- fbo = pixmap_priv->base.fbo;
+ fbo = pixmap_priv->fbo;
if (fbo == NULL)
return NULL;
- pixmap_priv->base.fbo = NULL;
+ pixmap_priv->fbo = NULL;
return fbo;
}
@@ -497,47 +483,40 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
pixmap_priv = glamor_get_pixmap_private(pixmap);
- if (pixmap_priv->base.fbo)
+ if (pixmap_priv->fbo)
return;
- pixmap_priv->base.fbo = fbo;
+ pixmap_priv->fbo = fbo;
switch (pixmap_priv->type) {
- case GLAMOR_TEXTURE_LARGE:
case GLAMOR_TEXTURE_ONLY:
case GLAMOR_TEXTURE_DRM:
- pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL;
- if (fbo->tex != 0)
- pixmap_priv->base.gl_tex = 1;
- else {
- /* XXX For the Xephyr only, may be broken now. */
- pixmap_priv->base.gl_tex = 0;
- }
- case GLAMOR_MEMORY_MAP:
+ pixmap_priv->gl_fbo = GLAMOR_FBO_NORMAL;
pixmap->devPrivate.ptr = NULL;
- break;
default:
break;
}
}
void
-glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv)
+glamor_pixmap_destroy_fbo(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);
glamor_pixmap_fbo *fbo;
- if (priv->type == GLAMOR_TEXTURE_LARGE) {
+ if (glamor_pixmap_priv_is_large(priv)) {
int i;
- glamor_pixmap_private_large_t *large = &priv->large;
- for (i = 0; i < large->block_wcnt * large->block_hcnt; i++)
- glamor_destroy_fbo(large->fbo_array[i]);
- free(large->fbo_array);
+ for (i = 0; i < priv->block_wcnt * priv->block_hcnt; i++)
+ glamor_destroy_fbo(glamor_priv, priv->fbo_array[i]);
+ free(priv->fbo_array);
}
else {
fbo = glamor_pixmap_detach_fbo(priv);
if (fbo)
- glamor_destroy_fbo(fbo);
+ glamor_destroy_fbo(glamor_priv, fbo);
}
}
@@ -550,7 +529,7 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
pixmap_priv = glamor_get_pixmap_private(pixmap);
- if (pixmap_priv->base.fbo == NULL) {
+ if (pixmap_priv->fbo == NULL) {
fbo = glamor_create_fbo(glamor_priv, pixmap->drawable.width,
pixmap->drawable.height, format, flag);
@@ -561,13 +540,13 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
}
else {
/* We do have a fbo, but it may lack of fb or tex. */
- if (!pixmap_priv->base.fbo->tex)
- pixmap_priv->base.fbo->tex =
+ if (!pixmap_priv->fbo->tex)
+ pixmap_priv->fbo->tex =
_glamor_create_tex(glamor_priv, pixmap->drawable.width,
pixmap->drawable.height, format);
- if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->base.fbo->fb == 0)
- if (glamor_pixmap_ensure_fb(pixmap_priv->base.fbo) != 0)
+ if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->fbo->fb == 0)
+ if (glamor_pixmap_ensure_fb(glamor_priv, pixmap_priv->fbo) != 0)
return FALSE;
}
@@ -582,7 +561,7 @@ glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back)
front_priv = glamor_get_pixmap_private(front);
back_priv = glamor_get_pixmap_private(back);
- temp_fbo = front_priv->base.fbo;
- front_priv->base.fbo = back_priv->base.fbo;
- back_priv->base.fbo = temp_fbo;
+ temp_fbo = front_priv->fbo;
+ front_priv->fbo = back_priv->fbo;
+ back_priv->fbo = temp_fbo;
}
diff --git a/xserver/glamor/glamor_font.c b/xserver/glamor/glamor_font.c
index 6b3a16abc..637e0dce1 100644
--- a/xserver/glamor/glamor_font.c
+++ b/xserver/glamor/glamor_font.c
@@ -77,9 +77,25 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
glamor_font->glyph_width_bytes = glyph_width_bytes;
glamor_font->glyph_height = glyph_height;
- overall_width = glyph_width_bytes * num_cols;
- overall_height = glyph_height * num_rows;
+ /*
+ * Layout the font two blocks of columns wide.
+ * This avoids a problem with some fonts that are too high to fit.
+ */
+ glamor_font->row_width = glyph_width_bytes * num_cols;
+
+ if (num_rows > 1) {
+ overall_width = glamor_font->row_width * 2;
+ overall_height = glyph_height * ((num_rows + 1) / 2);
+ } else {
+ overall_width = glamor_font->row_width;
+ overall_height = glyph_height;
+ }
+ if (overall_width > glamor_priv->max_fbo_size ||
+ overall_height > glamor_priv->max_fbo_size) {
+ /* fallback if we don't fit inside a texture */
+ return NULL;
+ }
bits = malloc(overall_width * overall_height);
if (!bits)
return NULL;
@@ -112,11 +128,17 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
(*font->get_glyphs)(font, 1, c, TwoD16Bit, &count, &glyph);
if (count) {
- char *dst = bits + row * glyph_height * overall_width +
- col * glyph_width_bytes;
+ char *dst;
char *src = glyph->bits;
unsigned y;
+ dst = bits;
+ /* get offset of start of first row */
+ dst += (row / 2) * glyph_height * overall_width;
+ /* add offset into second row */
+ dst += (row & 1) ? glamor_font->row_width : 0;
+
+ dst += col * glyph_width_bytes;
for (y = 0; y < GLYPHHEIGHTPIXELS(glyph); y++) {
memcpy(dst, src, GLYPHWIDTHBYTES(glyph));
dst += overall_width;
@@ -127,8 +149,13 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ glamor_priv->suppress_gl_out_of_memory_logging = true;
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, overall_width, overall_height,
0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, bits);
+ glamor_priv->suppress_gl_out_of_memory_logging = false;
+ if (glGetError() == GL_OUT_OF_MEMORY)
+ return NULL;
free(bits);
diff --git a/xserver/glamor/glamor_font.h b/xserver/glamor/glamor_font.h
index 36d20624d..4d41e0196 100644
--- a/xserver/glamor/glamor_font.h
+++ b/xserver/glamor/glamor_font.h
@@ -30,7 +30,7 @@ typedef struct {
CARD8 default_col;
GLuint texture_id;
-
+ GLuint row_width;
CARD16 glyph_width_bytes;
CARD16 glyph_width_pixels;
CARD16 glyph_height;
diff --git a/xserver/glamor/glamor_glyphblt.c b/xserver/glamor/glamor_glyphblt.c
index 73b1df51e..b21aa068e 100644
--- a/xserver/glamor/glamor_glyphblt.c
+++ b/xserver/glamor/glamor_glyphblt.c
@@ -48,7 +48,7 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
glamor_pixmap_private *pixmap_priv;
glamor_program *prog;
RegionPtr clip = gc->pCompositeClip;
- int box_x, box_y;
+ int box_index;
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
@@ -60,14 +60,14 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
&glamor_priv->poly_glyph_blt_progs,
&glamor_facet_poly_glyph_blt);
if (!prog)
- goto bail_ctx;
+ goto bail;
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
start_x += drawable->x;
y += drawable->y;
- glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ glamor_pixmap_loop(pixmap_priv, box_index) {
int x;
int n;
int num_points, max_points;
@@ -75,7 +75,7 @@ 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,
+ glamor_set_destination_drawable(drawable, box_index, FALSE, TRUE,
prog->matrix_uniform, &off_x, &off_y);
max_points = 500;
@@ -138,12 +138,9 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
}
}
- glDisable(GL_COLOR_LOGIC_OP);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
return TRUE;
-bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
bail:
return FALSE;
}
@@ -160,32 +157,6 @@ glamor_poly_glyph_blt(DrawablePtr drawable, GCPtr gc,
ppci, pglyph_base);
}
-Bool
-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))
- return TRUE;
- 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;
-}
-
-Bool
-glamor_image_glyph_blt_nf(DrawablePtr drawable, GCPtr gc,
- int start_x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, void *pglyph_base)
-{
- miImageGlyphBlt(drawable, gc, start_x, y, nglyph, ppci, pglyph_base);
- return TRUE;
-}
-
static Bool
glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
DrawablePtr drawable, int w, int h, int x, int y)
@@ -198,7 +169,7 @@ glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
int bitmap_stride = bitmap->devKind;
glamor_program *prog;
RegionPtr clip = gc->pCompositeClip;
- int box_x, box_y;
+ int box_index;
int yy, xx;
int num_points;
INT16 *points = NULL;
@@ -217,7 +188,7 @@ glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
&glamor_priv->poly_glyph_blt_progs,
&glamor_facet_poly_glyph_blt);
if (!prog)
- goto bail_ctx;
+ goto bail;
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
@@ -249,19 +220,16 @@ glamor_push_pixels_gl(GCPtr gc, PixmapPtr bitmap,
glamor_put_vbo_space(screen);
- glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
- glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, TRUE,
+ glamor_pixmap_loop(pixmap_priv, box_index) {
+ glamor_set_destination_drawable(drawable, box_index, FALSE, TRUE,
prog->matrix_uniform, NULL, NULL);
glDrawArrays(GL_POINTS, 0, num_points);
}
- glDisable(GL_COLOR_LOGIC_OP);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
return TRUE;
-bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
bail:
return FALSE;
}
@@ -275,21 +243,3 @@ glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
}
-
-Bool
-glamor_push_pixels_nf(GCPtr gc, PixmapPtr bitmap,
- DrawablePtr drawable, int w, int h, int x, int y)
-{
- 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/xserver/glamor/glamor_glyphs.c b/xserver/glamor/glamor_glyphs.c
deleted file mode 100644
index 1f1362487..000000000
--- a/xserver/glamor/glamor_glyphs.c
+++ /dev/null
@@ -1,1783 +0,0 @@
-/*
- * Copyright © 2008 Red Hat, Inc.
- * Partly based on code Copyright © 2000 SuSE, Inc.
- *
- * 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 Red Hat not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. Red Hat makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * Red Hat DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Red Hat
- * 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.
- *
- * 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 SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. SuSE makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * 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.
- *
- * Author: Owen Taylor <otaylor@fishsoup.net>
- * Based on code by: Keith Packard
- */
-
-#include <stdlib.h>
-
-#include "glamor_priv.h"
-
-#include <mipict.h>
-
-#if DEBUG_GLYPH_CACHE
-#define DBG_GLYPH_CACHE(a) ErrorF a
-#else
-#define DBG_GLYPH_CACHE(a)
-#endif
-
-/* Width of the pixmaps we use for the caches; this should be less than
- * max texture size of the driver; this may need to actually come from
- * the driver.
- */
-
-/* Maximum number of glyphs we buffer on the stack before flushing
- * rendering to the mask or destination surface.
- */
-#define GLYPH_BUFFER_SIZE 1024
-
-typedef struct {
- PicturePtr source;
- glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE + 4];
- int count;
-} glamor_glyph_buffer_t;
-
-struct glamor_glyph {
- glamor_glyph_cache_t *cache;
- uint16_t x, y;
- uint16_t size, pos;
- unsigned long long left_x1_map, left_x2_map;
- unsigned long long right_x1_map, right_x2_map; /* Use to check real intersect or not. */
- Bool has_edge_map;
- Bool cached;
-};
-
-typedef enum {
- GLAMOR_GLYPH_SUCCESS, /* Glyph added to render buffer */
- GLAMOR_GLYPH_FAIL, /* out of memory, etc */
- GLAMOR_GLYPH_NEED_FLUSH, /* would evict a glyph already in the buffer */
-} glamor_glyph_cache_result_t;
-
-#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
-static DevPrivateKeyRec glamor_glyph_key;
-
-static inline struct glamor_glyph *
-glamor_glyph_get_private(ScreenPtr screen, GlyphPtr glyph)
-{
- struct glamor_glyph *privates = (struct glamor_glyph*)glyph->devPrivates;
-
- return &privates[screen->myNum];
-}
-
-/*
- * Mask cache is located at the corresponding cache picture's last row.
- * and is deadicated for the mask picture when do the glyphs_via_mask.
- *
- * As we split the glyphs list according to its overlapped or non-overlapped,
- * we can reduce the length of glyphs to do the glyphs_via_mask to 2 or 3
- * glyphs one time for most cases. Thus it give us a case to allocate a
- * small portion of the corresponding cache directly as the mask picture.
- * Then we can rendering the glyphs to this mask picture, and latter we
- * can accumulate the second steps, composite the mask to the dest with
- * the other non-overlapped glyphs's rendering process.
- * Another major benefit is we now only need to clear a relatively small mask
- * region then before. It also make us implement a bunch mask picture clearing
- * algorithm to avoid too frequently small region clearing.
- *
- * If there is no any overlapping, this method will not get performance gain.
- * If there is some overlapping, then this algorithm can get about 15% performance
- * gain.
- */
-
-static void
-clear_mask_cache_bitmap(glamor_glyph_mask_cache_t *maskcache,
- unsigned int clear_mask_bits)
-{
- unsigned int i = 0;
- BoxRec box[MASK_CACHE_WIDTH];
- int box_cnt = 0;
-
- assert((clear_mask_bits & ~MASK_CACHE_MASK) == 0);
- for (i = 0; i < MASK_CACHE_WIDTH; i++) {
- if (clear_mask_bits & (1 << i)) {
- box[box_cnt].x1 = maskcache->mcache[i].x;
- box[box_cnt].x2 = maskcache->mcache[i].x + MASK_CACHE_MAX_SIZE;
- box[box_cnt].y1 = maskcache->mcache[i].y;
- box[box_cnt].y2 = maskcache->mcache[i].y + MASK_CACHE_MAX_SIZE;
- box_cnt++;
- }
- }
- glamor_solid_boxes(maskcache->pixmap, box, box_cnt, 0);
- maskcache->cleared_bitmap |= clear_mask_bits;
-}
-
-static void
-clear_mask_cache(glamor_glyph_mask_cache_t *maskcache)
-{
- int x = 0;
- int cnt = MASK_CACHE_WIDTH;
- unsigned int i = 0;
- struct glamor_glyph_mask_cache_entry *mce;
-
- glamor_solid(maskcache->pixmap, 0, CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE,
- MASK_CACHE_MAX_SIZE, 0);
- mce = &maskcache->mcache[0];
- while (cnt--) {
- mce->width = 0;
- mce->height = 0;
- mce->x = x;
- mce->y = CACHE_PICTURE_SIZE;
- mce->idx = i++;
- x += MASK_CACHE_MAX_SIZE;
- mce++;
- }
- maskcache->free_bitmap = MASK_CACHE_MASK;
- maskcache->cleared_bitmap = MASK_CACHE_MASK;
-}
-
-static int
-find_continuous_bits(unsigned int bits, int bits_cnt, unsigned int *pbits_mask)
-{
- int idx = 0;
- unsigned int bits_mask;
-
- bits_mask = ((1LL << bits_cnt) - 1);
-
- if (_X_UNLIKELY(bits_cnt > 56)) {
- while (bits) {
- if ((bits & bits_mask) == bits_mask) {
- *pbits_mask = bits_mask << idx;
- return idx;
- }
- bits >>= 1;
- idx++;
- }
- }
- else {
- idx = __fls(bits);
- while (bits) {
- unsigned int temp_bits;
-
- temp_bits = bits_mask << (idx - bits_cnt + 1);
- if ((bits & temp_bits) == temp_bits) {
- *pbits_mask = temp_bits;
- return (idx - bits_cnt + 1);
- }
- /* Find first zero. And clear the tested bit. */
- bits &= ~(1LL << idx);
- idx = __fls(~bits);
- bits &= ~((1LL << idx) - 1);
- idx--;
- }
- }
- return -1;
-}
-
-static struct glamor_glyph_mask_cache_entry *
-get_mask_cache(glamor_glyph_mask_cache_t *maskcache, int blocks)
-{
- int free_cleared_bit, idx = -1;
- int retry_cnt = 0;
- unsigned int bits_mask = 0;
-
- if (maskcache->free_bitmap == 0)
- return NULL;
- retry:
- free_cleared_bit = maskcache->free_bitmap & maskcache->cleared_bitmap;
- if (free_cleared_bit && blocks == 1) {
- idx = __fls(free_cleared_bit);
- bits_mask = 1 << idx;
- }
- else if (free_cleared_bit && blocks > 1) {
- idx = find_continuous_bits(free_cleared_bit, blocks, &bits_mask);
- }
-
- if (idx < 0) {
- clear_mask_cache_bitmap(maskcache, maskcache->free_bitmap);
- if (retry_cnt++ > 2)
- return NULL;
- goto retry;
- }
-
- maskcache->cleared_bitmap &= ~bits_mask;
- maskcache->free_bitmap &= ~bits_mask;
- DEBUGF("get idx %d free %x clear %x \n",
- idx, maskcache->free_bitmap, maskcache->cleared_bitmap);
- return &maskcache->mcache[idx];
-}
-
-static void
-put_mask_cache_bitmap(glamor_glyph_mask_cache_t *maskcache,
- unsigned int bitmap)
-{
- maskcache->free_bitmap |= bitmap;
- DEBUGF("put bitmap %x free %x clear %x \n",
- bitmap, maskcache->free_bitmap, maskcache->cleared_bitmap);
-}
-
-static void
-glamor_unrealize_glyph_caches(ScreenPtr pScreen)
-{
- glamor_screen_private *glamor = glamor_get_screen_private(pScreen);
- int i;
-
- if (!glamor->glyph_caches_realized)
- return;
-
- for (i = 0; i < GLAMOR_NUM_GLYPH_CACHE_FORMATS; i++) {
- glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
-
- if (cache->picture)
- FreePicture(cache->picture, 0);
-
- if (cache->glyphs)
- free(cache->glyphs);
-
- if (glamor->mask_cache[i])
- free(glamor->mask_cache[i]);
- }
- glamor->glyph_caches_realized = FALSE;
-}
-
-void
-glamor_glyphs_fini(ScreenPtr pScreen)
-{
- glamor_unrealize_glyph_caches(pScreen);
-}
-
-/* All caches for a single format share a single pixmap for glyph storage,
- * allowing mixing glyphs of different sizes without paying a penalty
- * for switching between source pixmaps. (Note that for a size of font
- * right at the border between two sizes, we might be switching for almost
- * every glyph.)
- *
- * This function allocates the storage pixmap, and then fills in the
- * rest of the allocated structures for all caches with the given format.
- */
-
-Bool
-glamor_realize_glyph_caches(ScreenPtr pScreen)
-{
- glamor_screen_private *glamor = glamor_get_screen_private(pScreen);
-
- unsigned int formats[] = {
- PIXMAN_a8,
- PIXMAN_a8r8g8b8,
- };
- int i;
-
- if (glamor->glyph_caches_realized)
- return TRUE;
-
- memset(glamor->glyphCaches, 0, sizeof(glamor->glyphCaches));
-
- for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
- glamor_glyph_cache_t *cache = &glamor->glyphCaches[i];
- PixmapPtr pixmap;
- PicturePtr picture;
- XID component_alpha;
- int depth = PIXMAN_FORMAT_DEPTH(formats[i]);
- int error;
- PictFormatPtr pPictFormat =
- PictureMatchFormat(pScreen, depth, formats[i]);
- if (!pPictFormat)
- goto bail;
-
- /* Now allocate the pixmap and picture */
- pixmap = pScreen->CreatePixmap(pScreen,
- CACHE_PICTURE_SIZE,
- CACHE_PICTURE_SIZE + MASK_CACHE_MAX_SIZE,
- depth, GLAMOR_CREATE_NO_LARGE);
- if (!pixmap)
- goto bail;
-
- component_alpha = NeedsComponent(pPictFormat->format);
- picture = CreatePicture(0, &pixmap->drawable, pPictFormat,
- CPComponentAlpha, &component_alpha,
- serverClient, &error);
-
- pScreen->DestroyPixmap(pixmap);
- if (!picture)
- goto bail;
-
- ValidatePicture(picture);
-
- cache->picture = picture;
- cache->glyphs = calloc(sizeof(GlyphPtr), GLYPH_CACHE_SIZE);
- if (!cache->glyphs)
- goto bail;
-
- cache->evict = rand() % GLYPH_CACHE_SIZE;
- glamor->mask_cache[i] = calloc(1, sizeof(*glamor->mask_cache[i]));
- glamor->mask_cache[i]->pixmap = pixmap;
- clear_mask_cache(glamor->mask_cache[i]);
- }
- assert(i == GLAMOR_NUM_GLYPH_CACHE_FORMATS);
-
- glamor->glyph_caches_realized = TRUE;
- return TRUE;
-
- bail:
- glamor_unrealize_glyph_caches(pScreen);
- return FALSE;
-}
-
-/**
- * Called by glamor_create_screen_resources() to set up the glyph cache.
- *
- * This was previously required to be called by the drivers, but not
- * as of the xserver 1.16 ABI.
- */
-Bool
-glamor_glyphs_init(ScreenPtr pScreen)
-{
- if (!dixRegisterPrivateKey(&glamor_glyph_key,
- PRIVATE_GLYPH,
- screenInfo.numScreens * sizeof(struct glamor_glyph)))
- return FALSE;
-
- return TRUE;
-}
-
-/* The most efficient thing to way to upload the glyph to the screen
- * is to use CopyArea; glamor pixmaps are always offscreen.
- */
-static void
-glamor_glyph_cache_upload_glyph(ScreenPtr screen,
- glamor_glyph_cache_t *cache,
- GlyphPtr glyph, int x, int y)
-{
- PicturePtr pGlyphPicture = GlyphPicture(glyph)[screen->myNum];
- PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable;
- PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable;
- PixmapPtr scratch;
- BoxRec box;
- GCPtr gc;
-
- gc = GetScratchGC(pCachePixmap->drawable.depth, screen);
- if (!gc)
- return;
-
- ValidateGC(&pCachePixmap->drawable, gc);
-
- scratch = pGlyphPixmap;
- if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth) {
-
- scratch = glamor_create_pixmap(screen,
- glyph->info.width,
- glyph->info.height,
- pCachePixmap->drawable.depth, 0);
- if (scratch) {
- PicturePtr picture;
- int error;
-
- picture =
- CreatePicture(0,
- &scratch->drawable,
- PictureMatchFormat
- (screen,
- pCachePixmap->drawable.depth,
- cache->picture->format),
- 0, NULL, serverClient, &error);
- if (picture) {
- ValidatePicture(picture);
- glamor_composite(PictOpSrc,
- pGlyphPicture,
- NULL, picture,
- 0, 0, 0, 0, 0,
- 0, glyph->info.width, glyph->info.height);
- FreePicture(picture, 0);
- }
- }
- else {
- scratch = pGlyphPixmap;
- }
- }
-
- box.x1 = x;
- box.y1 = y;
- box.x2 = x + glyph->info.width;
- box.y2 = y + glyph->info.height;
- glamor_copy(&scratch->drawable,
- &pCachePixmap->drawable, NULL,
- &box, 1, -x, -y, FALSE, FALSE, 0, NULL);
- if (scratch != pGlyphPixmap)
- screen->DestroyPixmap(scratch);
-
- FreeScratchGC(gc);
-}
-
-void
-glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph)
-{
- struct glamor_glyph *priv;
-
- /* Use Lookup in case we have not attached to this glyph. */
- priv = glamor_glyph_get_private(screen, glyph);
-
- if (priv->cached)
- priv->cache->glyphs[priv->pos] = NULL;
-}
-
-/* Cut and paste from render/glyph.c - probably should export it instead */
-static void
-glamor_glyph_extents(int nlist,
- GlyphListPtr list, GlyphPtr *glyphs, BoxPtr extents)
-{
- int x1, x2, y1, y2;
- int x, y, n;
-
- x1 = y1 = MAXSHORT;
- x2 = y2 = MINSHORT;
- x = y = 0;
- while (nlist--) {
- x += list->xOff;
- y += list->yOff;
- n = list->len;
- list++;
- while (n--) {
- GlyphPtr glyph = *glyphs++;
- int v;
-
- v = x - glyph->info.x;
- if (v < x1)
- x1 = v;
- v += glyph->info.width;
- if (v > x2)
- x2 = v;
-
- v = y - glyph->info.y;
- if (v < y1)
- y1 = v;
- v += glyph->info.height;
- if (v > y2)
- y2 = v;
-
- x += glyph->info.xOff;
- y += glyph->info.yOff;
- }
- }
-
- extents->x1 = x1 < MINSHORT ? MINSHORT : x1;
- extents->x2 = x2 > MAXSHORT ? MAXSHORT : x2;
- extents->y1 = y1 < MINSHORT ? MINSHORT : y1;
- extents->y2 = y2 > MAXSHORT ? MAXSHORT : y2;
-}
-
-static void
-glamor_glyph_priv_get_edge_map(GlyphPtr glyph, struct glamor_glyph *priv,
- PicturePtr glyph_picture)
-{
- PixmapPtr glyph_pixmap = (PixmapPtr) glyph_picture->pDrawable;
- int j;
- unsigned long long left_x1_map = 0, left_x2_map = 0;
- unsigned long long right_x1_map = 0, right_x2_map = 0;
- int bitsPerPixel;
- int stride;
- void *bits;
- int width;
- unsigned int left_x1_data = 0, left_x2_data = 0;
- unsigned int right_x1_data = 0, right_x2_data = 0;
-
- bitsPerPixel = glyph_pixmap->drawable.bitsPerPixel;
- stride = glyph_pixmap->devKind;
- bits = glyph_pixmap->devPrivate.ptr;
- width = glyph->info.width;
-
- if (glyph_pixmap->drawable.width < 2
- || !(glyph_pixmap->drawable.depth == 8
- || glyph_pixmap->drawable.depth == 1
- || glyph_pixmap->drawable.depth == 32)) {
- priv->has_edge_map = FALSE;
- return;
- }
-
- left_x1_map = left_x2_map = 0;
- right_x1_map = right_x2_map = 0;
-
- for (j = 0; j < glyph_pixmap->drawable.height; j++) {
- if (bitsPerPixel == 8) {
- unsigned char *data;
-
- data = (unsigned char *) ((unsigned char *) bits + stride * j);
- left_x1_data = *data++;
- left_x2_data = *data;
- data =
- (unsigned char *) ((unsigned char *) bits + stride * j + width -
- 2);
- right_x1_data = *data++;
- right_x2_data = *data;
- }
- else if (bitsPerPixel == 32) {
- left_x1_data = *((unsigned int *) bits + stride / 4 * j);
- left_x2_data = *((unsigned int *) bits + stride / 4 * j + 1);
- right_x1_data =
- *((unsigned int *) bits + stride / 4 * j + width - 2);
- right_x2_data =
- *((unsigned int *) bits + stride / 4 * j + width - 1);
- }
- else if (bitsPerPixel == 1) {
- unsigned char temp;
-
- temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr
- + glyph_pixmap->devKind * j) & 0x3;
- left_x1_data = temp & 0x1;
- left_x2_data = temp & 0x2;
-
- temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr
- + glyph_pixmap->devKind * j
- + (glyph_pixmap->drawable.width - 2) / 8);
- right_x1_data = temp
- & (1 << ((glyph_pixmap->drawable.width - 2) % 8));
- temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr
- + glyph_pixmap->devKind * j
- + (glyph_pixmap->drawable.width - 1) / 8);
- right_x2_data = temp
- & (1 << ((glyph_pixmap->drawable.width - 1) % 8));
- }
- left_x1_map |= (left_x1_data != 0) << j;
- left_x2_map |= (left_x2_data != 0) << j;
- right_x1_map |= (right_x1_data != 0) << j;
- right_x2_map |= (right_x2_data != 0) << j;
- }
-
- priv->left_x1_map = left_x1_map;
- priv->left_x2_map = left_x2_map;
- priv->right_x1_map = right_x1_map;
- priv->right_x2_map = right_x2_map;
- priv->has_edge_map = TRUE;
- return;
-}
-
-/**
- * Returns TRUE if the glyphs in the lists intersect. Only checks based on
- * bounding box, which appears to be good enough to catch most cases at least.
- */
-
-#define INTERSECTED_TYPE_MASK 1
-#define NON_INTERSECTED 0
-#define INTERSECTED 1
-
-struct glamor_glyph_list {
- int nlist;
- GlyphListPtr list;
- GlyphPtr *glyphs;
- int type;
-};
-
-static Bool
-glyph_new_fixed_list(struct glamor_glyph_list *fixed_list,
- GlyphPtr *cur_glyphs,
- GlyphPtr ** head_glyphs,
- GlyphListPtr cur_list,
- int cur_pos, int cur_x, int cur_y,
- int x1, int y1, int x2, int y2,
- GlyphListPtr *head_list,
- int *head_pos,
- int *head_x,
- int *head_y, int *fixed_cnt, int type, BoxPtr prev_extents)
-{
- int x_off = 0;
- int y_off = 0;
- int n_off = 0;
- int list_cnt;
-
- if (type == NON_INTERSECTED) {
- if (x1 < prev_extents->x2 && x2 > prev_extents->x1
- && y1 < prev_extents->y2 && y2 > prev_extents->y1)
- return FALSE;
- x_off = (*(cur_glyphs - 1))->info.xOff;
- y_off = (*(cur_glyphs - 1))->info.yOff;
- n_off = 1;
- }
-
- list_cnt = cur_list - *head_list + 1;
- if (cur_pos <= n_off) {
- DEBUGF("break at %d n_off %d\n", cur_pos, n_off);
- list_cnt--;
- if (cur_pos < n_off) {
- /* we overlap with previous list's last glyph. */
- x_off += cur_list->xOff;
- y_off += cur_list->yOff;
- cur_list--;
- cur_pos = cur_list->len;
- if (cur_pos <= n_off) {
- list_cnt--;
- }
- }
- }
- DEBUGF("got %d lists\n", list_cnt);
- if (list_cnt != 0) {
- fixed_list->list = malloc(list_cnt * sizeof(*cur_list));
- memcpy(fixed_list->list, *head_list, list_cnt * sizeof(*cur_list));
- fixed_list->list[0].xOff = *head_x;
- fixed_list->list[0].yOff = *head_y;
- fixed_list->glyphs = *head_glyphs;
- fixed_list->type = type & INTERSECTED_TYPE_MASK;
- fixed_list->nlist = list_cnt;
- if (cur_list != *head_list) {
- fixed_list->list[0].len = (*head_list)->len - *head_pos;
- if (cur_pos != n_off)
- fixed_list->list[list_cnt - 1].len = cur_pos - n_off;
- }
- else
- fixed_list->list[0].len = cur_pos - *head_pos - n_off;
- (*fixed_cnt)++;
- }
-
- if (type <= INTERSECTED) {
- *head_list = cur_list;
- *head_pos = cur_pos - n_off;
- *head_x = cur_x - x_off;
- *head_y = cur_y - y_off;
- *head_glyphs = cur_glyphs - n_off;
- }
- return TRUE;
-}
-
-/*
- * This function detects glyph lists's overlapping.
- *
- * If check_fake_overlap is set, then it will check the glyph's left
- * and right small boxes's real overlapping pixels. And if there is
- * no real pixel overlapping, then it will not be treated as overlapped
- * case. And we also can configured it to ignore less than 2 pixels
- * overlappig.
- *
- * This function analyzes all the lists and split the list to multiple
- * lists which are pure overlapped glyph lists or pure non-overlapped
- * list if the overlapping only ocurr on the two adjacent glyphs.
- * Otherwise, it return -1.
- *
- **/
-
-static int
-glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs,
- PictFormatShort mask_format,
- ScreenPtr screen, Bool check_fake_overlap,
- struct glamor_glyph_list *fixed_list, int fixed_size)
-{
- int x1, x2, y1, y2;
- int n;
- int x, y;
- BoxPtr extents;
- BoxRec prev_extents;
- Bool first = TRUE, first_list = TRUE;
- Bool need_free_list_region = FALSE;
- Bool need_free_fixed_list = FALSE;
- struct glamor_glyph *priv = NULL;
- Bool in_non_intersected_list = -1;
- GlyphListPtr head_list;
- int head_x, head_y, head_pos;
- int fixed_cnt = 0;
- GlyphPtr *head_glyphs;
- GlyphListPtr cur_list = list;
- RegionRec list_region;
- RegionRec current_region;
- BoxRec current_box;
-
- if (nlist > 1) {
- pixman_region_init(&list_region);
- need_free_list_region = TRUE;
- }
-
- pixman_region_init(&current_region);
-
- extents = pixman_region_extents(&current_region);
-
- x = 0;
- y = 0;
- x1 = x2 = y1 = y2 = 0;
- n = 0;
- extents->x1 = 0;
- extents->y1 = 0;
- extents->x2 = 0;
- extents->y2 = 0;
-
- head_list = list;
- DEBUGF("has %d lists.\n", nlist);
- while (nlist--) {
- BoxRec left_box, right_box = { 0 };
- Bool has_left_edge_box = FALSE, has_right_edge_box = FALSE;
- Bool left_to_right;
- struct glamor_glyph *left_priv = NULL, *right_priv = NULL;
-
- x += list->xOff;
- y += list->yOff;
- n = list->len;
- left_to_right = TRUE;
- cur_list = list++;
-
- if (_X_UNLIKELY(!first_list)) {
- pixman_region_init_with_extents(&current_region, extents);
- pixman_region_union(&list_region, &list_region, &current_region);
- first = TRUE;
- }
- else {
- head_list = cur_list;
- head_pos = cur_list->len - n;
- head_x = x;
- head_y = y;
- head_glyphs = glyphs;
- }
-
- DEBUGF("current list %p has %d glyphs\n", cur_list, n);
- while (n--) {
- GlyphPtr glyph = *glyphs++;
-
- DEBUGF("the %dth glyph\n", cur_list->len - n - 1);
- if (glyph->info.width == 0 || glyph->info.height == 0) {
- x += glyph->info.xOff;
- y += glyph->info.yOff;
- continue;
- }
- if (mask_format
- && mask_format != GlyphPicture(glyph)[screen->myNum]->format) {
- need_free_fixed_list = TRUE;
- goto done;
- }
-
- x1 = x - glyph->info.x;
- if (x1 < MINSHORT)
- x1 = MINSHORT;
- y1 = y - glyph->info.y;
- if (y1 < MINSHORT)
- y1 = MINSHORT;
- if (check_fake_overlap)
- priv = glamor_glyph_get_private(screen, glyph);
-
- x2 = x1 + glyph->info.width;
- y2 = y1 + glyph->info.height;
-
- if (x2 > MAXSHORT)
- x2 = MAXSHORT;
- if (y2 > MAXSHORT)
- y2 = MAXSHORT;
-
- if (first) {
- extents->x1 = x1;
- extents->y1 = y1;
- extents->x2 = x2;
- extents->y2 = y2;
-
- prev_extents = *extents;
-
- first = FALSE;
- if (check_fake_overlap && priv
- && priv->has_edge_map && glyph->info.yOff == 0) {
- left_box.x1 = x1;
- left_box.x2 = x1 + 1;
- left_box.y1 = y1;
-
- right_box.x1 = x2 - 2;
- right_box.x2 = x2 - 1;
- right_box.y1 = y1;
- left_priv = right_priv = priv;
- has_left_edge_box = TRUE;
- has_right_edge_box = TRUE;
- }
- }
- else {
- if (_X_UNLIKELY(!first_list)) {
- current_box.x1 = x1;
- current_box.y1 = y1;
- current_box.x2 = x2;
- current_box.y2 = y2;
- if (pixman_region_contains_rectangle
- (&list_region, &current_box) != PIXMAN_REGION_OUT) {
- need_free_fixed_list = TRUE;
- goto done;
- }
- }
-
- if (x1 < extents->x2 && x2 > extents->x1
- && y1 < extents->y2 && y2 > extents->y1) {
-
- if (check_fake_overlap &&
- (has_left_edge_box || has_right_edge_box)
- && priv->has_edge_map && glyph->info.yOff == 0) {
- int left_dx, right_dx;
- unsigned long long intersected;
-
- left_dx = has_left_edge_box ? 1 : 0;
- right_dx = has_right_edge_box ? 1 : 0;
- if (x1 + 1 < extents->x2 - right_dx &&
- x2 - 1 > extents->x1 + left_dx)
- goto real_intersected;
-
- if (left_to_right && has_right_edge_box) {
- if (x1 == right_box.x1) {
- intersected =
- ((priv->left_x1_map & right_priv->
- right_x1_map)
- | (priv->left_x2_map & right_priv->
- right_x2_map));
- if (intersected)
- goto real_intersected;
- }
- else if (x1 == right_box.x2) {
- intersected =
- (priv->left_x1_map & right_priv->
- right_x2_map);
- if (intersected) {
-#ifdef GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
- /* tolerate with two pixels overlap. */
- intersected &= ~(1 << __fls(intersected));
- if ((intersected & (intersected - 1)))
-#endif
- goto real_intersected;
- }
- }
- }
- else if (!left_to_right && has_left_edge_box) {
- if (x2 - 1 == left_box.x1) {
- intersected =
- (priv->right_x2_map & left_priv->
- left_x1_map);
- if (intersected) {
-#ifdef GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
- /* tolerate with two pixels overlap. */
- intersected &= ~(1 << __fls(intersected));
- if ((intersected & (intersected - 1)))
-#endif
- goto real_intersected;
- }
- }
- else if (x2 - 1 == right_box.x2) {
- if ((priv->right_x1_map & left_priv->
- left_x1_map)
- || (priv->right_x2_map & left_priv->
- left_x2_map))
- goto real_intersected;
- }
- }
- else {
- if (x1 < extents->x2 && x1 + 2 > extents->x1)
- goto real_intersected;
- }
- goto non_intersected;
- }
- else {
- real_intersected:
- DEBUGF("overlap with previous glyph.\n");
- if (in_non_intersected_list == 1) {
- if (fixed_cnt >= fixed_size) {
- need_free_fixed_list = TRUE;
- goto done;
- }
- if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
- glyphs - 1,
- &head_glyphs,
- cur_list,
- cur_list->len - (n + 1),
- x, y, x1, y1, x2, y2,
- &head_list, &head_pos,
- &head_x, &head_y,
- &fixed_cnt,
- NON_INTERSECTED,
- &prev_extents)) {
- need_free_fixed_list = TRUE;
- goto done;
- }
- }
-
- in_non_intersected_list = 0;
-
- }
- }
- else {
- non_intersected:
- DEBUGF("doesn't overlap with previous glyph.\n");
- if (in_non_intersected_list == 0) {
- if (fixed_cnt >= fixed_size) {
- need_free_fixed_list = TRUE;
- goto done;
- }
- if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
- glyphs - 1,
- &head_glyphs,
- cur_list,
- cur_list->len - (n + 1), x, y,
- x1, y1, x2, y2,
- &head_list,
- &head_pos,
- &head_x,
- &head_y, &fixed_cnt,
- INTERSECTED, &prev_extents)) {
- need_free_fixed_list = TRUE;
- goto done;
- }
- }
- in_non_intersected_list = 1;
- }
- prev_extents = *extents;
- }
-
- if (check_fake_overlap && priv
- && priv->has_edge_map && glyph->info.yOff == 0) {
- if (!has_left_edge_box || x1 < extents->x1) {
- left_box.x1 = x1;
- left_box.x2 = x1 + 1;
- left_box.y1 = y1;
- has_left_edge_box = TRUE;
- left_priv = priv;
- }
-
- if (!has_right_edge_box || x2 > extents->x2) {
- right_box.x1 = x2 - 2;
- right_box.x2 = x2 - 1;
- right_box.y1 = y1;
- has_right_edge_box = TRUE;
- right_priv = priv;
- }
- }
-
- if (x1 < extents->x1)
- extents->x1 = x1;
- if (x2 > extents->x2)
- extents->x2 = x2;
-
- if (y1 < extents->y1)
- extents->y1 = y1;
- if (y2 > extents->y2)
- extents->y2 = y2;
-
- x += glyph->info.xOff;
- y += glyph->info.yOff;
- }
- first_list = FALSE;
- }
-
- if (in_non_intersected_list == 0 && fixed_cnt == 0) {
- fixed_cnt = -1;
- goto done;
- }
-
- if ((in_non_intersected_list != -1 || head_pos != n) && (fixed_cnt > 0)) {
- if (fixed_cnt >= fixed_size) {
- need_free_fixed_list = TRUE;
- goto done;
- }
- if (!glyph_new_fixed_list(&fixed_list[fixed_cnt],
- glyphs - 1,
- &head_glyphs,
- cur_list,
- cur_list->len - (n + 1), x, y,
- x1, y1, x2, y2,
- &head_list,
- &head_pos,
- &head_x,
- &head_y, &fixed_cnt,
- (!in_non_intersected_list) | 0x80,
- &prev_extents)) {
- need_free_fixed_list = TRUE;
- goto done;
- }
- }
-
- done:
- if (need_free_list_region)
- pixman_region_fini(&list_region);
- pixman_region_fini(&current_region);
-
- if (need_free_fixed_list && fixed_cnt >= 0) {
- while (fixed_cnt--) {
- free(fixed_list[fixed_cnt].list);
- }
- }
-
- DEBUGF("Got %d fixed list \n", fixed_cnt);
- return fixed_cnt;
-}
-
-static inline unsigned int
-glamor_glyph_size_to_count(int size)
-{
- size /= GLYPH_MIN_SIZE;
- return size * size;
-}
-
-static inline unsigned int
-glamor_glyph_count_to_mask(int count)
-{
- return ~(count - 1);
-}
-
-static inline unsigned int
-glamor_glyph_size_to_mask(int size)
-{
- return glamor_glyph_count_to_mask(glamor_glyph_size_to_count(size));
-}
-
-static PicturePtr
-glamor_glyph_cache(glamor_screen_private *glamor, GlyphPtr glyph, int *out_x,
- int *out_y)
-{
- ScreenPtr screen = glamor->screen;
- PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum];
- glamor_glyph_cache_t *cache =
- &glamor->glyphCaches[PICT_FORMAT_RGB(glyph_picture->format) != 0];
- struct glamor_glyph *priv = NULL, *evicted_priv = NULL;
- int size, mask, pos, s;
-
- if (glyph->info.width > GLYPH_MAX_SIZE
- || glyph->info.height > GLYPH_MAX_SIZE)
- return NULL;
-
- for (size = GLYPH_MIN_SIZE; size <= GLYPH_MAX_SIZE; size *= 2)
- if (glyph->info.width <= size && glyph->info.height <= size)
- break;
-
- s = glamor_glyph_size_to_count(size);
- mask = glamor_glyph_count_to_mask(s);
- pos = (cache->count + s - 1) & mask;
-
- priv = glamor_glyph_get_private(screen, glyph);
- if (pos < GLYPH_CACHE_SIZE) {
- cache->count = pos + s;
- }
- else {
- for (s = size; s <= GLYPH_MAX_SIZE; s *= 2) {
- int i = cache->evict & glamor_glyph_size_to_mask(s);
- GlyphPtr evicted = cache->glyphs[i];
-
- if (evicted == NULL)
- continue;
-
- evicted_priv = glamor_glyph_get_private(screen, evicted);
- assert(evicted_priv->pos == i);
- if (evicted_priv->size >= s) {
- cache->glyphs[i] = NULL;
- evicted_priv->cached = FALSE;
- pos = cache->evict & glamor_glyph_size_to_mask(size);
- }
- else
- evicted_priv = NULL;
- break;
- }
- if (evicted_priv == NULL) {
- int count = glamor_glyph_size_to_count(size);
-
- mask = glamor_glyph_count_to_mask(count);
- pos = cache->evict & mask;
- for (s = 0; s < count; s++) {
- GlyphPtr evicted = cache->glyphs[pos + s];
-
- if (evicted != NULL) {
-
- evicted_priv = glamor_glyph_get_private(screen, evicted);
-
- assert(evicted_priv->pos == pos + s);
- evicted_priv->cached = FALSE;
- cache->glyphs[pos + s] = NULL;
- }
- }
-
- }
- /* And pick a new eviction position */
- cache->evict = rand() % GLYPH_CACHE_SIZE;
- }
-
- cache->glyphs[pos] = glyph;
-
- priv->cache = cache;
- priv->size = size;
- priv->pos = pos;
- s = pos / ((GLYPH_MAX_SIZE / GLYPH_MIN_SIZE) *
- (GLYPH_MAX_SIZE / GLYPH_MIN_SIZE));
- priv->x = s % (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE) * GLYPH_MAX_SIZE;
- priv->y = (s / (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE)) * GLYPH_MAX_SIZE;
- for (s = GLYPH_MIN_SIZE; s < GLYPH_MAX_SIZE; s *= 2) {
- if (pos & 1)
- priv->x += s;
- if (pos & 2)
- priv->y += s;
- pos >>= 2;
- }
-
- glamor_glyph_cache_upload_glyph(screen, cache, glyph, priv->x, priv->y);
-#ifndef GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
- if (priv->has_edge_map == FALSE && glyph->info.width >= 2)
- glamor_glyph_priv_get_edge_map(glyph, priv, glyph_picture);
-#endif
- priv->cached = TRUE;
-
- *out_x = priv->x;
- *out_y = priv->y;
- return cache->picture;
-}
-
-typedef void (*glyphs_flush_func) (void *arg);
-struct glyphs_flush_dst_arg {
- CARD8 op;
- PicturePtr src;
- PicturePtr dst;
- glamor_glyph_buffer_t *buffer;
- int x_src, y_src;
- int x_dst, y_dst;
-};
-
-static struct glyphs_flush_dst_arg dst_arg;
-static struct glyphs_flush_mask_arg mask_arg;
-static glamor_glyph_buffer_t dst_buffer;
-static glamor_glyph_buffer_t mask_buffer;
-unsigned long long mask_glyphs_cnt = 0;
-unsigned long long dst_glyphs_cnt = 0;
-
-#define GLYPHS_DST_MODE_VIA_MASK 0
-#define GLYPHS_DST_MODE_VIA_MASK_CACHE 1
-#define GLYPHS_DST_MODE_TO_DST 2
-#define GLYPHS_DST_MODE_MASK_TO_DST 3
-
-struct glyphs_flush_mask_arg {
- PicturePtr mask;
- glamor_glyph_buffer_t *buffer;
- glamor_glyph_mask_cache_t *maskcache;
- unsigned int used_bitmap;
-};
-
-static void
-glamor_glyphs_flush_mask(struct glyphs_flush_mask_arg *arg)
-{
- if (arg->buffer->count > 0) {
-#ifdef RENDER
- glamor_composite_glyph_rects(PictOpAdd, arg->buffer->source,
- NULL, arg->mask,
- arg->buffer->count, arg->buffer->rects);
-#endif
- }
- arg->buffer->count = 0;
- arg->buffer->source = NULL;
-
-}
-
-static void
-glamor_glyphs_flush_dst(struct glyphs_flush_dst_arg *arg)
-{
- if (!arg->buffer)
- return;
-
- if (mask_buffer.count > 0) {
- glamor_glyphs_flush_mask(&mask_arg);
- }
- if (mask_arg.used_bitmap) {
- put_mask_cache_bitmap(mask_arg.maskcache, mask_arg.used_bitmap);
- mask_arg.used_bitmap = 0;
- }
-
- if (arg->buffer->count > 0) {
- glamor_composite_glyph_rects(arg->op, arg->src,
- arg->buffer->source, arg->dst,
- arg->buffer->count,
- &arg->buffer->rects[0]);
- arg->buffer->count = 0;
- arg->buffer->source = NULL;
- }
-}
-
-static glamor_glyph_cache_result_t
-glamor_buffer_glyph(glamor_screen_private *glamor_priv,
- glamor_glyph_buffer_t *buffer,
- PictFormatShort format,
- GlyphPtr glyph, struct glamor_glyph *priv,
- int x_glyph, int y_glyph,
- int dx, int dy, int w, int h,
- int glyphs_dst_mode,
- glyphs_flush_func glyphs_flush, void *flush_arg)
-{
- ScreenPtr screen = glamor_priv->screen;
- glamor_composite_rect_t *rect;
- PicturePtr source;
- int x, y;
- glamor_glyph_cache_t *cache;
-
- if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST)
- priv = glamor_glyph_get_private(screen, glyph);
-
- if (PICT_FORMAT_BPP(format) == 1)
- format = PICT_a8;
-
- cache = &glamor_priv->glyphCaches[PICT_FORMAT_RGB(format) != 0];
-
- if (buffer->source && buffer->source != cache->picture && glyphs_flush) {
- (*glyphs_flush) (flush_arg);
- glyphs_flush = NULL;
- }
-
- if (buffer->count == GLYPH_BUFFER_SIZE && glyphs_flush) {
- (*glyphs_flush) (flush_arg);
- glyphs_flush = NULL;
- }
-
- if (priv && priv->cached) {
- rect = &buffer->rects[buffer->count++];
- rect->x_src = priv->x + dx;
- rect->y_src = priv->y + dy;
- if (buffer->source == NULL)
- buffer->source = priv->cache->picture;
- if (glyphs_dst_mode <= GLYPHS_DST_MODE_VIA_MASK_CACHE)
- assert(priv->cache->glyphs[priv->pos] == glyph);
- }
- else {
- assert(glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST);
- if (glyphs_flush)
- (*glyphs_flush) (flush_arg);
- source = glamor_glyph_cache(glamor_priv, glyph, &x, &y);
-
- if (source != NULL) {
- rect = &buffer->rects[buffer->count++];
- rect->x_src = x + dx;
- rect->y_src = y + dy;
- if (buffer->source == NULL)
- buffer->source = source;
- if (glyphs_dst_mode == GLYPHS_DST_MODE_VIA_MASK_CACHE) {
- /* mode 1 means we are using global mask cache,
- * thus we have to composite from the cache picture
- * to the cache picture, we need a flush here to make
- * sure latter we get the corret glyphs data.*/
- glamor_make_current(glamor_priv);
- glFlush();
- }
- }
- else {
- /* Couldn't find the glyph in the cache, use the glyph picture directly */
- source = GlyphPicture(glyph)[screen->myNum];
- if (buffer->source && buffer->source != source && glyphs_flush)
- (*glyphs_flush) (flush_arg);
- buffer->source = source;
-
- rect = &buffer->rects[buffer->count++];
- rect->x_src = 0 + dx;
- rect->y_src = 0 + dy;
- }
- priv = glamor_glyph_get_private(screen, glyph);
- }
-
- rect->x_dst = x_glyph;
- rect->y_dst = y_glyph;
- if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST) {
- rect->x_dst -= glyph->info.x;
- rect->y_dst -= glyph->info.y;
- }
- rect->width = w;
- rect->height = h;
- if (glyphs_dst_mode > GLYPHS_DST_MODE_VIA_MASK_CACHE) {
- rect->x_mask = rect->x_src;
- rect->y_mask = rect->y_src;
- rect->x_src = dst_arg.x_src + rect->x_dst - dst_arg.x_dst;
- rect->y_src = dst_arg.y_src + rect->y_dst - dst_arg.y_dst;
- }
-
- return GLAMOR_GLYPH_SUCCESS;
-}
-
-static void
-glamor_buffer_glyph_clip(glamor_screen_private *glamor_priv,
- BoxPtr rects,
- int nrect, PictFormatShort format,
- GlyphPtr glyph, struct glamor_glyph *priv,
- int glyph_x, int glyph_y,
- int glyph_dx, int glyph_dy,
- int width, int height,
- int glyphs_mode,
- glyphs_flush_func flush_func, void *arg)
-{
- int i;
-
- for (i = 0; i < nrect; i++) {
- int dst_x, dst_y;
- int dx, dy;
- int x2, y2;
-
- dst_x = glyph_x - glyph_dx;
- dst_y = glyph_y - glyph_dy;
- x2 = dst_x + width;
- y2 = dst_y + height;
- dx = dy = 0;
- if (rects[i].y1 >= y2)
- break;
-
- if (dst_x < rects[i].x1)
- dx = rects[i].x1 - dst_x, dst_x = rects[i].x1;
- if (x2 > rects[i].x2)
- x2 = rects[i].x2;
- if (dst_y < rects[i].y1)
- dy = rects[i].y1 - dst_y, dst_y = rects[i].y1;
- if (y2 > rects[i].y2)
- y2 = rects[i].y2;
- if (dst_x < x2 && dst_y < y2) {
-
- glamor_buffer_glyph(glamor_priv,
- &dst_buffer,
- format,
- glyph, priv,
- dst_x + glyph_dx,
- dst_y + glyph_dy,
- dx, dy,
- x2 - dst_x, y2 - dst_y,
- glyphs_mode, flush_func, arg);
- }
- }
-}
-
-static void
-glamor_glyphs_via_mask(CARD8 op,
- PicturePtr src,
- PicturePtr dst,
- PictFormatPtr mask_format,
- INT16 x_src,
- INT16 y_src,
- int nlist, GlyphListPtr list, GlyphPtr *glyphs,
- Bool use_mask_cache)
-{
- PixmapPtr mask_pixmap = 0;
- PicturePtr mask;
- ScreenPtr screen = dst->pDrawable->pScreen;
- int width = 0, height = 0;
- int x, y;
- int x_dst = list->xOff, y_dst = list->yOff;
- int n;
- GlyphPtr glyph;
- int error;
- BoxRec extents = { 0, 0, 0, 0 };
- XID component_alpha;
- glamor_screen_private *glamor_priv;
- int need_free_mask = FALSE;
- glamor_glyph_buffer_t buffer;
- struct glyphs_flush_mask_arg arg;
- glamor_glyph_buffer_t *pmask_buffer;
- struct glyphs_flush_mask_arg *pmask_arg;
- struct glamor_glyph_mask_cache_entry *mce = NULL;
- glamor_glyph_mask_cache_t *maskcache;
- glamor_glyph_cache_t *cache;
- int glyphs_dst_mode;
-
- glamor_glyph_extents(nlist, list, glyphs, &extents);
-
- if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
- return;
- glamor_priv = glamor_get_screen_private(screen);
- width = extents.x2 - extents.x1;
- height = extents.y2 - extents.y1;
-
- if (mask_format->depth == 1) {
- PictFormatPtr a8Format = PictureMatchFormat(screen, 8, PICT_a8);
-
- if (a8Format)
- mask_format = a8Format;
- }
-
- cache = &glamor_priv->glyphCaches
- [PICT_FORMAT_RGB(mask_format->format) != 0];
- maskcache = glamor_priv->mask_cache[PICT_FORMAT_RGB(mask_format->format) != 0];
-
- x = -extents.x1;
- y = -extents.y1;
- if (!use_mask_cache || width > (CACHE_PICTURE_SIZE / 4)
- || height > MASK_CACHE_MAX_SIZE) {
- new_mask_pixmap:
- mask_pixmap = glamor_create_pixmap(screen, width, height,
- mask_format->depth,
- CREATE_PIXMAP_USAGE_SCRATCH);
- if (!mask_pixmap) {
- glamor_destroy_pixmap(mask_pixmap);
- return;
- }
- glamor_solid(mask_pixmap, 0, 0, width, height, 0);
- component_alpha = NeedsComponent(mask_format->format);
- mask = CreatePicture(0, &mask_pixmap->drawable,
- mask_format, CPComponentAlpha,
- &component_alpha, serverClient, &error);
- if (!mask)
- return;
- need_free_mask = TRUE;
- pmask_arg = &arg;
- pmask_buffer = &buffer;
- pmask_buffer->count = 0;
- pmask_buffer->source = NULL;
- pmask_arg->used_bitmap = 0;
- glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK;
- }
- else {
- int retry_cnt = 0;
-
- retry:
- mce = get_mask_cache(maskcache,
- (width + MASK_CACHE_MAX_SIZE -
- 1) / MASK_CACHE_MAX_SIZE);
-
- if (mce == NULL) {
- glamor_glyphs_flush_dst(&dst_arg);
- retry_cnt++;
- if (retry_cnt > 2) {
- assert(0);
- goto new_mask_pixmap;
- }
- goto retry;
- }
-
- mask = cache->picture;
- x += mce->x;
- y += mce->y;
- mce->width = (width + MASK_CACHE_MAX_SIZE - 1) / MASK_CACHE_MAX_SIZE;
- mce->height = 1;
- if (mask_arg.mask && mask_arg.mask != mask && mask_buffer.count != 0)
- glamor_glyphs_flush_dst(&dst_arg);
- pmask_arg = &mask_arg;
- pmask_buffer = &mask_buffer;
- pmask_arg->maskcache = maskcache;
- glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK_CACHE;
- }
- pmask_arg->mask = mask;
- pmask_arg->buffer = pmask_buffer;
- while (nlist--) {
- x += list->xOff;
- y += list->yOff;
- n = list->len;
- mask_glyphs_cnt += n;
- while (n--) {
- glyph = *glyphs++;
- if (glyph->info.width > 0 && glyph->info.height > 0) {
- glyphs_flush_func flush_func;
- void *temp_arg;
-
- if (need_free_mask) {
- if (pmask_buffer->count)
- flush_func =
- (glyphs_flush_func) glamor_glyphs_flush_mask;
- else
- flush_func = NULL;
- temp_arg = pmask_arg;
- }
- else {
- /* If we are using global mask cache, then we need to
- * flush dst instead of mask. As some dst depends on the
- * previous mask result. Just flush mask can't get all previous's
- * overlapped glyphs.*/
- if (dst_buffer.count || mask_buffer.count)
- flush_func =
- (glyphs_flush_func) glamor_glyphs_flush_dst;
- else
- flush_func = NULL;
- temp_arg = &dst_arg;
- }
- glamor_buffer_glyph(glamor_priv, pmask_buffer,
- mask_format->format,
- glyph, NULL, x, y,
- 0, 0,
- glyph->info.width, glyph->info.height,
- glyphs_dst_mode,
- flush_func, (void *) temp_arg);
- }
- x += glyph->info.xOff;
- y += glyph->info.yOff;
- }
- list++;
- }
-
- x = extents.x1;
- y = extents.y1;
- if (need_free_mask) {
- glamor_glyphs_flush_mask(pmask_arg);
- CompositePicture(op,
- src,
- mask,
- dst,
- x_src + x - x_dst,
- y_src + y - y_dst, 0, 0, x, y, width, height);
- FreePicture(mask, 0);
- glamor_destroy_pixmap(mask_pixmap);
- }
- else {
- struct glamor_glyph priv;
- glyphs_flush_func flush_func;
- BoxPtr rects;
- int nrect;
-
- priv.cache = cache;
- priv.x = mce->x;
- priv.y = mce->y;
- priv.cached = TRUE;
- rects = REGION_RECTS(dst->pCompositeClip);
- nrect = REGION_NUM_RECTS(dst->pCompositeClip);
-
- pmask_arg->used_bitmap |= ((1 << mce->width) - 1) << mce->idx;
- dst_arg.op = op;
- dst_arg.src = src;
- dst_arg.dst = dst;
- dst_arg.buffer = &dst_buffer;
- dst_arg.x_src = x_src;
- dst_arg.y_src = y_src;
- dst_arg.x_dst = x_dst;
- dst_arg.y_dst = y_dst;
-
- if (dst_buffer.source == NULL) {
- dst_buffer.source = cache->picture;
- }
- else if (dst_buffer.source != cache->picture) {
- glamor_glyphs_flush_dst(&dst_arg);
- dst_buffer.source = cache->picture;
- }
-
- x += dst->pDrawable->x;
- y += dst->pDrawable->y;
-
- if (dst_buffer.count || mask_buffer.count)
- flush_func = (glyphs_flush_func) glamor_glyphs_flush_dst;
- else
- flush_func = NULL;
-
- glamor_buffer_glyph_clip(glamor_priv,
- rects, nrect,
- mask_format->format,
- NULL, &priv,
- x, y,
- 0, 0,
- width, height,
- GLYPHS_DST_MODE_MASK_TO_DST,
- flush_func, (void *) &dst_arg);
- }
-}
-
-static void
-glamor_glyphs_to_dst(CARD8 op,
- PicturePtr src,
- PicturePtr dst,
- INT16 x_src,
- INT16 y_src,
- int nlist, GlyphListPtr list, GlyphPtr *glyphs)
-{
- ScreenPtr screen = dst->pDrawable->pScreen;
- int x = 0, y = 0;
- int x_dst = list->xOff, y_dst = list->yOff;
- int n;
- GlyphPtr glyph;
- BoxPtr rects;
- int nrect;
- glamor_screen_private *glamor_priv;
-
- rects = REGION_RECTS(dst->pCompositeClip);
- nrect = REGION_NUM_RECTS(dst->pCompositeClip);
-
- glamor_priv = glamor_get_screen_private(screen);
-
- dst_arg.op = op;
- dst_arg.src = src;
- dst_arg.dst = dst;
- dst_arg.buffer = &dst_buffer;
- dst_arg.x_src = x_src;
- dst_arg.y_src = y_src;
- dst_arg.x_dst = x_dst;
- dst_arg.y_dst = y_dst;
-
- x = dst->pDrawable->x;
- y = dst->pDrawable->y;
-
- while (nlist--) {
- x += list->xOff;
- y += list->yOff;
- n = list->len;
- dst_glyphs_cnt += n;
- while (n--) {
- glyph = *glyphs++;
-
- if (glyph->info.width > 0 && glyph->info.height > 0) {
- glyphs_flush_func flush_func;
-
- if (dst_buffer.count || mask_buffer.count)
- flush_func = (glyphs_flush_func) glamor_glyphs_flush_dst;
- else
- flush_func = NULL;
- glamor_buffer_glyph_clip(glamor_priv,
- rects, nrect,
- (GlyphPicture(glyph)[screen->myNum])->
- format, glyph, NULL, x, y,
- glyph->info.x, glyph->info.y,
- glyph->info.width, glyph->info.height,
- GLYPHS_DST_MODE_TO_DST, flush_func,
- (void *) &dst_arg);
- }
-
- x += glyph->info.xOff;
- y += glyph->info.yOff;
- }
- list++;
- }
-}
-
-#define MAX_FIXED_SIZE
-static void
-glamor_glyphs_reset_buffer(glamor_glyph_buffer_t *buffer)
-{
- buffer->count = 0;
- buffer->source = NULL;
-}
-
-static Bool
-_glamor_glyphs(CARD8 op,
- PicturePtr src,
- PicturePtr dst,
- PictFormatPtr mask_format,
- INT16 x_src,
- INT16 y_src, int nlist, GlyphListPtr list,
- GlyphPtr *glyphs, Bool fallback)
-{
- PictFormatShort format;
- int fixed_size, fixed_cnt = 0;
- struct glamor_glyph_list *fixed_list = NULL;
- Bool need_free_list = FALSE;
-
-#ifndef GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
- Bool check_fake_overlap = TRUE;
-
- if (!(op == PictOpOver || op == PictOpAdd || op == PictOpXor)) {
- /* C = (0,0,0,0) D = glyphs , SRC = A, DEST = B (faked overlapped glyphs, overlapped with (0,0,0,0)).
- * For those op, (A IN (C ADD D)) OP B != (A IN D) OP ((A IN C) OP B)
- * or (A IN (D ADD C)) OP B != (A IN C) OP ((A IN D) OP B)
- * We need to split the faked regions to three or two, and composite the disoverlapped small
- * boxes one by one. For other Ops, it's safe to composite the whole box. */
- check_fake_overlap = FALSE;
- }
-#else
- Bool check_fake_overlap = FALSE;
-#endif
- if (mask_format)
- format = mask_format->depth << 24 | mask_format->format;
- else
- format = 0;
-
- fixed_size = 32;
- glamor_glyphs_reset_buffer(&dst_buffer);
-
- if (!mask_format || (((nlist == 1 && list->len == 1) || op == PictOpAdd)
- && (dst->format ==
- ((mask_format->depth << 24) | mask_format->
- format)))) {
- glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist, list, glyphs);
- goto last_flush;
- }
-
- glamor_glyphs_reset_buffer(&mask_buffer);
-
- /* We have mask_format. Need to check the real overlap or not. */
- format = mask_format->depth << 24 | mask_format->format;
-
- fixed_list = calloc(fixed_size, sizeof(*fixed_list));
- if (_X_UNLIKELY(fixed_list == NULL))
- fixed_size = 0;
- fixed_cnt = glamor_glyphs_intersect(nlist, list, glyphs,
- format, dst->pDrawable->pScreen,
- check_fake_overlap,
- fixed_list, fixed_size);
- if (fixed_cnt == 0)
- mask_format = NULL;
- need_free_list = TRUE;
-
- if (fixed_cnt <= 0) {
- if (mask_format == NULL) {
- glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist,
- list, glyphs);
- goto last_flush;
- }
- else {
- glamor_glyphs_via_mask(op, src, dst, mask_format,
- x_src, y_src, nlist, list, glyphs, FALSE);
- goto free_fixed_list;
- }
- }
- else {
-
- /* We have splitted the original list to serval list, some are overlapped
- * and some are non-overlapped. For the non-overlapped, we render it to
- * dst directly. For the overlapped, we render it to mask picture firstly,
- * then render the mask to dst. If we can use mask cache which is in the
- * glyphs cache's last row, we can accumulate the rendering of mask to dst
- * with the other dst_buffer's rendering operations thus can reduce the call
- * of glDrawElements.
- *
- * */
- struct glamor_glyph_list *saved_list;
-
- saved_list = fixed_list;
- mask_arg.used_bitmap = 0;
- while (fixed_cnt--) {
- if (fixed_list->type == NON_INTERSECTED) {
- glamor_glyphs_to_dst(op, src, dst,
- x_src, y_src,
- fixed_list->nlist,
- fixed_list->list, fixed_list->glyphs);
- }
- else
- glamor_glyphs_via_mask(op, src, dst,
- mask_format, x_src, y_src,
- fixed_list->nlist,
- fixed_list->list,
- fixed_list->glyphs, TRUE);
-
- free(fixed_list->list);
- fixed_list++;
- }
- free(saved_list);
- need_free_list = FALSE;
- }
-
- last_flush:
- if (dst_buffer.count || mask_buffer.count)
- glamor_glyphs_flush_dst(&dst_arg);
- free_fixed_list:
- if (need_free_list) {
- assert(fixed_cnt <= 0);
- free(fixed_list);
- }
- return TRUE;
-}
-
-void
-glamor_glyphs(CARD8 op,
- PicturePtr src,
- PicturePtr dst,
- PictFormatPtr mask_format,
- INT16 x_src,
- INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr *glyphs)
-{
- _glamor_glyphs(op, src, dst, mask_format, x_src,
- y_src, nlist, list, glyphs, TRUE);
-}
-
-Bool
-glamor_glyphs_nf(CARD8 op,
- PicturePtr src,
- PicturePtr dst,
- PictFormatPtr mask_format,
- INT16 x_src,
- INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr *glyphs)
-{
- return _glamor_glyphs(op, src, dst, mask_format, x_src,
- y_src, nlist, list, glyphs, FALSE);
-}
diff --git a/xserver/glamor/glamor_gradient.c b/xserver/glamor/glamor_gradient.c
index 4ded89dcd..c50542a32 100644
--- a/xserver/glamor/glamor_gradient.c
+++ b/xserver/glamor/glamor_gradient.c
@@ -32,8 +32,6 @@
#include "glamor_priv.h"
-#ifdef RENDER
-
#define LINEAR_SMALL_STOPS (6 + 2)
#define LINEAR_LARGE_STOPS (16 + 2)
@@ -584,27 +582,6 @@ glamor_init_gradient_shader(ScreenPtr screen)
_glamor_create_radial_gradient_program(screen, RADIAL_LARGE_STOPS, 0);
}
-void
-glamor_fini_gradient_shader(ScreenPtr screen)
-{
- glamor_screen_private *glamor_priv;
- int i = 0;
-
- glamor_priv = glamor_get_screen_private(screen);
- glamor_make_current(glamor_priv);
-
- for (i = 0; i < 3; i++) {
- /* Linear Gradient */
- if (glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i])
- glDeleteProgram(glamor_priv->gradient_prog
- [SHADER_GRADIENT_LINEAR][i]);
-
- if (glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i])
- glDeleteProgram(glamor_priv->gradient_prog
- [SHADER_GRADIENT_RADIAL][i]);
- }
-}
-
static void
_glamor_gradient_convert_trans_matrix(PictTransform *from, float to[3][3],
int width, int height, int normalize)
@@ -670,12 +647,12 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
PicturePtr dst_picture,
GLfloat *xscale, GLfloat *yscale,
int x_source, int y_source,
- float vertices[8],
- float tex_vertices[8],
int tex_normalize)
{
glamor_pixmap_private *pixmap_priv;
PixmapPtr pixmap = NULL;
+ GLfloat *v;
+ char *vbo_offset;
pixmap = glamor_get_drawable_pixmap(dst_picture->pDrawable);
pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -684,22 +661,24 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
return 0;
}
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+ glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
- pixmap_priv_get_dest_scale(pixmap_priv, xscale, yscale);
+ pixmap_priv_get_dest_scale(pixmap, pixmap_priv, xscale, yscale);
DEBUGF("xscale = %f, yscale = %f,"
" x_source = %d, y_source = %d, width = %d, height = %d\n",
*xscale, *yscale, x_source, y_source,
dst_picture->pDrawable->width, dst_picture->pDrawable->height);
+ v = glamor_get_vbo_space(screen, 16 * sizeof(GLfloat), &vbo_offset);
+
glamor_set_normalize_vcoords_tri_strip(*xscale, *yscale,
0, 0,
(INT16) (dst_picture->pDrawable->
width),
(INT16) (dst_picture->pDrawable->
height),
- vertices);
+ v);
if (tex_normalize) {
glamor_set_normalize_tcoords_tri_stripe(*xscale, *yscale,
@@ -710,7 +689,7 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
(INT16) (dst_picture->
pDrawable->height +
y_source),
- tex_vertices);
+ &v[8]);
}
else {
glamor_set_tcoords_tri_strip(x_source, y_source,
@@ -718,28 +697,29 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
x_source,
(INT16) (dst_picture->pDrawable->height) +
y_source,
- tex_vertices);
+ &v[8]);
}
DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
"rightbottom: %f X %f, leftbottom : %f X %f\n",
- vertices[0], vertices[1], vertices[2], vertices[3],
- vertices[4], vertices[5], vertices[6], vertices[7]);
+ v[0], v[1], v[2], v[3],
+ v[4], v[5], v[6], v[7]);
DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
"rightbottom: %f X %f, leftbottom : %f X %f\n",
- tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3],
- tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]);
+ v[8], v[9], v[10], v[11],
+ v[12], v[13], v[14], v[15]);
glamor_make_current(glamor_priv);
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
- GL_FALSE, 0, vertices);
+ GL_FALSE, 0, vbo_offset);
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
- GL_FALSE, 0, tex_vertices);
+ GL_FALSE, 0, vbo_offset + 8 * sizeof(GLfloat));
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+ glamor_put_vbo_space(screen);
return 1;
}
@@ -835,13 +815,11 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
PixmapPtr pixmap = NULL;
GLint gradient_prog = 0;
int error;
- float tex_vertices[8];
int stops_count = 0;
int count = 0;
GLfloat *stop_colors = NULL;
GLfloat *n_stops = NULL;
GLfloat xscale, yscale;
- float vertices[8];
float transform_mat[3][3];
static const float identity_mat[3][3] = { {1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
@@ -992,18 +970,20 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
if (!_glamor_gradient_set_pixmap_destination
(screen, glamor_priv, dst_picture, &xscale, &yscale, x_source, y_source,
- vertices, tex_vertices, 0))
+ 0))
goto GRADIENT_FAIL;
+ glamor_set_alu(screen, GXcopy);
+
/* Set all the stops and colors to shader. */
if (stops_count > RADIAL_SMALL_STOPS) {
- stop_colors = malloc(4 * stops_count * sizeof(float));
+ stop_colors = xallocarray(stops_count, 4 * sizeof(float));
if (stop_colors == NULL) {
ErrorF("Failed to allocate stop_colors memory.\n");
goto GRADIENT_FAIL;
}
- n_stops = malloc(stops_count * sizeof(float));
+ n_stops = xallocarray(stops_count, sizeof(float));
if (n_stops == NULL) {
ErrorF("Failed to allocate n_stops memory.\n");
goto GRADIENT_FAIL;
@@ -1144,7 +1124,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
float pt_distance;
float p1_distance;
GLfloat cos_val;
- float tex_vertices[8];
int stops_count = 0;
GLfloat *stop_colors = NULL;
GLfloat *n_stops = NULL;
@@ -1152,7 +1131,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
float slope;
GLfloat xscale, yscale;
GLfloat pt1[2], pt2[2];
- float vertices[8];
float transform_mat[3][3];
static const float identity_mat[3][3] = { {1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
@@ -1308,9 +1286,11 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
if (!_glamor_gradient_set_pixmap_destination
(screen, glamor_priv, dst_picture, &xscale, &yscale, x_source, y_source,
- vertices, tex_vertices, 1))
+ 1))
goto GRADIENT_FAIL;
+ glamor_set_alu(screen, GXcopy);
+
/* Normalize the PTs. */
glamor_set_normalize_pt(xscale, yscale,
pixman_fixed_to_double(src_picture->pSourcePict->
@@ -1336,13 +1316,13 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
/* Set all the stops and colors to shader. */
if (stops_count > LINEAR_SMALL_STOPS) {
- stop_colors = malloc(4 * stops_count * sizeof(float));
+ stop_colors = xallocarray(stops_count, 4 * sizeof(float));
if (stop_colors == NULL) {
ErrorF("Failed to allocate stop_colors memory.\n");
goto GRADIENT_FAIL;
}
- n_stops = malloc(stops_count * sizeof(float));
+ n_stops = xallocarray(stops_count, sizeof(float));
if (n_stops == NULL) {
ErrorF("Failed to allocate n_stops memory.\n");
goto GRADIENT_FAIL;
@@ -1473,5 +1453,3 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
}
#endif /* End of GLAMOR_GRADIENT_SHADER */
-
-#endif /* End of RENDER */
diff --git a/xserver/glamor/glamor_image.c b/xserver/glamor/glamor_image.c
index 90fda4079..315874995 100644
--- a/xserver/glamor/glamor_image.c
+++ b/xserver/glamor/glamor_image.c
@@ -49,7 +49,7 @@ glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
if (gc->alu != GXcopy)
goto bail;
- if (!glamor_pm_is_solid(&pixmap->drawable, gc->planemask))
+ if (!glamor_pm_is_solid(gc->depth, gc->planemask))
goto bail;
if (format == XYPixmap && drawable->depth == 1 && leftPad == 0)
@@ -102,19 +102,6 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
}
-Bool
-glamor_put_image_nf(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
- int w, int h, int leftPad, int format, char *bits)
-{
- if (glamor_put_image_gl(drawable, gc, depth, x, y, w, h, leftPad, format, bits))
- return TRUE;
- if (glamor_ddx_fallback_check_pixmap(drawable) &&
- glamor_ddx_fallback_check_gc(gc))
- return FALSE;
- glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
- return TRUE;
-}
-
static Bool
glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h,
unsigned int format, unsigned long plane_mask, char *d)
@@ -129,7 +116,7 @@ glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h,
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
goto bail;
- if (format != ZPixmap || !glamor_pm_is_solid(drawable, plane_mask))
+ if (format != ZPixmap || !glamor_pm_is_solid(drawable->depth, plane_mask))
goto bail;
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
@@ -163,17 +150,3 @@ glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
return;
glamor_get_image_bail(drawable, x, y, w, h, format, plane_mask, d);
}
-
-Bool
-glamor_get_image_nf(DrawablePtr drawable, int x, int y, int w, int h,
- unsigned int format, unsigned long plane_mask, char *d)
-{
- if (glamor_get_image_gl(drawable, x, y, w, h, format, plane_mask, d))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable))
- return FALSE;
-
- glamor_get_image_bail(drawable, x, y, w, h, format, plane_mask, d);
- return TRUE;
-}
diff --git a/xserver/glamor/glamor_largepixmap.c b/xserver/glamor/glamor_largepixmap.c
index b9c3b9af1..9a6c95ee9 100644
--- a/xserver/glamor/glamor_largepixmap.c
+++ b/xserver/glamor/glamor_largepixmap.c
@@ -2,10 +2,14 @@
#include "glamor_priv.h"
-static inline glamor_pixmap_private_large_t *
+static void
+glamor_get_transform_extent_from_box(struct pixman_box32 *box,
+ struct pixman_transform *transform);
+
+static inline glamor_pixmap_private *
__glamor_large(glamor_pixmap_private *pixmap_priv) {
- assert(pixmap_priv->type == GLAMOR_TEXTURE_LARGE);
- return &pixmap_priv->large;
+ assert(glamor_pixmap_priv_is_large(pixmap_priv));
+ return pixmap_priv;
}
/**
@@ -150,12 +154,13 @@ __glamor_compute_clipped_regions(int block_w,
*/
glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
+glamor_compute_clipped_regions_ext(PixmapPtr pixmap,
RegionPtr region,
int *n_region,
int inner_block_w, int inner_block_h,
int reverse, int upsidedown)
{
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_pixmap_clipped_regions *clipped_regions, *inner_regions,
*result_regions;
int i, j, x, y, k, inner_n_regions;
@@ -166,7 +171,7 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
DEBUGF("ext called \n");
- if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
+ if (glamor_pixmap_priv_is_small(pixmap_priv)) {
clipped_regions = calloc(1, sizeof(*clipped_regions));
if (clipped_regions == NULL) {
*n_region = 0;
@@ -176,24 +181,22 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
clipped_regions[0].block_idx = 0;
RegionCopy(clipped_regions[0].region, region);
*n_region = 1;
- block_w = pixmap_priv->base.pixmap->drawable.width;
- block_h = pixmap_priv->base.pixmap->drawable.height;
+ block_w = pixmap->drawable.width;
+ block_h = pixmap->drawable.height;
box_array = &small_box;
small_box.x1 = small_box.y1 = 0;
small_box.x2 = block_w;
small_box.y2 = block_h;
}
else {
- glamor_pixmap_private_large_t *priv = __glamor_large(pixmap_priv);
+ glamor_pixmap_private *priv = __glamor_large(pixmap_priv);
clipped_regions = __glamor_compute_clipped_regions(priv->block_w,
priv->block_h,
priv->block_wcnt,
0, 0,
- priv->base.pixmap->
- drawable.width,
- priv->base.pixmap->
- drawable.height,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
region, n_region,
reverse, upsidedown);
@@ -336,7 +339,8 @@ _glamor_largepixmap_reflect_fixup(short *xy1, short *xy2, int wh)
*
*/
static glamor_pixmap_clipped_regions *
-_glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
+_glamor_compute_clipped_regions(PixmapPtr pixmap,
+ glamor_pixmap_private *pixmap_priv,
RegionPtr region, int *n_region,
int repeat_type, int is_transform,
int reverse, int upsidedown)
@@ -352,10 +356,10 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
int right_shift = 0;
int down_shift = 0;
int x_center_shift = 0, y_center_shift = 0;
- glamor_pixmap_private_large_t *priv;
+ glamor_pixmap_private *priv;
DEBUGRegionPrint(region);
- if (pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
+ if (glamor_pixmap_priv_is_small(pixmap_priv)) {
clipped_regions = calloc(1, sizeof(*clipped_regions));
clipped_regions[0].region = RegionCreate(NULL, 1);
clipped_regions[0].block_idx = 0;
@@ -366,8 +370,8 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
priv = __glamor_large(pixmap_priv);
- pixmap_width = priv->base.pixmap->drawable.width;
- pixmap_height = priv->base.pixmap->drawable.height;
+ pixmap_width = pixmap->drawable.width;
+ pixmap_height = pixmap->drawable.height;
if (repeat_type == 0 || repeat_type == RepeatPad) {
RegionPtr saved_region = NULL;
@@ -385,10 +389,8 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
priv->block_h,
priv->block_wcnt,
0, 0,
- priv->base.pixmap->
- drawable.width,
- priv->base.pixmap->
- drawable.height,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
region, n_region,
reverse, upsidedown);
if (saved_region)
@@ -670,24 +672,27 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
}
glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region,
+glamor_compute_clipped_regions(PixmapPtr pixmap,
+ RegionPtr region,
int *n_region, int repeat_type,
int reverse, int upsidedown)
{
- return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type,
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+ return _glamor_compute_clipped_regions(pixmap, priv, region, n_region, repeat_type,
0, reverse, upsidedown);
}
/* XXX overflow still exist. maybe we need to change to use region32.
* by default. Or just use region32 for repeat cases?
**/
-glamor_pixmap_clipped_regions *
-glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
+static glamor_pixmap_clipped_regions *
+glamor_compute_transform_clipped_regions(PixmapPtr pixmap,
struct pixman_transform *transform,
RegionPtr region, int *n_region,
int dx, int dy, int repeat_type,
int reverse, int upsidedown)
{
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
BoxPtr temp_extent;
struct pixman_box32 temp_box;
struct pixman_box16 short_box;
@@ -714,8 +719,8 @@ glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
temp_box.x1 = 0;
if (temp_box.y1 < 0)
temp_box.y1 = 0;
- temp_box.x2 = MIN(temp_box.x2, priv->base.pixmap->drawable.width);
- temp_box.y2 = MIN(temp_box.y2, priv->base.pixmap->drawable.height);
+ temp_box.x2 = MIN(temp_box.x2, pixmap->drawable.width);
+ temp_box.y2 = MIN(temp_box.y2, pixmap->drawable.height);
}
/* Now copy back the box32 to a box16 box. */
short_box.x1 = temp_box.x1;
@@ -725,7 +730,8 @@ glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
RegionInitBoxes(temp_region, &short_box, 1);
DEBUGF("copy to temp source region \n");
DEBUGRegionPrint(temp_region);
- ret = _glamor_compute_clipped_regions(priv,
+ ret = _glamor_compute_clipped_regions(pixmap,
+ priv,
temp_region,
n_region,
repeat_type, 1, reverse, upsidedown);
@@ -747,12 +753,12 @@ glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
* if the clipped result cross the region boundary.
*/
static void
-glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
+glamor_merge_clipped_regions(PixmapPtr pixmap,
+ glamor_pixmap_private *pixmap_priv,
int repeat_type,
glamor_pixmap_clipped_regions *clipped_regions,
int *n_regions, int *need_clean_fbo)
{
- BoxPtr temp_extent;
BoxRec temp_box, copy_box;
RegionPtr temp_region;
glamor_pixmap_private *temp_priv;
@@ -760,11 +766,11 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
int overlap;
int i;
int pixmap_width, pixmap_height;
- glamor_pixmap_private_large_t *priv;
+ glamor_pixmap_private *priv;
priv = __glamor_large(pixmap_priv);
- pixmap_width = priv->base.pixmap->drawable.width;
- pixmap_height = priv->base.pixmap->drawable.height;
+ pixmap_width = pixmap->drawable.width;
+ pixmap_height =pixmap->drawable.height;
temp_region = RegionCreate(NULL, 4);
for (i = 0; i < *n_regions; i++) {
@@ -776,18 +782,17 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
RegionValidate(temp_region, &overlap);
DEBUGF("temp region: \n");
DEBUGRegionPrint(temp_region);
- temp_extent = RegionExtents(temp_region);
- temp_box = *temp_extent;
+ temp_box = *RegionExtents(temp_region);
DEBUGF("need copy region: \n");
DEBUGF("%d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2,
temp_box.y2);
temp_pixmap =
- glamor_create_pixmap(priv->base.pixmap->drawable.pScreen,
+ glamor_create_pixmap(pixmap->drawable.pScreen,
temp_box.x2 - temp_box.x1,
temp_box.y2 - temp_box.y1,
- priv->base.pixmap->drawable.depth,
+ pixmap->drawable.depth,
GLAMOR_CREATE_PIXMAP_FIXUP);
if (temp_pixmap == NULL) {
assert(0);
@@ -795,20 +800,20 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
}
temp_priv = glamor_get_pixmap_private(temp_pixmap);
- assert(temp_priv->type != GLAMOR_TEXTURE_LARGE);
+ assert(glamor_pixmap_priv_is_small(temp_priv));
priv->box = temp_box;
- if (temp_extent->x1 >= 0 && temp_extent->x2 <= pixmap_width
- && temp_extent->y1 >= 0 && temp_extent->y2 <= pixmap_height) {
+ if (temp_box.x1 >= 0 && temp_box.x2 <= pixmap_width
+ && temp_box.y1 >= 0 && temp_box.y2 <= pixmap_height) {
int dx, dy;
copy_box.x1 = 0;
copy_box.y1 = 0;
- copy_box.x2 = temp_extent->x2 - temp_extent->x1;
- copy_box.y2 = temp_extent->y2 - temp_extent->y1;
- dx = temp_extent->x1;
- dy = temp_extent->y1;
- glamor_copy(&priv->base.pixmap->drawable,
+ copy_box.x2 = temp_box.x2 - temp_box.x1;
+ copy_box.y2 = temp_box.y2 - temp_box.y1;
+ dx = temp_box.x1;
+ dy = temp_box.y1;
+ glamor_copy(&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,
@@ -840,7 +845,7 @@ 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(&priv->base.pixmap->drawable,
+ glamor_copy(&pixmap->drawable,
&temp_pixmap->drawable,
NULL, &copy_box, 1, dx, dy, 0, 0, 0, NULL);
@@ -855,7 +860,7 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
RegionDestroy(clipped_regions[i].region);
RegionDestroy(temp_region);
priv->box = temp_box;
- priv->base.fbo = glamor_pixmap_detach_fbo(temp_priv);
+ priv->fbo = glamor_pixmap_detach_fbo(temp_priv);
DEBUGF("priv box x1 %d y1 %d x2 %d y2 %d \n",
priv->box.x1, priv->box.y1, priv->box.x2, priv->box.y2);
glamor_destroy_pixmap(temp_pixmap);
@@ -875,7 +880,7 @@ glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv,
* boundary and can avoid some overhead.
*
**/
-Bool
+static Bool
glamor_get_transform_block_size(struct pixman_transform *transform,
int block_w, int block_h,
int *transformed_block_w,
@@ -920,11 +925,11 @@ glamor_get_transform_block_size(struct pixman_transform *transform,
return TRUE;
}
-#define VECTOR_FROM_POINT(p, x, y) \
+#define VECTOR_FROM_POINT(p, x, y) do {\
p.v[0] = x; \
p.v[1] = y; \
- p.v[2] = 1.0;
-void
+ p.v[2] = 1.0; } while (0)
+static void
glamor_get_transform_extent_from_box(struct pixman_box32 *box,
struct pixman_transform *transform)
{
@@ -933,12 +938,12 @@ glamor_get_transform_extent_from_box(struct pixman_box32 *box,
struct pixman_f_transform ftransform;
- VECTOR_FROM_POINT(p0, box->x1, box->y1)
- VECTOR_FROM_POINT(p1, box->x2, box->y1)
- VECTOR_FROM_POINT(p2, box->x2, box->y2)
- VECTOR_FROM_POINT(p3, box->x1, box->y2)
+ VECTOR_FROM_POINT(p0, box->x1, box->y1);
+ VECTOR_FROM_POINT(p1, box->x2, box->y1);
+ VECTOR_FROM_POINT(p2, box->x2, box->y2);
+ VECTOR_FROM_POINT(p3, box->x1, box->y2);
- pixman_f_transform_from_pixman_transform(&ftransform, transform);
+ pixman_f_transform_from_pixman_transform(&ftransform, transform);
pixman_f_transform_point(&ftransform, &p0);
pixman_f_transform_point(&ftransform, &p1);
pixman_f_transform_point(&ftransform, &p2);
@@ -966,7 +971,8 @@ glamor_get_transform_extent_from_box(struct pixman_box32 *box,
}
static void
-_glamor_process_transformed_clipped_region(glamor_pixmap_private *priv,
+_glamor_process_transformed_clipped_region(PixmapPtr pixmap,
+ glamor_pixmap_private *priv,
int repeat_type,
glamor_pixmap_clipped_regions *
clipped_regions, int *n_regions,
@@ -976,7 +982,7 @@ _glamor_process_transformed_clipped_region(glamor_pixmap_private *priv,
if (*n_regions != 1) {
/* Merge all source regions into one region. */
- glamor_merge_clipped_regions(priv, repeat_type,
+ glamor_merge_clipped_regions(pixmap, priv, repeat_type,
clipped_regions, n_regions,
need_clean_fbo);
}
@@ -990,22 +996,22 @@ _glamor_process_transformed_clipped_region(glamor_pixmap_private *priv,
int rem;
temp_box = RegionExtents(clipped_regions[0].region);
- modulus(temp_box->x1, priv->base.pixmap->drawable.width, rem);
- shift_x = (temp_box->x1 - rem) / priv->base.pixmap->drawable.width;
- modulus(temp_box->y1, priv->base.pixmap->drawable.height, rem);
- shift_y = (temp_box->y1 - rem) / priv->base.pixmap->drawable.height;
+ modulus(temp_box->x1, pixmap->drawable.width, rem);
+ shift_x = (temp_box->x1 - rem) / pixmap->drawable.width;
+ modulus(temp_box->y1, pixmap->drawable.height, rem);
+ shift_y = (temp_box->y1 - rem) / pixmap->drawable.height;
if (shift_x != 0) {
__glamor_large(priv)->box.x1 +=
- shift_x * priv->base.pixmap->drawable.width;
+ shift_x * pixmap->drawable.width;
__glamor_large(priv)->box.x2 +=
- shift_x * priv->base.pixmap->drawable.width;
+ shift_x * pixmap->drawable.width;
}
if (shift_y != 0) {
__glamor_large(priv)->box.y1 +=
- shift_y * priv->base.pixmap->drawable.height;
+ shift_y * pixmap->drawable.height;
__glamor_large(priv)->box.y2 +=
- shift_y * priv->base.pixmap->drawable.height;
+ shift_y * pixmap->drawable.height;
}
}
}
@@ -1016,9 +1022,9 @@ glamor_composite_largepixmap_region(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
- glamor_pixmap_private *source_pixmap_priv,
- glamor_pixmap_private *mask_pixmap_priv,
- glamor_pixmap_private *dest_pixmap_priv,
+ PixmapPtr source_pixmap,
+ PixmapPtr mask_pixmap,
+ PixmapPtr dest_pixmap,
RegionPtr region, Bool force_clip,
INT16 x_source,
INT16 y_source,
@@ -1027,6 +1033,11 @@ glamor_composite_largepixmap_region(CARD8 op,
INT16 x_dest, INT16 y_dest,
CARD16 width, CARD16 height)
{
+ ScreenPtr screen = dest_pixmap->drawable.pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ glamor_pixmap_private *source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+ glamor_pixmap_private *mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+ glamor_pixmap_private *dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
glamor_pixmap_clipped_regions *clipped_dest_regions;
glamor_pixmap_clipped_regions *clipped_source_regions;
glamor_pixmap_clipped_regions *clipped_mask_regions;
@@ -1046,11 +1057,11 @@ glamor_composite_largepixmap_region(CARD8 op,
int source_repeat_type = 0, mask_repeat_type = 0;
int ok = TRUE;
- if (source_pixmap_priv == dest_pixmap_priv) {
+ if (source_pixmap == dest_pixmap) {
glamor_fallback("source and dest pixmaps are the same\n");
return FALSE;
}
- if (mask_pixmap_priv == dest_pixmap_priv) {
+ if (mask_pixmap == dest_pixmap) {
glamor_fallback("mask and dest pixmaps are the same\n");
return FALSE;
}
@@ -1065,12 +1076,12 @@ glamor_composite_largepixmap_region(CARD8 op,
else
mask_repeat_type = RepeatNone;
- if (dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ if (glamor_pixmap_priv_is_large(dest_pixmap_priv)) {
dest_block_width = __glamor_large(dest_pixmap_priv)->block_w;
dest_block_height = __glamor_large(dest_pixmap_priv)->block_h;
} else {
- dest_block_width = dest_pixmap_priv->base.pixmap->drawable.width;
- dest_block_height = dest_pixmap_priv->base.pixmap->drawable.height;
+ dest_block_width = dest_pixmap->drawable.width;
+ dest_block_height = dest_pixmap->drawable.height;
}
fixed_block_width = dest_block_width;
fixed_block_height = dest_block_height;
@@ -1096,7 +1107,7 @@ glamor_composite_largepixmap_region(CARD8 op,
*/
if (source_pixmap_priv
&& source->transform
- && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ && glamor_pixmap_priv_is_large(source_pixmap_priv)) {
int source_transformed_block_width, source_transformed_block_height;
if (!glamor_get_transform_block_size(source->transform,
@@ -1118,7 +1129,7 @@ glamor_composite_largepixmap_region(CARD8 op,
}
if (mask_pixmap_priv
- && mask->transform && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ && mask->transform && glamor_pixmap_priv_is_large(mask_pixmap_priv)) {
int mask_transformed_block_width, mask_transformed_block_height;
if (!glamor_get_transform_block_size(mask->transform,
@@ -1143,12 +1154,12 @@ glamor_composite_largepixmap_region(CARD8 op,
if (force_clip || fixed_block_width < dest_block_width
|| fixed_block_height < dest_block_height)
clipped_dest_regions =
- glamor_compute_clipped_regions_ext(dest_pixmap_priv, region,
+ glamor_compute_clipped_regions_ext(dest_pixmap, region,
&n_dest_regions,
fixed_block_width,
fixed_block_height, 0, 0);
else
- clipped_dest_regions = glamor_compute_clipped_regions(dest_pixmap_priv,
+ clipped_dest_regions = glamor_compute_clipped_regions(dest_pixmap,
region,
&n_dest_regions,
0, 0, 0);
@@ -1156,7 +1167,7 @@ glamor_composite_largepixmap_region(CARD8 op,
if (source_pixmap_priv
&& (source_pixmap_priv == dest_pixmap_priv ||
source_pixmap_priv == mask_pixmap_priv)
- && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ && glamor_pixmap_priv_is_large(source_pixmap_priv)) {
/* XXX self-copy... */
need_free_source_pixmap_priv = source_pixmap_priv;
source_pixmap_priv = malloc(sizeof(*source_pixmap_priv));
@@ -1172,12 +1183,12 @@ glamor_composite_largepixmap_region(CARD8 op,
glamor_set_pixmap_fbo_current(dest_pixmap_priv,
clipped_dest_regions[i].block_idx);
if (source_pixmap_priv &&
- source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ glamor_pixmap_priv_is_large(source_pixmap_priv)) {
if (!source->transform && source_repeat_type != RepeatPad) {
RegionTranslate(clipped_dest_regions[i].region,
x_source - x_dest, y_source - y_dest);
clipped_source_regions =
- glamor_compute_clipped_regions(source_pixmap_priv,
+ glamor_compute_clipped_regions(source_pixmap,
clipped_dest_regions[i].
region, &n_source_regions,
source_repeat_type, 0, 0);
@@ -1185,7 +1196,7 @@ glamor_composite_largepixmap_region(CARD8 op,
}
else {
clipped_source_regions =
- glamor_compute_transform_clipped_regions(source_pixmap_priv,
+ glamor_compute_transform_clipped_regions(source_pixmap,
source->transform,
clipped_dest_regions
[i].region,
@@ -1202,7 +1213,7 @@ glamor_composite_largepixmap_region(CARD8 op,
}
else
_glamor_process_transformed_clipped_region
- (source_pixmap_priv, source_repeat_type,
+ (source_pixmap, source_pixmap_priv, source_repeat_type,
clipped_source_regions, &n_source_regions,
&need_clean_source_fbo);
}
@@ -1213,7 +1224,7 @@ glamor_composite_largepixmap_region(CARD8 op,
clipped_source_regions[j].block_idx);
if (mask_pixmap_priv &&
- mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ glamor_pixmap_priv_is_large(mask_pixmap_priv)) {
if (is_normal_mask_fbo && is_normal_source_fbo) {
/* both mask and source are normal fbo box without transform or repeatpad.
* The region is clipped against source and then we clip it against mask here.*/
@@ -1223,7 +1234,7 @@ glamor_composite_largepixmap_region(CARD8 op,
RegionTranslate(clipped_source_regions[j].region,
-x_source + x_mask, -y_source + y_mask);
clipped_mask_regions =
- glamor_compute_clipped_regions(mask_pixmap_priv,
+ glamor_compute_clipped_regions(mask_pixmap,
clipped_source_regions
[j].region,
&n_mask_regions,
@@ -1239,7 +1250,7 @@ glamor_composite_largepixmap_region(CARD8 op,
RegionTranslate(clipped_dest_regions[i].region,
-x_dest + x_mask, -y_dest + y_mask);
clipped_mask_regions =
- glamor_compute_clipped_regions(mask_pixmap_priv,
+ glamor_compute_clipped_regions(mask_pixmap,
clipped_dest_regions
[i].region,
&n_mask_regions,
@@ -1253,14 +1264,14 @@ glamor_composite_largepixmap_region(CARD8 op,
if (!is_normal_source_fbo)
clipped_mask_regions =
glamor_compute_transform_clipped_regions
- (mask_pixmap_priv, mask->transform,
+ (mask_pixmap, mask->transform,
clipped_dest_regions[i].region,
&n_mask_regions, x_mask - x_dest,
y_mask - y_dest, mask_repeat_type, 0, 0);
else
clipped_mask_regions =
glamor_compute_transform_clipped_regions
- (mask_pixmap_priv, mask->transform,
+ (mask_pixmap, mask->transform,
clipped_source_regions[j].region,
&n_mask_regions, x_mask - x_source,
y_mask - y_source, mask_repeat_type, 0, 0);
@@ -1272,7 +1283,7 @@ glamor_composite_largepixmap_region(CARD8 op,
}
else
_glamor_process_transformed_clipped_region
- (mask_pixmap_priv, mask_repeat_type,
+ (mask_pixmap, mask_pixmap_priv, mask_repeat_type,
clipped_mask_regions, &n_mask_regions,
&need_clean_mask_fbo);
}
@@ -1282,9 +1293,9 @@ glamor_composite_largepixmap_region(CARD8 op,
if (!glamor_composite_clipped_region(op, \
null_source ? NULL : source, \
null_mask ? NULL : mask, dest, \
- null_source ? NULL : source_pixmap_priv, \
- null_mask ? NULL : mask_pixmap_priv, \
- dest_pixmap_priv, region, \
+ null_source ? NULL : source_pixmap, \
+ null_mask ? NULL : mask_pixmap, \
+ dest_pixmap, region, \
x_source, y_source, x_mask, y_mask, \
x_dest, y_dest)) { \
assert(0); \
@@ -1335,8 +1346,8 @@ glamor_composite_largepixmap_region(CARD8 op,
null_mask = 0;
if (need_clean_mask_fbo) {
assert(is_normal_mask_fbo == 0);
- glamor_destroy_fbo(mask_pixmap_priv->base.fbo);
- mask_pixmap_priv->base.fbo = NULL;
+ glamor_destroy_fbo(glamor_priv, mask_pixmap_priv->fbo);
+ mask_pixmap_priv->fbo = NULL;
need_clean_mask_fbo = 0;
}
}
@@ -1364,19 +1375,19 @@ glamor_composite_largepixmap_region(CARD8 op,
null_source = 0;
if (need_clean_source_fbo) {
assert(is_normal_source_fbo == 0);
- glamor_destroy_fbo(source_pixmap_priv->base.fbo);
- source_pixmap_priv->base.fbo = NULL;
+ glamor_destroy_fbo(glamor_priv, source_pixmap_priv->fbo);
+ source_pixmap_priv->fbo = NULL;
need_clean_source_fbo = 0;
}
}
else {
if (mask_pixmap_priv &&
- mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
+ glamor_pixmap_priv_is_large(mask_pixmap_priv)) {
if (!mask->transform && mask_repeat_type != RepeatPad) {
RegionTranslate(clipped_dest_regions[i].region,
x_mask - x_dest, y_mask - y_dest);
clipped_mask_regions =
- glamor_compute_clipped_regions(mask_pixmap_priv,
+ glamor_compute_clipped_regions(mask_pixmap,
clipped_dest_regions[i].
region, &n_mask_regions,
mask_repeat_type, 0, 0);
@@ -1385,7 +1396,7 @@ glamor_composite_largepixmap_region(CARD8 op,
else {
clipped_mask_regions =
glamor_compute_transform_clipped_regions
- (mask_pixmap_priv, mask->transform,
+ (mask_pixmap, mask->transform,
clipped_dest_regions[i].region, &n_mask_regions,
x_mask - x_dest, y_mask - y_dest, mask_repeat_type, 0,
0);
@@ -1397,7 +1408,7 @@ glamor_composite_largepixmap_region(CARD8 op,
}
else
_glamor_process_transformed_clipped_region
- (mask_pixmap_priv, mask_repeat_type,
+ (mask_pixmap, mask_pixmap_priv, mask_repeat_type,
clipped_mask_regions, &n_mask_regions,
&need_clean_mask_fbo);
}
@@ -1426,8 +1437,8 @@ glamor_composite_largepixmap_region(CARD8 op,
if (null_mask)
null_mask = 0;
if (need_clean_mask_fbo) {
- glamor_destroy_fbo(mask_pixmap_priv->base.fbo);
- mask_pixmap_priv->base.fbo = NULL;
+ glamor_destroy_fbo(glamor_priv, mask_pixmap_priv->fbo);
+ mask_pixmap_priv->fbo = NULL;
need_clean_mask_fbo = 0;
}
}
diff --git a/xserver/glamor/glamor_lines.c b/xserver/glamor/glamor_lines.c
index e9a619505..a2c9b1fcc 100644
--- a/xserver/glamor/glamor_lines.c
+++ b/xserver/glamor/glamor_lines.c
@@ -44,7 +44,7 @@ glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc,
int off_x, off_y;
DDXPointPtr v;
char *vbo_offset;
- int box_x, box_y;
+ int box_index;
int add_last;
pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -65,7 +65,7 @@ glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc,
&glamor_facet_poly_lines);
if (!prog)
- goto bail_ctx;
+ goto bail;
/* Set up the vertex buffers for the points */
@@ -99,11 +99,11 @@ glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc,
glEnable(GL_SCISSOR_TEST);
- glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ glamor_pixmap_loop(pixmap_priv, box_index) {
int nbox = RegionNumRects(gc->pCompositeClip);
BoxPtr box = RegionRects(gc->pCompositeClip);
- glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE,
+ glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE,
prog->matrix_uniform, &off_x, &off_y);
while (nbox--) {
@@ -117,12 +117,9 @@ glamor_poly_lines_solid_gl(DrawablePtr drawable, GCPtr gc,
}
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;
}
@@ -167,21 +164,3 @@ glamor_poly_lines(DrawablePtr drawable, GCPtr gc,
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/xserver/glamor/glamor_picture.c b/xserver/glamor/glamor_picture.c
index bc658f801..b069ce56b 100644
--- a/xserver/glamor/glamor_picture.c
+++ b/xserver/glamor/glamor_picture.c
@@ -31,83 +31,904 @@
#include "glamor_priv.h"
#include "mipict.h"
-/* Upload picture to texture. We may need to flip the y axis or
- * wire alpha to 1. So we may conditional create fbo for the picture.
- * */
-enum glamor_pixmap_status
-glamor_upload_picture_to_texture(PicturePtr picture)
+/*
+ * Map picture's format to the correct gl texture format and type.
+ * no_alpha is used to indicate whehter we need to wire alpha to 1.
+ *
+ * Although opengl support A1/GL_BITMAP, we still don't use it
+ * here, it seems that mesa has bugs when uploading a A1 bitmap.
+ *
+ * Return 0 if find a matched texture type. Otherwise return -1.
+ **/
+static int
+glamor_get_tex_format_type_from_pictformat_gl(ScreenPtr pScreen,
+ PictFormatShort format,
+ GLenum *tex_format,
+ GLenum *tex_type,
+ int *no_alpha,
+ int *revert,
+ int *swap_rb, int is_upload)
{
- PixmapPtr pixmap;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
+ *no_alpha = 0;
+ *revert = REVERT_NONE;
+ *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
+ switch (format) {
+ case PICT_a1:
+ *tex_format = glamor_priv->one_channel_format;
+ *tex_type = GL_UNSIGNED_BYTE;
+ *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
+ break;
+ case PICT_b8g8r8x8:
+ *no_alpha = 1;
+ case PICT_b8g8r8a8:
+ *tex_format = GL_BGRA;
+ *tex_type = GL_UNSIGNED_INT_8_8_8_8;
+ break;
- assert(picture->pDrawable);
- pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+ case PICT_x8r8g8b8:
+ *no_alpha = 1;
+ case PICT_a8r8g8b8:
+ *tex_format = GL_BGRA;
+ *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ break;
+ case PICT_x8b8g8r8:
+ *no_alpha = 1;
+ case PICT_a8b8g8r8:
+ *tex_format = GL_RGBA;
+ *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ break;
+ case PICT_x2r10g10b10:
+ *no_alpha = 1;
+ case PICT_a2r10g10b10:
+ *tex_format = GL_BGRA;
+ *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+ break;
+ case PICT_x2b10g10r10:
+ *no_alpha = 1;
+ case PICT_a2b10g10r10:
+ *tex_format = GL_RGBA;
+ *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
+ break;
+
+ case PICT_r5g6b5:
+ *tex_format = GL_RGB;
+ *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+ break;
+ case PICT_b5g6r5:
+ *tex_format = GL_RGB;
+ *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
+ break;
+ case PICT_x1b5g5r5:
+ *no_alpha = 1;
+ case PICT_a1b5g5r5:
+ *tex_format = GL_RGBA;
+ *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+ break;
+
+ case PICT_x1r5g5b5:
+ *no_alpha = 1;
+ case PICT_a1r5g5b5:
+ *tex_format = GL_BGRA;
+ *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+ break;
+ case PICT_a8:
+ *tex_format = glamor_priv->one_channel_format;
+ *tex_type = GL_UNSIGNED_BYTE;
+ break;
+ case PICT_x4r4g4b4:
+ *no_alpha = 1;
+ case PICT_a4r4g4b4:
+ *tex_format = GL_BGRA;
+ *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+ break;
+
+ case PICT_x4b4g4r4:
+ *no_alpha = 1;
+ case PICT_a4b4g4r4:
+ *tex_format = GL_RGBA;
+ *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+ break;
+
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+#define IS_LITTLE_ENDIAN (IMAGE_BYTE_ORDER == LSBFirst)
+
+static int
+glamor_get_tex_format_type_from_pictformat_gles2(ScreenPtr pScreen,
+ PictFormatShort format,
+ GLenum *tex_format,
+ GLenum *tex_type,
+ int *no_alpha,
+ int *revert,
+ int *swap_rb, int is_upload)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
+ int need_swap_rb = 0;
+
+ *no_alpha = 0;
+ *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
+
+ switch (format) {
+ case PICT_b8g8r8x8:
+ *no_alpha = 1;
+ case PICT_b8g8r8a8:
+ *tex_format = GL_RGBA;
+ *tex_type = GL_UNSIGNED_BYTE;
+ need_swap_rb = 1;
+ *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
+ break;
+
+ case PICT_x8r8g8b8:
+ *no_alpha = 1;
+ case PICT_a8r8g8b8:
+ *tex_format = GL_RGBA;
+ *tex_type = GL_UNSIGNED_BYTE;
+ need_swap_rb = 1;
+ break;
+
+ case PICT_x8b8g8r8:
+ *no_alpha = 1;
+ case PICT_a8b8g8r8:
+ *tex_format = GL_RGBA;
+ *tex_type = GL_UNSIGNED_BYTE;
+ break;
+
+ case PICT_x2r10g10b10:
+ *no_alpha = 1;
+ case PICT_a2r10g10b10:
+ *tex_format = GL_RGBA;
+ /* glReadPixmap doesn't support GL_UNSIGNED_INT_10_10_10_2.
+ * we have to use GL_UNSIGNED_BYTE and do the conversion in
+ * shader latter.*/
+ *tex_type = GL_UNSIGNED_BYTE;
+ if (is_upload == 1) {
+ if (!IS_LITTLE_ENDIAN)
+ *revert = REVERT_UPLOADING_10_10_10_2;
+ else
+ *revert = REVERT_UPLOADING_2_10_10_10;
+ }
+ else {
+ if (!IS_LITTLE_ENDIAN) {
+ *revert = REVERT_DOWNLOADING_10_10_10_2;
+ }
+ else {
+ *revert = REVERT_DOWNLOADING_2_10_10_10;
+ }
+ }
+ need_swap_rb = 1;
+
+ break;
+
+ case PICT_x2b10g10r10:
+ *no_alpha = 1;
+ case PICT_a2b10g10r10:
+ *tex_format = GL_RGBA;
+ *tex_type = GL_UNSIGNED_BYTE;
+ if (is_upload == 1) {
+ if (!IS_LITTLE_ENDIAN)
+ *revert = REVERT_UPLOADING_10_10_10_2;
+ else
+ *revert = REVERT_UPLOADING_2_10_10_10;
+ }
+ else {
+ if (!IS_LITTLE_ENDIAN) {
+ *revert = REVERT_DOWNLOADING_10_10_10_2;
+ }
+ else {
+ *revert = REVERT_DOWNLOADING_2_10_10_10;
+ }
+ }
+ break;
+
+ case PICT_r5g6b5:
+ *tex_format = GL_RGB;
+ *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+ *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
+
+ break;
+
+ case PICT_b5g6r5:
+ *tex_format = GL_RGB;
+ *tex_type = GL_UNSIGNED_SHORT_5_6_5;
+ need_swap_rb = IS_LITTLE_ENDIAN ? 1 : 0;
+ break;
+
+ case PICT_x1b5g5r5:
+ *no_alpha = 1;
+ case PICT_a1b5g5r5:
+ *tex_format = GL_RGBA;
+ *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
+ if (IS_LITTLE_ENDIAN) {
+ *revert =
+ is_upload ? REVERT_UPLOADING_1_5_5_5 :
+ REVERT_DOWNLOADING_1_5_5_5;
+ }
+ else
+ *revert = REVERT_NONE;
+ break;
+
+ case PICT_x1r5g5b5:
+ *no_alpha = 1;
+ case PICT_a1r5g5b5:
+ *tex_format = GL_RGBA;
+ *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
+ if (IS_LITTLE_ENDIAN) {
+ *revert =
+ is_upload ? REVERT_UPLOADING_1_5_5_5 :
+ REVERT_DOWNLOADING_1_5_5_5;
+ }
+ else
+ *revert = REVERT_NONE;
+ need_swap_rb = 1;
+ break;
+
+ case PICT_a1:
+ *tex_format = glamor_priv->one_channel_format;
+ *tex_type = GL_UNSIGNED_BYTE;
+ *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
+ break;
+
+ case PICT_a8:
+ *tex_format = glamor_priv->one_channel_format;
+ *tex_type = GL_UNSIGNED_BYTE;
+ *revert = REVERT_NONE;
+ break;
+
+ case PICT_x4r4g4b4:
+ *no_alpha = 1;
+ case PICT_a4r4g4b4:
+ *tex_format = GL_RGBA;
+ *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
+ *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
+ need_swap_rb = 1;
+ break;
+
+ case PICT_x4b4g4r4:
+ *no_alpha = 1;
+ case PICT_a4b4g4r4:
+ *tex_format = GL_RGBA;
+ *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
+ *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
+ break;
+
+ default:
+ LogMessageVerb(X_INFO, 0,
+ "fail to get matched format for %x \n", format);
+ return -1;
+ }
- return glamor_upload_pixmap_to_texture(pixmap);
+ if (need_swap_rb)
+ *swap_rb = is_upload ? SWAP_UPLOADING : SWAP_DOWNLOADING;
+ else
+ *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
+ return 0;
+}
+
+static int
+glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
+ PictFormatShort pict_format,
+ GLenum *format,
+ GLenum *type,
+ int *no_alpha,
+ int *revert, int *swap_rb, int is_upload)
+{
+ glamor_screen_private *glamor_priv =
+ glamor_get_screen_private(pixmap->drawable.pScreen);
+
+ if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+ return glamor_get_tex_format_type_from_pictformat_gl(pixmap->drawable.pScreen,
+ pict_format,
+ format, type,
+ no_alpha,
+ revert,
+ swap_rb,
+ is_upload);
+ } else {
+ return glamor_get_tex_format_type_from_pictformat_gles2(pixmap->drawable.pScreen,
+ pict_format,
+ format, type,
+ no_alpha,
+ revert,
+ swap_rb,
+ is_upload);
+ }
+}
+
+static void *
+_glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h,
+ int stride, int revert)
+{
+ PictFormatShort dst_format, src_format;
+ pixman_image_t *dst_image;
+ pixman_image_t *src_image;
+ int src_stride;
+
+ if (revert == REVERT_UPLOADING_A1) {
+ src_format = PICT_a1;
+ dst_format = PICT_a8;
+ src_stride = PixmapBytePad(w, 1);
+ }
+ else {
+ dst_format = PICT_a1;
+ src_format = PICT_a8;
+ src_stride = (((w * 8 + 7) / 8) + 3) & ~3;
+ }
+
+ dst_image = pixman_image_create_bits(dst_format, w, h, dst_bits, stride);
+ if (dst_image == NULL) {
+ return NULL;
+ }
+
+ src_image = pixman_image_create_bits(src_format,
+ w, h, src_bits, src_stride);
+
+ if (src_image == NULL) {
+ pixman_image_unref(dst_image);
+ return NULL;
+ }
+
+ pixman_image_composite(PictOpSrc, src_image, NULL, dst_image,
+ 0, 0, 0, 0, 0, 0, w, h);
+
+ pixman_image_unref(src_image);
+ pixman_image_unref(dst_image);
+ return dst_bits;
+}
+
+#define ADJUST_BITS(d, src_bits, dst_bits) (((dst_bits) == (src_bits)) ? (d) : \
+ (((dst_bits) > (src_bits)) ? \
+ (((d) << ((dst_bits) - (src_bits))) \
+ + (( 1 << ((dst_bits) - (src_bits))) >> 1)) \
+ : ((d) >> ((src_bits) - (dst_bits)))))
+
+#define GLAMOR_DO_CONVERT(src, dst, no_alpha, swap, \
+ a_shift_src, a_bits_src, \
+ b_shift_src, b_bits_src, \
+ g_shift_src, g_bits_src, \
+ r_shift_src, r_bits_src, \
+ a_shift, a_bits, \
+ b_shift, b_bits, \
+ g_shift, g_bits, \
+ r_shift, r_bits) \
+ do { \
+ typeof(src) a,b,g,r; \
+ typeof(src) a_mask_src, b_mask_src, g_mask_src, r_mask_src;\
+ a_mask_src = (((1 << (a_bits_src)) - 1) << a_shift_src);\
+ b_mask_src = (((1 << (b_bits_src)) - 1) << b_shift_src);\
+ g_mask_src = (((1 << (g_bits_src)) - 1) << g_shift_src);\
+ r_mask_src = (((1 << (r_bits_src)) - 1) << r_shift_src);\
+ if (no_alpha) \
+ a = (a_mask_src) >> (a_shift_src); \
+ else \
+ a = ((src) & (a_mask_src)) >> (a_shift_src); \
+ b = ((src) & (b_mask_src)) >> (b_shift_src); \
+ g = ((src) & (g_mask_src)) >> (g_shift_src); \
+ r = ((src) & (r_mask_src)) >> (r_shift_src); \
+ a = ADJUST_BITS(a, a_bits_src, a_bits); \
+ b = ADJUST_BITS(b, b_bits_src, b_bits); \
+ g = ADJUST_BITS(g, g_bits_src, g_bits); \
+ r = ADJUST_BITS(r, r_bits_src, r_bits); \
+ if (swap == 0) \
+ (*dst) = ((a) << (a_shift)) | ((b) << (b_shift)) | ((g) << (g_shift)) | ((r) << (r_shift)); \
+ else \
+ (*dst) = ((a) << (a_shift)) | ((r) << (b_shift)) | ((g) << (g_shift)) | ((b) << (r_shift)); \
+ } while (0)
+
+static void *
+_glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h,
+ int stride, int no_alpha, int revert,
+ int swap_rb)
+{
+ int x, y;
+ unsigned int *words, *saved_words, *source_words;
+ int swap = !(swap_rb == SWAP_NONE_DOWNLOADING ||
+ swap_rb == SWAP_NONE_UPLOADING);
+
+ source_words = src_bits;
+ words = dst_bits;
+ saved_words = words;
+
+ for (y = 0; y < h; y++) {
+ DEBUGF("Line %d : ", y);
+ for (x = 0; x < w; x++) {
+ unsigned int pixel = source_words[x];
+
+ if (revert == REVERT_DOWNLOADING_2_10_10_10)
+ GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+ 24, 8, 16, 8, 8, 8, 0, 8,
+ 30, 2, 20, 10, 10, 10, 0, 10);
+ else
+ GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+ 30, 2, 20, 10, 10, 10, 0, 10,
+ 24, 8, 16, 8, 8, 8, 0, 8);
+ DEBUGF("%x:%x ", pixel, words[x]);
+ }
+ DEBUGF("\n");
+ words += stride / sizeof(*words);
+ source_words += stride / sizeof(*words);
+ }
+ DEBUGF("\n");
+ return saved_words;
+
+}
+
+static void *
+_glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h,
+ int stride, int no_alpha, int revert, int swap_rb)
+{
+ int x, y;
+ unsigned short *words, *saved_words, *source_words;
+ int swap = !(swap_rb == SWAP_NONE_DOWNLOADING ||
+ swap_rb == SWAP_NONE_UPLOADING);
+
+ words = dst_bits;
+ source_words = src_bits;
+ saved_words = words;
+
+ for (y = 0; y < h; y++) {
+ DEBUGF("Line %d : ", y);
+ for (x = 0; x < w; x++) {
+ unsigned short pixel = source_words[x];
+
+ if (revert == REVERT_DOWNLOADING_1_5_5_5)
+ GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+ 0, 1, 1, 5, 6, 5, 11, 5,
+ 15, 1, 10, 5, 5, 5, 0, 5);
+ else
+ GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
+ 15, 1, 10, 5, 5, 5, 0, 5,
+ 0, 1, 1, 5, 6, 5, 11, 5);
+ DEBUGF("%04x:%04x ", pixel, words[x]);
+ }
+ DEBUGF("\n");
+ words += stride / sizeof(*words);
+ source_words += stride / sizeof(*words);
+ }
+ DEBUGF("\n");
+ return saved_words;
}
/*
- * We should already have drawable attached to it, if it has one.
- * Then set the attached pixmap to is_picture format, and set
- * the pict format.
- * */
-int
-glamor_create_picture(PicturePtr picture)
+ * This function is to convert an unsupported color format to/from a
+ * supported GL format.
+ * Here are the current scenarios:
+ *
+ * @no_alpha:
+ * If it is set, then we need to wire the alpha value to 1.
+ * @revert:
+ REVERT_DOWNLOADING_A1 : convert an Alpha8 buffer to a A1 buffer.
+ REVERT_UPLOADING_A1 : convert an A1 buffer to an Alpha8 buffer
+ REVERT_DOWNLOADING_2_10_10_10 : convert r10G10b10X2 to X2B10G10R10
+ REVERT_UPLOADING_2_10_10_10 : convert X2B10G10R10 to R10G10B10X2
+ REVERT_DOWNLOADING_1_5_5_5 : convert B5G5R5X1 to X1R5G5B5
+ REVERT_UPLOADING_1_5_5_5 : convert X1R5G5B5 to B5G5R5X1
+ @swap_rb: if we have the swap_rb set, then we need to swap the R and B's position.
+ *
+ */
+
+static void *
+glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h,
+ int stride, int no_alpha, int revert, int swap_rb)
{
- PixmapPtr pixmap;
+ if (revert == REVERT_DOWNLOADING_A1 || revert == REVERT_UPLOADING_A1) {
+ return _glamor_color_convert_a1_a8(src_bits, dst_bits, w, h, stride,
+ revert);
+ }
+ else if (revert == REVERT_DOWNLOADING_2_10_10_10 ||
+ revert == REVERT_UPLOADING_2_10_10_10) {
+ return _glamor_color_revert_x2b10g10r10(src_bits, dst_bits, w, h,
+ stride, no_alpha, revert,
+ swap_rb);
+ }
+ else if (revert == REVERT_DOWNLOADING_1_5_5_5 ||
+ revert == REVERT_UPLOADING_1_5_5_5) {
+ return _glamor_color_revert_x1b5g5r5(src_bits, dst_bits, w, h, stride,
+ no_alpha, revert, swap_rb);
+ }
+ else
+ ErrorF("convert a non-supported mode %x.\n", revert);
+
+ return NULL;
+}
+
+/**
+ * Upload pixmap to a specified texture.
+ * This texture may not be the one attached to it.
+ **/
+static Bool
+__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
+ GLenum format,
+ GLenum type,
+ int x, int y, int w, int h,
+ void *bits, int pbo)
+{
+ glamor_screen_private *glamor_priv =
+ glamor_get_screen_private(pixmap->drawable.pScreen);
+ int non_sub = 0;
+ unsigned int iformat = 0;
+
+ glamor_make_current(glamor_priv);
+ if (*tex == 0) {
+ glGenTextures(1, tex);
+ if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+ iformat = gl_iformat_for_pixmap(pixmap);
+ else
+ iformat = format;
+ non_sub = 1;
+ assert(x == 0 && y == 0);
+ }
+
+ glBindTexture(GL_TEXTURE_2D, *tex);
+ 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);
+
+ assert(pbo || bits != 0);
+ if (bits == NULL) {
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
+ glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
+ }
+ glamor_priv->suppress_gl_out_of_memory_logging = true;
+ if (non_sub)
+ glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits);
+ else
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, type, bits);
+ glamor_priv->suppress_gl_out_of_memory_logging = false;
+ if (glGetError() == GL_OUT_OF_MEMORY) {
+ if (non_sub) {
+ glDeleteTextures(1, tex);
+ *tex = 0;
+ }
+ return FALSE;
+ }
+
+ if (bits == NULL)
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+
+ return TRUE;
+}
+
+static Bool
+_glamor_upload_bits_to_pixmap_texture(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)
+{
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+ glamor_screen_private *glamor_priv =
+ glamor_get_screen_private(pixmap->drawable.pScreen);
+ float dst_xscale, dst_yscale;
+ GLuint tex = 0;
+ int need_free_bits = 0;
+
+ if (bits == NULL)
+ goto ready_to_upload;
+
+ if (revert > REVERT_NORMAL) {
+ /* XXX if we are restoring the pixmap, then we may not need to allocate
+ * new buffer */
+ void *converted_bits;
+
+ if (pixmap->drawable.depth == 1)
+ stride = (((w * 8 + 7) / 8) + 3) & ~3;
+
+ converted_bits = xallocarray(h, stride);
+
+ if (converted_bits == NULL)
+ return FALSE;
+ bits = glamor_color_convert_to_bits(bits, converted_bits, w, h,
+ stride, no_alpha, revert, swap_rb);
+ if (bits == NULL) {
+ free(converted_bits);
+ ErrorF("Failed to convert pixmap no_alpha %d,"
+ "revert mode %d, swap mode %d\n", no_alpha, revert, swap_rb);
+ return FALSE;
+ }
+ no_alpha = 0;
+ revert = REVERT_NONE;
+ swap_rb = SWAP_NONE_UPLOADING;
+ need_free_bits = TRUE;
+ }
+
+ ready_to_upload:
+
+ /* 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
+#ifdef WALKAROUND_LARGE_TEXTURE_MAP
+ && glamor_pixmap_priv_is_small(pixmap_priv)
+#endif
+ ) {
+ int fbo_x_off, fbo_y_off;
+
+ assert(pixmap_priv->fbo->tex);
+ pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
+
+ assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0);
+ assert(x + fbo_x_off + w <= pixmap_priv->fbo->width);
+ assert(y + fbo_y_off + h <= pixmap_priv->fbo->height);
+ if (!__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->fbo->tex,
+ format, type,
+ x + fbo_x_off, y + fbo_y_off,
+ w, h,
+ bits, pbo)) {
+ if (need_free_bits)
+ free(bits);
+ return FALSE;
+ }
+ } else {
+ static const float texcoords_inv[8] = { 0, 0,
+ 1, 0,
+ 1, 1,
+ 0, 1
+ };
+ GLfloat *v;
+ char *vbo_offset;
+
+ v = glamor_get_vbo_space(screen, 16 * sizeof(GLfloat), &vbo_offset);
+
+ pixmap_priv_get_dest_scale(pixmap, pixmap_priv, &dst_xscale, &dst_yscale);
+ glamor_set_normalize_vcoords(pixmap_priv, dst_xscale,
+ dst_yscale,
+ x, y,
+ x + w, y + h,
+ v);
+ /* Slow path, we need to flip y or wire alpha to 1. */
+ glamor_make_current(glamor_priv);
+
+ if (!__glamor_upload_pixmap_to_texture(pixmap, &tex,
+ format, type, 0, 0, w, h, bits,
+ pbo)) {
+ if (need_free_bits)
+ free(bits);
+ return FALSE;
+ }
+
+ memcpy(&v[8], texcoords_inv, 8 * sizeof(GLfloat));
+
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
+ GL_FALSE, 2 * sizeof(float), vbo_offset);
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
+ GL_FALSE, 2 * sizeof(float), vbo_offset + 8 * sizeof(GLfloat));
+ glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+ glamor_put_vbo_space(screen);
+ glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
+ glamor_set_alu(screen, GXcopy);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, tex);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+ glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
+ glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+ glDeleteTextures(1, &tex);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+
+ if (need_free_bits)
+ free(bits);
+ return TRUE;
+}
+
+/*
+ * Prepare to upload a pixmap to texture memory.
+ * no_alpha equals 1 means the format needs to wire alpha to 1.
+ */
+static int
+glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
+ int revert, int swap_rb)
+{
+ int flag = 0;
glamor_pixmap_private *pixmap_priv;
+ glamor_screen_private *glamor_priv;
+ glamor_pixmap_fbo *fbo;
+ GLenum iformat;
+
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+ glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
- if (!picture || !picture->pDrawable)
+ if (pixmap_priv->gl_fbo != GLAMOR_FBO_UNATTACHED)
return 0;
- pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
- pixmap_priv = glamor_get_pixmap_private(pixmap);
- if (!pixmap_priv) {
- /* We must create a pixmap priv to track the picture format even
- * if the pixmap is a pure in memory pixmap. The reason is that
- * we may need to upload this pixmap to a texture on the fly. During
- * the uploading, we need to know the picture format. */
- glamor_set_pixmap_type(pixmap, GLAMOR_MEMORY);
- pixmap_priv = glamor_get_pixmap_private(pixmap);
+ if (pixmap_priv->fbo
+ && (pixmap_priv->fbo->width < pixmap->drawable.width
+ || pixmap_priv->fbo->height < pixmap->drawable.height)) {
+ fbo = glamor_pixmap_detach_fbo(pixmap_priv);
+ glamor_destroy_fbo(glamor_priv, fbo);
}
- else {
- if (GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
- /* If the picture format is not compatible with glamor fbo format,
- * we have to mark this pixmap as a separated texture, and don't
- * fallback to DDX layer. */
- if (pixmap_priv->type == GLAMOR_TEXTURE_DRM
- && !glamor_pict_format_is_compatible(picture))
- glamor_set_pixmap_type(pixmap, GLAMOR_SEPARATE_TEXTURE);
- }
+
+ if (pixmap_priv->fbo && pixmap_priv->fbo->fb)
+ return 0;
+
+ if (!(no_alpha || (revert == REVERT_NORMAL)
+ || (swap_rb != SWAP_NONE_UPLOADING))) {
+ /* We don't need a fbo, a simple texture uploading should work. */
+
+ flag = GLAMOR_CREATE_FBO_NO_FBO;
}
- pixmap_priv->base.is_picture = 1;
- pixmap_priv->base.picture = picture;
+ if ((flag == GLAMOR_CREATE_FBO_NO_FBO
+ && pixmap_priv->fbo && pixmap_priv->fbo->tex))
+ return 0;
+
+ if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
+ iformat = gl_iformat_for_pixmap(pixmap);
+ else
+ iformat = format;
+
+ if (!glamor_pixmap_ensure_fbo(pixmap, iformat, flag))
+ return -1;
- return miCreatePicture(picture);
+ return 0;
}
-void
-glamor_destroy_picture(PicturePtr picture)
+/*
+ * upload sub region to a large region.
+ * */
+static void
+glamor_put_bits(char *dst_bits, int dst_stride, char *src_bits,
+ int src_stride, int bpp, int x, int y, int w, int h)
{
- PixmapPtr pixmap;
+ int j;
+ int byte_per_pixel;
+
+ byte_per_pixel = bpp / 8;
+ src_bits += y * src_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;
+ }
+}
+
+static Bool
+glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
+ int h, int stride, void *bits, int pbo,
+ PictFormatShort pict_format)
+{
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ GLenum format, type;
+ int no_alpha, revert, swap_rb;
glamor_pixmap_private *pixmap_priv;
+ Bool force_clip;
- if (!picture || !picture->pDrawable)
- return;
+ if (glamor_get_tex_format_type_from_pixmap(pixmap,
+ pict_format,
+ &format,
+ &type,
+ &no_alpha,
+ &revert, &swap_rb, 1)) {
+ glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
+ return FALSE;
+ }
+ if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
+ return FALSE;
- pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
pixmap_priv = glamor_get_pixmap_private(pixmap);
+ force_clip = glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP
+ && !glamor_check_fbo_size(glamor_priv, w, h);
+
+ if (glamor_pixmap_priv_is_large(pixmap_priv) || force_clip) {
+ RegionRec region;
+ BoxRec box;
+ int n_region;
+ glamor_pixmap_clipped_regions *clipped_regions;
+ void *sub_bits;
+ int i, j;
+
+ sub_bits = xallocarray(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, &region, &n_region,
+ 0, 0, 0);
+ else
+ clipped_regions =
+ glamor_compute_clipped_regions_ext(pixmap, &region,
+ &n_region,
+ pixmap_priv->block_w,
+ pixmap_priv->block_h,
+ 0,
+ 0);
+ DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap);
+ for (i = 0; i < n_region; i++) {
+ BoxPtr boxes;
+ int nbox;
+ int temp_stride;
+ void *temp_bits;
+
+ assert(pbo == 0);
+
+ glamor_set_pixmap_fbo_current(pixmap_priv, clipped_regions[i].block_idx);
+
+ boxes = RegionRects(clipped_regions[i].region);
+ nbox = RegionNumRects(clipped_regions[i].region);
+ DEBUGF("split to %d boxes\n", nbox);
+ for (j = 0; j < nbox; j++) {
+ temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1,
+ pixmap->drawable.depth);
- if (pixmap_priv) {
- pixmap_priv->base.is_picture = 0;
- pixmap_priv->base.picture = NULL;
+ if (boxes[j].x1 == x && temp_stride == stride) {
+ temp_bits = (char *) bits + (boxes[j].y1 - y) * stride;
+ }
+ else {
+ temp_bits = sub_bits;
+ glamor_put_bits(temp_bits, temp_stride, bits, stride,
+ pixmap->drawable.bitsPerPixel,
+ boxes[j].x1 - x, boxes[j].y1 - y,
+ boxes[j].x2 - boxes[j].x1,
+ boxes[j].y2 - boxes[j].y1);
+ }
+ DEBUGF("upload x %d y %d w %d h %d temp stride %d \n",
+ boxes[j].x1 - x, boxes[j].y1 - y,
+ boxes[j].x2 - boxes[j].x1,
+ boxes[j].y2 - boxes[j].y1, temp_stride);
+ if (_glamor_upload_bits_to_pixmap_texture
+ (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) == FALSE) {
+ RegionUninit(&region);
+ free(sub_bits);
+ assert(0);
+ return FALSE;
+ }
+ }
+ RegionDestroy(clipped_regions[i].region);
+ }
+ free(sub_bits);
+ free(clipped_regions);
+ RegionUninit(&region);
+ return TRUE;
}
- miDestroyPicture(picture);
+ else
+ return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type,
+ no_alpha, revert, swap_rb,
+ x, y, w, h, stride, bits,
+ pbo);
}
-void
-glamor_picture_format_fixup(PicturePtr picture,
- glamor_pixmap_private *pixmap_priv)
+/* Upload picture to texture. We may need to flip the y axis or
+ * wire alpha to 1. So we may conditional create fbo for the picture.
+ * */
+enum glamor_pixmap_status
+glamor_upload_picture_to_texture(PicturePtr picture)
{
- pixmap_priv->base.picture = picture;
+ PixmapPtr pixmap;
+
+ assert(picture->pDrawable);
+ pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
+
+ if (glamor_upload_sub_pixmap_to_texture(pixmap, 0, 0,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
+ pixmap->devKind,
+ pixmap->devPrivate.ptr, 0,
+ picture->format))
+ return GLAMOR_UPLOAD_DONE;
+ else
+ return GLAMOR_UPLOAD_FAILED;
}
diff --git a/xserver/glamor/glamor_pixmap.c b/xserver/glamor/glamor_pixmap.c
index 0d92710cf..166bde509 100644
--- a/xserver/glamor/glamor_pixmap.c
+++ b/xserver/glamor/glamor_pixmap.c
@@ -63,31 +63,36 @@ glamor_pixmap_fini(ScreenPtr screen)
}
void
-glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *fbo, int x0, int y0,
+glamor_set_destination_pixmap_fbo(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *fbo, int x0, int y0,
int width, int height)
{
- glamor_make_current(fbo->glamor_priv);
+ glamor_make_current(glamor_priv);
glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
glViewport(x0, y0, width, height);
}
void
-glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv)
+glamor_set_destination_pixmap_priv_nc(glamor_screen_private *glamor_priv,
+ PixmapPtr pixmap,
+ glamor_pixmap_private *pixmap_priv)
{
int w, h;
- PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap_priv, w, h);
- glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0, w, h);
+ PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, pixmap_priv, w, h);
+ glamor_set_destination_pixmap_fbo(glamor_priv, pixmap_priv->fbo, 0, 0, w, h);
}
int
-glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv)
+glamor_set_destination_pixmap_priv(glamor_screen_private *glamor_priv,
+ PixmapPtr pixmap,
+ glamor_pixmap_private *pixmap_priv)
{
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
return -1;
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+ glamor_set_destination_pixmap_priv_nc(glamor_priv, pixmap, pixmap_priv);
return 0;
}
@@ -96,15 +101,17 @@ glamor_set_destination_pixmap(PixmapPtr pixmap)
{
int err;
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- err = glamor_set_destination_pixmap_priv(pixmap_priv);
+ err = glamor_set_destination_pixmap_priv(glamor_priv, pixmap, pixmap_priv);
return err;
}
Bool
-glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask)
+glamor_set_planemask(int depth, unsigned long planemask)
{
- if (glamor_pm_is_solid(&pixmap->drawable, planemask)) {
+ if (glamor_pm_is_solid(depth, planemask)) {
return GL_TRUE;
}
@@ -182,1012 +189,3 @@ glamor_set_alu(ScreenPtr screen, unsigned char alu)
return TRUE;
}
-
-/*
- * Map picture's format to the correct gl texture format and type.
- * no_alpha is used to indicate whehter we need to wire alpha to 1.
- *
- * Although opengl support A1/GL_BITMAP, we still don't use it
- * here, it seems that mesa has bugs when uploading a A1 bitmap.
- *
- * Return 0 if find a matched texture type. Otherwise return -1.
- **/
-static int
-glamor_get_tex_format_type_from_pictformat_gl(PictFormatShort format,
- GLenum *tex_format,
- GLenum *tex_type,
- int *no_alpha,
- int *revert,
- int *swap_rb, int is_upload)
-{
- *no_alpha = 0;
- *revert = REVERT_NONE;
- *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
- switch (format) {
- case PICT_a1:
- *tex_format = GL_ALPHA;
- *tex_type = GL_UNSIGNED_BYTE;
- *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
- break;
- case PICT_b8g8r8x8:
- *no_alpha = 1;
- case PICT_b8g8r8a8:
- *tex_format = GL_BGRA;
- *tex_type = GL_UNSIGNED_INT_8_8_8_8;
- break;
-
- case PICT_x8r8g8b8:
- *no_alpha = 1;
- case PICT_a8r8g8b8:
- *tex_format = GL_BGRA;
- *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
- break;
- case PICT_x8b8g8r8:
- *no_alpha = 1;
- case PICT_a8b8g8r8:
- *tex_format = GL_RGBA;
- *tex_type = GL_UNSIGNED_INT_8_8_8_8_REV;
- break;
- case PICT_x2r10g10b10:
- *no_alpha = 1;
- case PICT_a2r10g10b10:
- *tex_format = GL_BGRA;
- *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
- break;
- case PICT_x2b10g10r10:
- *no_alpha = 1;
- case PICT_a2b10g10r10:
- *tex_format = GL_RGBA;
- *tex_type = GL_UNSIGNED_INT_2_10_10_10_REV;
- break;
-
- case PICT_r5g6b5:
- *tex_format = GL_RGB;
- *tex_type = GL_UNSIGNED_SHORT_5_6_5;
- break;
- case PICT_b5g6r5:
- *tex_format = GL_RGB;
- *tex_type = GL_UNSIGNED_SHORT_5_6_5_REV;
- break;
- case PICT_x1b5g5r5:
- *no_alpha = 1;
- case PICT_a1b5g5r5:
- *tex_format = GL_RGBA;
- *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
- break;
-
- case PICT_x1r5g5b5:
- *no_alpha = 1;
- case PICT_a1r5g5b5:
- *tex_format = GL_BGRA;
- *tex_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
- break;
- case PICT_a8:
- *tex_format = GL_ALPHA;
- *tex_type = GL_UNSIGNED_BYTE;
- break;
- case PICT_x4r4g4b4:
- *no_alpha = 1;
- case PICT_a4r4g4b4:
- *tex_format = GL_BGRA;
- *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
- break;
-
- case PICT_x4b4g4r4:
- *no_alpha = 1;
- case PICT_a4b4g4r4:
- *tex_format = GL_RGBA;
- *tex_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
- break;
-
- default:
- return -1;
- }
- return 0;
-}
-
-#define IS_LITTLE_ENDIAN (IMAGE_BYTE_ORDER == LSBFirst)
-
-static int
-glamor_get_tex_format_type_from_pictformat_gles2(PictFormatShort format,
- GLenum *tex_format,
- GLenum *tex_type,
- int *no_alpha,
- int *revert,
- int *swap_rb, int is_upload)
-{
- int need_swap_rb = 0;
-
- *no_alpha = 0;
- *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
-
- switch (format) {
- case PICT_b8g8r8x8:
- *no_alpha = 1;
- case PICT_b8g8r8a8:
- *tex_format = GL_RGBA;
- *tex_type = GL_UNSIGNED_BYTE;
- need_swap_rb = 1;
- *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
- break;
-
- case PICT_x8r8g8b8:
- *no_alpha = 1;
- case PICT_a8r8g8b8:
- *tex_format = GL_RGBA;
- *tex_type = GL_UNSIGNED_BYTE;
- need_swap_rb = 1;
- break;
-
- case PICT_x8b8g8r8:
- *no_alpha = 1;
- case PICT_a8b8g8r8:
- *tex_format = GL_RGBA;
- *tex_type = GL_UNSIGNED_BYTE;
- break;
-
- case PICT_x2r10g10b10:
- *no_alpha = 1;
- case PICT_a2r10g10b10:
- *tex_format = GL_RGBA;
- /* glReadPixmap doesn't support GL_UNSIGNED_INT_10_10_10_2.
- * we have to use GL_UNSIGNED_BYTE and do the conversion in
- * shader latter.*/
- *tex_type = GL_UNSIGNED_BYTE;
- if (is_upload == 1) {
- if (!IS_LITTLE_ENDIAN)
- *revert = REVERT_UPLOADING_10_10_10_2;
- else
- *revert = REVERT_UPLOADING_2_10_10_10;
- }
- else {
- if (!IS_LITTLE_ENDIAN) {
- *revert = REVERT_DOWNLOADING_10_10_10_2;
- }
- else {
- *revert = REVERT_DOWNLOADING_2_10_10_10;
- }
- }
- need_swap_rb = 1;
-
- break;
-
- case PICT_x2b10g10r10:
- *no_alpha = 1;
- case PICT_a2b10g10r10:
- *tex_format = GL_RGBA;
- *tex_type = GL_UNSIGNED_BYTE;
- if (is_upload == 1) {
- if (!IS_LITTLE_ENDIAN)
- *revert = REVERT_UPLOADING_10_10_10_2;
- else
- *revert = REVERT_UPLOADING_2_10_10_10;
- }
- else {
- if (!IS_LITTLE_ENDIAN) {
- *revert = REVERT_DOWNLOADING_10_10_10_2;
- }
- else {
- *revert = REVERT_DOWNLOADING_2_10_10_10;
- }
- }
- break;
-
- case PICT_r5g6b5:
- *tex_format = GL_RGB;
- *tex_type = GL_UNSIGNED_SHORT_5_6_5;
- *revert = IS_LITTLE_ENDIAN ? REVERT_NONE : REVERT_NORMAL;
-
- break;
-
- case PICT_b5g6r5:
- *tex_format = GL_RGB;
- *tex_type = GL_UNSIGNED_SHORT_5_6_5;
- need_swap_rb = IS_LITTLE_ENDIAN ? 1 : 0;;
- break;
-
- case PICT_x1b5g5r5:
- *no_alpha = 1;
- case PICT_a1b5g5r5:
- *tex_format = GL_RGBA;
- *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
- if (IS_LITTLE_ENDIAN) {
- *revert =
- is_upload ? REVERT_UPLOADING_1_5_5_5 :
- REVERT_DOWNLOADING_1_5_5_5;
- }
- else
- *revert = REVERT_NONE;
- break;
-
- case PICT_x1r5g5b5:
- *no_alpha = 1;
- case PICT_a1r5g5b5:
- *tex_format = GL_RGBA;
- *tex_type = GL_UNSIGNED_SHORT_5_5_5_1;
- if (IS_LITTLE_ENDIAN) {
- *revert =
- is_upload ? REVERT_UPLOADING_1_5_5_5 :
- REVERT_DOWNLOADING_1_5_5_5;
- }
- else
- *revert = REVERT_NONE;
- need_swap_rb = 1;
- break;
-
- case PICT_a1:
- *tex_format = GL_ALPHA;
- *tex_type = GL_UNSIGNED_BYTE;
- *revert = is_upload ? REVERT_UPLOADING_A1 : REVERT_DOWNLOADING_A1;
- break;
-
- case PICT_a8:
- *tex_format = GL_ALPHA;
- *tex_type = GL_UNSIGNED_BYTE;
- *revert = REVERT_NONE;
- break;
-
- case PICT_x4r4g4b4:
- *no_alpha = 1;
- case PICT_a4r4g4b4:
- *tex_format = GL_RGBA;
- *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
- *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
- need_swap_rb = 1;
- break;
-
- case PICT_x4b4g4r4:
- *no_alpha = 1;
- case PICT_a4b4g4r4:
- *tex_format = GL_RGBA;
- *tex_type = GL_UNSIGNED_SHORT_4_4_4_4;
- *revert = IS_LITTLE_ENDIAN ? REVERT_NORMAL : REVERT_NONE;
- break;
-
- default:
- LogMessageVerb(X_INFO, 0,
- "fail to get matched format for %x \n", format);
- return -1;
- }
-
- if (need_swap_rb)
- *swap_rb = is_upload ? SWAP_UPLOADING : SWAP_DOWNLOADING;
- else
- *swap_rb = is_upload ? SWAP_NONE_UPLOADING : SWAP_NONE_DOWNLOADING;
- return 0;
-}
-
-static int
-glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
- GLenum *format,
- GLenum *type,
- int *no_alpha,
- int *revert, int *swap_rb, int is_upload)
-{
- glamor_pixmap_private *pixmap_priv;
- PictFormatShort pict_format;
- glamor_screen_private *glamor_priv =
- glamor_get_screen_private(pixmap->drawable.pScreen);
-
- pixmap_priv = glamor_get_pixmap_private(pixmap);
- if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
- pict_format = pixmap_priv->base.picture->format;
- else
- pict_format = format_for_depth(pixmap->drawable.depth);
-
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
- return glamor_get_tex_format_type_from_pictformat_gl(pict_format,
- format, type,
- no_alpha,
- revert,
- swap_rb,
- is_upload);
- } else {
- return glamor_get_tex_format_type_from_pictformat_gles2(pict_format,
- format, type,
- no_alpha,
- revert,
- swap_rb,
- is_upload);
- }
-}
-
-static void *
-_glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h,
- int stride, int revert)
-{
- PictFormatShort dst_format, src_format;
- pixman_image_t *dst_image;
- pixman_image_t *src_image;
- int src_stride;
-
- if (revert == REVERT_UPLOADING_A1) {
- src_format = PICT_a1;
- dst_format = PICT_a8;
- src_stride = PixmapBytePad(w, 1);
- }
- else {
- dst_format = PICT_a1;
- src_format = PICT_a8;
- src_stride = (((w * 8 + 7) / 8) + 3) & ~3;
- }
-
- dst_image = pixman_image_create_bits(dst_format, w, h, dst_bits, stride);
- if (dst_image == NULL) {
- return NULL;
- }
-
- src_image = pixman_image_create_bits(src_format,
- w, h, src_bits, src_stride);
-
- if (src_image == NULL) {
- pixman_image_unref(dst_image);
- return NULL;
- }
-
- pixman_image_composite(PictOpSrc, src_image, NULL, dst_image,
- 0, 0, 0, 0, 0, 0, w, h);
-
- pixman_image_unref(src_image);
- pixman_image_unref(dst_image);
- return dst_bits;
-}
-
-#define ADJUST_BITS(d, src_bits, dst_bits) (((dst_bits) == (src_bits)) ? (d) : \
- (((dst_bits) > (src_bits)) ? \
- (((d) << ((dst_bits) - (src_bits))) \
- + (( 1 << ((dst_bits) - (src_bits))) >> 1)) \
- : ((d) >> ((src_bits) - (dst_bits)))))
-
-#define GLAMOR_DO_CONVERT(src, dst, no_alpha, swap, \
- a_shift_src, a_bits_src, \
- b_shift_src, b_bits_src, \
- g_shift_src, g_bits_src, \
- r_shift_src, r_bits_src, \
- a_shift, a_bits, \
- b_shift, b_bits, \
- g_shift, g_bits, \
- r_shift, r_bits) \
- do { \
- typeof(src) a,b,g,r; \
- typeof(src) a_mask_src, b_mask_src, g_mask_src, r_mask_src;\
- a_mask_src = (((1 << (a_bits_src)) - 1) << a_shift_src);\
- b_mask_src = (((1 << (b_bits_src)) - 1) << b_shift_src);\
- g_mask_src = (((1 << (g_bits_src)) - 1) << g_shift_src);\
- r_mask_src = (((1 << (r_bits_src)) - 1) << r_shift_src);\
- if (no_alpha) \
- a = (a_mask_src) >> (a_shift_src); \
- else \
- a = ((src) & (a_mask_src)) >> (a_shift_src); \
- b = ((src) & (b_mask_src)) >> (b_shift_src); \
- g = ((src) & (g_mask_src)) >> (g_shift_src); \
- r = ((src) & (r_mask_src)) >> (r_shift_src); \
- a = ADJUST_BITS(a, a_bits_src, a_bits); \
- b = ADJUST_BITS(b, b_bits_src, b_bits); \
- g = ADJUST_BITS(g, g_bits_src, g_bits); \
- r = ADJUST_BITS(r, r_bits_src, r_bits); \
- if (swap == 0) \
- (*dst) = ((a) << (a_shift)) | ((b) << (b_shift)) | ((g) << (g_shift)) | ((r) << (r_shift)); \
- else \
- (*dst) = ((a) << (a_shift)) | ((r) << (b_shift)) | ((g) << (g_shift)) | ((b) << (r_shift)); \
- } while (0)
-
-static void *
-_glamor_color_revert_x2b10g10r10(void *src_bits, void *dst_bits, int w, int h,
- int stride, int no_alpha, int revert,
- int swap_rb)
-{
- int x, y;
- unsigned int *words, *saved_words, *source_words;
- int swap = !(swap_rb == SWAP_NONE_DOWNLOADING ||
- swap_rb == SWAP_NONE_UPLOADING);
-
- source_words = src_bits;
- words = dst_bits;
- saved_words = words;
-
- for (y = 0; y < h; y++) {
- DEBUGF("Line %d : ", y);
- for (x = 0; x < w; x++) {
- unsigned int pixel = source_words[x];
-
- if (revert == REVERT_DOWNLOADING_2_10_10_10)
- GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
- 24, 8, 16, 8, 8, 8, 0, 8,
- 30, 2, 20, 10, 10, 10, 0, 10);
- else
- GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
- 30, 2, 20, 10, 10, 10, 0, 10,
- 24, 8, 16, 8, 8, 8, 0, 8);
- DEBUGF("%x:%x ", pixel, words[x]);
- }
- DEBUGF("\n");
- words += stride / sizeof(*words);
- source_words += stride / sizeof(*words);
- }
- DEBUGF("\n");
- return saved_words;
-
-}
-
-static void *
-_glamor_color_revert_x1b5g5r5(void *src_bits, void *dst_bits, int w, int h,
- int stride, int no_alpha, int revert, int swap_rb)
-{
- int x, y;
- unsigned short *words, *saved_words, *source_words;
- int swap = !(swap_rb == SWAP_NONE_DOWNLOADING ||
- swap_rb == SWAP_NONE_UPLOADING);
-
- words = dst_bits;
- source_words = src_bits;
- saved_words = words;
-
- for (y = 0; y < h; y++) {
- DEBUGF("Line %d : ", y);
- for (x = 0; x < w; x++) {
- unsigned short pixel = source_words[x];
-
- if (revert == REVERT_DOWNLOADING_1_5_5_5)
- GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
- 0, 1, 1, 5, 6, 5, 11, 5,
- 15, 1, 10, 5, 5, 5, 0, 5);
- else
- GLAMOR_DO_CONVERT(pixel, &words[x], no_alpha, swap,
- 15, 1, 10, 5, 5, 5, 0, 5,
- 0, 1, 1, 5, 6, 5, 11, 5);
- DEBUGF("%04x:%04x ", pixel, words[x]);
- }
- DEBUGF("\n");
- words += stride / sizeof(*words);
- source_words += stride / sizeof(*words);
- }
- DEBUGF("\n");
- return saved_words;
-}
-
-/*
- * This function is to convert an unsupported color format to/from a
- * supported GL format.
- * Here are the current scenarios:
- *
- * @no_alpha:
- * If it is set, then we need to wire the alpha value to 1.
- * @revert:
- REVERT_DOWNLOADING_A1 : convert an Alpha8 buffer to a A1 buffer.
- REVERT_UPLOADING_A1 : convert an A1 buffer to an Alpha8 buffer
- REVERT_DOWNLOADING_2_10_10_10 : convert r10G10b10X2 to X2B10G10R10
- REVERT_UPLOADING_2_10_10_10 : convert X2B10G10R10 to R10G10B10X2
- REVERT_DOWNLOADING_1_5_5_5 : convert B5G5R5X1 to X1R5G5B5
- REVERT_UPLOADING_1_5_5_5 : convert X1R5G5B5 to B5G5R5X1
- @swap_rb: if we have the swap_rb set, then we need to swap the R and B's position.
- *
- */
-
-static void *
-glamor_color_convert_to_bits(void *src_bits, void *dst_bits, int w, int h,
- int stride, int no_alpha, int revert, int swap_rb)
-{
- if (revert == REVERT_DOWNLOADING_A1 || revert == REVERT_UPLOADING_A1) {
- return _glamor_color_convert_a1_a8(src_bits, dst_bits, w, h, stride,
- revert);
- }
- else if (revert == REVERT_DOWNLOADING_2_10_10_10 ||
- revert == REVERT_UPLOADING_2_10_10_10) {
- return _glamor_color_revert_x2b10g10r10(src_bits, dst_bits, w, h,
- stride, no_alpha, revert,
- swap_rb);
- }
- else if (revert == REVERT_DOWNLOADING_1_5_5_5 ||
- revert == REVERT_UPLOADING_1_5_5_5) {
- return _glamor_color_revert_x1b5g5r5(src_bits, dst_bits, w, h, stride,
- no_alpha, revert, swap_rb);
- }
- else
- ErrorF("convert a non-supported mode %x.\n", revert);
-
- return NULL;
-}
-
-/**
- * Upload pixmap to a specified texture.
- * This texture may not be the one attached to it.
- **/
-static void
-__glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
- GLenum format,
- GLenum type,
- int x, int y, int w, int h,
- void *bits, int pbo)
-{
- glamor_screen_private *glamor_priv =
- glamor_get_screen_private(pixmap->drawable.pScreen);
- int non_sub = 0;
- unsigned int iformat = 0;
-
- glamor_make_current(glamor_priv);
- if (*tex == 0) {
- glGenTextures(1, tex);
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
- iformat = gl_iformat_for_pixmap(pixmap);
- else
- iformat = format;
- non_sub = 1;
- assert(x == 0 && y == 0);
- }
-
- glBindTexture(GL_TEXTURE_2D, *tex);
- 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);
-
- assert(pbo || bits != 0);
- if (bits == NULL) {
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
- glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
- }
- if (non_sub)
- glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits);
- else
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, type, bits);
-
- if (bits == NULL)
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-}
-
-static Bool
-_glamor_upload_bits_to_pixmap_texture(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_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
- glamor_screen_private *glamor_priv =
- glamor_get_screen_private(pixmap->drawable.pScreen);
- static float vertices[8];
-
- static float texcoords_inv[8] = { 0, 0,
- 1, 0,
- 1, 1,
- 0, 1
- };
- float *ptexcoords;
- float dst_xscale, dst_yscale;
- GLuint tex = 0;
- int need_free_bits = 0;
-
- if (bits == NULL)
- goto ready_to_upload;
-
- if (revert > REVERT_NORMAL) {
- /* XXX if we are restoring the pixmap, then we may not need to allocate
- * new buffer */
- void *converted_bits;
-
- if (pixmap->drawable.depth == 1)
- stride = (((w * 8 + 7) / 8) + 3) & ~3;
-
- converted_bits = malloc(h * stride);
-
- if (converted_bits == NULL)
- return FALSE;
- bits = glamor_color_convert_to_bits(bits, converted_bits, w, h,
- stride, no_alpha, revert, swap_rb);
- if (bits == NULL) {
- free(converted_bits);
- ErrorF("Failed to convert pixmap no_alpha %d,"
- "revert mode %d, swap mode %d\n", no_alpha, revert, swap_rb);
- return FALSE;
- }
- no_alpha = 0;
- revert = REVERT_NONE;
- swap_rb = SWAP_NONE_UPLOADING;
- need_free_bits = TRUE;
- }
-
- ready_to_upload:
-
- /* 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
-#ifdef WALKAROUND_LARGE_TEXTURE_MAP
- && pixmap_priv->type != GLAMOR_TEXTURE_LARGE
-#endif
- ) {
- int fbo_x_off, fbo_y_off;
-
- assert(pixmap_priv->base.fbo->tex);
- pixmap_priv_get_fbo_off(pixmap_priv, &fbo_x_off, &fbo_y_off);
-
- assert(x + fbo_x_off >= 0 && y + fbo_y_off >= 0);
- assert(x + fbo_x_off + w <= pixmap_priv->base.fbo->width);
- assert(y + fbo_y_off + h <= pixmap_priv->base.fbo->height);
- __glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex,
- format, type,
- x + fbo_x_off, y + fbo_y_off, w, h,
- bits, pbo);
- } else {
- 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,
- 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,
- GL_FALSE, 2 * sizeof(float), vertices);
- glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
- glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
- GL_FALSE, 2 * sizeof(float), ptexcoords);
- glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
- __glamor_upload_pixmap_to_texture(pixmap, &tex,
- format, type, 0, 0, w, h, bits, pbo);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, tex);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
- glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
- glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- glDeleteTextures(1, &tex);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- }
-
- if (need_free_bits)
- free(bits);
- return TRUE;
-}
-
-/*
- * Prepare to upload a pixmap to texture memory.
- * no_alpha equals 1 means the format needs to wire alpha to 1.
- */
-static int
-glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha,
- int revert, int swap_rb)
-{
- int flag = 0;
- glamor_pixmap_private *pixmap_priv;
- glamor_screen_private *glamor_priv;
- glamor_pixmap_fbo *fbo;
- GLenum iformat;
-
- pixmap_priv = glamor_get_pixmap_private(pixmap);
- glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen);
-
- if (pixmap_priv->base.gl_fbo != GLAMOR_FBO_UNATTACHED)
- return 0;
-
- if (pixmap_priv->base.fbo
- && (pixmap_priv->base.fbo->width < pixmap->drawable.width
- || pixmap_priv->base.fbo->height < pixmap->drawable.height)) {
- fbo = glamor_pixmap_detach_fbo(pixmap_priv);
- glamor_destroy_fbo(fbo);
- }
-
- if (pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb)
- return 0;
-
- if (!(no_alpha || (revert == REVERT_NORMAL)
- || (swap_rb != SWAP_NONE_UPLOADING))) {
- /* We don't need a fbo, a simple texture uploading should work. */
-
- flag = GLAMOR_CREATE_FBO_NO_FBO;
- }
-
- if ((flag == GLAMOR_CREATE_FBO_NO_FBO
- && pixmap_priv->base.fbo && pixmap_priv->base.fbo->tex)
- || (flag == 0 && pixmap_priv->base.fbo && pixmap_priv->base.fbo->fb))
- return 0;
-
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
- iformat = gl_iformat_for_pixmap(pixmap);
- else
- iformat = format;
-
- if (!glamor_pixmap_ensure_fbo(pixmap, iformat, flag))
- return -1;
-
- return 0;
-}
-
-/*
- * upload sub region to a large region.
- * */
-static void
-glamor_put_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;
- src_bits += y * src_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)
-{
- 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, 1)) {
- glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth);
- return FALSE;
- }
- if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb))
- return FALSE;
-
- pixmap_priv = glamor_get_pixmap_private(pixmap);
- 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("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap);
- for (i = 0; i < n_region; i++) {
- BoxPtr boxes;
- int nbox;
- int temp_stride;
- void *temp_bits;
-
- assert(pbo == 0);
-
- glamor_set_pixmap_fbo_current(pixmap_priv, clipped_regions[i].block_idx);
-
- boxes = RegionRects(clipped_regions[i].region);
- nbox = RegionNumRects(clipped_regions[i].region);
- DEBUGF("split to %d boxes\n", nbox);
- 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;
- glamor_put_bits(temp_bits, temp_stride, bits, stride,
- pixmap->drawable.bitsPerPixel,
- boxes[j].x1 - x, boxes[j].y1 - y,
- boxes[j].x2 - boxes[j].x1,
- boxes[j].y2 - boxes[j].y1);
- }
- DEBUGF("upload x %d y %d w %d h %d temp stride %d \n",
- boxes[j].x1 - x, boxes[j].y1 - y,
- boxes[j].x2 - boxes[j].x1,
- boxes[j].y2 - boxes[j].y1, temp_stride);
- if (_glamor_upload_bits_to_pixmap_texture
- (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) == FALSE) {
- RegionUninit(&region);
- free(sub_bits);
- assert(0);
- return FALSE;
- }
- }
- RegionDestroy(clipped_regions[i].region);
- }
- free(sub_bits);
- free(clipped_regions);
- RegionUninit(&region);
- return TRUE;
- }
- else
- return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type,
- no_alpha, revert, swap_rb,
- x, y, w, h, stride, bits,
- pbo);
-}
-
-enum glamor_pixmap_status
-glamor_upload_pixmap_to_texture(PixmapPtr pixmap)
-{
- glamor_pixmap_private *pixmap_priv;
- void *data;
- int pbo;
- int ret;
-
- pixmap_priv = glamor_get_pixmap_private(pixmap);
-
- if ((pixmap_priv->base.fbo)
- && (pixmap_priv->base.fbo->pbo_valid)) {
- data = NULL;
- pbo = pixmap_priv->base.fbo->pbo;
- }
- else {
- data = pixmap->devPrivate.ptr;
- pbo = 0;
- }
-
- if (glamor_upload_sub_pixmap_to_texture(pixmap, 0, 0,
- pixmap->drawable.width,
- pixmap->drawable.height,
- pixmap->devKind, data, pbo))
- ret = GLAMOR_UPLOAD_DONE;
- else
- ret = GLAMOR_UPLOAD_FAILED;
-
- return ret;
-}
-
-/*
- * as gles2 only support a very small set of color format and
- * type when do glReadPixel,
- * Before we use glReadPixels to get back a textured pixmap,
- * Use shader to convert it to a supported format and thus
- * get a new temporary pixmap returned.
- * */
-
-glamor_pixmap_fbo *
-glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
- GLenum format, GLenum type, int no_alpha,
- int revert, int swap_rb)
-{
- glamor_pixmap_private *source_priv;
- glamor_screen_private *glamor_priv;
- ScreenPtr screen;
- glamor_pixmap_fbo *temp_fbo;
- float temp_xscale, temp_yscale, source_xscale, source_yscale;
- static float vertices[8];
- static float texcoords[8];
-
- screen = source->drawable.pScreen;
-
- glamor_priv = glamor_get_screen_private(screen);
- source_priv = glamor_get_pixmap_private(source);
- temp_fbo = glamor_create_fbo(glamor_priv, w, h, format, 0);
- if (temp_fbo == NULL)
- return NULL;
-
- glamor_make_current(glamor_priv);
- temp_xscale = 1.0 / w;
- temp_yscale = 1.0 / h;
-
- glamor_set_normalize_vcoords((struct glamor_pixmap_private *) NULL,
- temp_xscale, temp_yscale, 0, 0, w, h,
- vertices);
-
- glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
- 2 * sizeof(float), vertices);
- glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-
- pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale);
- glamor_set_normalize_tcoords(source_priv, source_xscale,
- source_yscale,
- x, y,
- x + w, y + h,
- texcoords);
-
- glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
- 2 * sizeof(float), texcoords);
- glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h);
- glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
- glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
- glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- return temp_fbo;
-}
-
-/* fixup a fbo to the exact size as the pixmap. */
-/* XXX LARGE pixmap? */
-Bool
-glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv)
-{
- glamor_pixmap_fbo *old_fbo;
- glamor_pixmap_fbo *new_fbo = NULL;
- PixmapPtr scratch = NULL;
- glamor_pixmap_private *scratch_priv;
- DrawablePtr drawable;
- GCPtr gc = NULL;
- int ret = FALSE;
-
- drawable = &pixmap_priv->base.pixmap->drawable;
-
- if (!GLAMOR_PIXMAP_FBO_NOT_EXACT_SIZE(pixmap_priv))
- return TRUE;
-
- old_fbo = pixmap_priv->base.fbo;
-
- if (!old_fbo)
- return FALSE;
-
- gc = GetScratchGC(drawable->depth, screen);
- if (!gc)
- goto fail;
-
- scratch = glamor_create_pixmap(screen, drawable->width, drawable->height,
- drawable->depth, GLAMOR_CREATE_PIXMAP_FIXUP);
-
- scratch_priv = glamor_get_pixmap_private(scratch);
-
- if (!scratch_priv->base.fbo)
- goto fail;
-
- ValidateGC(&scratch->drawable, gc);
- glamor_copy_area(drawable,
- &scratch->drawable,
- gc, 0, 0, drawable->width, drawable->height, 0, 0);
- old_fbo = glamor_pixmap_detach_fbo(pixmap_priv);
- new_fbo = glamor_pixmap_detach_fbo(scratch_priv);
- glamor_pixmap_attach_fbo(pixmap_priv->base.pixmap, new_fbo);
- glamor_pixmap_attach_fbo(scratch, old_fbo);
-
- DEBUGF("old %dx%d type %d\n",
- drawable->width, drawable->height, pixmap_priv->type);
- DEBUGF("copy tex %d %dx%d to tex %d %dx%d \n",
- old_fbo->tex, old_fbo->width, old_fbo->height, new_fbo->tex,
- new_fbo->width, new_fbo->height);
- ret = TRUE;
- fail:
- if (gc)
- FreeScratchGC(gc);
- if (scratch)
- glamor_destroy_pixmap(scratch);
-
- return ret;
-}
diff --git a/xserver/glamor/glamor_points.c b/xserver/glamor/glamor_points.c
index 84383d254..facfe8240 100644
--- a/xserver/glamor/glamor_points.c
+++ b/xserver/glamor/glamor_points.c
@@ -46,7 +46,7 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
int off_x, off_y;
GLshort *vbo_ppt;
char *vbo_offset;
- int box_x, box_y;
+ int box_index;
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
@@ -55,17 +55,18 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
glamor_make_current(glamor_priv);
if (prog->failed)
- goto bail_ctx;
+ goto bail;
if (!prog->prog) {
if (!glamor_build_program(screen, prog,
&glamor_facet_point,
- &glamor_fill_solid))
- goto bail_ctx;
+ &glamor_fill_solid,
+ NULL, NULL))
+ goto bail;
}
if (!glamor_use_program(pixmap, gc, prog, NULL))
- goto bail_ctx;
+ goto bail;
vbo_ppt = glamor_get_vbo_space(screen, npt * (2 * sizeof (INT16)), &vbo_offset);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
@@ -85,11 +86,12 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
glEnable(GL_SCISSOR_TEST);
- glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ glamor_pixmap_loop(pixmap_priv, box_index) {
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);
+ glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE,
+ prog->matrix_uniform, &off_x, &off_y);
while (nbox--) {
glScissor(box->x1 + off_x,
@@ -102,13 +104,10 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
}
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;
}
@@ -121,18 +120,3 @@ glamor_poly_point(DrawablePtr drawable, GCPtr gc, int mode, int npt,
return;
miPolyPoint(drawable, gc, mode, npt, ppt);
}
-
-Bool
-glamor_poly_point_nf(DrawablePtr drawable, GCPtr gc, int mode, int npt,
- DDXPointPtr ppt)
-{
- if (glamor_poly_point_gl(drawable, gc, mode, npt, ppt))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
- return FALSE;
-
- miPolyPoint(drawable, gc, mode, npt, ppt);
- return TRUE;
-}
-
diff --git a/xserver/glamor/glamor_prepare.c b/xserver/glamor/glamor_prepare.c
index 40b7b4feb..5a73e6c7d 100644
--- a/xserver/glamor/glamor_prepare.c
+++ b/xserver/glamor/glamor_prepare.c
@@ -56,7 +56,7 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
* we'll assume that it's directly mapped
* by a lower level driver
*/
- if (!priv->base.prepared)
+ if (!priv->prepared)
return TRUE;
/* In X, multiple Drawables can be stored in the same Pixmap (such as
@@ -67,38 +67,38 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
* 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);
+ RegionSubtract(&region, &region, &priv->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);
+ if (priv->pbo) {
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->pbo);
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
pixmap->devPrivate.ptr = NULL;
}
} else {
- RegionInit(&priv->base.prepare_region, box, 1);
+ RegionInit(&priv->prepare_region, box, 1);
if (glamor_priv->has_rw_pbo) {
- if (priv->base.pbo == 0)
- glGenBuffers(1, &priv->base.pbo);
+ if (priv->pbo == 0)
+ glGenBuffers(1, &priv->pbo);
gl_usage = GL_STREAM_READ;
- glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->base.pbo);
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->pbo);
glBufferData(GL_PIXEL_PACK_BUFFER,
pixmap->devKind * pixmap->drawable.height, NULL,
gl_usage);
} else {
- pixmap->devPrivate.ptr = malloc(pixmap->devKind *
- pixmap->drawable.height);
+ pixmap->devPrivate.ptr = xallocarray(pixmap->devKind,
+ pixmap->drawable.height);
if (!pixmap->devPrivate.ptr)
return FALSE;
}
- priv->base.map_access = access;
+ priv->map_access = access;
}
glamor_download_boxes(pixmap, RegionRects(&region), RegionNumRects(&region),
@@ -107,7 +107,7 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
RegionUninit(&region);
if (glamor_priv->has_rw_pbo) {
- if (priv->base.map_access == GLAMOR_ACCESS_RW)
+ if (priv->map_access == GLAMOR_ACCESS_RW)
gl_access = GL_READ_WRITE;
else
gl_access = GL_READ_ONLY;
@@ -116,7 +116,7 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
}
- priv->base.prepared = TRUE;
+ priv->prepared = TRUE;
return TRUE;
}
@@ -135,34 +135,34 @@ glamor_fini_pixmap(PixmapPtr pixmap)
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv))
return;
- if (!priv->base.prepared)
+ if (!priv->prepared)
return;
if (glamor_priv->has_rw_pbo) {
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->base.pbo);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->pbo);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
pixmap->devPrivate.ptr = NULL;
}
- if (priv->base.map_access == GLAMOR_ACCESS_RW) {
+ if (priv->map_access == GLAMOR_ACCESS_RW) {
glamor_upload_boxes(pixmap,
- RegionRects(&priv->base.prepare_region),
- RegionNumRects(&priv->base.prepare_region),
+ RegionRects(&priv->prepare_region),
+ RegionNumRects(&priv->prepare_region),
0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind);
}
- RegionUninit(&priv->base.prepare_region);
+ RegionUninit(&priv->prepare_region);
if (glamor_priv->has_rw_pbo) {
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- glDeleteBuffers(1, &priv->base.pbo);
- priv->base.pbo = 0;
+ glDeleteBuffers(1, &priv->pbo);
+ priv->pbo = 0;
} else {
free(pixmap->devPrivate.ptr);
pixmap->devPrivate.ptr = NULL;
}
- priv->base.prepared = FALSE;
+ priv->prepared = FALSE;
}
Bool
@@ -222,8 +222,22 @@ glamor_prepare_access_picture_box(PicturePtr picture, glamor_access_t access,
{
if (!picture || !picture->pDrawable)
return TRUE;
- return glamor_prepare_access_box(picture->pDrawable, access,
- x, y, w, h);
+
+ /* If a transform is set, we don't know what the bounds is on the
+ * source, so just prepare the whole pixmap. XXX: We could
+ * potentially work out where in the source would be sampled based
+ * on the transform, and we don't need do do this for destination
+ * pixmaps at all.
+ */
+ if (picture->transform) {
+ return glamor_prepare_access_box(picture->pDrawable, access,
+ 0, 0,
+ picture->pDrawable->width,
+ picture->pDrawable->height);
+ } else {
+ return glamor_prepare_access_box(picture->pDrawable, access,
+ x, y, w, h);
+ }
}
void
diff --git a/xserver/glamor/glamor_priv.h b/xserver/glamor/glamor_priv.h
index 612701a19..a70f10eb4 100644
--- a/xserver/glamor/glamor_priv.h
+++ b/xserver/glamor/glamor_priv.h
@@ -48,9 +48,7 @@
"precision mediump float;\n" \
"#endif\n"
-#ifdef RENDER
#include "glyphstr.h"
-#endif
#include "glamor_debug.h"
#include "glamor_context.h"
@@ -74,7 +72,7 @@ typedef struct glamor_composite_shader {
union {
float source_solid_color[4];
struct {
- struct glamor_pixmap_private *source_priv;
+ PixmapPtr source_pixmap;
PicturePtr source;
};
};
@@ -82,12 +80,18 @@ typedef struct glamor_composite_shader {
union {
float mask_solid_color[4];
struct {
- struct glamor_pixmap_private *mask_priv;
+ PixmapPtr mask_pixmap;
PicturePtr mask;
};
};
} glamor_composite_shader;
+enum ca_state {
+ CA_NONE,
+ CA_TWO_PASS,
+ CA_DUAL_BLEND,
+};
+
enum shader_source {
SHADER_SOURCE_SOLID,
SHADER_SOURCE_TEXTURE,
@@ -103,18 +107,17 @@ enum shader_mask {
SHADER_MASK_COUNT,
};
-enum shader_in {
- SHADER_IN_SOURCE_ONLY,
- SHADER_IN_NORMAL,
- SHADER_IN_CA_SOURCE,
- SHADER_IN_CA_ALPHA,
- SHADER_IN_COUNT,
+enum shader_dest_swizzle {
+ SHADER_DEST_SWIZZLE_DEFAULT,
+ SHADER_DEST_SWIZZLE_ALPHA_TO_RED,
+ SHADER_DEST_SWIZZLE_COUNT,
};
struct shader_key {
enum shader_source source;
enum shader_mask mask;
- enum shader_in in;
+ glamor_program_alpha in;
+ enum shader_dest_swizzle dest_swizzle;
};
struct blendinfo {
@@ -156,41 +159,8 @@ enum glamor_gl_flavor {
GLAMOR_GL_ES2 // OPENGL ES2.0 API
};
-#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
-
#define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024)
-typedef struct {
- PicturePtr picture; /* Where the glyphs of the cache are stored */
- GlyphPtr *glyphs;
- uint16_t count;
- uint16_t evict;
-} glamor_glyph_cache_t;
-
-#define CACHE_PICTURE_SIZE 1024
-#define GLYPH_MIN_SIZE 8
-#define GLYPH_MAX_SIZE 64
-#define GLYPH_CACHE_SIZE ((CACHE_PICTURE_SIZE) * CACHE_PICTURE_SIZE / (GLYPH_MIN_SIZE * GLYPH_MIN_SIZE))
-
-#define MASK_CACHE_MAX_SIZE 32
-#define MASK_CACHE_WIDTH (CACHE_PICTURE_SIZE / MASK_CACHE_MAX_SIZE)
-#define MASK_CACHE_MASK ((1LL << (MASK_CACHE_WIDTH)) - 1)
-
-struct glamor_glyph_mask_cache_entry {
- int idx;
- int width;
- int height;
- int x;
- int y;
-};
-
-typedef struct {
- PixmapPtr pixmap;
- struct glamor_glyph_mask_cache_entry mcache[MASK_CACHE_WIDTH];
- unsigned int free_bitmap;
- unsigned int cleared_bitmap;
-} glamor_glyph_mask_cache_t;
-
struct glamor_saved_procs {
CloseScreenProcPtr close_screen;
CreateScreenResourcesProcPtr create_screen_resources;
@@ -208,10 +178,6 @@ struct glamor_saved_procs {
BitmapToRegionProcPtr bitmap_to_region;
TrianglesProcPtr triangles;
AddTrapsProcPtr addtraps;
- CreatePictureProcPtr create_picture;
- DestroyPictureProcPtr destroy_picture;
- UnrealizeGlyphProcPtr unrealize_glyph;
- SetWindowPixmapProcPtr set_window_pixmap;
#if XSYNC
SyncScreenFuncsRec sync_screen_funcs;
#endif
@@ -230,16 +196,22 @@ typedef struct glamor_screen_private {
unsigned int tick;
enum glamor_gl_flavor gl_flavor;
int glsl_version;
- int has_pack_invert;
- int has_fbo_blit;
- int has_map_buffer_range;
- int has_buffer_storage;
- int has_khr_debug;
- int has_nv_texture_barrier;
- int has_pack_subimage;
- int has_unpack_subimage;
+ Bool has_pack_invert;
+ Bool has_fbo_blit;
+ Bool has_map_buffer_range;
+ Bool has_buffer_storage;
+ Bool has_khr_debug;
+ Bool has_nv_texture_barrier;
+ Bool has_pack_subimage;
+ Bool has_unpack_subimage;
+ Bool has_rw_pbo;
+ Bool use_quads;
+ Bool has_vertex_array_object;
+ Bool has_dual_blend;
+ Bool is_core_profile;
int max_fbo_size;
- int has_rw_pbo;
+
+ GLuint one_channel_format;
struct xorg_list
fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
@@ -276,11 +248,21 @@ typedef struct glamor_screen_private {
glamor_program_fill on_off_dash_line_progs;
glamor_program double_dash_line_prog;
- /* vertext/elment_index buffer object for render */
- GLuint vbo, ebo;
+ /* glamor composite_glyphs shaders */
+ glamor_program_render glyphs_program;
+ struct glamor_glyph_atlas *glyph_atlas_a;
+ struct glamor_glyph_atlas *glyph_atlas_argb;
+ int glyph_atlas_dim;
+ int glyph_max_dim;
+ char *glyph_defines;
+
+ /** Vertex buffer for all GPU rendering. */
+ GLuint vao;
+ GLuint vbo;
/** Next offset within the VBO that glamor_get_vbo_space() will use. */
int vbo_offset;
int vbo_size;
+ Bool vbo_mapped;
/**
* Pointer to glamor_get_vbo_space()'s current VBO mapping.
*
@@ -289,14 +271,20 @@ typedef struct glamor_screen_private {
*/
char *vb;
int vb_stride;
+
+ /** Cached index buffer for translating GL_QUADS to triangles. */
+ GLuint ib;
+ /** Index buffer type: GL_UNSIGNED_SHORT or GL_UNSIGNED_INT */
+ GLenum ib_type;
+ /** Number of quads the index buffer has indices for. */
+ unsigned ib_size;
+
Bool has_source_coords, has_mask_coords;
- int render_nr_verts;
+ int render_nr_quads;
glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT]
[SHADER_MASK_COUNT]
- [SHADER_IN_COUNT];
- glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
- glamor_glyph_mask_cache_t *mask_cache[GLAMOR_NUM_GLYPH_CACHE_FORMATS];
- Bool glyph_caches_realized;
+ [glamor_program_alpha_count]
+ [SHADER_DEST_SWIZZLE_COUNT];
/* shaders to restore a texture to another texture. */
GLint finish_access_prog[2];
@@ -317,8 +305,11 @@ typedef struct glamor_screen_private {
ScreenPtr screen;
int dri3_enabled;
+ Bool suppress_gl_out_of_memory_logging;
+ Bool logged_any_fbo_allocation_failure;
+
/* xv */
- GLint xv_prog;
+ glamor_program xv_prog;
struct glamor_context ctx;
} glamor_screen_private;
@@ -336,110 +327,34 @@ enum glamor_fbo_state {
* point at anything.
*/
GLAMOR_FBO_NORMAL,
- /**
- * The FBO is present and can be accessed as a linear memory
- * mapping through devPrivate.ptr.
- */
- GLAMOR_FBO_DOWNLOADED,
};
-/* glamor_pixmap_fbo:
- * @list: to be used to link to the cache pool list.
- * @expire: when push to cache pool list, set a expire count.
- * will be freed when glamor_priv->tick is equal or
- * larger than this expire count in block handler.
- * @pbo_valid: The pbo has a valid copy of the pixmap's data.
- * @tex: attached texture.
- * @fb: attached fbo.
- * @pbo: attached pbo.
- * @width: width of this fbo.
- * @height: height of this fbo.
- * @external set when the texture was not created by glamor
- * @format: internal format of this fbo's texture.
- * @type: internal type of this fbo's texture.
- * @glamor_priv: point to glamor private data.
- */
typedef struct glamor_pixmap_fbo {
- struct xorg_list list;
+ struct xorg_list list; /**< linked list pointers when in the fbo cache */
+ /** glamor_priv->tick number when this FBO will be expired from the cache. */
unsigned int expire;
- unsigned char pbo_valid;
- GLuint tex;
- GLuint fb;
- GLuint pbo;
- int width;
- int height;
+ GLuint tex; /**< GL texture name */
+ GLuint fb; /**< GL FBO name */
+ int width; /**< width in pixels */
+ int height; /**< height in pixels */
+ /**
+ * Flag for when texture contents might be shared with a
+ * non-glamor user.
+ *
+ * This is used to avoid putting textures used by other clients
+ * into the FBO cache.
+ */
Bool external;
- GLenum format;
- GLenum type;
- glamor_screen_private *glamor_priv;
+ GLenum format; /**< GL format used to create the texture. */
+ GLenum type; /**< GL type used to create the texture. */
} glamor_pixmap_fbo;
-/*
- * glamor_pixmap_private - glamor pixmap's private structure.
- * @gl_tex: The pixmap is in a gl texture originally.
- * @is_picture: The drawable is attached to a picture.
- * @pict_format: the corresponding picture's format.
- * @pixmap: The corresponding pixmap's pointer.
- *
- * For GLAMOR_TEXTURE_LARGE, nbox should larger than 1.
- * And the box and fbo will both have nbox elements.
- * and box[i] store the relatively coords in this pixmap
- * of the fbo[i]. The reason why use boxes not region to
- * represent this structure is we may need to use overlapped
- * boxes for one pixmap for some special reason.
- *
- * pixmap
- * ******************
- * * fbo0 * fbo1 *
- * * * *
- * ******************
- * * fbo2 * fbo3 *
- * * * *
- * ******************
- *
- * Let's assume the texture has size of 1024x1024
- * box[0] = {0,0,1024,1024}
- * box[1] = {1024,0,2048,2048}
- * ...
- *
- * For GLAMOR_TEXTURE_ATLAS nbox should be 1. And box
- * and fbo both has one elements, and the box store
- * the relatively coords in the fbo of this pixmap:
- *
- * fbo
- * ******************
- * * pixmap *
- * * ********* *
- * * * * *
- * * ********* *
- * * *
- * ******************
- *
- * Assume the pixmap is at the (100,100) relatively to
- * the fbo's origin.
- * box[0]={100, 100, 1124, 1124};
- *
- * Considering large pixmap is not a normal case, to keep
- * it simple, I designe it as the following way.
- * When deal with a large pixmap, it split the working
- * rectangle into serval boxes, and each box fit into a
- * corresponding fbo. And then the rendering function will
- * loop from the left-top box to the right-bottom box,
- * each time, we will set current box and current fbo
- * to the box and fbo elements. Thus the inner routines
- * can handle it as normal, only the coords calculation need
- * to aware of it's large pixmap.
- *
- * Currently, we haven't implemented the atlas pixmap.
- *
- **/
-
typedef struct glamor_pixmap_clipped_regions {
int block_idx;
RegionPtr region;
} glamor_pixmap_clipped_regions;
-typedef struct glamor_pixmap_private_base {
+typedef struct glamor_pixmap_private {
glamor_pixmap_type_t type;
enum glamor_fbo_state gl_fbo;
/**
@@ -448,137 +363,170 @@ typedef struct glamor_pixmap_private_base {
* that data on glamor_finish_access().
*/
glamor_access_t map_access;
- unsigned char is_picture:1;
- unsigned char gl_tex:1;
glamor_pixmap_fbo *fbo;
- PixmapPtr pixmap;
+ /** current fbo's coords in the whole pixmap. */
BoxRec box;
- int drm_stride;
- glamor_screen_private *glamor_priv;
- PicturePtr picture;
GLuint pbo;
RegionRec prepare_region;
Bool prepared;
#if GLAMOR_HAS_GBM
EGLImageKHR image;
#endif
-} glamor_pixmap_private_base_t;
-
-/*
- * @base.fbo: current fbo.
- * @box: current fbo's coords in the whole pixmap.
- * @block_w: block width of this large pixmap.
- * @block_h: block height of this large pixmap.
- * @block_wcnt: block count in one block row.
- * @block_hcnt: block count in one block column.
- * @nbox: total block count.
- * @box_array: contains each block's corresponding box.
- * @fbo_array: contains each block's fbo pointer.
- *
- **/
-typedef struct glamor_pixmap_private_large {
- union {
- glamor_pixmap_type_t type;
- glamor_pixmap_private_base_t base;
- };
- BoxRec box;
+ /** block width of this large pixmap. */
int block_w;
+ /** block height of this large pixmap. */
int block_h;
+
+ /** block_wcnt: block count in one block row. */
int block_wcnt;
+ /** block_hcnt: block count in one block column. */
int block_hcnt;
- int nbox;
+
+ /**
+ * The list of boxes for the bounds of the FBOs making up the
+ * pixmap.
+ *
+ * For a 2048x2048 pixmap with GL FBO size limits of 1024x1024:
+ *
+ * ******************
+ * * fbo0 * fbo1 *
+ * * * *
+ * ******************
+ * * fbo2 * fbo3 *
+ * * * *
+ * ******************
+ *
+ * box[0] = {0,0,1024,1024}
+ * box[1] = {1024,0,2048,2048}
+ * ...
+ */
BoxPtr box_array;
+
+ /**
+ * Array of fbo structs containing the actual GL texture/fbo
+ * names.
+ */
glamor_pixmap_fbo **fbo_array;
-} glamor_pixmap_private_large_t;
+} glamor_pixmap_private;
+
+extern DevPrivateKeyRec glamor_pixmap_private_key;
+
+static inline glamor_pixmap_private *
+glamor_get_pixmap_private(PixmapPtr pixmap)
+{
+ if (pixmap == NULL)
+ return NULL;
+
+ return dixLookupPrivate(&pixmap->devPrivates, &glamor_pixmap_private_key);
+}
/*
- * @box: the relative coords in the corresponding fbo.
+ * Returns TRUE if pixmap has no image object
*/
-typedef struct glamor_pixmap_private_atlas {
- union {
- glamor_pixmap_type_t type;
- glamor_pixmap_private_base_t base;
- };
- BoxRec box;
-} glamor_pixmap_private_atlas_t;
+static inline Bool
+glamor_pixmap_drm_only(PixmapPtr pixmap)
+{
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
-typedef struct glamor_pixmap_private {
- union {
- glamor_pixmap_type_t type;
- glamor_pixmap_private_base_t base;
- glamor_pixmap_private_large_t large;
- glamor_pixmap_private_atlas_t atlas;
- };
-} glamor_pixmap_private;
+ return priv->type == GLAMOR_DRM_ONLY;
+}
+
+/*
+ * Returns TRUE if pixmap is plain memory (not a GL object at all)
+ */
+static inline Bool
+glamor_pixmap_is_memory(PixmapPtr pixmap)
+{
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+
+ return priv->type == GLAMOR_MEMORY;
+}
+
+/*
+ * Returns TRUE if pixmap requires multiple textures to hold it
+ */
+static inline Bool
+glamor_pixmap_priv_is_large(glamor_pixmap_private *priv)
+{
+ return priv->block_wcnt > 1 || priv->block_hcnt > 1;
+}
+
+static inline Bool
+glamor_pixmap_priv_is_small(glamor_pixmap_private *priv)
+{
+ return priv->block_wcnt <= 1 && priv->block_hcnt <= 1;
+}
+
+static inline Bool
+glamor_pixmap_is_large(PixmapPtr pixmap)
+{
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+
+ return glamor_pixmap_priv_is_large(priv);
+}
+/*
+ * Returns TRUE if pixmap has an FBO
+ */
+static inline Bool
+glamor_pixmap_has_fbo(PixmapPtr pixmap)
+{
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+
+ return priv->gl_fbo == GLAMOR_FBO_NORMAL;
+}
static inline void
glamor_set_pixmap_fbo_current(glamor_pixmap_private *priv, int idx)
{
- if (priv->type == GLAMOR_TEXTURE_LARGE) {
- priv->large.base.fbo = priv->large.fbo_array[idx];
- priv->large.box = priv->large.box_array[idx];
+ if (glamor_pixmap_priv_is_large(priv)) {
+ priv->fbo = priv->fbo_array[idx];
+ priv->box = priv->box_array[idx];
}
}
static inline glamor_pixmap_fbo *
-glamor_pixmap_fbo_at(glamor_pixmap_private *priv, int x, int y)
+glamor_pixmap_fbo_at(glamor_pixmap_private *priv, int box)
{
- if (priv->type == GLAMOR_TEXTURE_LARGE) {
- assert(x < priv->large.block_wcnt);
- assert(y < priv->large.block_hcnt);
- return priv->large.fbo_array[y * priv->large.block_wcnt + x];
- }
- assert (x == 0);
- assert (y == 0);
- return priv->base.fbo;
+ assert(box < priv->block_wcnt * priv->block_hcnt);
+ return priv->fbo_array[box];
}
static inline BoxPtr
-glamor_pixmap_box_at(glamor_pixmap_private *priv, int x, int y)
+glamor_pixmap_box_at(glamor_pixmap_private *priv, int box)
{
- if (priv->type == GLAMOR_TEXTURE_LARGE) {
- assert(x < priv->large.block_wcnt);
- assert(y < priv->large.block_hcnt);
- return &priv->large.box_array[y * priv->large.block_wcnt + x];
- }
- assert (x == 0);
- assert (y == 0);
- return &priv->base.box;
+ assert(box < priv->block_wcnt * priv->block_hcnt);
+ return &priv->box_array[box];
}
static inline int
glamor_pixmap_wcnt(glamor_pixmap_private *priv)
{
- if (priv->type == GLAMOR_TEXTURE_LARGE)
- return priv->large.block_wcnt;
- return 1;
+ return priv->block_wcnt;
}
static inline int
glamor_pixmap_hcnt(glamor_pixmap_private *priv)
{
- if (priv->type == GLAMOR_TEXTURE_LARGE)
- return priv->large.block_hcnt;
- return 1;
+ return priv->block_hcnt;
}
-#define glamor_pixmap_loop(priv, x, y) \
- for (y = 0; y < glamor_pixmap_hcnt(priv); y++) \
- for (x = 0; x < glamor_pixmap_wcnt(priv); x++)
+#define glamor_pixmap_loop(priv, box_index) \
+ for (box_index = 0; box_index < glamor_pixmap_hcnt(priv) * \
+ glamor_pixmap_wcnt(priv); box_index++) \
-/*
- * Pixmap dynamic status, used by dynamic upload feature.
- *
- * GLAMOR_NONE: initial status, don't need to do anything.
- * GLAMOR_UPLOAD_PENDING: marked as need to be uploaded to gl texture.
- * GLAMOR_UPLOAD_DONE: the pixmap has been uploaded successfully.
- * GLAMOR_UPLOAD_FAILED: fail to upload the pixmap.
- *
- * */
+/**
+ * Pixmap upload status, used by glamor_render.c's support for
+ * temporarily uploading pixmaps to GL textures to get a Composite
+ * operation done.
+ */
typedef enum glamor_pixmap_status {
+ /** initial status, don't need to do anything. */
GLAMOR_NONE,
+ /** marked as need to be uploaded to gl texture. */
GLAMOR_UPLOAD_PENDING,
+ /** the pixmap has been uploaded successfully. */
GLAMOR_UPLOAD_DONE,
+ /** fail to upload the pixmap. */
GLAMOR_UPLOAD_FAILED
} glamor_pixmap_status_t;
@@ -592,7 +540,6 @@ typedef struct {
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)
@@ -607,22 +554,6 @@ glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv)
dixSetPrivate(&screen->devPrivates, &glamor_screen_private_key, priv);
}
-static inline glamor_pixmap_private *
-glamor_get_pixmap_private(PixmapPtr pixmap)
-{
- glamor_pixmap_private *priv;
-
- 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);
- }
- return priv;
-}
-
-void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
-
static inline glamor_gc_private *
glamor_get_gc_private(GCPtr gc)
{
@@ -634,10 +565,10 @@ glamor_get_gc_private(GCPtr gc)
* pixel values for pDrawable.
*/
static inline Bool
-glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask)
+glamor_pm_is_solid(int depth, unsigned long planemask)
{
- return (planemask & FbFullMask(drawable->depth)) ==
- FbFullMask(drawable->depth);
+ return (planemask & FbFullMask(depth)) ==
+ FbFullMask(depth);
}
extern int glamor_debug_level;
@@ -654,9 +585,9 @@ glamor_pixmap_fbo *glamor_create_fbo_from_tex(glamor_screen_private *
int flag);
glamor_pixmap_fbo *glamor_create_fbo(glamor_screen_private *glamor_priv, int w,
int h, GLenum format, int flag);
-void glamor_destroy_fbo(glamor_pixmap_fbo *fbo);
-void glamor_pixmap_destroy_fbo(glamor_pixmap_private *priv);
-
+void glamor_destroy_fbo(glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *fbo);
+void glamor_pixmap_destroy_fbo(PixmapPtr pixmap);
void glamor_init_pixmap_fbo(ScreenPtr screen);
void glamor_fini_pixmap_fbo(ScreenPtr screen);
Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap);
@@ -667,9 +598,11 @@ glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private *glamor_priv,
int flag, int block_w, int block_h,
glamor_pixmap_private *);
+void glamor_gldrawarrays_quads_using_indices(glamor_screen_private *glamor_priv,
+ unsigned count);
+
/* glamor_core.c */
void glamor_init_finish_access_shaders(ScreenPtr screen);
-void glamor_fini_finish_access_shaders(ScreenPtr screen);
Bool glamor_get_drawable_location(const DrawablePtr drawable);
void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap,
@@ -681,45 +614,29 @@ void glamor_get_color_4f_from_pixel(PixmapPtr pixmap,
unsigned long fg_pixel, GLfloat *color);
int glamor_set_destination_pixmap(PixmapPtr pixmap);
-int glamor_set_destination_pixmap_priv(glamor_pixmap_private *pixmap_priv);
-void glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *, int, int, int, int);
+int glamor_set_destination_pixmap_priv(glamor_screen_private *glamor_priv, PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv);
+void glamor_set_destination_pixmap_fbo(glamor_screen_private *glamor_priv, 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.
* */
-void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv);
-
-glamor_pixmap_fbo *glamor_es2_pixmap_read_prepare(PixmapPtr source, int x,
- int y, int w, int h,
- GLenum format, GLenum type,
- int no_alpha, int revert,
- int swap_rb);
+void glamor_set_destination_pixmap_priv_nc(glamor_screen_private *glamor_priv, PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv);
Bool glamor_set_alu(ScreenPtr screen, unsigned char alu);
-Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
+Bool glamor_set_planemask(int depth, unsigned long planemask);
RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
void
glamor_track_stipple(GCPtr gc);
-/* glamor_glyphs.c */
-Bool glamor_realize_glyph_caches(ScreenPtr screen);
-void glamor_glyphs_fini(ScreenPtr screen);
-void glamor_glyphs(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs);
-
/* glamor_render.c */
Bool glamor_composite_clipped_region(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
- glamor_pixmap_private *soruce_pixmap_priv,
- glamor_pixmap_private *mask_pixmap_priv,
- glamor_pixmap_private *dest_pixmap_priv,
+ PixmapPtr source_pixmap,
+ PixmapPtr mask_pixmap,
+ PixmapPtr dest_pixmap,
RegionPtr region,
int x_source,
int y_source,
@@ -736,38 +653,9 @@ void glamor_composite(CARD8 op,
INT16 yMask,
INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
-void glamor_init_composite_shaders(ScreenPtr screen);
-void glamor_fini_composite_shaders(ScreenPtr screen);
-void glamor_composite_glyph_rects(CARD8 op,
- PicturePtr src, PicturePtr mask,
- PicturePtr dst, int nrect,
- glamor_composite_rect_t *rects);
void glamor_composite_rects(CARD8 op,
PicturePtr pDst,
xRenderColor *color, int nRect, xRectangle *rects);
-PicturePtr glamor_convert_gradient_picture(ScreenPtr screen,
- PicturePtr source,
- int x_source,
- int y_source, int width, int height);
-
-Bool glamor_composite_choose_shader(CARD8 op,
- PicturePtr source,
- PicturePtr mask,
- PicturePtr dest,
- glamor_pixmap_private *source_pixmap_priv,
- glamor_pixmap_private *mask_pixmap_priv,
- glamor_pixmap_private *dest_pixmap_priv,
- struct shader_key *s_key,
- glamor_composite_shader ** shader,
- struct blendinfo *op_info,
- PictFormatShort *psaved_source_format);
-
-void glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
- struct shader_key *key,
- glamor_composite_shader *shader,
- struct blendinfo *op_info);
-
-void *glamor_setup_composite_vbo(ScreenPtr screen, int n_verts);
/* glamor_trapezoid.c */
void glamor_trapezoids(CARD8 op,
@@ -777,7 +665,6 @@ void glamor_trapezoids(CARD8 op,
/* glamor_gradient.c */
void glamor_init_gradient_shader(ScreenPtr screen);
-void glamor_fini_gradient_shader(ScreenPtr screen);
PicturePtr glamor_generate_linear_gradient_picture(ScreenPtr screen,
PicturePtr src_picture,
int x_source, int y_source,
@@ -821,44 +708,25 @@ glamor_put_vbo_space(ScreenPtr screen);
*/
Bool glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag);
-/**
- * Upload a pixmap to gl texture. Used by dynamic pixmap
- * uploading feature. The pixmap must be a software pixmap.
- * This function will change current FBO and current shaders.
- */
-enum glamor_pixmap_status glamor_upload_pixmap_to_texture(PixmapPtr pixmap);
-
-Bool glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
- int h, int stride, void *bits,
- int pbo);
-
glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions(glamor_pixmap_private *priv,
+glamor_compute_clipped_regions(PixmapPtr pixmap,
RegionPtr region, int *clipped_nbox,
int repeat_type, int reverse,
int upsidedown);
glamor_pixmap_clipped_regions *
-glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
+glamor_compute_clipped_regions_ext(PixmapPtr pixmap,
RegionPtr region, int *n_region,
int inner_block_w, int inner_block_h,
int reverse, int upsidedown);
-glamor_pixmap_clipped_regions *
-glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv,
- struct pixman_transform *transform,
- RegionPtr region,
- int *n_region, int dx, int dy,
- int repeat_type, int reverse,
- int upsidedown);
-
Bool glamor_composite_largepixmap_region(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
- glamor_pixmap_private *source_pixmap_priv,
- glamor_pixmap_private *mask_pixmap_priv,
- glamor_pixmap_private *dest_pixmap_priv,
+ PixmapPtr source_pixmap,
+ PixmapPtr mask_pixmap,
+ PixmapPtr dest_pixmap,
RegionPtr region, Bool force_clip,
INT16 x_source,
INT16 y_source,
@@ -867,42 +735,12 @@ Bool glamor_composite_largepixmap_region(CARD8 op,
INT16 x_dest, INT16 y_dest,
CARD16 width, CARD16 height);
-Bool glamor_get_transform_block_size(struct pixman_transform *transform,
- int block_w, int block_h,
- int *transformed_block_w,
- int *transformed_block_h);
-
-void glamor_get_transform_extent_from_box(struct pixman_box32 *temp_box,
- struct pixman_transform *transform);
-
/**
* Upload a picture to gl texture. Similar to the
* glamor_upload_pixmap_to_texture. Used in rendering.
**/
enum glamor_pixmap_status glamor_upload_picture_to_texture(PicturePtr picture);
-/**
- * Upload bits to a pixmap's texture. This function will
- * convert the bits to the specified format/type format
- * if the conversion is unavoidable.
- **/
-Bool glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
- GLenum type, int no_alpha, int revert,
- int swap_rb, void *bits);
-
-int glamor_create_picture(PicturePtr picture);
-
-void glamor_set_window_pixmap(WindowPtr pWindow, PixmapPtr pPixmap);
-
-void glamor_destroy_picture(PicturePtr picture);
-
-/* fixup a fbo to the exact size as the pixmap. */
-Bool glamor_fixup_pixmap_priv(ScreenPtr screen,
- glamor_pixmap_private *pixmap_priv);
-
-void glamor_picture_format_fixup(PicturePtr picture,
- glamor_pixmap_private *pixmap_priv);
-
void glamor_add_traps(PicturePtr pPicture,
INT16 x_off, INT16 y_off, int ntrap, xTrap *traps);
@@ -1009,6 +847,22 @@ void glamor_composite_rectangles(CARD8 op,
xRenderColor *color,
int num_rects, xRectangle *rects);
+/* glamor_composite_glyphs.c */
+Bool
+glamor_composite_glyphs_init(ScreenPtr pScreen);
+
+void
+glamor_composite_glyphs_fini(ScreenPtr pScreen);
+
+void
+glamor_composite_glyphs(CARD8 op,
+ PicturePtr src,
+ PicturePtr dst,
+ PictFormatPtr mask_format,
+ INT16 x_src,
+ INT16 y_src, int nlist,
+ GlyphListPtr list, GlyphPtr *glyphs);
+
/* glamor_sync.c */
Bool
glamor_sync_init(ScreenPtr screen);
@@ -1092,8 +946,6 @@ void glamor_xv_render(glamor_port_private *port_priv);
#if 0
#define MAX_FBO_SIZE 32 /* For test purpose only. */
#endif
-//#define GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK
-#define GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK
#include "glamor_font.h"
diff --git a/xserver/glamor/glamor_program.c b/xserver/glamor/glamor_program.c
index 3207aaf15..0a94de62f 100644
--- a/xserver/glamor/glamor_program.c
+++ b/xserver/glamor/glamor_program.c
@@ -40,14 +40,14 @@ const glamor_facet glamor_fill_solid = {
static Bool
use_tile(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
{
- return glamor_set_tiled(pixmap, gc, prog->fill_offset_uniform, prog->fill_size_uniform);
+ return glamor_set_tiled(pixmap, gc, prog->fill_offset_uniform, prog->fill_size_inv_uniform);
}
static const glamor_facet glamor_fill_tile = {
.name = "tile",
- .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
+ .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n",
.fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n",
- .locations = glamor_program_location_fill,
+ .locations = glamor_program_location_fillsamp | glamor_program_location_fillpos,
.use = use_tile,
};
@@ -56,17 +56,17 @@ 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);
+ prog->fill_size_inv_uniform);
}
static const glamor_facet glamor_fill_stipple = {
.name = "stipple",
- .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
+ .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\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,
+ .locations = glamor_program_location_fg | glamor_program_location_fillsamp | glamor_program_location_fillpos,
.use = use_stipple,
};
@@ -81,13 +81,13 @@ use_opaque_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
static const glamor_facet glamor_fill_opaque_stipple = {
.name = "opaque_stipple",
- .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / fill_size;\n",
+ .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\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_fillsamp | glamor_program_location_fillpos,
.use = use_opaque_stipple
};
@@ -114,12 +114,15 @@ static glamor_location_var location_vars[] = {
.fs_vars = "uniform vec4 bg;\n"
},
{
- .location = glamor_program_location_fill,
+ .location = glamor_program_location_fillsamp,
+ .fs_vars = "uniform sampler2D sampler;\n"
+ },
+ {
+ .location = glamor_program_location_fillpos,
.vs_vars = ("uniform vec2 fill_offset;\n"
- "uniform vec2 fill_size;\n"
+ "uniform vec2 fill_size_inv;\n"
"varying vec2 fill_pos;\n"),
- .fs_vars = ("uniform sampler2D sampler;\n"
- "uniform vec2 fill_size;\n"
+ .fs_vars = ("uniform vec2 fill_size_inv;\n"
"varying vec2 fill_pos;\n")
},
{
@@ -136,10 +139,12 @@ static glamor_location_var location_vars[] = {
.vs_vars = "uniform float dash_length;\n",
.fs_vars = "uniform sampler2D dash;\n",
},
+ {
+ .location = glamor_program_location_atlas,
+ .fs_vars = "uniform sampler2D atlas;\n",
+ },
};
-#define NUM_LOCATION_VARS (sizeof location_vars / sizeof location_vars[0])
-
static char *
add_var(char *cur, const char *add)
{
@@ -163,7 +168,7 @@ vs_location_vars(glamor_program_location locations)
int l;
char *vars = strdup("");
- for (l = 0; vars && l < NUM_LOCATION_VARS; l++)
+ for (l = 0; vars && l < ARRAY_SIZE(location_vars); l++)
if (locations & location_vars[l].location)
vars = add_var(vars, location_vars[l].vs_vars);
return vars;
@@ -175,7 +180,7 @@ fs_location_vars(glamor_program_location locations)
int l;
char *vars = strdup("");
- for (l = 0; vars && l < NUM_LOCATION_VARS; l++)
+ for (l = 0; vars && l < ARRAY_SIZE(location_vars); l++)
if (locations & location_vars[l].location)
vars = add_var(vars, location_vars[l].fs_vars);
return vars;
@@ -183,6 +188,7 @@ fs_location_vars(glamor_program_location locations)
static const char vs_template[] =
"%s" /* version */
+ "%s" /* defines */
"%s" /* prim vs_vars */
"%s" /* fill vs_vars */
"%s" /* location vs_vars */
@@ -195,12 +201,14 @@ static const char vs_template[] =
static const char fs_template[] =
"%s" /* version */
GLAMOR_DEFAULT_PRECISION
+ "%s" /* defines */
"%s" /* prim fs_vars */
"%s" /* fill fs_vars */
"%s" /* location fs_vars */
"void main() {\n"
"%s" /* prim fs_exec */
"%s" /* fill fs_exec */
+ "%s" /* combine */
"}\n";
static const char *
@@ -236,7 +244,9 @@ Bool
glamor_build_program(ScreenPtr screen,
glamor_program *prog,
const glamor_facet *prim,
- const glamor_facet *fill)
+ const glamor_facet *fill,
+ const char *combine,
+ const char *defines)
{
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
@@ -282,6 +292,7 @@ glamor_build_program(ScreenPtr screen,
if (asprintf(&vs_prog_string,
vs_template,
str(version_string),
+ str(defines),
str(prim->vs_vars),
str(fill->vs_vars),
vs_vars,
@@ -292,26 +303,30 @@ glamor_build_program(ScreenPtr screen,
if (asprintf(&fs_prog_string,
fs_template,
str(version_string),
+ str(defines),
str(prim->fs_vars),
str(fill->fs_vars),
fs_vars,
str(prim->fs_exec),
- str(fill->fs_exec)) < 0)
+ str(fill->fs_exec),
+ str(combine)) < 0)
fs_prog_string = NULL;
if (!vs_prog_string || !fs_prog_string)
goto fail;
+ prog->prog = glCreateProgram();
#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);
+ ErrorF("\n\tProgram %d for %s %s\n\tVertex shader:\n\n\t================\n%s\n\n\tFragment Shader:\n\n%s\t================\n",
+ prog->prog, prim->name, fill->name, vs_prog_string, fs_prog_string);
#endif
- prog->prog = glCreateProgram();
prog->flags = flags;
prog->locations = locations;
prog->prim_use = prim->use;
+ prog->prim_use_render = prim->use_render;
prog->fill_use = fill->use;
+ prog->fill_use_render = fill->use_render;
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_prog_string);
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_prog_string);
@@ -329,19 +344,24 @@ glamor_build_program(ScreenPtr screen,
#endif
glBindAttribLocation(prog->prog, GLAMOR_VERTEX_SOURCE, prim->source_name);
}
+ if (prog->alpha == glamor_program_alpha_dual_blend) {
+ glBindFragDataLocationIndexed(prog->prog, 0, 0, "color0");
+ glBindFragDataLocationIndexed(prog->prog, 0, 1, "color1");
+ }
glamor_link_glsl_prog(screen, prog->prog, "%s_%s", prim->name, fill->name);
prog->matrix_uniform = glamor_get_uniform(prog, glamor_program_location_none, "v_matrix");
prog->fg_uniform = glamor_get_uniform(prog, glamor_program_location_fg, "fg");
prog->bg_uniform = glamor_get_uniform(prog, glamor_program_location_bg, "bg");
- prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_offset");
- prog->fill_size_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_size");
+ prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fillpos, "fill_offset");
+ prog->fill_size_inv_uniform = glamor_get_uniform(prog, glamor_program_location_fillpos, "fill_size_inv");
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");
+ prog->atlas_uniform = glamor_get_uniform(prog, glamor_program_location_atlas, "atlas");
free(version_string);
free(fs_vars);
@@ -396,7 +416,7 @@ glamor_use_program_fill(PixmapPtr pixmap,
if (!fill)
return NULL;
- if (!glamor_build_program(screen, prog, prim, fill))
+ if (!glamor_build_program(screen, prog, prim, fill, NULL, NULL))
return NULL;
}
@@ -405,3 +425,259 @@ glamor_use_program_fill(PixmapPtr pixmap,
return prog;
}
+
+static struct blendinfo composite_op_info[] = {
+ [PictOpClear] = {0, 0, GL_ZERO, GL_ZERO},
+ [PictOpSrc] = {0, 0, GL_ONE, GL_ZERO},
+ [PictOpDst] = {0, 0, GL_ZERO, GL_ONE},
+ [PictOpOver] = {0, 1, GL_ONE, GL_ONE_MINUS_SRC_ALPHA},
+ [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE},
+ [PictOpIn] = {1, 0, GL_DST_ALPHA, GL_ZERO},
+ [PictOpInReverse] = {0, 1, GL_ZERO, GL_SRC_ALPHA},
+ [PictOpOut] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO},
+ [PictOpOutReverse] = {0, 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA},
+ [PictOpAtop] = {1, 1, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
+ [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA},
+ [PictOpXor] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
+ [PictOpAdd] = {0, 0, GL_ONE, GL_ONE},
+};
+
+static void
+glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst)
+{
+ GLenum src_blend, dst_blend;
+ struct blendinfo *op_info;
+
+ switch (alpha) {
+ case glamor_program_alpha_ca_first:
+ op = PictOpOutReverse;
+ break;
+ case glamor_program_alpha_ca_second:
+ op = PictOpAdd;
+ break;
+ default:
+ break;
+ }
+
+ if (op == PictOpSrc)
+ return;
+
+ op_info = &composite_op_info[op];
+
+ src_blend = op_info->source_blend;
+ dst_blend = op_info->dest_blend;
+
+ /* If there's no dst alpha channel, adjust the blend op so that we'll treat
+ * it as always 1.
+ */
+ if (PICT_FORMAT_A(dst->format) == 0 && op_info->dest_alpha) {
+ if (src_blend == GL_DST_ALPHA)
+ src_blend = GL_ONE;
+ else if (src_blend == GL_ONE_MINUS_DST_ALPHA)
+ src_blend = GL_ZERO;
+ }
+
+ /* Set up the source alpha value for blending in component alpha mode. */
+ if (alpha == glamor_program_alpha_dual_blend) {
+ switch (dst_blend) {
+ case GL_SRC_ALPHA:
+ dst_blend = GL_SRC1_COLOR;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ dst_blend = GL_ONE_MINUS_SRC1_COLOR;
+ break;
+ }
+ } else if (alpha != glamor_program_alpha_normal) {
+ switch (dst_blend) {
+ case GL_SRC_ALPHA:
+ dst_blend = GL_SRC_COLOR;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ dst_blend = GL_ONE_MINUS_SRC_COLOR;
+ break;
+ }
+ }
+
+ glEnable(GL_BLEND);
+ glBlendFunc(src_blend, dst_blend);
+}
+
+static Bool
+use_source_solid(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog)
+{
+
+ glamor_set_blend(op, prog->alpha, dst);
+
+ glamor_set_color_depth(dst->pDrawable->pScreen, 32,
+ src->pSourcePict->solidFill.color,
+ prog->fg_uniform);
+ return TRUE;
+}
+
+static const glamor_facet glamor_source_solid = {
+ .name = "render_solid",
+ .fs_exec = " vec4 source = fg;\n",
+ .locations = glamor_program_location_fg,
+ .use_render = use_source_solid,
+};
+
+static Bool
+use_source_picture(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog)
+{
+ glamor_set_blend(op, prog->alpha, dst);
+
+ return glamor_set_texture((PixmapPtr) src->pDrawable,
+ 0, 0,
+ prog->fill_offset_uniform,
+ prog->fill_size_inv_uniform);
+}
+
+static const glamor_facet glamor_source_picture = {
+ .name = "render_picture",
+ .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n",
+ .fs_exec = " vec4 source = texture2D(sampler, fill_pos);\n",
+ .locations = glamor_program_location_fillsamp | glamor_program_location_fillpos,
+ .use_render = use_source_picture,
+};
+
+static Bool
+use_source_1x1_picture(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog)
+{
+ glamor_set_blend(op, prog->alpha, dst);
+
+ return glamor_set_texture_pixmap((PixmapPtr) src->pDrawable);
+}
+
+static const glamor_facet glamor_source_1x1_picture = {
+ .name = "render_picture",
+ .fs_exec = " vec4 source = texture2D(sampler, vec2(0.5));\n",
+ .locations = glamor_program_location_fillsamp,
+ .use_render = use_source_1x1_picture,
+};
+
+static const glamor_facet *glamor_facet_source[glamor_program_source_count] = {
+ [glamor_program_source_solid] = &glamor_source_solid,
+ [glamor_program_source_picture] = &glamor_source_picture,
+ [glamor_program_source_1x1_picture] = &glamor_source_1x1_picture,
+};
+
+static const char *glamor_combine[] = {
+ [glamor_program_alpha_normal] = " gl_FragColor = source * mask.a;\n",
+ [glamor_program_alpha_ca_first] = " gl_FragColor = source.a * mask;\n",
+ [glamor_program_alpha_ca_second] = " gl_FragColor = source * mask;\n",
+ [glamor_program_alpha_dual_blend] = " color0 = source * mask;\n"
+ " color1 = source.a * mask;\n"
+};
+
+static Bool
+glamor_setup_one_program_render(ScreenPtr screen,
+ glamor_program *prog,
+ glamor_program_source source_type,
+ glamor_program_alpha alpha,
+ const glamor_facet *prim,
+ const char *defines)
+{
+ if (prog->failed)
+ return FALSE;
+
+ if (!prog->prog) {
+ const glamor_facet *fill = glamor_facet_source[source_type];
+
+ if (!fill)
+ return FALSE;
+
+ prog->alpha = alpha;
+ if (!glamor_build_program(screen, prog, prim, fill, glamor_combine[alpha], defines))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+glamor_program *
+glamor_setup_program_render(CARD8 op,
+ PicturePtr src,
+ PicturePtr mask,
+ PicturePtr dst,
+ glamor_program_render *program_render,
+ const glamor_facet *prim,
+ const char *defines)
+{
+ ScreenPtr screen = dst->pDrawable->pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ glamor_program_alpha alpha;
+ glamor_program_source source_type;
+ glamor_program *prog;
+
+ if (op > ARRAY_SIZE(composite_op_info))
+ return NULL;
+
+ if (glamor_is_component_alpha(mask)) {
+ if (glamor_priv->has_dual_blend) {
+ alpha = glamor_program_alpha_dual_blend;
+ } else {
+ /* This only works for PictOpOver */
+ if (op != PictOpOver)
+ return NULL;
+
+ alpha = glamor_program_alpha_ca_first;
+ }
+ } else
+ alpha = glamor_program_alpha_normal;
+
+ if (src->pDrawable) {
+
+ /* Can't do transforms, alphamaps or sourcing from non-pixmaps yet */
+ if (src->transform || src->alphaMap || src->pDrawable->type != DRAWABLE_PIXMAP)
+ return NULL;
+
+ if (src->pDrawable->width == 1 && src->pDrawable->height == 1 && src->repeat)
+ source_type = glamor_program_source_1x1_picture;
+ else
+ source_type = glamor_program_source_picture;
+ } else {
+ SourcePictPtr sp = src->pSourcePict;
+ if (!sp)
+ return NULL;
+ switch (sp->type) {
+ case SourcePictTypeSolidFill:
+ source_type = glamor_program_source_solid;
+ break;
+ default:
+ return NULL;
+ }
+ }
+
+ prog = &program_render->progs[source_type][alpha];
+ if (!glamor_setup_one_program_render(screen, prog, source_type, alpha, prim, defines))
+ return NULL;
+
+ if (alpha == glamor_program_alpha_ca_first) {
+
+ /* Make sure we can also build the second program before
+ * deciding to use this path.
+ */
+ if (!glamor_setup_one_program_render(screen,
+ &program_render->progs[source_type][glamor_program_alpha_ca_second],
+ source_type, glamor_program_alpha_ca_second, prim,
+ defines))
+ return NULL;
+ }
+ return prog;
+}
+
+Bool
+glamor_use_program_render(glamor_program *prog,
+ CARD8 op,
+ PicturePtr src,
+ PicturePtr dst)
+{
+ glUseProgram(prog->prog);
+
+ if (prog->prim_use_render && !prog->prim_use_render(op, src, dst, prog))
+ return FALSE;
+
+ if (prog->fill_use_render && !prog->fill_use_render(op, src, dst, prog))
+ return FALSE;
+ return TRUE;
+}
diff --git a/xserver/glamor/glamor_program.h b/xserver/glamor/glamor_program.h
index 56ba03aa8..ab6e46f7b 100644
--- a/xserver/glamor/glamor_program.h
+++ b/xserver/glamor/glamor_program.h
@@ -27,23 +27,37 @@ typedef enum {
glamor_program_location_none = 0,
glamor_program_location_fg = 1,
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_fillsamp = 4,
+ glamor_program_location_fillpos = 8,
+ glamor_program_location_font = 16,
+ glamor_program_location_bitplane = 32,
+ glamor_program_location_dash = 64,
+ glamor_program_location_atlas = 128,
} glamor_program_location;
typedef enum {
glamor_program_flag_none = 0,
} glamor_program_flag;
+typedef enum {
+ glamor_program_alpha_normal,
+ glamor_program_alpha_ca_first,
+ glamor_program_alpha_ca_second,
+ glamor_program_alpha_dual_blend,
+ glamor_program_alpha_count
+} glamor_program_alpha;
+
typedef struct _glamor_program glamor_program;
typedef Bool (*glamor_use) (PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg);
+typedef Bool (*glamor_use_render) (CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog);
+
typedef struct {
const char *name;
const int version;
+ char *vs_defines;
+ char *fs_defines;
const char *vs_vars;
const char *vs_exec;
const char *fs_vars;
@@ -52,6 +66,7 @@ typedef struct {
const glamor_program_flag flags;
const char *source_name;
glamor_use use;
+ glamor_use_render use_render;
} glamor_facet;
struct _glamor_program {
@@ -60,17 +75,21 @@ struct _glamor_program {
GLint matrix_uniform;
GLint fg_uniform;
GLint bg_uniform;
- GLint fill_size_uniform;
+ GLint fill_size_inv_uniform;
GLint fill_offset_uniform;
GLint font_uniform;
GLint bitplane_uniform;
GLint bitmul_uniform;
GLint dash_uniform;
GLint dash_length_uniform;
+ GLint atlas_uniform;
glamor_program_location locations;
glamor_program_flag flags;
glamor_use prim_use;
glamor_use fill_use;
+ glamor_program_alpha alpha;
+ glamor_use_render prim_use_render;
+ glamor_use_render fill_use_render;
};
typedef struct {
@@ -83,7 +102,9 @@ Bool
glamor_build_program(ScreenPtr screen,
glamor_program *prog,
const glamor_facet *prim,
- const glamor_facet *fill);
+ const glamor_facet *fill,
+ const char *combine,
+ const char *defines);
Bool
glamor_use_program(PixmapPtr pixmap,
@@ -97,4 +118,37 @@ glamor_use_program_fill(PixmapPtr pixmap,
glamor_program_fill *program_fill,
const glamor_facet *prim);
+typedef enum {
+ glamor_program_source_solid,
+ glamor_program_source_picture,
+ glamor_program_source_1x1_picture,
+ glamor_program_source_count,
+} glamor_program_source;
+
+typedef struct {
+ glamor_program progs[glamor_program_source_count][glamor_program_alpha_count];
+} glamor_program_render;
+
+static inline Bool
+glamor_is_component_alpha(PicturePtr mask) {
+ if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format))
+ return TRUE;
+ return FALSE;
+}
+
+glamor_program *
+glamor_setup_program_render(CARD8 op,
+ PicturePtr src,
+ PicturePtr mask,
+ PicturePtr dst,
+ glamor_program_render *program_render,
+ const glamor_facet *prim,
+ const char *defines);
+
+Bool
+glamor_use_program_render(glamor_program *prog,
+ CARD8 op,
+ PicturePtr src,
+ PicturePtr dst);
+
#endif /* _GLAMOR_PROGRAM_H_ */
diff --git a/xserver/glamor/glamor_rects.c b/xserver/glamor/glamor_rects.c
index 3a5c3f3f9..e4473209d 100644
--- a/xserver/glamor/glamor_rects.c
+++ b/xserver/glamor/glamor_rects.c
@@ -51,7 +51,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
int off_x, off_y;
GLshort *v;
char *vbo_offset;
- int box_x, box_y;
+ int box_index;
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
@@ -65,7 +65,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
&glamor_facet_polyfillrect_130);
if (!prog)
- goto bail_ctx;
+ goto bail;
/* Set up the vertex buffers for the points */
@@ -87,7 +87,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
&glamor_facet_polyfillrect_120);
if (!prog)
- goto bail_ctx;
+ goto bail;
/* Set up the vertex buffers for the points */
@@ -111,11 +111,12 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
glEnable(GL_SCISSOR_TEST);
- glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ glamor_pixmap_loop(pixmap_priv, box_index) {
int nbox = RegionNumRects(gc->pCompositeClip);
BoxPtr box = RegionRects(gc->pCompositeClip);
- glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y);
+ glamor_set_destination_drawable(drawable, box_index, TRUE, FALSE,
+ prog->matrix_uniform, &off_x, &off_y);
while (nbox--) {
glScissor(box->x1 + off_x,
@@ -126,27 +127,17 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
if (glamor_priv->glsl_version >= 130)
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nrect);
else {
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
- glDrawArrays(GL_QUADS, 0, nrect * 4);
- } else {
- int i;
- for (i = 0; i < nrect; i++) {
- glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
- }
- }
+ glamor_glDrawArrays_GL_QUADS(glamor_priv, nrect);
}
}
}
glDisable(GL_SCISSOR_TEST);
- glDisable(GL_COLOR_LOGIC_OP);
if (glamor_priv->glsl_version >= 130)
glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
return TRUE;
-bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
bail:
return FALSE;
}
@@ -173,15 +164,3 @@ glamor_poly_fill_rect(DrawablePtr drawable,
return;
glamor_poly_fill_rect_bail(drawable, gc, nrect, prect);
}
-
-Bool
-glamor_poly_fill_rect_nf(DrawablePtr drawable,
- GCPtr gc, int nrect, xRectangle *prect)
-{
- if (glamor_poly_fill_rect_gl(drawable, gc, nrect, prect))
- return TRUE;
- if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
- return FALSE;
- glamor_poly_fill_rect_bail(drawable, gc, nrect, prect);
- return TRUE;
-}
diff --git a/xserver/glamor/glamor_render.c b/xserver/glamor/glamor_render.c
index d9b16ea05..73ac831ee 100644
--- a/xserver/glamor/glamor_render.c
+++ b/xserver/glamor/glamor_render.c
@@ -34,7 +34,6 @@
#include "glamor_priv.h"
-#ifdef RENDER
#include "mipict.h"
#include "fbpict.h"
#if 0
@@ -73,146 +72,153 @@ glamor_create_composite_fs(struct shader_key *key)
"uniform int source_repeat_mode;\n"
"uniform int mask_repeat_mode;\n";
const char *relocate_texture =
- GLAMOR_DEFAULT_PRECISION
"vec2 rel_tex_coord(vec2 texture, vec4 wh, int repeat) \n"
"{\n"
- " vec2 rel_tex; \n"
- " rel_tex = texture * wh.xy; \n"
- " if (repeat == RepeatNone)\n"
+ " vec2 rel_tex; \n"
+ " rel_tex = texture * wh.xy; \n"
+ " if (repeat == RepeatFix + RepeatNone)\n"
" return rel_tex; \n"
- " else if (repeat == RepeatNormal) \n"
- " rel_tex = floor(rel_tex) + (fract(rel_tex) / wh.xy); \n"
- " else if(repeat == RepeatPad) { \n"
- " if (rel_tex.x >= 1.0) rel_tex.x = 1.0 - wh.z * wh.x / 2.; \n"
- " else if(rel_tex.x < 0.0) rel_tex.x = 0.0; \n"
- " if (rel_tex.y >= 1.0) rel_tex.y = 1.0 - wh.w * wh.y / 2.; \n"
- " else if(rel_tex.y < 0.0) rel_tex.y = 0.0; \n"
- " rel_tex = rel_tex / wh.xy; \n"
- " } \n"
- " else if(repeat == RepeatReflect) {\n"
+ " else if (repeat == RepeatFix + RepeatNormal) \n"
+ " rel_tex = floor(rel_tex) + (fract(rel_tex) / wh.xy); \n"
+ " else if (repeat == RepeatFix + RepeatPad) { \n"
+ " if (rel_tex.x >= 1.0) \n"
+ " rel_tex.x = 1.0 - wh.z * wh.x / 2.; \n"
+ " else if (rel_tex.x < 0.0) \n"
+ " rel_tex.x = 0.0; \n"
+ " if (rel_tex.y >= 1.0) \n"
+ " rel_tex.y = 1.0 - wh.w * wh.y / 2.; \n"
+ " else if (rel_tex.y < 0.0) \n"
+ " rel_tex.y = 0.0; \n"
+ " rel_tex = rel_tex / wh.xy; \n"
+ " } else if (repeat == RepeatFix + RepeatReflect) {\n"
" if ((1.0 - mod(abs(floor(rel_tex.x)), 2.0)) < 0.001)\n"
- " rel_tex.x = 2.0 - (1.0 - fract(rel_tex.x))/wh.x;\n"
+ " rel_tex.x = 2.0 - (1.0 - fract(rel_tex.x)) / wh.x;\n"
" else \n"
- " rel_tex.x = fract(rel_tex.x)/wh.x;\n"
+ " rel_tex.x = fract(rel_tex.x) / wh.x;\n"
" if ((1.0 - mod(abs(floor(rel_tex.y)), 2.0)) < 0.001)\n"
- " rel_tex.y = 2.0 - (1.0 - fract(rel_tex.y))/wh.y;\n"
+ " rel_tex.y = 2.0 - (1.0 - fract(rel_tex.y)) / wh.y;\n"
" else \n"
- " rel_tex.y = fract(rel_tex.y)/wh.y;\n"
- " } \n"
- " return rel_tex; \n"
+ " rel_tex.y = fract(rel_tex.y) / wh.y;\n"
+ " } \n"
+ " return rel_tex; \n"
"}\n";
/* The texture and the pixmap size is not match eaxctly, so can't sample it directly.
* rel_sampler will recalculate the texture coords.*/
const char *rel_sampler =
- " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec4 wh, int repeat, int set_alpha)\n"
+ " vec4 rel_sampler(sampler2D tex_image, vec2 tex, vec4 wh, int repeat)\n"
"{\n"
- " tex = rel_tex_coord(tex, wh, repeat - RepeatFix);\n"
- " if (repeat == RepeatFix) {\n"
- " if (!(tex.x >= 0.0 && tex.x < 1.0 \n"
- " && tex.y >= 0.0 && tex.y < 1.0))\n"
- " return vec4(0.0, 0.0, 0.0, set_alpha);\n"
- " tex = (fract(tex) / wh.xy);\n"
+ " if (repeat >= RepeatFix) {\n"
+ " tex = rel_tex_coord(tex, wh, repeat);\n"
+ " if (repeat == RepeatFix + RepeatNone) {\n"
+ " if (tex.x < 0.0 || tex.x >= 1.0 || \n"
+ " tex.y < 0.0 || tex.y >= 1.0)\n"
+ " return vec4(0.0, 0.0, 0.0, 0.0);\n"
+ " tex = (fract(tex) / wh.xy);\n"
+ " }\n"
" }\n"
- " if (set_alpha != 1)\n"
- " return texture2D(tex_image, tex);\n"
- " else\n"
- " return vec4(texture2D(tex_image, tex).rgb, 1.0);\n"
+ " return texture2D(tex_image, tex);\n"
"}\n";
const char *source_solid_fetch =
- GLAMOR_DEFAULT_PRECISION
"uniform vec4 source;\n"
"vec4 get_source()\n"
"{\n"
" return source;\n"
"}\n";
const char *source_alpha_pixmap_fetch =
- GLAMOR_DEFAULT_PRECISION
"varying vec2 source_texture;\n"
"uniform sampler2D source_sampler;\n"
"uniform vec4 source_wh;"
"vec4 get_source()\n"
"{\n"
- " if (source_repeat_mode < RepeatFix)\n"
- " return texture2D(source_sampler, source_texture);\n"
- " else \n"
- " return rel_sampler(source_sampler, source_texture,\n"
- " source_wh, source_repeat_mode, 0);\n"
+ " return rel_sampler(source_sampler, source_texture,\n"
+ " source_wh, source_repeat_mode);\n"
"}\n";
const char *source_pixmap_fetch =
- GLAMOR_DEFAULT_PRECISION
"varying vec2 source_texture;\n"
"uniform sampler2D source_sampler;\n"
"uniform vec4 source_wh;\n"
"vec4 get_source()\n"
"{\n"
- " if (source_repeat_mode < RepeatFix) \n"
- " return vec4(texture2D(source_sampler, source_texture).rgb, 1);\n"
- " else \n"
- " return rel_sampler(source_sampler, source_texture,\n"
- " source_wh, source_repeat_mode, 1);\n"
+ " return vec4(rel_sampler(source_sampler, source_texture,\n"
+ " source_wh, source_repeat_mode).rgb,\n"
+ " 1.0);\n"
+ "}\n";
+ const char *mask_none =
+ "vec4 get_mask()\n"
+ "{\n"
+ " return vec4(0.0, 0.0, 0.0, 1.0);\n"
"}\n";
const char *mask_solid_fetch =
- GLAMOR_DEFAULT_PRECISION
"uniform vec4 mask;\n"
"vec4 get_mask()\n"
"{\n"
" return mask;\n"
"}\n";
const char *mask_alpha_pixmap_fetch =
- GLAMOR_DEFAULT_PRECISION
"varying vec2 mask_texture;\n"
"uniform sampler2D mask_sampler;\n"
"uniform vec4 mask_wh;\n"
"vec4 get_mask()\n"
"{\n"
- " if (mask_repeat_mode < RepeatFix) \n"
- " return texture2D(mask_sampler, mask_texture);\n"
- " else \n"
- " return rel_sampler(mask_sampler, mask_texture,\n"
- " mask_wh, mask_repeat_mode, 0);\n"
+ " return rel_sampler(mask_sampler, mask_texture,\n"
+ " mask_wh, mask_repeat_mode);\n"
"}\n";
const char *mask_pixmap_fetch =
- GLAMOR_DEFAULT_PRECISION
"varying vec2 mask_texture;\n"
"uniform sampler2D mask_sampler;\n"
"uniform vec4 mask_wh;\n"
"vec4 get_mask()\n"
"{\n"
- " if (mask_repeat_mode < RepeatFix) \n"
- " return vec4(texture2D(mask_sampler, mask_texture).rgb, 1);\n"
- " else \n"
- " return rel_sampler(mask_sampler, mask_texture,\n"
- " mask_wh, mask_repeat_mode, 1);\n"
- "}\n";
- const char *in_source_only =
- GLAMOR_DEFAULT_PRECISION
- "void main()\n"
- "{\n"
- " gl_FragColor = get_source();\n"
+ " return vec4(rel_sampler(mask_sampler, mask_texture,\n"
+ " mask_wh, mask_repeat_mode).rgb, 1.0);\n"
"}\n";
+
+ const char *dest_swizzle_default =
+ "vec4 dest_swizzle(vec4 color)\n"
+ "{"
+ " return color;"
+ "}";
+ const char *dest_swizzle_alpha_to_red =
+ "vec4 dest_swizzle(vec4 color)\n"
+ "{"
+ " float undef;\n"
+ " return vec4(color.a, undef, undef, undef);"
+ "}";
+
const char *in_normal =
- GLAMOR_DEFAULT_PRECISION
"void main()\n"
"{\n"
- " gl_FragColor = get_source() * get_mask().a;\n"
+ " gl_FragColor = dest_swizzle(get_source() * get_mask().a);\n"
"}\n";
const char *in_ca_source =
- GLAMOR_DEFAULT_PRECISION
"void main()\n"
"{\n"
- " gl_FragColor = get_source() * get_mask();\n"
+ " gl_FragColor = dest_swizzle(get_source() * get_mask());\n"
"}\n";
const char *in_ca_alpha =
- GLAMOR_DEFAULT_PRECISION
"void main()\n"
"{\n"
- " gl_FragColor = get_source().a * get_mask();\n"
+ " gl_FragColor = dest_swizzle(get_source().a * get_mask());\n"
"}\n";
+ const char *in_ca_dual_blend =
+ "out vec4 color0;\n"
+ "out vec4 color1;\n"
+ "void main()\n"
+ "{\n"
+ " color0 = dest_swizzle(get_source() * get_mask());\n"
+ " color1 = dest_swizzle(get_source().a * get_mask());\n"
+ "}\n";
+ const char *header_ca_dual_blend =
+ "#version 130\n";
+
char *source;
const char *source_fetch;
const char *mask_fetch = "";
const char *in;
+ const char *header;
+ const char *header_norm = "";
+ const char *dest_swizzle;
GLuint prog;
switch (key->source) {
@@ -231,6 +237,7 @@ glamor_create_composite_fs(struct shader_key *key)
switch (key->mask) {
case SHADER_MASK_NONE:
+ mask_fetch = mask_none;
break;
case SHADER_MASK_SOLID:
mask_fetch = mask_solid_fetch;
@@ -245,25 +252,45 @@ glamor_create_composite_fs(struct shader_key *key)
FatalError("Bad composite shader mask");
}
- switch (key->in) {
- case SHADER_IN_SOURCE_ONLY:
- in = in_source_only;
+ /* If we're storing to an a8 texture but our texture format is
+ * GL_RED because of a core context, then we need to make sure to
+ * put the alpha into the red channel.
+ */
+ switch (key->dest_swizzle) {
+ case SHADER_DEST_SWIZZLE_DEFAULT:
+ dest_swizzle = dest_swizzle_default;
+ break;
+ case SHADER_DEST_SWIZZLE_ALPHA_TO_RED:
+ dest_swizzle = dest_swizzle_alpha_to_red;
break;
- case SHADER_IN_NORMAL:
+ default:
+ FatalError("Bad composite shader dest swizzle");
+ }
+
+ header = header_norm;
+ switch (key->in) {
+ case glamor_program_alpha_normal:
in = in_normal;
break;
- case SHADER_IN_CA_SOURCE:
+ case glamor_program_alpha_ca_first:
in = in_ca_source;
break;
- case SHADER_IN_CA_ALPHA:
+ case glamor_program_alpha_ca_second:
in = in_ca_alpha;
break;
+ case glamor_program_alpha_dual_blend:
+ in = in_ca_dual_blend;
+ header = header_ca_dual_blend;
+ break;
default:
FatalError("Bad composite IN type");
}
- XNFasprintf(&source, "%s%s%s%s%s%s", repeat_define, relocate_texture,
- rel_sampler, source_fetch, mask_fetch, in);
+ XNFasprintf(&source,
+ "%s"
+ GLAMOR_DEFAULT_PRECISION
+ "%s%s%s%s%s%s%s", header, repeat_define, relocate_texture,
+ rel_sampler, source_fetch, mask_fetch, dest_swizzle, in);
prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, source);
free(source);
@@ -332,6 +359,10 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0");
glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1");
+ if (key->in == glamor_program_alpha_dual_blend) {
+ glBindFragDataLocationIndexed(prog, 0, 0, "color0");
+ glBindFragDataLocationIndexed(prog, 0, 1, "color1");
+ }
glamor_link_glsl_prog(screen, prog, "composite");
shader->prog = prog;
@@ -373,73 +404,36 @@ glamor_lookup_composite_shader(ScreenPtr screen, struct
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_composite_shader *shader;
- shader = &glamor_priv->composite_shader[key->source][key->mask][key->in];
+ shader = &glamor_priv->composite_shader[key->source][key->mask][key->in][key->dest_swizzle];
if (shader->prog == 0)
glamor_create_composite_shader(screen, key, shader);
return shader;
}
-static void
-glamor_init_eb(unsigned short *eb, int vert_cnt)
+static GLenum
+glamor_translate_blend_alpha_to_red(GLenum blend)
{
- int i, j;
-
- for (i = 0, j = 0; j < vert_cnt; i += 6, j += 4) {
- eb[i] = j;
- eb[i + 1] = j + 1;
- eb[i + 2] = j + 2;
- eb[i + 3] = j;
- eb[i + 4] = j + 2;
- eb[i + 5] = j + 3;
+ switch (blend) {
+ case GL_SRC_ALPHA:
+ return GL_SRC_COLOR;
+ case GL_DST_ALPHA:
+ return GL_DST_COLOR;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ return GL_ONE_MINUS_SRC_COLOR;
+ case GL_ONE_MINUS_DST_ALPHA:
+ return GL_ONE_MINUS_DST_COLOR;
+ default:
+ return blend;
}
}
-void
-glamor_init_composite_shaders(ScreenPtr screen)
-{
- glamor_screen_private *glamor_priv;
- unsigned short *eb;
- int eb_size;
-
- glamor_priv = glamor_get_screen_private(screen);
- glamor_make_current(glamor_priv);
- glGenBuffers(1, &glamor_priv->ebo);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
-
- eb_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(short) * 2;
-
- eb = XNFalloc(eb_size);
- glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, eb_size, eb, GL_STATIC_DRAW);
- free(eb);
-}
-
-void
-glamor_fini_composite_shaders(ScreenPtr screen)
-{
- glamor_screen_private *glamor_priv;
- glamor_composite_shader *shader;
- int i, j, k;
-
- glamor_priv = glamor_get_screen_private(screen);
- glamor_make_current(glamor_priv);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glDeleteBuffers(1, &glamor_priv->ebo);
-
- for (i = 0; i < SHADER_SOURCE_COUNT; i++)
- for (j = 0; j < SHADER_MASK_COUNT; j++)
- for (k = 0; k < SHADER_IN_COUNT; k++) {
- shader = &glamor_priv->composite_shader[i][j][k];
- if (shader->prog)
- glDeleteProgram(shader->prog);
- }
-}
-
static Bool
glamor_set_composite_op(ScreenPtr screen,
CARD8 op, struct blendinfo *op_info_result,
- PicturePtr dest, PicturePtr mask)
+ PicturePtr dest, PicturePtr mask,
+ enum ca_state ca_state,
+ struct shader_key *key)
{
GLenum source_blend, dest_blend;
struct blendinfo *op_info;
@@ -448,6 +442,7 @@ glamor_set_composite_op(ScreenPtr screen,
glamor_fallback("unsupported render op %d \n", op);
return GL_FALSE;
}
+
op_info = &composite_op_info[op];
source_blend = op_info->source_blend;
@@ -464,12 +459,33 @@ glamor_set_composite_op(ScreenPtr screen,
}
/* Set up the source alpha value for blending in component alpha mode. */
- if (mask && mask->componentAlpha
- && PICT_FORMAT_RGB(mask->format) != 0 && op_info->source_alpha) {
- if (dest_blend == GL_SRC_ALPHA)
+ if (ca_state == CA_DUAL_BLEND) {
+ switch (dest_blend) {
+ case GL_SRC_ALPHA:
+ dest_blend = GL_SRC1_COLOR;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ dest_blend = GL_ONE_MINUS_SRC1_COLOR;
+ break;
+ }
+ } else if (mask && mask->componentAlpha
+ && PICT_FORMAT_RGB(mask->format) != 0 && op_info->source_alpha) {
+ switch (dest_blend) {
+ case GL_SRC_ALPHA:
dest_blend = GL_SRC_COLOR;
- else if (dest_blend == GL_ONE_MINUS_SRC_ALPHA)
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
dest_blend = GL_ONE_MINUS_SRC_COLOR;
+ break;
+ }
+ }
+
+ /* If we're outputting our alpha to the red channel, then any
+ * reads of alpha for blending need to come from the red channel.
+ */
+ if (key->dest_swizzle == SHADER_DEST_SWIZZLE_ALPHA_TO_RED) {
+ source_blend = glamor_translate_blend_alpha_to_red(source_blend);
+ dest_blend = glamor_translate_blend_alpha_to_red(dest_blend);
}
op_info_result->source_blend = source_blend;
@@ -483,15 +499,16 @@ glamor_set_composite_op(ScreenPtr screen,
static void
glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
PicturePtr picture,
- glamor_pixmap_private *pixmap_priv,
+ PixmapPtr pixmap,
GLuint wh_location, GLuint repeat_location)
{
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
float wh[4];
int repeat_type;
glamor_make_current(glamor_priv);
glActiveTexture(GL_TEXTURE0 + unit);
- glBindTexture(GL_TEXTURE_2D, pixmap_priv->base.fbo->tex);
+ glBindTexture(GL_TEXTURE_2D, pixmap_priv->fbo->tex);
repeat_type = picture->repeatType;
switch (picture->repeatType) {
case RepeatNone:
@@ -539,23 +556,15 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
* GLES2 doesn't support RepeatNone. We need to fix it anyway.
*
**/
- if (repeat_type != RepeatNone)
+ if (glamor_pixmap_priv_is_large(pixmap_priv) ||
+ (glamor_priv->gl_flavor == GLAMOR_GL_ES2 && repeat_type == RepeatNone &&
+ picture->transform)) {
+ glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap, pixmap_priv);
+ glUniform4fv(wh_location, 1, wh);
+
repeat_type += RepeatFix;
- else if (glamor_priv->gl_flavor == GLAMOR_GL_ES2
- || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
- if (picture->transform
- || (GLAMOR_PIXMAP_FBO_NOT_EXACT_SIZE(pixmap_priv)))
- repeat_type += RepeatFix;
- }
- if (repeat_type >= RepeatFix) {
- glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap_priv);
- if ((wh[0] != 1.0 || wh[1] != 1.0)
- || (glamor_priv->gl_flavor == GLAMOR_GL_ES2
- && repeat_type == RepeatFix))
- glUniform4fv(wh_location, 1, wh);
- else
- repeat_type -= RepeatFix;
}
+
glUniform1i(repeat_location, repeat_type);
}
@@ -565,33 +574,6 @@ glamor_set_composite_solid(float *color, GLint uniform_location)
glUniform4fv(uniform_location, 1, color);
}
-static int
-compatible_formats(CARD8 op, PicturePtr dst, PicturePtr src)
-{
- if (op == PictOpSrc) {
- if (src->format == dst->format)
- return 1;
-
- if (src->format == PICT_a8r8g8b8 && dst->format == PICT_x8r8g8b8)
- return 1;
-
- if (src->format == PICT_a8b8g8r8 && dst->format == PICT_x8b8g8r8)
- return 1;
- }
- else if (op == PictOpOver) {
- if (src->alphaMap || dst->alphaMap)
- return 0;
-
- if (src->format != dst->format)
- return 0;
-
- if (src->format == PICT_x8r8g8b8 || src->format == PICT_x8b8g8r8)
- return 1;
- }
-
- return 0;
-}
-
static char
glamor_get_picture_location(PicturePtr picture)
{
@@ -613,55 +595,7 @@ glamor_get_picture_location(PicturePtr picture)
return glamor_get_drawable_location(picture->pDrawable);
}
-static Bool
-glamor_composite_with_copy(CARD8 op,
- PicturePtr source,
- PicturePtr dest,
- INT16 x_source,
- INT16 y_source,
- INT16 x_dest, INT16 y_dest, RegionPtr region)
-{
- int ret = FALSE;
-
- if (!source->pDrawable)
- return FALSE;
-
- if (!compatible_formats(op, dest, source))
- return FALSE;
-
- if (source->repeat || source->transform) {
- return FALSE;
- }
-
- x_dest += dest->pDrawable->x;
- y_dest += dest->pDrawable->y;
- x_source += source->pDrawable->x;
- y_source += source->pDrawable->y;
- if (PICT_FORMAT_A(source->format) == 0) {
- /* Fallback if we sample outside the source so that we
- * swizzle the correct clear color for out-of-bounds texels.
- */
- if (region->extents.x1 + x_source - x_dest < 0)
- goto cleanup_region;
- if (region->extents.x2 + x_source - x_dest > source->pDrawable->width)
- goto cleanup_region;
-
- if (region->extents.y1 + y_source - y_dest < 0)
- goto cleanup_region;
- if (region->extents.y2 + y_source - y_dest > source->pDrawable->height)
- goto cleanup_region;
- }
- 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;
-}
-
-void *
+static void *
glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
{
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
@@ -669,7 +603,7 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
char *vbo_offset;
float *vb;
- glamor_priv->render_nr_verts = 0;
+ glamor_priv->render_nr_quads = 0;
glamor_priv->vb_stride = 2 * sizeof(float);
if (glamor_priv->has_source_coords)
glamor_priv->vb_stride += 2 * sizeof(float);
@@ -711,27 +645,20 @@ glamor_flush_composite_rects(ScreenPtr screen)
glamor_make_current(glamor_priv);
- if (!glamor_priv->render_nr_verts)
+ if (!glamor_priv->render_nr_quads)
return;
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
- glDrawRangeElements(GL_TRIANGLES, 0, glamor_priv->render_nr_verts,
- (glamor_priv->render_nr_verts * 3) / 2,
- GL_UNSIGNED_SHORT, NULL);
- } else {
- glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
- GL_UNSIGNED_SHORT, NULL);
- }
+ glamor_glDrawArrays_GL_QUADS(glamor_priv, glamor_priv->render_nr_quads);
}
-int pict_format_combine_tab[][3] = {
+static const int pict_format_combine_tab[][3] = {
{PICT_TYPE_ARGB, PICT_TYPE_A, PICT_TYPE_ARGB},
{PICT_TYPE_ABGR, PICT_TYPE_A, PICT_TYPE_ABGR},
};
static Bool
combine_pict_format(PictFormatShort * des, const PictFormatShort src,
- const PictFormatShort mask, enum shader_in in_ca)
+ const PictFormatShort mask, glamor_program_alpha in_ca)
{
PictFormatShort new_vis;
int src_type, mask_type, src_bpp;
@@ -748,20 +675,22 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
new_vis = PICT_FORMAT_VIS(src) | PICT_FORMAT_VIS(mask);
switch (in_ca) {
- case SHADER_IN_SOURCE_ONLY:
- return TRUE;
- case SHADER_IN_NORMAL:
+ case glamor_program_alpha_normal:
src_type = PICT_FORMAT_TYPE(src);
mask_type = PICT_TYPE_A;
break;
- case SHADER_IN_CA_SOURCE:
+ case glamor_program_alpha_ca_first:
src_type = PICT_FORMAT_TYPE(src);
mask_type = PICT_FORMAT_TYPE(mask);
break;
- case SHADER_IN_CA_ALPHA:
+ case glamor_program_alpha_ca_second:
src_type = PICT_TYPE_A;
mask_type = PICT_FORMAT_TYPE(mask);
break;
+ case glamor_program_alpha_dual_blend:
+ src_type = PICT_FORMAT_TYPE(src);
+ mask_type = PICT_FORMAT_TYPE(mask);
+ break;
default:
return FALSE;
}
@@ -771,10 +700,7 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
return TRUE;
}
- for (i = 0;
- i <
- sizeof(pict_format_combine_tab) /
- sizeof(pict_format_combine_tab[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(pict_format_combine_tab); i++) {
if ((src_type == pict_format_combine_tab[i][0]
&& mask_type == pict_format_combine_tab[i][1])
|| (src_type == pict_format_combine_tab[i][1]
@@ -788,7 +714,8 @@ combine_pict_format(PictFormatShort * des, const PictFormatShort src,
}
static void
-glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
+glamor_set_normalize_tcoords_generic(PixmapPtr pixmap,
+ glamor_pixmap_private *priv,
int repeat_type,
float *matrix,
float xscale, float yscale,
@@ -806,36 +733,61 @@ glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
x2, y2,
texcoords, stride);
else if (!matrix && repeat_type != RepeatNone)
- glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type,
+ glamor_set_repeat_normalize_tcoords_ext(pixmap, priv, repeat_type,
xscale, yscale,
x1, y1,
x2, y2,
texcoords, stride);
else if (matrix && repeat_type != RepeatNone)
- glamor_set_repeat_transformed_normalize_tcoords_ext(priv, repeat_type,
+ glamor_set_repeat_transformed_normalize_tcoords_ext(pixmap, priv, repeat_type,
matrix, xscale,
yscale, x1, y1, x2,
y2,
texcoords, stride);
}
-Bool
+/**
+ * Returns whether the general composite path supports this picture
+ * format for a pixmap that is permanently stored in an FBO (as
+ * opposed to the GLAMOR_PIXMAP_DYNAMIC_UPLOAD path).
+ *
+ * We could support many more formats by using GL_ARB_texture_view to
+ * parse the same bits as different formats. For now, we only support
+ * tweaking whether we sample the alpha bits of an a8r8g8b8, or just
+ * force them to 1.
+ */
+static Bool
+glamor_render_format_is_supported(PictFormatShort format)
+{
+ switch (format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ case PICT_a8:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+static Bool
glamor_composite_choose_shader(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
+ PixmapPtr source_pixmap,
+ PixmapPtr mask_pixmap,
+ PixmapPtr dest_pixmap,
glamor_pixmap_private *source_pixmap_priv,
glamor_pixmap_private *mask_pixmap_priv,
glamor_pixmap_private *dest_pixmap_priv,
struct shader_key *s_key,
glamor_composite_shader ** shader,
struct blendinfo *op_info,
- PictFormatShort *psaved_source_format)
+ PictFormatShort *psaved_source_format,
+ enum ca_state ca_state)
{
ScreenPtr screen = dest->pDrawable->pScreen;
- PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
- PixmapPtr source_pixmap = NULL;
- PixmapPtr mask_pixmap = NULL;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
enum glamor_pixmap_status source_status = GLAMOR_NONE;
enum glamor_pixmap_status mask_status = GLAMOR_NONE;
PictFormatShort saved_source_format = 0;
@@ -849,6 +801,11 @@ glamor_composite_choose_shader(CARD8 op,
goto fail;
}
+ if (!glamor_render_format_is_supported(dest->format)) {
+ glamor_fallback("Unsupported dest picture format.\n");
+ goto fail;
+ }
+
memset(&key, 0, sizeof(key));
if (!source) {
key.source = SHADER_SOURCE_SOLID;
@@ -894,17 +851,19 @@ glamor_composite_choose_shader(CARD8 op,
}
if (!mask->componentAlpha) {
- key.in = SHADER_IN_NORMAL;
+ key.in = glamor_program_alpha_normal;
}
else {
if (op == PictOpClear)
key.mask = SHADER_MASK_NONE;
+ else if (glamor_priv->has_dual_blend)
+ key.in = glamor_program_alpha_dual_blend;
else if (op == PictOpSrc || op == PictOpAdd
|| op == PictOpIn || op == PictOpOut
|| op == PictOpOverReverse)
- key.in = SHADER_IN_CA_SOURCE;
+ key.in = glamor_program_alpha_ca_second;
else if (op == PictOpOutReverse || op == PictOpInReverse) {
- key.in = SHADER_IN_CA_ALPHA;
+ key.in = glamor_program_alpha_ca_first;
}
else {
glamor_fallback("Unsupported component alpha op: %d\n", op);
@@ -914,7 +873,13 @@ glamor_composite_choose_shader(CARD8 op,
}
else {
key.mask = SHADER_MASK_NONE;
- key.in = SHADER_IN_SOURCE_ONLY;
+ }
+
+ if (dest_pixmap->drawable.bitsPerPixel <= 8 &&
+ glamor_priv->one_channel_format == GL_RED) {
+ key.dest_swizzle = SHADER_DEST_SWIZZLE_ALPHA_TO_RED;
+ } else {
+ key.dest_swizzle = SHADER_DEST_SWIZZLE_DEFAULT;
}
if (source && source->alphaMap) {
@@ -928,13 +893,12 @@ glamor_composite_choose_shader(CARD8 op,
if (key.source == SHADER_SOURCE_TEXTURE ||
key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
- source_pixmap = source_pixmap_priv->base.pixmap;
if (source_pixmap == dest_pixmap) {
/* XXX source and the dest share the same texture.
* Does it need special handle? */
glamor_fallback("source == dest\n");
}
- if (source_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) {
+ if (source_pixmap_priv->gl_fbo == GLAMOR_FBO_UNATTACHED) {
#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
source_status = GLAMOR_UPLOAD_PENDING;
#else
@@ -946,12 +910,11 @@ glamor_composite_choose_shader(CARD8 op,
if (key.mask == SHADER_MASK_TEXTURE ||
key.mask == SHADER_MASK_TEXTURE_ALPHA) {
- mask_pixmap = mask_pixmap_priv->base.pixmap;
if (mask_pixmap == dest_pixmap) {
glamor_fallback("mask == dest\n");
goto fail;
}
- if (mask_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) {
+ if (mask_pixmap_priv->gl_fbo == GLAMOR_FBO_UNATTACHED) {
#ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
mask_status = GLAMOR_UPLOAD_PENDING;
#else
@@ -976,9 +939,6 @@ glamor_composite_choose_shader(CARD8 op,
goto fail;
}
- if (source->format != saved_source_format) {
- glamor_picture_format_fixup(source, source_pixmap_priv);
- }
/* XXX
* By default, glamor_upload_picture_to_texture will wire alpha to 1
* if one picture doesn't have alpha. So we don't do that again in
@@ -1019,6 +979,11 @@ glamor_composite_choose_shader(CARD8 op,
glamor_fallback("Failed to upload source texture.\n");
goto fail;
}
+ } else {
+ if (!glamor_render_format_is_supported(source->format)) {
+ glamor_fallback("Unsupported source picture format.\n");
+ goto fail;
+ }
}
if (mask_status == GLAMOR_UPLOAD_PENDING) {
@@ -1027,6 +992,11 @@ glamor_composite_choose_shader(CARD8 op,
glamor_fallback("Failed to upload mask texture.\n");
goto fail;
}
+ } else if (mask) {
+ if (!glamor_render_format_is_supported(mask->format)) {
+ glamor_fallback("Unsupported mask picture format.\n");
+ goto fail;
+ }
}
}
#endif
@@ -1041,25 +1011,10 @@ glamor_composite_choose_shader(CARD8 op,
goto fail;
}
- /*Before enter the rendering stage, we need to fixup
- * transformed source and mask, if the transform is not int translate. */
- if (key.source != SHADER_SOURCE_SOLID
- && source->transform
- && !pixman_transform_is_int_translate(source->transform)
- && source_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
- if (!glamor_fixup_pixmap_priv(screen, source_pixmap_priv))
- goto fail;
- }
- if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID
- && mask->transform
- && !pixman_transform_is_int_translate(mask->transform)
- && mask_pixmap_priv->type != GLAMOR_TEXTURE_LARGE) {
- if (!glamor_fixup_pixmap_priv(screen, mask_pixmap_priv))
- goto fail;
- }
-
- if (!glamor_set_composite_op(screen, op, op_info, dest, mask))
+ if (!glamor_set_composite_op(screen, op, op_info, dest, mask, ca_state,
+ &key)) {
goto fail;
+ }
*shader = glamor_lookup_composite_shader(screen, &key);
if ((*shader)->prog == 0) {
@@ -1071,7 +1026,7 @@ glamor_composite_choose_shader(CARD8 op,
memcpy(&(*shader)->source_solid_color[0],
source_solid_color, 4 * sizeof(float));
else {
- (*shader)->source_priv = source_pixmap_priv;
+ (*shader)->source_pixmap = source_pixmap;
(*shader)->source = source;
}
@@ -1079,7 +1034,7 @@ glamor_composite_choose_shader(CARD8 op,
memcpy(&(*shader)->mask_solid_color[0],
mask_solid_color, 4 * sizeof(float));
else {
- (*shader)->mask_priv = mask_pixmap_priv;
+ (*shader)->mask_pixmap = mask_pixmap;
(*shader)->mask = mask;
}
@@ -1095,16 +1050,13 @@ glamor_composite_choose_shader(CARD8 op,
return ret;
}
-void
-glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
+static void
+glamor_composite_set_shader_blend(glamor_screen_private *glamor_priv,
+ glamor_pixmap_private *dest_priv,
struct shader_key *key,
glamor_composite_shader *shader,
struct blendinfo *op_info)
{
- glamor_screen_private *glamor_priv;
-
- glamor_priv = dest_priv->base.glamor_priv;
-
glamor_make_current(glamor_priv);
glUseProgram(shader->prog);
@@ -1115,7 +1067,7 @@ glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
else {
glamor_set_composite_texture(glamor_priv, 0,
shader->source,
- shader->source_priv, shader->source_wh,
+ shader->source_pixmap, shader->source_wh,
shader->source_repeat_mode);
}
@@ -1127,7 +1079,7 @@ glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
else {
glamor_set_composite_texture(glamor_priv, 1,
shader->mask,
- shader->mask_priv, shader->mask_wh,
+ shader->mask_pixmap, shader->mask_wh,
shader->mask_repeat_mode);
}
}
@@ -1146,17 +1098,17 @@ glamor_composite_with_shader(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
+ PixmapPtr source_pixmap,
+ PixmapPtr mask_pixmap,
+ PixmapPtr dest_pixmap,
glamor_pixmap_private *source_pixmap_priv,
glamor_pixmap_private *mask_pixmap_priv,
glamor_pixmap_private *dest_pixmap_priv,
int nrect, glamor_composite_rect_t *rects,
- Bool two_pass_ca)
+ enum ca_state ca_state)
{
ScreenPtr screen = dest->pDrawable->pScreen;
- glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv;
- PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
- PixmapPtr source_pixmap = NULL;
- PixmapPtr mask_pixmap = NULL;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
GLfloat dst_xscale, dst_yscale;
GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1;
struct shader_key key, key_ca;
@@ -1172,26 +1124,29 @@ glamor_composite_with_shader(CARD8 op,
struct blendinfo op_info, op_info_ca;
if (!glamor_composite_choose_shader(op, source, mask, dest,
+ source_pixmap, mask_pixmap, dest_pixmap,
source_pixmap_priv, mask_pixmap_priv,
dest_pixmap_priv,
&key, &shader, &op_info,
- &saved_source_format)) {
+ &saved_source_format, ca_state)) {
glamor_fallback("glamor_composite_choose_shader failed\n");
return ret;
}
- if (two_pass_ca) {
+ if (ca_state == CA_TWO_PASS) {
if (!glamor_composite_choose_shader(PictOpAdd, source, mask, dest,
+ source_pixmap, mask_pixmap, dest_pixmap,
source_pixmap_priv,
mask_pixmap_priv, dest_pixmap_priv,
&key_ca, &shader_ca, &op_info_ca,
- &saved_source_format)) {
+ &saved_source_format, ca_state)) {
glamor_fallback("glamor_composite_choose_shader failed\n");
return ret;
}
}
- glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
- glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info);
+ glamor_set_destination_pixmap_priv_nc(glamor_priv, dest_pixmap, dest_pixmap_priv);
+ glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv, &key, shader, &op_info);
+ glamor_set_alu(screen, GXcopy);
glamor_make_current(glamor_priv);
@@ -1203,10 +1158,9 @@ glamor_composite_with_shader(CARD8 op,
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
glamor_get_drawable_deltas(dest->pDrawable, dest_pixmap,
&dest_x_off, &dest_y_off);
- pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
+ pixmap_priv_get_dest_scale(dest_pixmap, dest_pixmap_priv, &dst_xscale, &dst_yscale);
if (glamor_priv->has_source_coords) {
- source_pixmap = source_pixmap_priv->base.pixmap;
glamor_get_drawable_deltas(source->pDrawable,
source_pixmap, &source_x_off, &source_y_off);
pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale);
@@ -1217,7 +1171,6 @@ glamor_composite_with_shader(CARD8 op,
}
if (glamor_priv->has_mask_coords) {
- mask_pixmap = mask_pixmap_priv->base.pixmap;
glamor_get_drawable_deltas(mask->pDrawable, mask_pixmap,
&mask_x_off, &mask_y_off);
pixmap_priv_get_scale(mask_pixmap_priv, &mask_xscale, &mask_yscale);
@@ -1269,7 +1222,8 @@ glamor_composite_with_shader(CARD8 op,
vb_stride);
vertices += 2;
if (key.source != SHADER_SOURCE_SOLID) {
- glamor_set_normalize_tcoords_generic(source_pixmap_priv,
+ glamor_set_normalize_tcoords_generic(source_pixmap,
+ source_pixmap_priv,
source->repeatType,
psrc_matrix, src_xscale,
src_yscale, x_source,
@@ -1280,7 +1234,8 @@ glamor_composite_with_shader(CARD8 op,
}
if (key.mask != SHADER_MASK_NONE && key.mask != SHADER_MASK_SOLID) {
- glamor_set_normalize_tcoords_generic(mask_pixmap_priv,
+ glamor_set_normalize_tcoords_generic(mask_pixmap,
+ mask_pixmap_priv,
mask->repeatType,
pmask_matrix, mask_xscale,
mask_yscale, x_mask,
@@ -1289,7 +1244,7 @@ glamor_composite_with_shader(CARD8 op,
vertices, vb_stride);
vertices += 2;
}
- glamor_priv->render_nr_verts += 4;
+ glamor_priv->render_nr_quads++;
rects++;
/* We've incremented by one of our 4 verts, now do the other 3. */
@@ -1298,12 +1253,12 @@ glamor_composite_with_shader(CARD8 op,
glamor_put_vbo_space(screen);
glamor_flush_composite_rects(screen);
nrect -= rect_processed;
- if (two_pass_ca) {
- glamor_composite_set_shader_blend(dest_pixmap_priv,
+ if (ca_state == CA_TWO_PASS) {
+ glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv,
&key_ca, shader_ca, &op_info_ca);
glamor_flush_composite_rects(screen);
if (nrect)
- glamor_composite_set_shader_blend(dest_pixmap_priv,
+ glamor_composite_set_shader_blend(glamor_priv, dest_pixmap_priv,
&key, shader, &op_info);
}
}
@@ -1320,7 +1275,7 @@ glamor_composite_with_shader(CARD8 op,
return ret;
}
-PicturePtr
+static PicturePtr
glamor_convert_gradient_picture(ScreenPtr screen,
PicturePtr source,
int x_source,
@@ -1329,12 +1284,17 @@ glamor_convert_gradient_picture(ScreenPtr screen,
PixmapPtr pixmap;
PicturePtr dst = NULL;
int error;
+ PictFormatPtr pFormat;
PictFormatShort format;
- if (!source->pDrawable)
+ if (source->pDrawable) {
+ pFormat = source->pFormat;
+ format = pFormat->format;
+ } else {
format = PICT_a8r8g8b8;
- else
- format = source->format;
+ pFormat = PictureMatchFormat(screen, 32, format);
+ }
+
#ifdef GLAMOR_GRADIENT_SHADER
if (!source->pDrawable) {
if (source->pSourcePict->type == SourcePictTypeLinear) {
@@ -1370,10 +1330,7 @@ glamor_convert_gradient_picture(ScreenPtr screen,
return NULL;
dst = CreatePicture(0,
- &pixmap->drawable,
- PictureMatchFormat(screen,
- PIXMAN_FORMAT_DEPTH(format),
- format), 0, 0, serverClient, &error);
+ &pixmap->drawable, pFormat, 0, 0, serverClient, &error);
glamor_destroy_pixmap(pixmap);
if (!dst)
return NULL;
@@ -1390,18 +1347,22 @@ glamor_composite_clipped_region(CARD8 op,
PicturePtr source,
PicturePtr mask,
PicturePtr dest,
- glamor_pixmap_private *source_pixmap_priv,
- glamor_pixmap_private *mask_pixmap_priv,
- glamor_pixmap_private *dest_pixmap_priv,
+ PixmapPtr source_pixmap,
+ PixmapPtr mask_pixmap,
+ PixmapPtr dest_pixmap,
RegionPtr region,
int x_source,
int y_source,
int x_mask, int y_mask, int x_dest, int y_dest)
{
+ glamor_pixmap_private *source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
+ glamor_pixmap_private *mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
+ glamor_pixmap_private *dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(dest_pixmap->drawable.pScreen);
ScreenPtr screen = dest->pDrawable->pScreen;
- PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
- PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
PicturePtr temp_src = source, temp_mask = mask;
+ PixmapPtr temp_src_pixmap = source_pixmap;
+ PixmapPtr temp_mask_pixmap = mask_pixmap;
glamor_pixmap_private *temp_src_priv = source_pixmap_priv;
glamor_pixmap_private *temp_mask_priv = mask_pixmap_priv;
int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
@@ -1415,7 +1376,7 @@ glamor_composite_clipped_region(CARD8 op,
int height;
BoxPtr box;
int nbox;
- Bool two_pass_ca = FALSE;
+ enum ca_state ca_state = CA_NONE;
extent = RegionExtents(region);
box = RegionRects(region);
@@ -1431,12 +1392,6 @@ glamor_composite_clipped_region(CARD8 op,
DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n",
x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
- if (source_pixmap_priv)
- source_pixmap = source_pixmap_priv->base.pixmap;
-
- if (mask_pixmap_priv)
- mask_pixmap = mask_pixmap_priv->base.pixmap;
-
/* XXX is it possible source mask have non-zero drawable.x/y? */
if (source
&& ((!source->pDrawable
@@ -1454,8 +1409,8 @@ glamor_composite_clipped_region(CARD8 op,
temp_src = source;
goto out;
}
- temp_src_priv =
- glamor_get_pixmap_private((PixmapPtr) (temp_src->pDrawable));
+ temp_src_pixmap = (PixmapPtr) (temp_src->pDrawable);
+ temp_src_priv = glamor_get_pixmap_private(temp_src_pixmap);
x_temp_src = -extent->x1 + x_dest + dest->pDrawable->x;
y_temp_src = -extent->y1 + y_dest + dest->pDrawable->y;
}
@@ -1478,36 +1433,28 @@ glamor_composite_clipped_region(CARD8 op,
temp_mask = mask;
goto out;
}
- temp_mask_priv =
- glamor_get_pixmap_private((PixmapPtr) (temp_mask->pDrawable));
+ temp_mask_pixmap = (PixmapPtr) (temp_mask->pDrawable);
+ temp_mask_priv = glamor_get_pixmap_private(temp_mask_pixmap);
x_temp_mask = -extent->x1 + x_dest + dest->pDrawable->x;
y_temp_mask = -extent->y1 + y_dest + dest->pDrawable->y;
}
- /* Do two-pass PictOpOver componentAlpha, until we enable
- * dual source color blending.
- */
if (mask && mask->componentAlpha) {
- if (op == PictOpOver) {
- two_pass_ca = TRUE;
- op = PictOpOutReverse;
- }
- }
-
- if (!mask && temp_src) {
- if (glamor_composite_with_copy(op, temp_src, dest,
- x_temp_src, y_temp_src,
- x_dest, y_dest, region)) {
- ok = TRUE;
- goto out;
+ if (glamor_priv->has_dual_blend) {
+ ca_state = CA_DUAL_BLEND;
+ } else {
+ if (op == PictOpOver) {
+ ca_state = CA_TWO_PASS;
+ op = PictOpOutReverse;
+ }
}
}
- if (source_pixmap == dest_pixmap) {
+ if (temp_src_pixmap == dest_pixmap) {
glamor_fallback("source and dest pixmaps are the same\n");
goto out;
}
- if (mask_pixmap == dest_pixmap) {
+ if (temp_mask_pixmap == dest_pixmap) {
glamor_fallback("mask and dest pixmaps are the same\n");
goto out;
}
@@ -1548,9 +1495,10 @@ glamor_composite_clipped_region(CARD8 op,
DEBUGF("dest %d %d \n", prect[i].x_dst, prect[i].y_dst);
}
ok = glamor_composite_with_shader(op, temp_src, temp_mask, dest,
+ temp_src_pixmap, temp_mask_pixmap, dest_pixmap,
temp_src_priv, temp_mask_priv,
dest_pixmap_priv,
- box_cnt, prect, two_pass_ca);
+ box_cnt, prect, ca_state);
if (!ok)
break;
nbox -= box_cnt;
@@ -1568,43 +1516,35 @@ glamor_composite_clipped_region(CARD8 op,
return ok;
}
-static Bool
-_glamor_composite(CARD8 op,
- PicturePtr source,
- PicturePtr mask,
- PicturePtr dest,
- INT16 x_source,
- INT16 y_source,
- INT16 x_mask,
- INT16 y_mask,
- INT16 x_dest, INT16 y_dest,
- CARD16 width, CARD16 height, Bool fallback)
+void
+glamor_composite(CARD8 op,
+ PicturePtr source,
+ PicturePtr mask,
+ PicturePtr dest,
+ INT16 x_source,
+ INT16 y_source,
+ INT16 x_mask,
+ INT16 y_mask,
+ INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height)
{
ScreenPtr screen = dest->pDrawable->pScreen;
- glamor_pixmap_private *dest_pixmap_priv;
- glamor_pixmap_private *source_pixmap_priv = NULL, *mask_pixmap_priv = NULL;
PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(dest->pDrawable);
PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- Bool ret = TRUE;
RegionRec region;
BoxPtr extent;
int nbox, ok = FALSE;
int force_clip = 0;
- dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
-
if (source->pDrawable) {
source_pixmap = glamor_get_drawable_pixmap(source->pDrawable);
- source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
- if (source_pixmap_priv && source_pixmap_priv->type == GLAMOR_DRM_ONLY)
+ if (glamor_pixmap_drm_only(source_pixmap))
goto fail;
}
if (mask && mask->pDrawable) {
mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
- mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
- if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_DRM_ONLY)
+ if (glamor_pixmap_drm_only(mask_pixmap))
goto fail;
}
@@ -1613,14 +1553,15 @@ _glamor_composite(CARD8 op,
source_pixmap, x_source, y_source, x_mask, y_mask, x_dest, y_dest,
width, height);
- if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
+ if (!glamor_pixmap_has_fbo(dest_pixmap))
goto fail;
- }
- if (op >= ARRAY_SIZE(composite_op_info))
+ if (op >= ARRAY_SIZE(composite_op_info)) {
+ glamor_fallback("Unsupported composite op %x\n", op);
goto fail;
+ }
- if (mask && mask->componentAlpha) {
+ if (mask && mask->componentAlpha && !glamor_priv->has_dual_blend) {
if (op == PictOpAtop
|| op == PictOpAtopReverse
|| op == PictOpXor || op >= PictOpSaturate) {
@@ -1647,18 +1588,16 @@ _glamor_composite(CARD8 op,
(mask_pixmap ? mask->pDrawable->y : 0),
x_dest + dest->pDrawable->x,
y_dest + dest->pDrawable->y, width, height)) {
- ret = TRUE;
- goto done;
+ return;
}
nbox = REGION_NUM_RECTS(&region);
DEBUGF("first clipped when compositing.\n");
DEBUGRegionPrint(&region);
extent = RegionExtents(&region);
- if (nbox == 0) {
- ret = TRUE;
- goto done;
- }
+ if (nbox == 0)
+ return;
+
/* If destination is not a large pixmap, but the region is larger
* than texture size limitation, and source or mask is memory pixmap,
* then there may be need to load a large memory pixmap to a
@@ -1667,28 +1606,28 @@ _glamor_composite(CARD8 op,
* pixmap. */
if (!glamor_check_fbo_size(glamor_priv,
extent->x2 - extent->x1, extent->y2 - extent->y1)
- && (dest_pixmap_priv->type != GLAMOR_TEXTURE_LARGE)
- && ((source_pixmap_priv
- && (source_pixmap_priv->type == GLAMOR_MEMORY ||
+ && glamor_pixmap_is_large(dest_pixmap)
+ && ((source_pixmap
+ && (glamor_pixmap_is_memory(source_pixmap) ||
source->repeatType == RepeatPad))
- || (mask_pixmap_priv &&
- (mask_pixmap_priv->type == GLAMOR_MEMORY ||
+ || (mask_pixmap &&
+ (glamor_pixmap_is_memory(mask_pixmap) ||
mask->repeatType == RepeatPad))
- || (!source_pixmap_priv &&
+ || (!source_pixmap &&
(source->pSourcePict->type != SourcePictTypeSolidFill))
- || (!mask_pixmap_priv && mask &&
+ || (!mask_pixmap && mask &&
mask->pSourcePict->type != SourcePictTypeSolidFill)))
force_clip = 1;
- if (force_clip || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
- || (source_pixmap_priv
- && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)
- || (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE))
+ if (force_clip || glamor_pixmap_is_large(dest_pixmap)
+ || (source_pixmap
+ && glamor_pixmap_is_large(source_pixmap))
+ || (mask_pixmap && glamor_pixmap_is_large(mask_pixmap)))
ok = glamor_composite_largepixmap_region(op,
source, mask, dest,
- source_pixmap_priv,
- mask_pixmap_priv,
- dest_pixmap_priv,
+ source_pixmap,
+ mask_pixmap,
+ dest_pixmap,
&region, force_clip,
x_source, y_source,
x_mask, y_mask,
@@ -1696,9 +1635,9 @@ _glamor_composite(CARD8 op,
else
ok = glamor_composite_clipped_region(op, source,
mask, dest,
- source_pixmap_priv,
- mask_pixmap_priv,
- dest_pixmap_priv,
+ source_pixmap,
+ mask_pixmap,
+ dest_pixmap,
&region,
x_source, y_source,
x_mask, y_mask, x_dest, y_dest);
@@ -1706,17 +1645,9 @@ _glamor_composite(CARD8 op,
REGION_UNINIT(dest->pDrawable->pScreen, &region);
if (ok)
- goto done;
- fail:
+ return;
- if (!fallback && glamor_ddx_fallback_check_pixmap(&dest_pixmap->drawable)
- && (!source_pixmap
- || glamor_ddx_fallback_check_pixmap(&source_pixmap->drawable))
- && (!mask_pixmap
- || glamor_ddx_fallback_check_pixmap(&mask_pixmap->drawable))) {
- ret = FALSE;
- goto done;
- }
+ fail:
glamor_fallback
("from picts %p:%p %dx%d / %p:%p %d x %d (%c,%c) to pict %p:%p %dx%d (%c)\n",
@@ -1747,192 +1678,4 @@ _glamor_composite(CARD8 op,
glamor_finish_access_picture(mask);
glamor_finish_access_picture(source);
glamor_finish_access_picture(dest);
-
- done:
- return ret;
}
-
-void
-glamor_composite(CARD8 op,
- PicturePtr source,
- PicturePtr mask,
- PicturePtr dest,
- INT16 x_source,
- INT16 y_source,
- INT16 x_mask,
- INT16 y_mask,
- INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height)
-{
- _glamor_composite(op, source, mask, dest, x_source, y_source,
- x_mask, y_mask, x_dest, y_dest, width, height, TRUE);
-}
-
-Bool
-glamor_composite_nf(CARD8 op,
- PicturePtr source,
- PicturePtr mask,
- PicturePtr dest,
- INT16 x_source,
- INT16 y_source,
- INT16 x_mask,
- INT16 y_mask,
- INT16 x_dest, INT16 y_dest, CARD16 width, CARD16 height)
-{
- return _glamor_composite(op, source, mask, dest, x_source, y_source,
- x_mask, y_mask, x_dest, y_dest, width, height,
- FALSE);
-}
-
-static void
-glamor_get_src_rect_extent(int nrect,
- glamor_composite_rect_t *rects, BoxPtr extent)
-{
- extent->x1 = MAXSHORT;
- extent->y1 = MAXSHORT;
- extent->x2 = MINSHORT;
- extent->y2 = MINSHORT;
-
- while (nrect--) {
- if (extent->x1 > rects->x_src)
- extent->x1 = rects->x_src;
- if (extent->y1 > rects->y_src)
- extent->y1 = rects->y_src;
- if (extent->x2 < rects->x_src + rects->width)
- extent->x2 = rects->x_src + rects->width;
- if (extent->y2 < rects->y_src + rects->height)
- extent->y2 = rects->y_src + rects->height;
- rects++;
- }
-}
-
-static void
-glamor_composite_src_rect_translate(int nrect,
- glamor_composite_rect_t *rects,
- int x, int y)
-{
- while (nrect--) {
- rects->x_src += x;
- rects->y_src += y;
- rects++;
- }
-}
-
-void
-glamor_composite_glyph_rects(CARD8 op,
- PicturePtr src, PicturePtr mask, PicturePtr dst,
- int nrect, glamor_composite_rect_t *rects)
-{
- int n;
- PicturePtr temp_src = NULL;
- glamor_composite_rect_t *r;
-
- ValidatePicture(src);
- ValidatePicture(dst);
- if (!(glamor_is_large_picture(src)
- || (mask && glamor_is_large_picture(mask))
- || glamor_is_large_picture(dst))) {
- glamor_pixmap_private *src_pixmap_priv = NULL;
- glamor_pixmap_private *mask_pixmap_priv = NULL;
- glamor_pixmap_private *dst_pixmap_priv;
- glamor_pixmap_private *temp_src_priv = NULL;
- BoxRec src_extent;
-
- dst_pixmap_priv = glamor_get_pixmap_private
- (glamor_get_drawable_pixmap(dst->pDrawable));
-
- if (mask && mask->pDrawable)
- mask_pixmap_priv = glamor_get_pixmap_private
- (glamor_get_drawable_pixmap(mask->pDrawable));
- if (src->pDrawable)
- src_pixmap_priv = glamor_get_pixmap_private
- (glamor_get_drawable_pixmap(src->pDrawable));
-
- if (!src->pDrawable
- && (src->pSourcePict->type != SourcePictTypeSolidFill)) {
- glamor_get_src_rect_extent(nrect, rects, &src_extent);
- temp_src = glamor_convert_gradient_picture(dst->pDrawable->pScreen,
- src,
- src_extent.x1,
- src_extent.y1,
- src_extent.x2 -
- src_extent.x1,
- src_extent.y2 -
- src_extent.y1);
- if (!temp_src)
- goto fallback;
-
- temp_src_priv = glamor_get_pixmap_private
- ((PixmapPtr) (temp_src->pDrawable));
- glamor_composite_src_rect_translate(nrect, rects,
- -src_extent.x1, -src_extent.y1);
- }
- else {
- temp_src = src;
- temp_src_priv = src_pixmap_priv;
- }
-
- if (mask && mask->componentAlpha) {
- if (op == PictOpOver) {
- if (glamor_composite_with_shader(PictOpOutReverse,
- temp_src, mask, dst,
- temp_src_priv,
- mask_pixmap_priv,
- dst_pixmap_priv, nrect, rects,
- TRUE))
- goto done;
- }
- }
- else {
- if (glamor_composite_with_shader
- (op, temp_src, mask, dst, temp_src_priv, mask_pixmap_priv,
- dst_pixmap_priv, nrect, rects, FALSE))
- goto done;
- }
- }
- fallback:
- n = nrect;
- r = rects;
-
- while (n--) {
- CompositePicture(op,
- temp_src ? temp_src : src,
- mask,
- dst,
- r->x_src, r->y_src,
- r->x_mask, r->y_mask,
- r->x_dst, r->y_dst, r->width, r->height);
- r++;
- }
-
- done:
- if (temp_src && temp_src != src)
- FreePicture(temp_src, 0);
-}
-
-static Bool
-_glamor_composite_rects(CARD8 op,
- PicturePtr pDst,
- xRenderColor *color,
- int nRect, xRectangle *rects, Bool fallback)
-{
- miCompositeRects(op, pDst, color, nRect, rects);
- return TRUE;
-}
-
-void
-glamor_composite_rects(CARD8 op,
- PicturePtr pDst,
- xRenderColor *color, int nRect, xRectangle *rects)
-{
- _glamor_composite_rects(op, pDst, color, nRect, rects, TRUE);
-}
-
-Bool
-glamor_composite_rects_nf(CARD8 op,
- PicturePtr pDst,
- xRenderColor *color, int nRect, xRectangle *rects)
-{
- return _glamor_composite_rects(op, pDst, color, nRect, rects, FALSE);
-}
-
-#endif /* RENDER */
diff --git a/xserver/glamor/glamor_segs.c b/xserver/glamor/glamor_segs.c
index ff0daef10..5fffa3b0f 100644
--- a/xserver/glamor/glamor_segs.c
+++ b/xserver/glamor/glamor_segs.c
@@ -44,7 +44,7 @@ glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc,
int off_x, off_y;
xSegment *v;
char *vbo_offset;
- int box_x, box_y;
+ int box_index;
int add_last;
pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -91,11 +91,11 @@ glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc,
glEnable(GL_SCISSOR_TEST);
- glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ glamor_pixmap_loop(pixmap_priv, box_index) {
int nbox = RegionNumRects(gc->pCompositeClip);
BoxPtr box = RegionRects(gc->pCompositeClip);
- glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE,
+ glamor_set_destination_drawable(drawable, box_index, TRUE, TRUE,
prog->matrix_uniform, &off_x, &off_y);
while (nbox--) {
@@ -109,12 +109,10 @@ glamor_poly_segment_solid_gl(DrawablePtr drawable, GCPtr gc,
}
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;
}
@@ -168,21 +166,3 @@ glamor_poly_segment(DrawablePtr drawable, GCPtr gc,
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/xserver/glamor/glamor_spans.c b/xserver/glamor/glamor_spans.c
index 6ebb12e18..89a9c5102 100644
--- a/xserver/glamor/glamor_spans.c
+++ b/xserver/glamor/glamor_spans.c
@@ -55,7 +55,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
GLshort *v;
char *vbo_offset;
int c;
- int box_x, box_y;
+ int box_index;
pixmap_priv = glamor_get_pixmap_private(pixmap);
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
@@ -68,7 +68,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
&glamor_facet_fillspans_130);
if (!prog)
- goto bail_ctx;
+ goto bail;
/* Set up the vertex buffers for the points */
@@ -93,7 +93,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
&glamor_facet_fillspans_120);
if (!prog)
- goto bail_ctx;
+ goto bail;
/* Set up the vertex buffers for the points */
@@ -119,11 +119,12 @@ glamor_fill_spans_gl(DrawablePtr drawable,
glEnable(GL_SCISSOR_TEST);
- glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ glamor_pixmap_loop(pixmap_priv, box_index) {
int nbox = RegionNumRects(gc->pCompositeClip);
BoxPtr box = RegionRects(gc->pCompositeClip);
- glamor_set_destination_drawable(drawable, box_x, box_y, FALSE, FALSE, prog->matrix_uniform, &off_x, &off_y);
+ glamor_set_destination_drawable(drawable, box_index, FALSE, FALSE,
+ prog->matrix_uniform, &off_x, &off_y);
while (nbox--) {
glScissor(box->x1 + off_x,
@@ -134,27 +135,17 @@ glamor_fill_spans_gl(DrawablePtr drawable,
if (glamor_priv->glsl_version >= 130)
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, n);
else {
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
- glDrawArrays(GL_QUADS, 0, 4 * n);
- } else {
- int i;
- for (i = 0; i < n; i++) {
- glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
- }
- }
+ glamor_glDrawArrays_GL_QUADS(glamor_priv, nbox);
}
}
}
glDisable(GL_SCISSOR_TEST);
- glDisable(GL_COLOR_LOGIC_OP);
if (glamor_priv->glsl_version >= 130)
glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
return TRUE;
-bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
bail:
return FALSE;
}
@@ -182,21 +173,6 @@ glamor_fill_spans(DrawablePtr drawable,
glamor_fill_spans_bail(drawable, gc, n, points, widths, sorted);
}
-Bool
-glamor_fill_spans_nf(DrawablePtr drawable,
- GCPtr gc,
- int n, DDXPointPtr points, int *widths, int sorted)
-{
- if (glamor_fill_spans_gl(drawable, gc, n, points, widths, sorted))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
- return FALSE;
-
- glamor_fill_spans_bail(drawable, gc, n, points, widths, sorted);
- return TRUE;
-}
-
static Bool
glamor_get_spans_gl(DrawablePtr drawable, int wmax,
DDXPointPtr points, int *widths, int count, char *dst)
@@ -205,7 +181,7 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax,
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
glamor_pixmap_private *pixmap_priv;
- int box_x, box_y;
+ int box_index;
int n;
char *d;
GLenum type;
@@ -222,9 +198,9 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax,
glamor_make_current(glamor_priv);
- glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
- BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y);
- glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y);
+ glamor_pixmap_loop(pixmap_priv, box_index) {
+ BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_index);
+ glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_index);
glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
glPixelStorei(GL_PACK_ALIGNMENT, 4);
@@ -282,20 +258,6 @@ glamor_get_spans(DrawablePtr drawable, int wmax,
glamor_get_spans_bail(drawable, wmax, points, widths, count, dst);
}
-Bool
-glamor_get_spans_nf(DrawablePtr drawable, int wmax,
- DDXPointPtr points, int *widths, int count, char *dst)
-{
- if (glamor_get_spans_gl(drawable, wmax, points, widths, count, dst))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable))
- return FALSE;
-
- glamor_get_spans_bail(drawable, wmax, points, widths, count, dst);
- return TRUE;
-}
-
static Bool
glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
DDXPointPtr points, int *widths, int numPoints, int sorted)
@@ -304,7 +266,7 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
glamor_pixmap_private *pixmap_priv;
- int box_x, box_y;
+ int box_index;
int n;
char *s;
GLenum type;
@@ -318,7 +280,7 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
if (gc->alu != GXcopy)
goto bail;
- if (!glamor_pm_is_solid(&pixmap->drawable, gc->planemask))
+ if (!glamor_pm_is_solid(gc->depth, gc->planemask))
goto bail;
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
@@ -328,9 +290,9 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
- BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y);
- glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y);
+ glamor_pixmap_loop(pixmap_priv, box_index) {
+ BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_index);
+ glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(pixmap_priv, box_index);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fbo->tex);
@@ -415,17 +377,3 @@ glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
return;
glamor_set_spans_bail(drawable, gc, src, points, widths, numPoints, sorted);
}
-
-Bool
-glamor_set_spans_nf(DrawablePtr drawable, GCPtr gc, char *src,
- DDXPointPtr points, int *widths, int numPoints, int sorted)
-{
- if (glamor_set_spans_gl(drawable, gc, src, points, widths, numPoints, sorted))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
- return FALSE;
-
- glamor_set_spans_bail(drawable, gc, src, points, widths, numPoints, sorted);
- return TRUE;
-}
diff --git a/xserver/glamor/glamor_text.c b/xserver/glamor/glamor_text.c
index 59cd0fdc8..c305305f4 100644
--- a/xserver/glamor/glamor_text.c
+++ b/xserver/glamor/glamor_text.c
@@ -107,7 +107,7 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
int firstCol = font->info.firstCol;
int glyph_spacing_x = glamor_font->glyph_width_bytes * 8;
int glyph_spacing_y = glamor_font->glyph_height;
- int box_x, box_y;
+ int box_index;
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
@@ -142,7 +142,7 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
int height = GLYPHHEIGHTPIXELS(ci);
int tx, ty = 0;
int row = 0, col;
-
+ int second_row = 0;
x += ci->metrics.characterWidth;
if (sixteen) {
@@ -153,8 +153,10 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
row = chars[0];
col = chars[1];
}
- if (FONTLASTROW(font) != 0)
- ty = (row - firstRow) * glyph_spacing_y;
+ if (FONTLASTROW(font) != 0) {
+ ty = ((row - firstRow) / 2) * glyph_spacing_y;
+ second_row = (row - firstRow) & 1;
+ }
else
col += row << 8;
} else {
@@ -165,6 +167,8 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
}
tx = (col - firstCol) * glyph_spacing_x;
+ /* adjust for second row layout */
+ tx += second_row * glamor_font->row_width * 8;
v[ 0] = x1;
v[ 1] = y1;
@@ -184,11 +188,13 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
glEnable(GL_SCISSOR_TEST);
- glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ glamor_pixmap_loop(pixmap_priv, box_index) {
BoxPtr box = RegionRects(gc->pCompositeClip);
int nbox = RegionNumRects(gc->pCompositeClip);
- glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y);
+ glamor_set_destination_drawable(drawable, box_index, TRUE, FALSE,
+ prog->matrix_uniform,
+ &off_x, &off_y);
/* Run over the clip list, drawing the glyphs
* in each box
@@ -210,7 +216,6 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- glDisable(GL_COLOR_LOGIC_OP);
return x;
}
@@ -286,34 +291,18 @@ glamor_poly_text(DrawablePtr drawable, GCPtr gc,
prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_text_progs, &glamor_facet_poly_text);
if (!prog)
- goto bail_ctx;
+ goto bail;
x = glamor_text(drawable, gc, glamor_font, prog,
x, y, count, chars, charinfo, sixteen);
- glDisable(GL_COLOR_LOGIC_OP);
-
*final_pos = x;
return TRUE;
-bail_ctx:
- glDisable(GL_COLOR_LOGIC_OP);
bail:
return FALSE;
}
-Bool
-glamor_poly_text8_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, char *chars, int *final_pos)
-{
- if (glamor_poly_text(drawable, gc, x, y, count, chars, FALSE, final_pos))
- return TRUE;
- if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
- return FALSE;
- *final_pos = miPolyText8(drawable, gc, x, y, count, chars);
- return TRUE;
-}
-
int
glamor_poly_text8(DrawablePtr drawable, GCPtr gc,
int x, int y, int count, char *chars)
@@ -325,19 +314,6 @@ glamor_poly_text8(DrawablePtr drawable, GCPtr gc,
return miPolyText8(drawable, gc, x, y, count, chars);
}
-Bool
-glamor_poly_text16_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, unsigned short *chars, int *final_pos)
-{
- if (glamor_poly_text(drawable, gc, x, y, count, (char *) chars, TRUE, final_pos))
- return TRUE;
-
- if (glamor_ddx_fallback_check_pixmap(drawable) && glamor_ddx_fallback_check_gc(gc))
- return FALSE;
- *final_pos = miPolyText16(drawable, gc, x, y, count, chars);
- return TRUE;
-}
-
int
glamor_poly_text16(DrawablePtr drawable, GCPtr gc,
int x, int y, int count, unsigned short *chars)
@@ -447,7 +423,7 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
fill_facet = &glamor_facet_image_fill;
}
- if (!glamor_build_program(screen, prog, prim_facet, fill_facet))
+ if (!glamor_build_program(screen, prog, prim_facet, fill_facet, NULL, NULL))
goto bail;
}
@@ -461,7 +437,7 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
/* Check planemask before drawing background to
* bail early if it's not OK
*/
- if (!glamor_set_planemask(pixmap, gc->planemask))
+ if (!glamor_set_planemask(gc->depth, gc->planemask))
goto bail;
for (c = 0; c < count; c++)
if (charinfo[c])
@@ -493,17 +469,9 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
return TRUE;
bail:
- glDisable(GL_COLOR_LOGIC_OP);
return FALSE;
}
-Bool
-glamor_image_text8_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, char *chars)
-{
- return glamor_image_text(drawable, gc, x, y, count, chars, FALSE);
-}
-
void
glamor_image_text8(DrawablePtr drawable, GCPtr gc,
int x, int y, int count, char *chars)
@@ -512,13 +480,6 @@ glamor_image_text8(DrawablePtr drawable, GCPtr gc,
miImageText8(drawable, gc, x, y, count, chars);
}
-Bool
-glamor_image_text16_nf(DrawablePtr drawable, GCPtr gc,
- int x, int y, int count, unsigned short *chars)
-{
- return glamor_image_text(drawable, gc, x, y, count, (char *) chars, TRUE);
-}
-
void
glamor_image_text16(DrawablePtr drawable, GCPtr gc,
int x, int y, int count, unsigned short *chars)
diff --git a/xserver/glamor/glamor_transfer.c b/xserver/glamor/glamor_transfer.c
index aa5e8616e..ed81195b6 100644
--- a/xserver/glamor/glamor_transfer.c
+++ b/xserver/glamor/glamor_transfer.c
@@ -42,7 +42,7 @@ glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type)
*type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
break;
case 8:
- *format = GL_ALPHA;
+ *format = glamor_get_screen_private(pixmap->drawable.pScreen)->one_channel_format;
*type = GL_UNSIGNED_BYTE;
break;
default:
@@ -63,7 +63,7 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
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 box_x, box_y;
+ int box_index;
int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
GLenum type;
GLenum format;
@@ -77,9 +77,9 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
if (glamor_priv->has_unpack_subimage)
glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
- glamor_pixmap_loop(priv, box_x, box_y) {
- BoxPtr box = glamor_pixmap_box_at(priv, box_x, box_y);
- glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_x, box_y);
+ glamor_pixmap_loop(priv, box_index) {
+ BoxPtr box = glamor_pixmap_box_at(priv, box_index);
+ glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_index);
BoxPtr boxes = in_boxes;
int nbox = in_nbox;
@@ -167,7 +167,7 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
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 box_x, box_y;
+ int box_index;
int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
GLenum type;
GLenum format;
@@ -180,12 +180,14 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
if (glamor_priv->has_pack_subimage)
glPixelStorei(GL_PACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
- glamor_pixmap_loop(priv, box_x, box_y) {
- BoxPtr box = glamor_pixmap_box_at(priv, box_x, box_y);
- glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_x, box_y);
+ glamor_pixmap_loop(priv, box_index) {
+ BoxPtr box = glamor_pixmap_box_at(priv, box_index);
+ glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_index);
BoxPtr boxes = in_boxes;
int nbox = in_nbox;
+ /* This should not be called on GLAMOR_FBO_NO_FBO-allocated pixmaps. */
+ assert(fbo->fb);
glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
while (nbox--) {
diff --git a/xserver/glamor/glamor_transform.c b/xserver/glamor/glamor_transform.c
index c1df56018..fc96fd670 100644
--- a/xserver/glamor/glamor_transform.c
+++ b/xserver/glamor/glamor_transform.c
@@ -35,18 +35,19 @@
void
glamor_set_destination_drawable(DrawablePtr drawable,
- int box_x,
- int box_y,
+ int box_index,
Bool do_drawable_translate,
Bool center_offset,
GLint matrix_uniform_location,
int *p_off_x,
int *p_off_y)
{
+ 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);
int off_x, off_y;
- BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y);
+ BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_index);
int w = box->x2 - box->x1;
int h = box->y2 - box->y1;
float scale_x = 2.0f / (float) w;
@@ -75,8 +76,6 @@ glamor_set_destination_drawable(DrawablePtr drawable,
* gl_x = (render_x + drawable->x + off_x) * 2 / width - 1
*
* gl_x = (render_x) * 2 / width + (drawable->x + off_x) * 2 / width - 1
- *
- * I'll think about yInverted later, when I have some way to test
*/
if (do_drawable_translate) {
@@ -95,7 +94,7 @@ glamor_set_destination_drawable(DrawablePtr drawable,
scale_x, (off_x + center_adjust) * scale_x - 1.0f,
scale_y, (off_y + center_adjust) * scale_y - 1.0f);
- glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y),
+ glamor_set_destination_pixmap_fbo(glamor_priv, glamor_pixmap_fbo_at(pixmap_priv, box_index),
0, 0, w, h);
}
@@ -105,15 +104,21 @@ glamor_set_destination_drawable(DrawablePtr drawable,
*/
void
-glamor_set_color(PixmapPtr pixmap,
- CARD32 pixel,
- GLint uniform)
+glamor_set_color_depth(ScreenPtr pScreen,
+ int depth,
+ CARD32 pixel,
+ GLint uniform)
{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
float color[4];
glamor_get_rgba_from_pixel(pixel,
&color[0], &color[1], &color[2], &color[3],
- format_for_pixmap(pixmap));
+ format_for_depth(depth));
+
+ if ((depth == 1 || depth == 8) &&
+ glamor_priv->one_channel_format == GL_RED)
+ color[0] = color[3];
glUniform4fv(uniform, 1, color);
}
@@ -127,7 +132,7 @@ glamor_set_solid(PixmapPtr pixmap,
CARD32 pixel;
int alu = use_alu ? gc->alu : GXcopy;
- if (!glamor_set_planemask(pixmap, gc->planemask))
+ if (!glamor_set_planemask(gc->depth, gc->planemask))
return FALSE;
pixel = gc->fgPixel;
@@ -153,12 +158,7 @@ glamor_set_solid(PixmapPtr pixmap,
}
Bool
-glamor_set_texture(PixmapPtr pixmap,
- PixmapPtr texture,
- int off_x,
- int off_y,
- GLint offset_uniform,
- GLint size_uniform)
+glamor_set_texture_pixmap(PixmapPtr texture)
{
glamor_pixmap_private *texture_priv;
@@ -167,14 +167,31 @@ glamor_set_texture(PixmapPtr pixmap,
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(texture_priv))
return FALSE;
- if (texture_priv->type == GLAMOR_TEXTURE_LARGE)
+ if (glamor_pixmap_priv_is_large(texture_priv))
return FALSE;
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture_priv->base.fbo->tex);
+ glBindTexture(GL_TEXTURE_2D, texture_priv->fbo->tex);
+
+ /* we're not setting the sampler uniform here as we always use
+ * GL_TEXTURE0, and the default value for uniforms is zero. So,
+ * save a bit of CPU time by taking advantage of that.
+ */
+ return TRUE;
+}
+
+Bool
+glamor_set_texture(PixmapPtr texture,
+ int off_x,
+ int off_y,
+ GLint offset_uniform,
+ GLint size_inv_uniform)
+{
+ if (!glamor_set_texture_pixmap(texture))
+ return FALSE;
glUniform2f(offset_uniform, off_x, off_y);
- glUniform2f(size_uniform, texture->drawable.width, texture->drawable.height);
+ glUniform2f(size_inv_uniform, 1.0f/texture->drawable.width, 1.0f/texture->drawable.height);
return TRUE;
}
@@ -182,20 +199,19 @@ Bool
glamor_set_tiled(PixmapPtr pixmap,
GCPtr gc,
GLint offset_uniform,
- GLint size_uniform)
+ GLint size_inv_uniform)
{
if (!glamor_set_alu(pixmap->drawable.pScreen, gc->alu))
return FALSE;
- if (!glamor_set_planemask(pixmap, gc->planemask))
+ if (!glamor_set_planemask(gc->depth, gc->planemask))
return FALSE;
- return glamor_set_texture(pixmap,
- gc->tile.pixmap,
+ return glamor_set_texture(gc->tile.pixmap,
-gc->patOrg.x,
-gc->patOrg.y,
offset_uniform,
- size_uniform);
+ size_inv_uniform);
}
static PixmapPtr
@@ -272,8 +288,7 @@ glamor_set_stippled(PixmapPtr pixmap,
if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform))
return FALSE;
- return glamor_set_texture(pixmap,
- stipple,
+ return glamor_set_texture(stipple,
-gc->patOrg.x,
-gc->patOrg.y,
offset_uniform,
diff --git a/xserver/glamor/glamor_transform.h b/xserver/glamor/glamor_transform.h
index 36b789af8..5a520ebb0 100644
--- a/xserver/glamor/glamor_transform.h
+++ b/xserver/glamor/glamor_transform.h
@@ -25,8 +25,7 @@
void
glamor_set_destination_drawable(DrawablePtr drawable,
- int box_x,
- int box_y,
+ int box_index,
Bool do_drawable_translate,
Bool center_offset,
GLint matrix_uniform_location,
@@ -34,13 +33,25 @@ glamor_set_destination_drawable(DrawablePtr drawable,
int *p_off_y);
void
+glamor_set_color_depth(ScreenPtr pScreen,
+ int depth,
+ CARD32 pixel,
+ GLint uniform);
+
+static inline void
glamor_set_color(PixmapPtr pixmap,
CARD32 pixel,
- GLint uniform);
+ GLint uniform)
+{
+ glamor_set_color_depth(pixmap->drawable.pScreen,
+ pixmap->drawable.depth, pixel, uniform);
+}
+
+Bool
+glamor_set_texture_pixmap(PixmapPtr texture);
Bool
-glamor_set_texture(PixmapPtr pixmap,
- PixmapPtr texture,
+glamor_set_texture(PixmapPtr texture,
int off_x,
int off_y,
GLint offset_uniform,
diff --git a/xserver/glamor/glamor_trapezoid.c b/xserver/glamor/glamor_trapezoid.c
index f8bf6c97f..a448a6b3e 100644
--- a/xserver/glamor/glamor_trapezoid.c
+++ b/xserver/glamor/glamor_trapezoid.c
@@ -32,7 +32,6 @@
#include "glamor_priv.h"
-#ifdef RENDER
#include "mipict.h"
#include "fbpict.h"
@@ -155,18 +154,3 @@ glamor_trapezoids(CARD8 op,
FreePicture(picture, 0);
}
-
-Bool
-glamor_trapezoids_nf(CARD8 op,
- PicturePtr src, PicturePtr dst,
- PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
- int ntrap, xTrapezoid *traps)
-{
- DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap);
-
- glamor_trapezoids(op, src, dst, mask_format, x_src,
- y_src, ntrap, traps);
- return TRUE;
-}
-
-#endif /* RENDER */
diff --git a/xserver/glamor/glamor_triangles.c b/xserver/glamor/glamor_triangles.c
index b89cb2de7..88a46c11f 100644
--- a/xserver/glamor/glamor_triangles.c
+++ b/xserver/glamor/glamor_triangles.c
@@ -28,29 +28,6 @@
#include "glamor_priv.h"
-static Bool
-_glamor_triangles(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris,
- Bool fallback)
-{
- if (!fallback && glamor_ddx_fallback_check_pixmap(pDst->pDrawable)
- && (!pSrc->pDrawable
- || glamor_ddx_fallback_check_pixmap(pSrc->pDrawable)))
- return FALSE;
-
- if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW) &&
- glamor_prepare_access_picture(pSrc, GLAMOR_ACCESS_RO)) {
- fbTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris);
- }
- glamor_finish_access_picture(pSrc);
- glamor_finish_access_picture(pDst);
-
- return TRUE;
-}
-
void
glamor_triangles(CARD8 op,
PicturePtr pSrc,
@@ -58,17 +35,10 @@ glamor_triangles(CARD8 op,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
{
- _glamor_triangles(op, pSrc, pDst, maskFormat,
- xSrc, ySrc, ntris, tris, TRUE);
-}
-
-Bool
-glamor_triangles_nf(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc, INT16 ySrc, int ntris, xTriangle * tris)
-{
- return _glamor_triangles(op, pSrc, pDst, maskFormat,
- xSrc, ySrc, ntris, tris, FALSE);
+ if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW) &&
+ glamor_prepare_access_picture(pSrc, GLAMOR_ACCESS_RO)) {
+ fbTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris);
+ }
+ glamor_finish_access_picture(pSrc);
+ glamor_finish_access_picture(pDst);
}
diff --git a/xserver/glamor/glamor_utils.c b/xserver/glamor/glamor_utils.c
index f06896096..d3e6fd3ff 100644
--- a/xserver/glamor/glamor_utils.c
+++ b/xserver/glamor/glamor_utils.c
@@ -31,7 +31,7 @@ glamor_solid_boxes(PixmapPtr pixmap,
xRectangle *rect;
int n;
- rect = malloc(nbox * sizeof (xRectangle));
+ rect = xallocarray(nbox, sizeof(xRectangle));
if (!rect)
return;
for (n = 0; n < nbox; n++) {
diff --git a/xserver/glamor/glamor_utils.h b/xserver/glamor/glamor_utils.h
index c15d17ca3..5128a33d8 100644
--- a/xserver/glamor/glamor_utils.h
+++ b/xserver/glamor/glamor_utils.h
@@ -33,58 +33,53 @@
#define __GLAMOR_UTILS_H__
#include "glamor_prepare.h"
+#include "mipict.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)
+#define v_from_x_coord_y(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0)
#define t_from_x_coord_x(_xscale_, _x_) ((_x_) * (_xscale_))
-#define t_from_x_coord_y(_yscale_, _y_) (1.0 - (_y_) * (_yscale_))
-#define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_))
+#define t_from_x_coord_y(_yscale_, _y_) ((_y_) * (_yscale_))
-#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
+#define pixmap_priv_get_dest_scale(pixmap, _pixmap_priv_, _pxscale_, _pyscale_) \
do { \
int _w_,_h_; \
- PIXMAP_PRIV_GET_ACTUAL_SIZE(_pixmap_priv_, _w_, _h_); \
+ PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, _pixmap_priv_, _w_, _h_); \
*(_pxscale_) = 1.0 / _w_; \
*(_pyscale_) = 1.0 / _h_; \
} while(0)
#define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
do { \
- *(_pxscale_) = 1.0 / (_pixmap_priv_)->base.fbo->width; \
- *(_pyscale_) = 1.0 / (_pixmap_priv_)->base.fbo->height; \
+ *(_pxscale_) = 1.0 / (_pixmap_priv_)->fbo->width; \
+ *(_pyscale_) = 1.0 / (_pixmap_priv_)->fbo->height; \
} while(0)
-#define GLAMOR_PIXMAP_FBO_NOT_EXACT_SIZE(priv) \
- (priv->base.fbo->width != priv->base.pixmap->drawable.width \
- || priv->base.fbo->height != priv->base.pixmap->drawable.height) \
-
-#define PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, w, h) \
+#define PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, w, h) \
do { \
- if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \
- w = priv->large.box.x2 - priv->large.box.x1; \
- h = priv->large.box.y2 - priv->large.box.y1; \
+ if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) { \
+ w = priv->box.x2 - priv->box.x1; \
+ h = priv->box.y2 - priv->box.y1; \
} else { \
- w = priv->base.pixmap->drawable.width; \
- h = priv->base.pixmap->drawable.height; \
+ w = (pixmap)->drawable.width; \
+ h = (pixmap)->drawable.height; \
} \
} while(0)
-#define glamor_pixmap_fbo_fix_wh_ratio(wh, priv) \
+#define glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap, priv) \
do { \
int actual_w, actual_h; \
- PIXMAP_PRIV_GET_ACTUAL_SIZE(priv, actual_w, actual_h); \
- wh[0] = (float)priv->base.fbo->width / actual_w; \
- wh[1] = (float)priv->base.fbo->height / actual_h; \
- wh[2] = 1.0 / priv->base.fbo->width; \
- wh[3] = 1.0 / priv->base.fbo->height; \
+ PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, actual_w, actual_h); \
+ wh[0] = (float)priv->fbo->width / actual_w; \
+ wh[1] = (float)priv->fbo->height / actual_h; \
+ wh[2] = 1.0 / priv->fbo->width; \
+ wh[3] = 1.0 / priv->fbo->height; \
} while(0)
#define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_) \
do { \
- if (_X_UNLIKELY(_priv_ && (_priv_)->type == GLAMOR_TEXTURE_LARGE)) { \
- *(_xoff_) = - (_priv_)->large.box.x1; \
- *(_yoff_) = - (_priv_)->large.box.y1; \
+ if (_X_UNLIKELY(_priv_ && glamor_pixmap_priv_is_large(_priv_))) { \
+ *(_xoff_) = - (_priv_)->box.x1; \
+ *(_yoff_) = - (_priv_)->box.y1; \
} else { \
*(_xoff_) = 0; \
*(_yoff_) = 0; \
@@ -193,33 +188,33 @@
txy = xy - bxy1; \
} while(0)
-#define _glamor_get_reflect_transform_coords(priv, repeat_type, \
+#define _glamor_get_reflect_transform_coords(pixmap, priv, repeat_type, \
tx1, ty1, \
_x1_, _y1_) \
do { \
int odd_x, odd_y; \
float c, d; \
fodd_repeat_mod(_x1_,priv->box.x2, \
- priv->base.pixmap->drawable.width, \
+ (pixmap)->drawable.width, \
odd_x, c); \
fodd_repeat_mod(_y1_, priv->box.y2, \
- priv->base.pixmap->drawable.height, \
+ (pixmap)->drawable.height, \
odd_y, d); \
DEBUGF("c %f d %f oddx %d oddy %d \n", \
c, d, odd_x, odd_y); \
DEBUGF("x2 %d x1 %d fbo->width %d \n", priv->box.x2, \
- priv->box.x1, priv->base.fbo->width); \
+ priv->box.x1, priv->fbo->width); \
DEBUGF("y2 %d y1 %d fbo->height %d \n", priv->box.y2, \
- priv->box.y1, priv->base.fbo->height); \
+ priv->box.y1, priv->fbo->height); \
_glamor_repeat_reflect_fixup(tx1, _x1_, c, odd_x, \
- priv->base.pixmap->drawable.width, \
+ (pixmap)->drawable.width, \
priv->box.x1, priv->box.x2); \
_glamor_repeat_reflect_fixup(ty1, _y1_, d, odd_y, \
- priv->base.pixmap->drawable.height, \
+ (pixmap)->drawable.height, \
priv->box.y1, priv->box.y2); \
} while(0)
-#define _glamor_get_repeat_coords(priv, repeat_type, tx1, \
+#define _glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, \
ty1, tx2, ty2, \
_x1_, _y1_, _x2_, \
_y2_, c, d, odd_x, odd_y) \
@@ -228,10 +223,10 @@
DEBUGF("x1 y1 %d %d\n", \
_x1_, _y1_ ); \
DEBUGF("width %d box.x1 %d \n", \
- (priv)->base.pixmap->drawable.width, \
+ (pixmap)->drawable.width, \
priv->box.x1); \
if (odd_x) { \
- c = (priv)->base.pixmap->drawable.width \
+ c = (pixmap)->drawable.width \
- c; \
tx1 = c - priv->box.x1; \
tx2 = tx1 - ((_x2_) - (_x1_)); \
@@ -240,7 +235,7 @@
tx2 = tx1 + ((_x2_) - (_x1_)); \
} \
if (odd_y){ \
- d = (priv)->base.pixmap->drawable.height\
+ d = (pixmap)->drawable.height\
- d; \
ty1 = d - priv->box.y1; \
ty2 = ty1 - ((_y2_) - (_y1_)); \
@@ -257,11 +252,11 @@
} while(0)
/* _x1_ ... _y2_ may has fractional. */
-#define glamor_get_repeat_transform_coords(priv, repeat_type, tx1, \
+#define glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, tx1, \
ty1, _x1_, _y1_) \
do { \
DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n", \
- (priv)->base.pixmap->drawable.width, \
+ (pixmap)->drawable.width, \
priv->box.x1, priv->box.x2, priv->box.y1, \
priv->box.y2); \
DEBUGF("x1 %f y1 %f \n", _x1_, _y1_); \
@@ -269,33 +264,33 @@
tx1 = _x1_ - priv->box.x1; \
ty1 = _y1_ - priv->box.y1; \
} else \
- _glamor_get_reflect_transform_coords(priv, repeat_type, \
+ _glamor_get_reflect_transform_coords(pixmap, priv, repeat_type, \
tx1, ty1, \
_x1_, _y1_); \
DEBUGF("tx1 %f ty1 %f \n", tx1, ty1); \
} while(0)
/* _x1_ ... _y2_ must be integer. */
-#define glamor_get_repeat_coords(priv, repeat_type, tx1, \
+#define glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, \
ty1, tx2, ty2, _x1_, _y1_, _x2_, \
_y2_) \
do { \
int c, d; \
int odd_x = 0, odd_y = 0; \
DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n", \
- (priv)->base.pixmap->drawable.width, \
+ (pixmap)->drawable.width, \
priv->box.x1, priv->box.x2, \
priv->box.y1, priv->box.y2); \
- modulus((_x1_), (priv)->base.pixmap->drawable.width, c); \
- modulus((_y1_), (priv)->base.pixmap->drawable.height, d); \
+ modulus((_x1_), (pixmap)->drawable.width, c); \
+ modulus((_y1_), (pixmap)->drawable.height, d); \
DEBUGF("c %d d %d \n", c, d); \
if (repeat_type == RepeatReflect) { \
odd_x = abs((_x1_ - c) \
- / (priv->base.pixmap->drawable.width)) & 1; \
+ / ((pixmap)->drawable.width)) & 1; \
odd_y = abs((_y1_ - d) \
- / (priv->base.pixmap->drawable.height)) & 1; \
+ / ((pixmap)->drawable.height)) & 1; \
} \
- _glamor_get_repeat_coords(priv, repeat_type, tx1, ty1, tx2, ty2,\
+ _glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, ty1, tx2, ty2, \
_x1_, _y1_, _x2_, _y2_, c, d, \
odd_x, odd_y); \
} while(0)
@@ -316,12 +311,12 @@
texcoord) \
do { \
(texcoord)[0] = t_from_x_coord_x(xscale, _tx_); \
- (texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_); \
+ (texcoord)[1] = t_from_x_coord_y(yscale, _ty_); \
DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0], \
(texcoord)[1]); \
} while(0)
-#define glamor_set_transformed_point(priv, matrix, xscale, \
+#define glamor_set_transformed_point(priv, matrix, xscale, \
yscale, texcoord, \
x, y) \
do { \
@@ -335,7 +330,7 @@
tx += fbo_x_off; \
ty += fbo_y_off; \
(texcoord)[0] = t_from_x_coord_x(xscale, tx); \
- (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \
+ (texcoord)[1] = t_from_x_coord_y(yscale, ty); \
DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]); \
} while(0)
@@ -404,7 +399,7 @@
texcoords+4); \
} while (0)
-#define glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \
+#define glamor_set_repeat_transformed_normalize_tcoords_ext(pixmap, priv, \
repeat_type, \
matrix, \
xscale, \
@@ -414,7 +409,7 @@
texcoords, \
stride) \
do { \
- if (_X_LIKELY(priv->type != GLAMOR_TEXTURE_LARGE)) { \
+ if (_X_LIKELY(glamor_pixmap_priv_is_small(priv))) { \
glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, \
yscale, _x1_, _y1_, \
_x2_, _y2_, \
@@ -429,16 +424,16 @@
glamor_transform_point(matrix, tx4, ty4, _x1_, _y2_); \
DEBUGF("transformed %f %f %f %f %f %f %f %f\n", \
tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4); \
- glamor_get_repeat_transform_coords((&priv->large), repeat_type, \
+ glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
ttx1, tty1, \
tx1, ty1); \
- glamor_get_repeat_transform_coords((&priv->large), repeat_type, \
+ glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
ttx2, tty2, \
tx2, ty2); \
- glamor_get_repeat_transform_coords((&priv->large), repeat_type, \
+ glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
ttx3, tty3, \
tx3, ty3); \
- glamor_get_repeat_transform_coords((&priv->large), repeat_type, \
+ glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
ttx4, tty4, \
tx4, ty4); \
DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, \
@@ -454,7 +449,8 @@
} \
} while (0)
-#define glamor_set_repeat_transformed_normalize_tcoords( priv, \
+#define glamor_set_repeat_transformed_normalize_tcoords( pixmap, \
+ priv, \
repeat_type, \
matrix, \
xscale, \
@@ -463,7 +459,8 @@
_x2_, _y2_, \
texcoords) \
do { \
- glamor_set_repeat_transformed_normalize_tcoords_ext( priv, \
+ glamor_set_repeat_transformed_normalize_tcoords_ext( pixmap, \
+ priv, \
repeat_type, \
matrix, \
xscale, \
@@ -485,8 +482,8 @@
(vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2); \
(vertices)[2 * stride] = _t2_; \
(vertices)[3 * stride] = _t0_; \
- (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] = _t1_ = t_from_x_coord_y(yscale, ty1); \
+ (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y(yscale, ty2); \
(vertices)[1 * stride + 1] = _t1_; \
(vertices)[3 * stride + 1] = _t5_; \
} while(0)
@@ -495,7 +492,7 @@
x1, y1, x2, y2, \
vertices, stride) \
do { \
- if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \
+ if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) { \
float tx1, tx2, ty1, ty2; \
int fbo_x_off, fbo_y_off; \
pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \
@@ -520,20 +517,20 @@
vertices, 2); \
} while(0)
-#define glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \
+#define glamor_set_repeat_normalize_tcoords_ext(pixmap, priv, repeat_type, \
xscale, yscale, \
_x1_, _y1_, _x2_, _y2_, \
vertices, stride) \
do { \
- if (_X_UNLIKELY(priv->type == GLAMOR_TEXTURE_LARGE)) { \
+ if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) { \
float tx1, tx2, ty1, ty2; \
if (repeat_type == RepeatPad) { \
- tx1 = _x1_ - priv->large.box.x1; \
- ty1 = _y1_ - priv->large.box.y1; \
+ tx1 = _x1_ - priv->box.x1; \
+ ty1 = _y1_ - priv->box.y1; \
tx2 = tx1 + ((_x2_) - (_x1_)); \
ty2 = ty1 + ((_y2_) - (_y1_)); \
} else { \
- glamor_get_repeat_coords((&priv->large), repeat_type, \
+ glamor_get_repeat_coords(pixmap, priv, repeat_type, \
tx1, ty1, tx2, ty2, \
_x1_, _y1_, _x2_, _y2_); \
} \
@@ -565,8 +562,8 @@
(vertices)[2] = t_from_x_coord_x(xscale, x2); \
(vertices)[6] = (vertices)[2]; \
(vertices)[4] = (vertices)[0]; \
- (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \
- (vertices)[7] = t_from_x_coord_y_inverted(yscale, y2); \
+ (vertices)[1] = t_from_x_coord_y(yscale, y1); \
+ (vertices)[7] = t_from_x_coord_y(yscale, y2); \
(vertices)[3] = (vertices)[1]; \
(vertices)[5] = (vertices)[7]; \
} while(0)
@@ -599,7 +596,7 @@
vertices) \
do { \
(vertices)[0] = v_from_x_coord_x(xscale, x); \
- (vertices)[1] = v_from_x_coord_y_inverted(yscale, y); \
+ (vertices)[1] = v_from_x_coord_y(yscale, y); \
} while(0)
#define glamor_set_normalize_tri_vcoords(xscale, yscale, vtx, \
@@ -642,11 +639,9 @@
x2 + fbo_x_off); \
(vertices)[2 * stride] = _t2_; \
(vertices)[3 * stride] = _t0_; \
- (vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale, \
- y1 + fbo_y_off); \
+ (vertices)[1] = _t1_ = v_from_x_coord_y(yscale, y1 + fbo_y_off); \
(vertices)[2 * stride + 1] = _t5_ = \
- v_from_x_coord_y_inverted(yscale, \
- y2 + fbo_y_off); \
+ v_from_x_coord_y(yscale, y2 + fbo_y_off); \
(vertices)[1 * stride + 1] = _t1_; \
(vertices)[3 * stride + 1] = _t5_; \
} while(0)
@@ -678,8 +673,8 @@
(vertices)[2] = v_from_x_coord_x(xscale, x2); \
(vertices)[6] = (vertices)[2]; \
(vertices)[4] = (vertices)[0]; \
- (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \
- (vertices)[7] = v_from_x_coord_y_inverted(yscale, y2); \
+ (vertices)[1] = v_from_x_coord_y(yscale, y1); \
+ (vertices)[7] = v_from_x_coord_y(yscale, y2); \
(vertices)[3] = (vertices)[1]; \
(vertices)[5] = (vertices)[7]; \
} while(0)
@@ -688,7 +683,7 @@
pt) \
do { \
(pt)[0] = t_from_x_coord_x(xscale, x); \
- (pt)[1] = t_from_x_coord_y_inverted(yscale, y); \
+ (pt)[1] = t_from_x_coord_y(yscale, y); \
} while(0)
#define glamor_set_circle_centre(width, height, x, y, \
@@ -698,45 +693,6 @@
(c)[1] = (float)y; \
} while(0)
-inline static void
-glamor_calculate_boxes_bound(BoxPtr bound, BoxPtr boxes, int nbox)
-{
- int x_min, y_min;
- int x_max, y_max;
- int i;
-
- x_min = y_min = MAXSHORT;
- x_max = y_max = MINSHORT;
- for (i = 0; i < nbox; i++) {
- if (x_min > boxes[i].x1)
- x_min = boxes[i].x1;
- if (y_min > boxes[i].y1)
- y_min = boxes[i].y1;
-
- if (x_max < boxes[i].x2)
- x_max = boxes[i].x2;
- if (y_max < boxes[i].y2)
- y_max = boxes[i].y2;
- }
- bound->x1 = x_min;
- bound->y1 = y_min;
- bound->x2 = x_max;
- bound->y2 = y_max;
-}
-
-inline static void
-glamor_translate_boxes(BoxPtr boxes, int nbox, int dx, int dy)
-{
- int i;
-
- for (i = 0; i < nbox; i++) {
- boxes[i].x1 += dx;
- boxes[i].y1 += dy;
- boxes[i].x2 += dx;
- boxes[i].y2 += dy;
- }
-}
-
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#endif
@@ -758,9 +714,7 @@ glamor_translate_boxes(BoxPtr boxes, int nbox, int dx, int dy)
|| _depth_ == 30 \
|| _depth_ == 32)
-#define GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) (pixmap_priv && pixmap_priv->base.is_picture == 1)
-#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv && pixmap_priv->base.gl_fbo == GLAMOR_FBO_NORMAL)
-#define GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv) (pixmap_priv && (pixmap_priv->base.gl_fbo == GLAMOR_FBO_DOWNLOADED))
+#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
/**
* Borrow from uxa.
@@ -795,11 +749,11 @@ static inline GLenum
gl_iformat_for_pixmap(PixmapPtr pixmap)
{
glamor_screen_private *glamor_priv =
- glamor_get_screen_private(pixmap->drawable.pScreen);
+ glamor_get_screen_private((pixmap)->drawable.pScreen);
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
- (pixmap->drawable.depth == 1 || pixmap->drawable.depth == 8)) {
- return GL_ALPHA;
+ ((pixmap)->drawable.depth == 1 || (pixmap)->drawable.depth == 8)) {
+ return glamor_priv->one_channel_format;
} else {
return GL_RGBA;
}
@@ -808,16 +762,7 @@ gl_iformat_for_pixmap(PixmapPtr pixmap)
static inline CARD32
format_for_pixmap(PixmapPtr pixmap)
{
- glamor_pixmap_private *pixmap_priv;
- PictFormatShort pict_format;
-
- pixmap_priv = glamor_get_pixmap_private(pixmap);
- if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv))
- pict_format = pixmap_priv->base.picture->format;
- else
- pict_format = format_for_depth(pixmap->drawable.depth);
-
- return pict_format;
+ return format_for_depth((pixmap)->drawable.depth);
}
#define REVERT_NONE 0
@@ -836,21 +781,6 @@ format_for_pixmap(PixmapPtr pixmap)
#define SWAP_UPLOADING 2
#define SWAP_NONE_UPLOADING 3
-inline static int
-cache_format(GLenum format)
-{
- switch (format) {
- case GL_ALPHA:
- return 2;
- case GL_RGB:
- return 1;
- case GL_RGBA:
- return 0;
- default:
- return -1;
- }
-}
-
/* borrowed from uxa */
static inline Bool
glamor_get_rgba_from_pixel(CARD32 pixel,
@@ -922,91 +852,20 @@ glamor_get_rgba_from_pixel(CARD32 pixel,
}
inline static Bool
-glamor_pict_format_is_compatible(PicturePtr picture)
-{
- GLenum iformat;
- PixmapPtr pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
-
- iformat = gl_iformat_for_pixmap(pixmap);
- switch (iformat) {
- case GL_RGBA:
- return (picture->format == PICT_a8r8g8b8 ||
- picture->format == PICT_x8r8g8b8);
- case GL_ALPHA:
- return (picture->format == PICT_a8);
- default:
- return FALSE;
- }
-}
-
-/* return TRUE if we can access this pixmap at DDX driver. */
-inline static Bool
-glamor_ddx_fallback_check_pixmap(DrawablePtr drawable)
-{
- PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
- glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-
- return (!pixmap_priv
- || (pixmap_priv->type == GLAMOR_TEXTURE_DRM
- || pixmap_priv->type == GLAMOR_MEMORY
- || pixmap_priv->type == GLAMOR_DRM_ONLY));
-}
-
-inline static Bool
-glamor_ddx_fallback_check_gc(GCPtr gc)
-{
- PixmapPtr pixmap;
-
- if (!gc)
- return TRUE;
- switch (gc->fillStyle) {
- case FillStippled:
- case FillOpaqueStippled:
- pixmap = gc->stipple;
- break;
- case FillTiled:
- pixmap = gc->tile.pixmap;
- break;
- default:
- pixmap = NULL;
- }
- return (!pixmap || glamor_ddx_fallback_check_pixmap(&pixmap->drawable));
-}
-
-inline static Bool
glamor_is_large_pixmap(PixmapPtr pixmap)
{
glamor_pixmap_private *priv;
priv = glamor_get_pixmap_private(pixmap);
- return (priv->type == GLAMOR_TEXTURE_LARGE);
-}
-
-inline static Bool
-glamor_is_large_picture(PicturePtr picture)
-{
- PixmapPtr pixmap;
-
- if (picture->pDrawable) {
- pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
- return glamor_is_large_pixmap(pixmap);
- }
- return FALSE;
-}
-
-inline static Bool
-glamor_tex_format_is_readable(GLenum format)
-{
- return ((format == GL_RGBA || format == GL_RGB || format == GL_ALPHA));
-
+ return (glamor_pixmap_priv_is_large(priv));
}
static inline void
_glamor_dump_pixmap_bits(PixmapPtr pixmap, int x, int y, int w, int h)
{
int i, j;
- unsigned char *p = pixmap->devPrivate.ptr;
- int stride = pixmap->devKind;
+ unsigned char *p = (pixmap)->devPrivate.ptr;
+ int stride = (pixmap)->devKind;
p = p + y * stride + x;
@@ -1023,8 +882,8 @@ static inline void
_glamor_dump_pixmap_byte(PixmapPtr pixmap, int x, int y, int w, int h)
{
int i, j;
- unsigned char *p = pixmap->devPrivate.ptr;
- int stride = pixmap->devKind;
+ unsigned char *p = (pixmap)->devPrivate.ptr;
+ int stride = (pixmap)->devKind;
p = p + y * stride + x;
@@ -1041,8 +900,8 @@ static inline void
_glamor_dump_pixmap_sword(PixmapPtr pixmap, int x, int y, int w, int h)
{
int i, j;
- unsigned short *p = pixmap->devPrivate.ptr;
- int stride = pixmap->devKind / 2;
+ unsigned short *p = (pixmap)->devPrivate.ptr;
+ int stride = (pixmap)->devKind / 2;
p = p + y * stride + x;
@@ -1059,8 +918,8 @@ static inline void
_glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h)
{
int i, j;
- unsigned int *p = pixmap->devPrivate.ptr;
- int stride = pixmap->devKind / 4;
+ unsigned int *p = (pixmap)->devPrivate.ptr;
+ int stride = (pixmap)->devKind / 4;
p = p + y * stride + x;
@@ -1076,11 +935,11 @@ _glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h)
static inline void
glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h)
{
- w = ((x + w) > pixmap->drawable.width) ? (pixmap->drawable.width - x) : w;
- h = ((y + h) > pixmap->drawable.height) ? (pixmap->drawable.height - y) : h;
+ w = ((x + w) > (pixmap)->drawable.width) ? ((pixmap)->drawable.width - x) : w;
+ h = ((y + h) > (pixmap)->drawable.height) ? ((pixmap)->drawable.height - y) : h;
- glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO);
- switch (pixmap->drawable.depth) {
+ glamor_prepare_access(&(pixmap)->drawable, GLAMOR_ACCESS_RO);
+ switch ((pixmap)->drawable.depth) {
case 8:
_glamor_dump_pixmap_byte(pixmap, x, y, w, h);
break;
@@ -1097,9 +956,9 @@ glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h)
_glamor_dump_pixmap_bits(pixmap, x, y, w, h);
break;
default:
- ErrorF("dump depth %d, not implemented.\n", pixmap->drawable.depth);
+ ErrorF("dump depth %d, not implemented.\n", (pixmap)->drawable.depth);
}
- glamor_finish_access(&pixmap->drawable);
+ glamor_finish_access(&(pixmap)->drawable);
}
static inline void
@@ -1297,7 +1156,7 @@ glamor_compare_pictures(ScreenPtr screen,
GLAMOR_CREATE_PIXMAP_CPU);
pixman_pic = CreatePicture(0,
- &pixmap->drawable,
+ &(pixmap)->drawable,
PictureMatchFormat(screen,
PIXMAN_FORMAT_DEPTH
(format), format), 0, 0,
@@ -1325,7 +1184,7 @@ glamor_compare_pictures(ScreenPtr screen,
GLAMOR_CREATE_PIXMAP_CPU);
pixman_pic = CreatePicture(0,
- &pixmap->drawable,
+ &(pixmap)->drawable,
PictureMatchFormat(screen,
PIXMAN_FORMAT_DEPTH
(format), format), 0, 0,
@@ -1345,9 +1204,9 @@ glamor_compare_pictures(ScreenPtr screen,
if (fst_pixmap->drawable.depth != snd_pixmap->drawable.depth) {
if (fst_generated)
- glamor_destroy_picture(fst_picture);
+ miDestroyPicture(fst_picture);
if (snd_generated)
- glamor_destroy_picture(snd_picture);
+ miDestroyPicture(snd_picture);
ErrorF("Different pixmap depth can not compare!\n");
return;
@@ -1373,9 +1232,9 @@ glamor_compare_pictures(ScreenPtr screen,
glamor_finish_access(&snd_pixmap->drawable);
if (fst_generated)
- glamor_destroy_picture(fst_picture);
+ miDestroyPicture(fst_picture);
if (snd_generated)
- glamor_destroy_picture(snd_picture);
+ miDestroyPicture(snd_picture);
return;
}
@@ -1429,4 +1288,19 @@ glamor_make_current(glamor_screen_private *glamor_priv)
}
}
+/**
+ * Helper function for implementing draws with GL_QUADS on GLES2,
+ * where we don't have them.
+ */
+static inline void
+glamor_glDrawArrays_GL_QUADS(glamor_screen_private *glamor_priv, unsigned count)
+{
+ if (glamor_priv->use_quads) {
+ glDrawArrays(GL_QUADS, 0, count * 4);
+ } else {
+ glamor_gldrawarrays_quads_using_indices(glamor_priv, count);
+ }
+}
+
+
#endif
diff --git a/xserver/glamor/glamor_vbo.c b/xserver/glamor/glamor_vbo.c
index e90610102..b8db0092b 100644
--- a/xserver/glamor/glamor_vbo.c
+++ b/xserver/glamor/glamor_vbo.c
@@ -96,6 +96,15 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset)
data = glamor_priv->vb + glamor_priv->vbo_offset;
glamor_priv->vbo_offset += size;
} else if (glamor_priv->has_map_buffer_range) {
+ /* Avoid GL errors on GL 4.5 / ES 3.0 with mapping size == 0,
+ * which callers may sometimes pass us (for example, if
+ * clipping leads to zero rectangles left). Prior to that
+ * version, Mesa would sometimes throw errors on unmapping a
+ * zero-size mapping.
+ */
+ if (size == 0)
+ return NULL;
+
if (glamor_priv->vbo_size < glamor_priv->vbo_offset + size) {
glamor_priv->vbo_size = MAX(GLAMOR_VBO_SIZE, size);
glamor_priv->vbo_offset = 0;
@@ -109,9 +118,9 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset)
GL_MAP_WRITE_BIT |
GL_MAP_UNSYNCHRONIZED_BIT |
GL_MAP_INVALIDATE_RANGE_BIT);
- assert(data != NULL);
*vbo_offset = (char *)(uintptr_t)glamor_priv->vbo_offset;
glamor_priv->vbo_offset += size;
+ glamor_priv->vbo_mapped = TRUE;
} else {
/* Return a pointer to the statically allocated non-VBO
* memory. We'll upload it through glBufferData() later.
@@ -145,7 +154,10 @@ glamor_put_vbo_space(ScreenPtr screen)
* reach the end of the buffer.
*/
} else if (glamor_priv->has_map_buffer_range) {
- glUnmapBuffer(GL_ARRAY_BUFFER);
+ if (glamor_priv->vbo_mapped) {
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+ glamor_priv->vbo_mapped = FALSE;
+ }
} else {
glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
glamor_priv->vb, GL_DYNAMIC_DRAW);
@@ -162,6 +174,11 @@ glamor_init_vbo(ScreenPtr screen)
glamor_make_current(glamor_priv);
glGenBuffers(1, &glamor_priv->vbo);
+ if (glamor_priv->has_vertex_array_object) {
+ glGenVertexArrays(1, &glamor_priv->vao);
+ glBindVertexArray(glamor_priv->vao);
+ } else
+ glamor_priv->vao = 0;
}
void
@@ -171,7 +188,10 @@ glamor_fini_vbo(ScreenPtr screen)
glamor_make_current(glamor_priv);
- glDeleteBuffers(1, &glamor_priv->vbo);
+ if (glamor_priv->vao != 0) {
+ glDeleteVertexArrays(1, &glamor_priv->vao);
+ glamor_priv->vao = 0;
+ }
if (!glamor_priv->has_map_buffer_range)
free(glamor_priv->vb);
}
diff --git a/xserver/glamor/glamor_window.c b/xserver/glamor/glamor_window.c
index 60647bf80..5fd463b43 100644
--- a/xserver/glamor/glamor_window.c
+++ b/xserver/glamor/glamor_window.c
@@ -65,35 +65,3 @@ glamor_change_window_attributes(WindowPtr pWin, unsigned long mask)
}
return TRUE;
}
-
-void
-glamor_set_window_pixmap(WindowPtr win, PixmapPtr pPixmap)
-{
- ScreenPtr screen = win->drawable.pScreen;
- glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- PixmapPtr old = screen->GetWindowPixmap(win);
-
- if (pPixmap != old) {
- glamor_pixmap_private *pixmap_priv;
- PicturePtr pic = NULL;
-
- pixmap_priv = glamor_get_pixmap_private(old);
- if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv) &&
- pixmap_priv->base.picture->pDrawable == (DrawablePtr) win) {
- pic = pixmap_priv->base.picture;
- pixmap_priv->base.is_picture = 0;
- pixmap_priv->base.picture = NULL;
- }
-
- pixmap_priv = glamor_get_pixmap_private(pPixmap);
- if (pixmap_priv) {
- pixmap_priv->base.is_picture = ! !pic;
- pixmap_priv->base.picture = pic;
- }
- }
-
- screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap;
- (screen->SetWindowPixmap) (win, pPixmap);
- glamor_priv->saved_procs.set_window_pixmap = screen->SetWindowPixmap;
- screen->SetWindowPixmap = glamor_set_window_pixmap;
-}
diff --git a/xserver/glamor/glamor_xv.c b/xserver/glamor/glamor_xv.c
index 83e24adb2..3bcf909b0 100644
--- a/xserver/glamor/glamor_xv.c
+++ b/xserver/glamor/glamor_xv.c
@@ -37,6 +37,8 @@
#endif
#include "glamor_priv.h"
+#include "glamor_transform.h"
+#include "glamor_transfer.h"
#include <X11/extensions/Xv.h>
#include "../hw/xfree86/common/fourcc.h"
@@ -57,36 +59,36 @@ typedef struct tagREF_TRANSFORM {
#define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0)
#define RTFHue(a) (((a)*3.1416)/1000.0)
-static const char *xv_vs = "attribute vec4 v_position;\n"
- "attribute vec4 v_texcoord0;\n"
- "varying vec2 tcs;\n"
- "void main()\n"
- "{\n"
- " gl_Position = v_position;\n"
- "tcs = v_texcoord0.xy;\n"
- "}\n";
-
-static const char *xv_ps = GLAMOR_DEFAULT_PRECISION
- "uniform sampler2D y_sampler;\n"
- "uniform sampler2D u_sampler;\n"
- "uniform sampler2D v_sampler;\n"
- "uniform vec4 offsetyco;\n"
- "uniform vec4 ucogamma;\n"
- "uniform vec4 vco;\n"
- "varying vec2 tcs;\n"
- "float sample;\n"
- "vec4 temp1;\n"
- "void main()\n"
- "{\n"
- "sample = texture2D(y_sampler, tcs).w;\n"
- "temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n"
- "sample = texture2D(u_sampler, tcs).w;\n"
- "temp1.xyz = ucogamma.xyz * vec3(sample) + temp1.xyz;\n"
- "sample = texture2D(v_sampler, tcs).w;\n"
- "temp1.xyz = clamp(vco.xyz * vec3(sample) + temp1.xyz, 0.0, 1.0);\n"
- "temp1.w = 1.0;\n"
- "gl_FragColor = temp1;\n"
- "}\n";
+static const glamor_facet glamor_facet_xv_planar = {
+ .name = "xv_planar",
+
+ .source_name = "v_texcoord0",
+ .vs_vars = ("attribute vec2 position;\n"
+ "attribute vec2 v_texcoord0;\n"
+ "varying vec2 tcs;\n"),
+ .vs_exec = (GLAMOR_POS(gl_Position, position)
+ " tcs = v_texcoord0;\n"),
+
+ .fs_vars = ("uniform sampler2D y_sampler;\n"
+ "uniform sampler2D u_sampler;\n"
+ "uniform sampler2D v_sampler;\n"
+ "uniform vec4 offsetyco;\n"
+ "uniform vec4 ucogamma;\n"
+ "uniform vec4 vco;\n"
+ "varying vec2 tcs;\n"),
+ .fs_exec = (
+ " float sample;\n"
+ " vec4 temp1;\n"
+ " sample = texture2D(y_sampler, tcs).w;\n"
+ " temp1.xyz = offsetyco.www * vec3(sample) + offsetyco.xyz;\n"
+ " sample = texture2D(u_sampler, tcs).w;\n"
+ " temp1.xyz = ucogamma.xyz * vec3(sample) + temp1.xyz;\n"
+ " sample = texture2D(v_sampler, tcs).w;\n"
+ " temp1.xyz = clamp(vco.xyz * vec3(sample) + temp1.xyz, 0.0, 1.0);\n"
+ " temp1.w = 1.0;\n"
+ " gl_FragColor = temp1;\n"
+ ),
+};
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
@@ -112,23 +114,21 @@ int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
static void
glamor_init_xv_shader(ScreenPtr screen)
{
- glamor_screen_private *glamor_priv;
- GLint fs_prog, vs_prog;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ GLint sampler_loc;
+
+ glamor_build_program(screen,
+ &glamor_priv->xv_prog,
+ &glamor_facet_xv_planar, NULL, NULL, NULL);
+
+ glUseProgram(glamor_priv->xv_prog.prog);
+ sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "y_sampler");
+ glUniform1i(sampler_loc, 0);
+ sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "u_sampler");
+ glUniform1i(sampler_loc, 1);
+ sampler_loc = glGetUniformLocation(glamor_priv->xv_prog.prog, "v_sampler");
+ glUniform1i(sampler_loc, 2);
- glamor_priv = glamor_get_screen_private(screen);
- glamor_make_current(glamor_priv);
- glamor_priv->xv_prog = glCreateProgram();
-
- vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xv_vs);
- fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xv_ps);
- glAttachShader(glamor_priv->xv_prog, vs_prog);
- glAttachShader(glamor_priv->xv_prog, fs_prog);
-
- glBindAttribLocation(glamor_priv->xv_prog,
- GLAMOR_VERTEX_POS, "v_position");
- glBindAttribLocation(glamor_priv->xv_prog,
- GLAMOR_VERTEX_SOURCE, "v_texcoord0");
- glamor_link_glsl_prog(screen, glamor_priv->xv_prog, "xv");
}
#define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v))
@@ -241,14 +241,11 @@ 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);
- glamor_pixmap_private *pixmap_priv =
- glamor_get_pixmap_private(port_priv->pPixmap);
+ PixmapPtr pixmap = port_priv->pPixmap;
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
glamor_pixmap_private *src_pixmap_priv[3];
- float vertices[32], texcoords[8];
BoxPtr box = REGION_RECTS(&port_priv->clip);
int nBox = REGION_NUM_RECTS(&port_priv->clip);
- int dst_x_off, dst_y_off;
- GLfloat dst_xscale, dst_yscale;
GLfloat src_xscale[3], src_yscale[3];
int i;
const float Loff = -0.0627;
@@ -258,9 +255,12 @@ glamor_xv_render(glamor_port_private *port_priv)
float uco[3], vco[3], off[3];
float bright, cont, gamma;
int ref = port_priv->transform_index;
- GLint uloc, sampler_loc;
+ GLint uloc;
+ GLfloat *v;
+ char *vbo_offset;
+ int dst_box_index;
- if (!glamor_priv->xv_prog)
+ if (!glamor_priv->xv_prog.prog)
glamor_init_xv_shader(screen);
cont = RTFContrast(port_priv->contrast);
@@ -282,10 +282,7 @@ glamor_xv_render(glamor_port_private *port_priv)
off[2] = Loff * yco + Coff * (uco[2] + vco[2]) + bright;
gamma = 1.0;
- pixmap_priv_get_dest_scale(pixmap_priv, &dst_xscale, &dst_yscale);
- glamor_get_drawable_deltas(port_priv->pDraw, port_priv->pPixmap, &dst_x_off,
- &dst_y_off);
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
+ glamor_set_alu(screen, GXcopy);
for (i = 0; i < 3; i++) {
if (port_priv->src_pix[i]) {
@@ -296,90 +293,101 @@ glamor_xv_render(glamor_port_private *port_priv)
}
}
glamor_make_current(glamor_priv);
- glUseProgram(glamor_priv->xv_prog);
+ glUseProgram(glamor_priv->xv_prog.prog);
- uloc = glGetUniformLocation(glamor_priv->xv_prog, "offsetyco");
+ uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "offsetyco");
glUniform4f(uloc, off[0], off[1], off[2], yco);
- uloc = glGetUniformLocation(glamor_priv->xv_prog, "ucogamma");
+ uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "ucogamma");
glUniform4f(uloc, uco[0], uco[1], uco[2], gamma);
- uloc = glGetUniformLocation(glamor_priv->xv_prog, "vco");
+ uloc = glGetUniformLocation(glamor_priv->xv_prog.prog, "vco");
glUniform4f(uloc, vco[0], vco[1], vco[2], 0);
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->base.fbo->tex);
+ glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->base.fbo->tex);
+ glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glActiveTexture(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->base.fbo->tex);
+ glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->fbo->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "y_sampler");
- glUniform1i(sampler_loc, 0);
- sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "u_sampler");
- glUniform1i(sampler_loc, 1);
- sampler_loc = glGetUniformLocation(glamor_priv->xv_prog, "v_sampler");
- glUniform1i(sampler_loc, 2);
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+ glEnable(GL_SCISSOR_TEST);
+
+ v = glamor_get_vbo_space(screen, 3 * 4 * sizeof(GLfloat), &vbo_offset);
+
+ /* Set up a single primitive covering the area being drawn. We'll
+ * clip it to port_priv->clip using GL scissors instead of just
+ * emitting a GL_QUAD per box, because this way we hopefully avoid
+ * diagonal tearing between the two trangles used to rasterize a
+ * GL_QUAD.
+ */
+ i = 0;
+ v[i++] = port_priv->drw_x;
+ v[i++] = port_priv->drw_y;
+
+ v[i++] = port_priv->drw_x + port_priv->dst_w * 2;
+ v[i++] = port_priv->drw_y;
+
+ v[i++] = port_priv->drw_x;
+ v[i++] = port_priv->drw_y + port_priv->dst_h * 2;
+
+ v[i++] = t_from_x_coord_x(src_xscale[0], port_priv->src_x);
+ v[i++] = t_from_x_coord_y(src_yscale[0], port_priv->src_y);
+
+ v[i++] = t_from_x_coord_x(src_xscale[0], port_priv->src_x +
+ port_priv->src_w * 2);
+ v[i++] = t_from_x_coord_y(src_yscale[0], port_priv->src_y);
+
+ v[i++] = t_from_x_coord_x(src_xscale[0], port_priv->src_x);
+ v[i++] = t_from_x_coord_y(src_yscale[0], port_priv->src_y +
+ port_priv->src_h * 2);
+
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 2,
+ GL_FLOAT, GL_FALSE,
+ 2 * sizeof(float), vbo_offset);
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
GL_FLOAT, GL_FALSE,
- 2 * sizeof(float), texcoords);
- glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+ 2 * sizeof(float), vbo_offset + 6 * sizeof(GLfloat));
- glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
- GL_FALSE, 2 * sizeof(float), vertices);
+ glamor_put_vbo_space(screen);
- glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
- glEnable(GL_SCISSOR_TEST);
- for (i = 0; i < nBox; i++) {
- float off_x = box[i].x1 - port_priv->drw_x;
- float off_y = box[i].y1 - port_priv->drw_y;
- float diff_x = (float) port_priv->src_w / (float) port_priv->dst_w;
- float diff_y = (float) port_priv->src_h / (float) port_priv->dst_h;
- float srcx, srcy, srcw, srch;
- int dstx, dsty, dstw, dsth;
-
- dstx = box[i].x1 + dst_x_off;
- dsty = box[i].y1 + dst_y_off;
- dstw = box[i].x2 - box[i].x1;
- dsth = box[i].y2 - box[i].y1;
-
- srcx = port_priv->src_x + off_x * diff_x;
- srcy = port_priv->src_y + off_y * diff_y;
- srcw = (port_priv->src_w * dstw) / (float) port_priv->dst_w;
- srch = (port_priv->src_h * dsth) / (float) port_priv->dst_h;
-
- glamor_set_normalize_vcoords(pixmap_priv,
- dst_xscale, dst_yscale,
- dstx - dstw,
- dsty,
- dstx + dstw,
- dsty + dsth * 2,
- vertices);
-
- glamor_set_normalize_tcoords(src_pixmap_priv[0],
- src_xscale[0],
- src_yscale[0],
- srcx - srcw,
- srcy,
- srcx + srcw,
- srcy + srch * 2,
- texcoords);
-
- glScissor(dstx, dsty, dstw, dsth);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 3);
+ /* Now draw our big triangle, clipped to each of the clip boxes. */
+ glamor_pixmap_loop(pixmap_priv, dst_box_index) {
+ int dst_off_x, dst_off_y;
+
+ glamor_set_destination_drawable(port_priv->pDraw,
+ dst_box_index,
+ FALSE, FALSE,
+ glamor_priv->xv_prog.matrix_uniform,
+ &dst_off_x, &dst_off_y);
+
+ for (i = 0; i < nBox; i++) {
+ int dstx, dsty, dstw, dsth;
+
+ dstx = box[i].x1 + dst_off_x;
+ dsty = box[i].y1 + dst_off_y;
+ dstw = box[i].x2 - box[i].x1;
+ dsth = box[i].y2 - box[i].y1;
+
+ glScissor(dstx, dsty, dstw, dsth);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 3);
+ }
}
glDisable(GL_SCISSOR_TEST);
@@ -409,6 +417,7 @@ glamor_xv_put_image(glamor_port_private *port_priv,
int srcPitch, srcPitch2;
int top, nlines;
int s2offset, s3offset, tmp;
+ BoxRec full_box, half_box;
s2offset = s3offset = srcPitch2 = 0;
@@ -451,20 +460,28 @@ glamor_xv_put_image(glamor_port_private *port_priv,
s2offset = s3offset;
s3offset = tmp;
}
- glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[0],
- 0, 0, width, nlines,
- srcPitch,
- buf + (top * srcPitch), 0);
-
- glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[1],
- 0, 0, width >> 1, (nlines + 1) >> 1,
- srcPitch2,
- buf + s2offset, 0);
-
- glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[2],
- 0, 0, width >> 1, (nlines + 1) >> 1,
- srcPitch2,
- buf + s3offset, 0);
+
+ full_box.x1 = 0;
+ full_box.y1 = 0;
+ full_box.x2 = width;
+ full_box.y2 = nlines;
+
+ half_box.x1 = 0;
+ half_box.y1 = 0;
+ half_box.x2 = width >> 1;
+ half_box.y2 = (nlines + 1) >> 1;
+
+ glamor_upload_boxes(port_priv->src_pix[0], &full_box, 1,
+ 0, 0, 0, 0,
+ buf + (top * srcPitch), srcPitch);
+
+ glamor_upload_boxes(port_priv->src_pix[1], &half_box, 1,
+ 0, 0, 0, 0,
+ buf + s2offset, srcPitch2);
+
+ glamor_upload_boxes(port_priv->src_pix[2], &half_box, 1,
+ 0, 0, 0, 0,
+ buf + s3offset, srcPitch2);
break;
default:
return BadMatch;
@@ -478,7 +495,7 @@ glamor_xv_put_image(glamor_port_private *port_priv,
RegionCopy(&port_priv->clip, clipBoxes);
port_priv->src_x = src_x;
- port_priv->src_y = src_y;
+ port_priv->src_y = src_y - top;
port_priv->src_w = src_w;
port_priv->src_h = src_h;
port_priv->dst_w = drw_w;