aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/glamor
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2014-03-28 17:43:20 +0100
committermarha <marha@users.sourceforge.net>2014-03-28 17:43:20 +0100
commitf0f09f4aa3cdd0267f58b362a7c9fc5ae0921afd (patch)
treeafbeb028495328a2817aedbac7aae484a2c71a83 /xorg-server/glamor
parentbf0cbcc1d00962ef2221cb4ceae87cc5ae737454 (diff)
parentcbfb19790917d271b8ca6156554b16acc802719f (diff)
downloadvcxsrv-f0f09f4aa3cdd0267f58b362a7c9fc5ae0921afd.tar.gz
vcxsrv-f0f09f4aa3cdd0267f58b362a7c9fc5ae0921afd.tar.bz2
vcxsrv-f0f09f4aa3cdd0267f58b362a7c9fc5ae0921afd.zip
Merge remote-tracking branch 'origin/released'
Conflicts: X11/xtrans/Xtrans.c
Diffstat (limited to 'xorg-server/glamor')
-rw-r--r--xorg-server/glamor/Makefile.am5
-rw-r--r--xorg-server/glamor/glamor.c32
-rw-r--r--xorg-server/glamor/glamor.h7
-rw-r--r--xorg-server/glamor/glamor_core.c45
-rw-r--r--xorg-server/glamor/glamor_fbo.c3
-rw-r--r--xorg-server/glamor/glamor_fill.c3
-rw-r--r--xorg-server/glamor/glamor_glyphs.c2
-rw-r--r--xorg-server/glamor/glamor_gradient.c60
-rw-r--r--xorg-server/glamor/glamor_largepixmap.c10
-rw-r--r--xorg-server/glamor/glamor_pixmap.c14
-rw-r--r--xorg-server/glamor/glamor_points.c129
-rw-r--r--xorg-server/glamor/glamor_polyops.c82
-rw-r--r--xorg-server/glamor/glamor_priv.h65
-rw-r--r--xorg-server/glamor/glamor_program.c394
-rw-r--r--xorg-server/glamor/glamor_program.h94
-rw-r--r--xorg-server/glamor/glamor_render.c29
-rw-r--r--xorg-server/glamor/glamor_segment.c39
-rw-r--r--xorg-server/glamor/glamor_transform.c215
-rw-r--r--xorg-server/glamor/glamor_transform.h87
-rw-r--r--xorg-server/glamor/glamor_trapezoid.c6
-rw-r--r--xorg-server/glamor/glamor_vbo.c6
21 files changed, 1065 insertions, 262 deletions
diff --git a/xorg-server/glamor/Makefile.am b/xorg-server/glamor/Makefile.am
index ffc8c23d8..8555e4087 100644
--- a/xorg-server/glamor/Makefile.am
+++ b/xorg-server/glamor/Makefile.am
@@ -20,8 +20,11 @@ libglamor_la_SOURCES = \
glamor_polylines.c \
glamor_putimage.c \
glamor_setspans.c \
+ glamor_segment.c \
glamor_render.c \
glamor_gradient.c \
+ glamor_program.c \
+ glamor_transform.c \
glamor_trapezoid.c \
glamor_tile.c \
glamor_triangles.c\
@@ -29,7 +32,7 @@ libglamor_la_SOURCES = \
glamor_getimage.c\
glamor_copyplane.c\
glamor_glyphblt.c\
- glamor_polyops.c\
+ glamor_points.c\
glamor_priv.h\
glamor_pixmap.c\
glamor_largepixmap.c\
diff --git a/xorg-server/glamor/glamor.c b/xorg-server/glamor/glamor.c
index 0f7d68b70..30944326b 100644
--- a/xorg-server/glamor/glamor.c
+++ b/xorg-server/glamor/glamor.c
@@ -76,6 +76,10 @@ glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
pixmap_priv->base.glamor_priv = glamor_priv;
}
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;
}
_X_EXPORT void
@@ -178,8 +182,14 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
- if (type == GLAMOR_MEMORY_MAP || glamor_check_fbo_size(glamor_priv, w, h)) {
+ if (type == GLAMOR_MEMORY_MAP || 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;
fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
}
else {
@@ -341,7 +351,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
else
glamor_priv->gl_flavor = GLAMOR_GL_ES2;
- gl_version = glamor_gl_get_version();
+ gl_version = epoxy_gl_version();
/* We'd like to require GL_ARB_map_buffer_range or
* GL_OES_map_buffer_range, since it offers more information to
@@ -357,29 +367,31 @@ glamor_init(ScreenPtr screen, unsigned int flags)
* Windows with Intel 4-series (G45) graphics or older.
*/
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
- if (gl_version < GLAMOR_GL_VERSION_ENCODE(1, 3)) {
- ErrorF("Require OpenGL version 1.3 or later.\n");
+ if (gl_version < 21) {
+ ErrorF("Require OpenGL version 2.1 or later.\n");
goto fail;
}
} else {
- if (gl_version < GLAMOR_GL_VERSION_ENCODE(2, 0)) {
+ if (gl_version < 20) {
ErrorF("Require Open GLES2.0 or later.\n");
goto fail;
}
- if (!glamor_gl_has_extension("GL_EXT_texture_format_BGRA8888")) {
+ if (!epoxy_has_gl_extension("GL_EXT_texture_format_BGRA8888")) {
ErrorF("GL_EXT_texture_format_BGRA8888 required\n");
goto fail;
}
}
- glamor_priv->has_khr_debug = glamor_gl_has_extension("GL_KHR_debug");
+ glamor_priv->has_khr_debug = epoxy_has_gl_extension("GL_KHR_debug");
glamor_priv->has_pack_invert =
- glamor_gl_has_extension("GL_MESA_pack_invert");
+ epoxy_has_gl_extension("GL_MESA_pack_invert");
glamor_priv->has_fbo_blit =
- glamor_gl_has_extension("GL_EXT_framebuffer_blit");
+ epoxy_has_gl_extension("GL_EXT_framebuffer_blit");
+ glamor_priv->has_map_buffer_range =
+ epoxy_has_gl_extension("GL_ARB_map_buffer_range");
glamor_priv->has_buffer_storage =
- glamor_gl_has_extension("GL_ARB_buffer_storage");
+ epoxy_has_gl_extension("GL_ARB_buffer_storage");
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size);
#ifdef MAX_FBO_SIZE
glamor_priv->max_fbo_size = MAX_FBO_SIZE;
diff --git a/xorg-server/glamor/glamor.h b/xorg-server/glamor/glamor.h
index d05d2f4ea..11ec49361 100644
--- a/xorg-server/glamor/glamor.h
+++ b/xorg-server/glamor/glamor.h
@@ -140,9 +140,16 @@ extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap,
glamor_pixmap_type_t type);
extern _X_EXPORT void glamor_destroy_textured_pixmap(PixmapPtr pixmap);
extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
+
extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h,
int depth, unsigned int usage);
+#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
+
/* @glamor_egl_exchange_buffers: Exchange the underlying buffers(KHR image,fbo).
*
* @front: front pixmap.
diff --git a/xorg-server/glamor/glamor_core.c b/xorg-server/glamor/glamor_core.c
index 6c0b3c834..5711be72f 100644
--- a/xorg-server/glamor/glamor_core.c
+++ b/xorg-server/glamor/glamor_core.c
@@ -559,48 +559,3 @@ glamor_bitmap_to_region(PixmapPtr pixmap)
return ret;
}
-/* Borrow from cairo. */
-Bool
-glamor_gl_has_extension(const char *extension)
-{
- const char *pext;
- int ext_len;
-
- ext_len = strlen(extension);
-
- pext = (const char *) glGetString(GL_EXTENSIONS);
-
- if (pext == NULL || extension == NULL)
- return FALSE;
-
- while ((pext = strstr(pext, extension)) != NULL) {
- if (pext[ext_len] == ' ' || pext[ext_len] == '\0')
- return TRUE;
- pext += ext_len;
- }
- return FALSE;
-}
-
-int
-glamor_gl_get_version(void)
-{
- int major, minor;
- const char *version = (const char *) glGetString(GL_VERSION);
- const char *dot = version == NULL ? NULL : strchr(version, '.');
- const char *major_start = dot;
-
- /* Sanity check */
- if (dot == NULL || dot == version || *(dot + 1) == '\0') {
- major = 0;
- minor = 0;
- }
- else {
- /* Find the start of the major version in the string */
- while (major_start > version && *major_start != ' ')
- --major_start;
- major = strtol(major_start, NULL, 10);
- minor = strtol(dot + 1, NULL, 10);
- }
-
- return GLAMOR_GL_VERSION_ENCODE(major, minor);
-}
diff --git a/xorg-server/glamor/glamor_fbo.c b/xorg-server/glamor/glamor_fbo.c
index 640b6fd81..4f6da67fb 100644
--- a/xorg-server/glamor/glamor_fbo.c
+++ b/xorg-server/glamor/glamor_fbo.c
@@ -361,9 +361,6 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
GLint tex = 0;
int cache_flag;
- if (!glamor_check_fbo_size(glamor_priv, w, h))
- return NULL;
-
if (flag == GLAMOR_CREATE_FBO_NO_FBO)
goto new_fbo;
diff --git a/xorg-server/glamor/glamor_fill.c b/xorg-server/glamor/glamor_fill.c
index 7461b62fa..2fa726e72 100644
--- a/xorg-server/glamor/glamor_fill.c
+++ b/xorg-server/glamor/glamor_fill.c
@@ -218,9 +218,6 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
}
}
- if (_X_UNLIKELY(nbox > 1))
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
-
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
GL_FALSE, 2 * sizeof(float), vertices);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
diff --git a/xorg-server/glamor/glamor_glyphs.c b/xorg-server/glamor/glamor_glyphs.c
index 2b2c735d4..a04ae8261 100644
--- a/xorg-server/glamor/glamor_glyphs.c
+++ b/xorg-server/glamor/glamor_glyphs.c
@@ -332,7 +332,7 @@ glamor_realize_glyph_caches(ScreenPtr pScreen)
pixmap = pScreen->CreatePixmap(pScreen,
CACHE_PICTURE_SIZE,
CACHE_PICTURE_SIZE + MASK_CACHE_MAX_SIZE,
- depth, 0);
+ depth, GLAMOR_CREATE_NO_LARGE);
if (!pixmap)
goto bail;
diff --git a/xorg-server/glamor/glamor_gradient.c b/xorg-server/glamor/glamor_gradient.c
index f77d6a8e3..c24f3427f 100644
--- a/xorg-server/glamor/glamor_gradient.c
+++ b/xorg-server/glamor/glamor_gradient.c
@@ -247,7 +247,6 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
"{\n"\
" float t = 0.0;\n"\
" float sqrt_value;\n"\
- " int revserse = 0;\n"\
" t_invalid = 0;\n"\
" \n"\
" vec3 tmp = vec3(source_texture.x, source_texture.y, 1.0);\n"\
@@ -295,30 +294,11 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
" }\n"\
" \n"\
" if(repeat_type == %d){\n" /* repeat normal*/\
- " while(t > 1.0) \n"\
- " t = t - 1.0; \n"\
- " while(t < 0.0) \n"\
- " t = t + 1.0; \n"\
+ " t = fract(t);\n"\
" }\n"\
" \n"\
" if(repeat_type == %d) {\n" /* repeat reflect*/\
- " while(t > 1.0) {\n"\
- " t = t - 1.0; \n"\
- " if(revserse == 0)\n"\
- " revserse = 1;\n"\
- " else\n"\
- " revserse = 0;\n"\
- " }\n"\
- " while(t < 0.0) {\n"\
- " t = t + 1.0; \n"\
- " if(revserse == 0)\n"\
- " revserse = 1;\n"\
- " else\n"\
- " revserse = 0;\n"\
- " }\n"\
- " if(revserse == 1) {\n"\
- " t = 1.0 - t; \n"\
- " }\n"\
+ " t = abs(fract(t * 0.5 + 0.5) * 2.0 - 1.0);\n"\
" }\n"\
" \n"\
" return t;\n"\
@@ -492,7 +472,6 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
" vec4 stop_color_before;\n"\
" vec4 stop_color_after;\n"\
" float new_alpha; \n"\
- " int revserse = 0;\n"\
" vec4 gradient_color;\n"\
" float percentage; \n"\
" vec3 source_texture_trans = transform_mat * tmp;\n"\
@@ -512,30 +491,11 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
" distance = distance - _p1_distance; \n"\
" \n"\
" if(repeat_type == %d){\n" /* repeat normal*/\
- " while(distance > _pt_distance) \n"\
- " distance = distance - (_pt_distance); \n"\
- " while(distance < 0.0) \n"\
- " distance = distance + (_pt_distance); \n"\
+ " distance = mod(distance, _pt_distance);\n"\
" }\n"\
" \n"\
" if(repeat_type == %d) {\n" /* repeat reflect*/\
- " while(distance > _pt_distance) {\n"\
- " distance = distance - (_pt_distance); \n"\
- " if(revserse == 0)\n"\
- " revserse = 1;\n"\
- " else\n"\
- " revserse = 0;\n"\
- " }\n"\
- " while(distance < 0.0) {\n"\
- " distance = distance + (_pt_distance); \n"\
- " if(revserse == 0)\n"\
- " revserse = 1;\n"\
- " else\n"\
- " revserse = 0;\n"\
- " }\n"\
- " if(revserse == 1) {\n"\
- " distance = (_pt_distance) - distance; \n"\
- " }\n"\
+ " distance = abs(mod(distance + _pt_distance, 2.0 * _pt_distance) - _pt_distance);\n"\
" }\n"\
" \n"\
" len_percentage = distance/(_pt_distance);\n"\
@@ -1160,9 +1120,6 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
free(stop_colors);
}
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
@@ -1181,9 +1138,6 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
free(stop_colors);
}
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glamor_put_context(glamor_priv);
@@ -1511,9 +1465,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
free(stop_colors);
}
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
@@ -1532,9 +1483,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
free(stop_colors);
}
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glamor_put_context(glamor_priv);
diff --git a/xorg-server/glamor/glamor_largepixmap.c b/xorg-server/glamor/glamor_largepixmap.c
index b8c064038..b3a8d5d20 100644
--- a/xorg-server/glamor/glamor_largepixmap.c
+++ b/xorg-server/glamor/glamor_largepixmap.c
@@ -1015,7 +1015,6 @@ glamor_composite_largepixmap_region(CARD8 op,
INT16 x_dest, INT16 y_dest,
CARD16 width, CARD16 height)
{
- glamor_screen_private *glamor_priv;
glamor_pixmap_clipped_regions *clipped_dest_regions;
glamor_pixmap_clipped_regions *clipped_source_regions;
glamor_pixmap_clipped_regions *clipped_mask_regions;
@@ -1044,9 +1043,8 @@ glamor_composite_largepixmap_region(CARD8 op,
else
mask_repeat_type = RepeatNone;
- glamor_priv = dest_pixmap_priv->base.glamor_priv;
- fixed_block_width = glamor_priv->max_fbo_size;
- fixed_block_height = glamor_priv->max_fbo_size;
+ fixed_block_width = dest_pixmap_priv->large.block_w;
+ fixed_block_height = dest_pixmap_priv->large.block_h;
/* If we got an totally out-of-box region for a source or mask
* region without repeat, we need to set it as null_source and
* give it a solid color (0,0,0,0). */
@@ -1112,8 +1110,8 @@ glamor_composite_largepixmap_region(CARD8 op,
/*compute the correct block width and height whose transformed source/mask
*region can fit into one texture.*/
- if (force_clip || fixed_block_width < glamor_priv->max_fbo_size
- || fixed_block_height < glamor_priv->max_fbo_size)
+ if (force_clip || fixed_block_width < dest_pixmap_priv->large.block_w
+ || fixed_block_height < dest_pixmap_priv->large.block_h)
clipped_dest_regions =
glamor_compute_clipped_regions_ext(dest_pixmap_priv, region,
&n_dest_regions,
diff --git a/xorg-server/glamor/glamor_pixmap.c b/xorg-server/glamor/glamor_pixmap.c
index 615faad33..891ecdd37 100644
--- a/xorg-server/glamor/glamor_pixmap.c
+++ b/xorg-server/glamor/glamor_pixmap.c
@@ -1013,10 +1013,9 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w,
clipped_regions =
glamor_compute_clipped_regions_ext(pixmap_priv, &region,
&n_region,
- pixmap_priv->base.
- glamor_priv->max_fbo_size,
- pixmap_priv->base.
- glamor_priv->max_fbo_size, 0,
+ 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++) {
@@ -1374,10 +1373,9 @@ glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, int h,
clipped_regions =
glamor_compute_clipped_regions_ext(pixmap_priv, &region,
&n_region,
- pixmap_priv->base.
- glamor_priv->max_fbo_size,
- pixmap_priv->base.
- glamor_priv->max_fbo_size, 0,
+ pixmap_priv->large.block_w,
+ pixmap_priv->large.block_h,
+ 0,
0);
DEBUGF("start download large pixmap %p %dx%d \n", pixmap, w, h);
diff --git a/xorg-server/glamor/glamor_points.c b/xorg-server/glamor/glamor_points.c
new file mode 100644
index 000000000..5399f96e8
--- /dev/null
+++ b/xorg-server/glamor/glamor_points.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ * Copyright © 1998 Keith Packard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Zhigang Gong <zhigang.gong@linux.intel.com>
+ *
+ */
+
+#include "glamor_priv.h"
+#include "glamor_transform.h"
+
+static const glamor_facet glamor_facet_point = {
+ .name = "poly_point",
+ .vs_vars = "attribute vec2 primitive;\n",
+ .vs_exec = GLAMOR_POS(gl_Position, primitive),
+};
+
+Bool
+glamor_poly_point_nf(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPointPtr ppt)
+{
+ ScreenPtr screen = drawable->pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_program *prog = &glamor_priv->point_prog;
+ glamor_pixmap_private *pixmap_priv;
+ int off_x, off_y;
+ GLshort *vbo_ppt;
+ char *vbo_offset;
+ int box_x, box_y;
+
+ pixmap_priv = glamor_get_pixmap_private(pixmap);
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+ goto bail;
+
+ glamor_get_context(glamor_priv);
+
+ if (prog->failed)
+ goto bail_ctx;
+
+ if (!prog->prog) {
+ if (!glamor_build_program(screen, prog,
+ &glamor_facet_point,
+ &glamor_fill_solid))
+ goto bail_ctx;
+ }
+
+ if (!glamor_use_program(pixmap, gc, prog, NULL))
+ goto bail_ctx;
+
+ vbo_ppt = glamor_get_vbo_space(screen, npt * (2 * sizeof (INT16)), &vbo_offset);
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, 0, vbo_offset);
+ if (mode == CoordModePrevious) {
+ int n = npt;
+ INT16 x = 0, y = 0;
+ while (n--) {
+ vbo_ppt[0] = (x += ppt->x);
+ vbo_ppt[1] = (y += ppt->y);
+ vbo_ppt += 2;
+ ppt++;
+ }
+ } else
+ memcpy(vbo_ppt, ppt, npt * (2 * sizeof (INT16)));
+ glamor_put_vbo_space(screen);
+
+ glEnable(GL_SCISSOR_TEST);
+
+ glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
+ int nbox = RegionNumRects(gc->pCompositeClip);
+ BoxPtr box = RegionRects(gc->pCompositeClip);
+
+ glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, TRUE, prog->matrix_uniform, &off_x, &off_y);
+
+ while (nbox--) {
+ glScissor(box->x1 + off_x,
+ box->y1 + off_y,
+ box->x2 - box->x1,
+ box->y2 - box->y1);
+ box++;
+ glDrawArrays(GL_POINTS, 0, npt);
+ }
+ }
+
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_COLOR_LOGIC_OP);
+ glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+ glamor_put_context(glamor_priv);
+
+ glamor_priv->state = RENDER_STATE;
+ glamor_priv->render_idle_cnt = 0;
+
+ return TRUE;
+
+bail_ctx:
+ glDisable(GL_COLOR_LOGIC_OP);
+ glamor_put_context(glamor_priv);
+bail:
+ return FALSE;
+}
+
+void
+glamor_poly_point(DrawablePtr drawable, GCPtr gc, int mode, int npt,
+ DDXPointPtr ppt)
+{
+ if (glamor_poly_point_nf(drawable, gc, mode, npt, ppt))
+ return;
+ miPolyPoint(drawable, gc, mode, npt, ppt);
+}
diff --git a/xorg-server/glamor/glamor_polyops.c b/xorg-server/glamor/glamor_polyops.c
deleted file mode 100644
index 1484d80f1..000000000
--- a/xorg-server/glamor/glamor_polyops.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright © 2009 Intel Corporation
- * Copyright © 1998 Keith Packard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- * Zhigang Gong <zhigang.gong@linux.intel.com>
- *
- */
-
-#include "glamor_priv.h"
-
-static Bool
-_glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
- DDXPointPtr ppt, Bool fallback)
-{
- if (!fallback && glamor_ddx_fallback_check_gc(pGC)
- && glamor_ddx_fallback_check_pixmap(pDrawable))
- return FALSE;
-
- miPolyPoint(pDrawable, pGC, mode, npt, ppt);
-
- return TRUE;
-}
-
-void
-glamor_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
- DDXPointPtr ppt)
-{
- _glamor_poly_point(pDrawable, pGC, mode, npt, ppt, TRUE);
-}
-
-Bool
-glamor_poly_point_nf(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
- DDXPointPtr ppt)
-{
- return _glamor_poly_point(pDrawable, pGC, mode, npt, ppt, FALSE);
-}
-
-static Bool
-_glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
- xSegment *pSeg, Bool fallback)
-{
- if (!fallback && glamor_ddx_fallback_check_gc(pGC)
- && glamor_ddx_fallback_check_pixmap(pDrawable))
- return FALSE;
-
- miPolySegment(pDrawable, pGC, nseg, pSeg);
-
- return TRUE;
-}
-
-void
-glamor_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSeg)
-{
- _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, TRUE);
-}
-
-Bool
-glamor_poly_segment_nf(DrawablePtr pDrawable, GCPtr pGC, int nseg,
- xSegment *pSeg)
-{
- return _glamor_poly_segment(pDrawable, pGC, nseg, pSeg, FALSE);
-}
diff --git a/xorg-server/glamor/glamor_priv.h b/xorg-server/glamor/glamor_priv.h
index bc7d3f827..4c305abfc 100644
--- a/xorg-server/glamor/glamor_priv.h
+++ b/xorg-server/glamor/glamor_priv.h
@@ -52,6 +52,7 @@
#include "glamor_debug.h"
#include "glamor_context.h"
+#include "glamor_program.h"
#include <list.h>
@@ -153,13 +154,6 @@ enum glamor_gl_flavor {
GLAMOR_GL_ES2 // OPENGL ES2.0 API
};
-#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_TEXTURE_EXACT_SIZE 0x104
-
#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2
#define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024)
@@ -213,6 +207,7 @@ typedef struct glamor_screen_private {
enum glamor_gl_flavor gl_flavor;
int has_pack_invert;
int has_fbo_blit;
+ int has_map_buffer_range;
int has_buffer_storage;
int has_khr_debug;
int max_fbo_size;
@@ -225,6 +220,9 @@ typedef struct glamor_screen_private {
GLint solid_prog;
GLint solid_color_uniform_location;
+ /* glamor point shader */
+ glamor_program point_prog;
+
/* vertext/elment_index buffer object for render */
GLuint vbo, ebo;
/** Next offset within the VBO that glamor_get_vbo_space() will use. */
@@ -421,6 +419,7 @@ typedef struct glamor_pixmap_private_base {
unsigned char gl_tex:1;
glamor_pixmap_fbo *fbo;
PixmapPtr pixmap;
+ BoxRec box;
int drm_stride;
glamor_screen_private *glamor_priv;
PicturePtr picture;
@@ -476,6 +475,52 @@ typedef struct glamor_pixmap_private {
};
} glamor_pixmap_private;
+static inline glamor_pixmap_fbo *
+glamor_pixmap_fbo_at(glamor_pixmap_private *priv, int x, int y)
+{
+ 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;
+}
+
+static inline BoxPtr
+glamor_pixmap_box_at(glamor_pixmap_private *priv, int x, int y)
+{
+ 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;
+}
+
+static inline int
+glamor_pixmap_wcnt(glamor_pixmap_private *priv)
+{
+ if (priv->type == GLAMOR_TEXTURE_LARGE)
+ return priv->large.block_wcnt;
+ return 1;
+}
+
+static inline int
+glamor_pixmap_hcnt(glamor_pixmap_private *priv)
+{
+ if (priv->type == GLAMOR_TEXTURE_LARGE)
+ return priv->large.block_hcnt;
+ return 1;
+}
+
+#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++)
+
/*
* Pixmap dynamic status, used by dynamic upload feature.
*
@@ -619,12 +664,6 @@ Bool glamor_set_alu(ScreenPtr screen, unsigned char alu);
Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
-Bool glamor_gl_has_extension(const char *extension);
-int glamor_gl_get_version(void);
-
-#define GLAMOR_GL_VERSION_ENCODE(major, minor) ( \
- ((major) * 256) \
- + ((minor) * 1))
/* glamor_fill.c */
Bool glamor_fill(DrawablePtr drawable,
diff --git a/xorg-server/glamor/glamor_program.c b/xorg-server/glamor/glamor_program.c
new file mode 100644
index 000000000..e2e1434ee
--- /dev/null
+++ b/xorg-server/glamor/glamor_program.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "glamor_priv.h"
+#include "glamor_transform.h"
+#include "glamor_program.h"
+
+static Bool
+use_solid(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg)
+{
+ return glamor_set_solid(pixmap, gc, TRUE, prog->fg_uniform);
+}
+
+const glamor_facet glamor_fill_solid = {
+ .name = "solid",
+ .fs_exec = " gl_FragColor = fg;\n",
+ .locations = glamor_program_location_fg,
+ .use = use_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);
+}
+
+static const glamor_facet glamor_fill_tile = {
+ .name = "tile",
+ .version = 130,
+ .vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n",
+ .fs_exec = " gl_FragColor = texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0);\n",
+ .locations = glamor_program_location_fill,
+ .use = use_tile,
+};
+
+#if 0
+static Bool
+use_stipple(PixmapPtr pixmap, GCPtr gc, glamor_program *prog)
+{
+ return glamor_set_stippled(pixmap, gc, prog->fg_uniform, prog->fill_offset_uniform, prog->fill_size_uniform);
+}
+
+static const glamor_facet glamor_fill_stipple = {
+ .name = "stipple",
+ .version = 130,
+ .vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n";
+ .fs_exec = (" if (texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0).x == 0)\n"
+ " discard;\n"
+ " gl_FragColor = fg;\n")
+ .locations = glamor_program_location_fg | glamor_program_location_fill
+ .use = use_stipple,
+};
+
+static const glamor_facet glamor_fill_opaque_stipple = {
+ .name = "opaque_stipple",
+ .version = 130,
+ .vs_exec = " fill_pos = fill_offset + primitive.xy + pos;\n";
+ .fs_exec = (" if (texelFetch(sampler, ivec2(mod(fill_pos,fill_size)), 0).x == 0)\n"
+ " gl_FragColor = bg;\n"
+ " else\n"
+ " gl_FragColor = fg;\n"),
+ .locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_fill
+ .use = use_opaque_stipple
+};
+#endif
+
+static const glamor_facet *glamor_facet_fill[4] = {
+ &glamor_fill_solid,
+ &glamor_fill_tile,
+ NULL,
+ NULL,
+};
+
+typedef struct {
+ glamor_program_location location;
+ const char *vs_vars;
+ const char *fs_vars;
+} glamor_location_var;
+
+static glamor_location_var location_vars[] = {
+ {
+ .location = glamor_program_location_fg,
+ .fs_vars = "uniform vec4 fg;\n"
+ },
+ {
+ .location = glamor_program_location_bg,
+ .fs_vars = "uniform vec4 bg;\n"
+ },
+ {
+ .location = glamor_program_location_fill,
+ .vs_vars = ("uniform vec2 fill_offset;\n"
+ "varying vec2 fill_pos;\n"),
+ .fs_vars = ("uniform sampler2D sampler;\n"
+ "uniform vec2 fill_size;\n"
+ "varying vec2 fill_pos;\n")
+ },
+ {
+ .location = glamor_program_location_font,
+ .fs_vars = "uniform usampler2D font;\n",
+ },
+};
+
+#define NUM_LOCATION_VARS (sizeof location_vars / sizeof location_vars[0])
+
+static char *
+add_var(char *cur, const char *add)
+{
+ char *new;
+
+ if (!add)
+ return cur;
+
+ new = realloc(cur, strlen(cur) + strlen(add) + 1);
+ if (!new) {
+ free(cur);
+ return NULL;
+ }
+ strcat(new, add);
+ return new;
+}
+
+static char *
+vs_location_vars(glamor_program_location locations)
+{
+ int l;
+ char *vars = strdup("");
+
+ for (l = 0; vars && l < NUM_LOCATION_VARS; l++)
+ if (locations & location_vars[l].location)
+ vars = add_var(vars, location_vars[l].vs_vars);
+ return vars;
+}
+
+static char *
+fs_location_vars(glamor_program_location locations)
+{
+ int l;
+ char *vars = strdup("");
+
+ for (l = 0; vars && l < NUM_LOCATION_VARS; l++)
+ if (locations & location_vars[l].location)
+ vars = add_var(vars, location_vars[l].fs_vars);
+ return vars;
+}
+
+static const char vs_template[] =
+ "%s" /* version */
+ "%s" /* prim vs_vars */
+ "%s" /* fill vs_vars */
+ "%s" /* location vs_vars */
+ GLAMOR_DECLARE_MATRIX
+ "void main() {\n"
+ "%s" /* prim vs_exec, outputs 'pos' and gl_Position */
+ "%s" /* fill vs_exec */
+ "}\n";
+
+static const char fs_template[] =
+ "%s" /* version */
+ GLAMOR_DEFAULT_PRECISION
+ "%s" /* prim fs_vars */
+ "%s" /* fill fs_vars */
+ "%s" /* location fs_vars */
+ "void main() {\n"
+ "%s" /* prim fs_exec */
+ "%s" /* fill fs_exec */
+ "}\n";
+
+static const char *
+str(const char *s)
+{
+ if (!s)
+ return "";
+ return s;
+}
+
+static const glamor_facet facet_null_fill = {
+ .name = ""
+};
+
+static GLint
+glamor_get_uniform(glamor_program *prog,
+ glamor_program_location location,
+ const char *name)
+{
+ GLint uniform;
+ if (location && (prog->locations & location) == 0)
+ return -2;
+ uniform = glGetUniformLocation(prog->prog, name);
+#if DBG
+ ErrorF("%s uniform %d\n", name, uniform);
+#endif
+ return uniform;
+}
+
+Bool
+glamor_build_program(ScreenPtr screen,
+ glamor_program *prog,
+ const glamor_facet *prim,
+ const glamor_facet *fill)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ glamor_program_location locations = prim->locations;
+ glamor_program_flag flags = prim->flags;
+
+ int version = prim->version;
+ char *version_string = NULL;
+
+ char *fs_vars = NULL;
+ char *vs_vars = NULL;
+
+ char *vs_prog_string;
+ char *fs_prog_string;
+
+ GLint fs_prog, vs_prog;
+
+ if (!fill)
+ fill = &facet_null_fill;
+
+ locations |= fill->locations;
+ flags |= fill->flags;
+ version = MAX(version, fill->version);
+
+ if (version >= 130) {
+
+ /* 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 ||
+ epoxy_gl_version() < 30) {
+ goto fail;
+ }
+ }
+
+ vs_vars = vs_location_vars(locations);
+ fs_vars = fs_location_vars(locations);
+
+ if (!vs_vars)
+ goto fail;
+ if (!fs_vars)
+ goto fail;
+
+ if (version) {
+ if (asprintf(&version_string, "#version %d\n", version) < 0)
+ version_string = NULL;
+ if (!version_string)
+ goto fail;
+ }
+
+ if (asprintf(&vs_prog_string,
+ vs_template,
+ str(version_string),
+ str(prim->vs_vars),
+ str(fill->vs_vars),
+ vs_vars,
+ str(prim->vs_exec),
+ str(fill->vs_exec)) < 0)
+ vs_prog_string = NULL;
+
+ if (asprintf(&fs_prog_string,
+ fs_template,
+ str(version_string),
+ str(prim->fs_vars),
+ str(fill->fs_vars),
+ fs_vars,
+ str(prim->fs_exec),
+ str(fill->fs_exec)) < 0)
+ fs_prog_string = NULL;
+
+ if (!vs_prog_string || !fs_prog_string)
+ goto fail;
+
+#define DBG 0
+#if DBG
+ ErrorF("\nPrograms for %s %s\nVertex shader:\n\n%s\n\nFragment Shader:\n\n%s",
+ prim->name, fill->name, vs_prog_string, fs_prog_string);
+#endif
+
+ prog->prog = glCreateProgram();
+ prog->flags = flags;
+ prog->locations = locations;
+ prog->prim_use = prim->use;
+ prog->fill_use = fill->use;
+
+ vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_prog_string);
+ fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_prog_string);
+ free(vs_prog_string);
+ free(fs_prog_string);
+ glAttachShader(prog->prog, vs_prog);
+ glDeleteShader(vs_prog);
+ glAttachShader(prog->prog, fs_prog);
+ glDeleteShader(fs_prog);
+ glBindAttribLocation(prog->prog, GLAMOR_VERTEX_POS, "primitive");
+
+ if (prim->source_name) {
+#if DBG
+ ErrorF("Bind GLAMOR_VERTEX_SOURCE to %s\n", prim->source_name);
+#endif
+ glBindAttribLocation(prog->prog, GLAMOR_VERTEX_SOURCE, prim->source_name);
+ }
+
+ 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->font_uniform = glamor_get_uniform(prog, glamor_program_location_font, "font");
+
+ if (glGetError() != GL_NO_ERROR)
+ goto fail;
+
+ free(version_string);
+ free(fs_vars);
+ free(vs_vars);
+ return TRUE;
+fail:
+ prog->failed = 1;
+ if (prog->prog) {
+ glDeleteProgram(prog->prog);
+ prog->prog = 0;
+ }
+ free(version_string);
+ free(fs_vars);
+ free(vs_vars);
+ return FALSE;
+}
+
+Bool
+glamor_use_program(PixmapPtr pixmap,
+ GCPtr gc,
+ glamor_program *prog,
+ void *arg)
+{
+ glUseProgram(prog->prog);
+
+ if (prog->prim_use && !prog->prim_use(pixmap, gc, prog, arg))
+ return FALSE;
+
+ if (prog->fill_use && !prog->fill_use(pixmap, gc, prog, arg))
+ return FALSE;
+
+ return TRUE;
+}
+
+glamor_program *
+glamor_use_program_fill(PixmapPtr pixmap,
+ GCPtr gc,
+ glamor_program_fill *program_fill,
+ const glamor_facet *prim)
+{
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ glamor_program *prog = &program_fill->progs[gc->fillStyle];
+
+ int fill_style = gc->fillStyle;
+ const glamor_facet *fill;
+
+ if (prog->failed)
+ return FALSE;
+
+ if (!prog->prog) {
+ fill = glamor_facet_fill[fill_style];
+ if (!fill)
+ return NULL;
+
+ if (!glamor_build_program(screen, prog, prim, fill))
+ return NULL;
+ }
+
+ if (!glamor_use_program(pixmap, gc, prog, NULL))
+ return NULL;
+
+ return prog;
+}
diff --git a/xorg-server/glamor/glamor_program.h b/xorg-server/glamor/glamor_program.h
new file mode 100644
index 000000000..88efc3593
--- /dev/null
+++ b/xorg-server/glamor/glamor_program.h
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+#ifndef _GLAMOR_PROGRAM_H_
+#define _GLAMOR_PROGRAM_H_
+
+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;
+
+typedef enum {
+ glamor_program_flag_none = 0,
+} glamor_program_flag;
+
+typedef struct _glamor_program glamor_program;
+
+typedef Bool (*glamor_use) (PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg);
+
+typedef struct {
+ const char *name;
+ const int version;
+ const char *vs_vars;
+ const char *vs_exec;
+ const char *fs_vars;
+ const char *fs_exec;
+ const glamor_program_location locations;
+ const glamor_program_flag flags;
+ const char *source_name;
+ glamor_use use;
+} glamor_facet;
+
+struct _glamor_program {
+ GLint prog;
+ GLint failed;
+ GLint matrix_uniform;
+ GLint fg_uniform;
+ GLint bg_uniform;
+ GLint fill_size_uniform;
+ GLint fill_offset_uniform;
+ GLint font_uniform;
+ glamor_program_location locations;
+ glamor_program_flag flags;
+ glamor_use prim_use;
+ glamor_use fill_use;
+};
+
+typedef struct {
+ glamor_program progs[4];
+} glamor_program_fill;
+
+extern const glamor_facet glamor_fill_solid;
+
+Bool
+glamor_build_program(ScreenPtr screen,
+ glamor_program *prog,
+ const glamor_facet *prim,
+ const glamor_facet *fill);
+
+Bool
+glamor_use_program(PixmapPtr pixmap,
+ GCPtr gc,
+ glamor_program *prog,
+ void *arg);
+
+glamor_program *
+glamor_use_program_fill(PixmapPtr pixmap,
+ GCPtr gc,
+ glamor_program_fill *program_fill,
+ const glamor_facet *prim);
+
+#endif /* _GLAMOR_PROGRAM_H_ */
diff --git a/xorg-server/glamor/glamor_render.c b/xorg-server/glamor/glamor_render.c
index c0ee22c2f..cdf8effdc 100644
--- a/xorg-server/glamor/glamor_render.c
+++ b/xorg-server/glamor/glamor_render.c
@@ -412,29 +412,10 @@ glamor_init_composite_shaders(ScreenPtr screen)
eb_size = GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(short) * 2;
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, eb_size, NULL, GL_STATIC_DRAW);
- eb = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
- }
- else {
- eb = malloc(eb_size);
- }
-
- if (eb == NULL)
- FatalError
- ("fatal error, fail to get element buffer. GL context may be not created correctly.\n");
+ eb = XNFalloc(eb_size);
glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT);
-
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
- glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
- else {
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, eb_size, eb, GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
- free(eb);
- }
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, eb_size, eb, GL_STATIC_DRAW);
+ free(eb);
glamor_put_context(glamor_priv);
}
@@ -448,6 +429,7 @@ glamor_fini_composite_shaders(ScreenPtr screen)
glamor_priv = glamor_get_screen_private(screen);
glamor_get_context(glamor_priv);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &glamor_priv->ebo);
for (i = 0; i < SHADER_SOURCE_COUNT; i++)
@@ -706,8 +688,6 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
glamor_get_context(glamor_priv);
vb = glamor_get_vbo_space(screen, vert_size, &vbo_offset);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
-
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
glamor_priv->vb_stride, vbo_offset);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
@@ -1329,7 +1309,6 @@ glamor_composite_with_shader(CARD8 op,
}
}
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
diff --git a/xorg-server/glamor/glamor_segment.c b/xorg-server/glamor/glamor_segment.c
new file mode 100644
index 000000000..84b27acce
--- /dev/null
+++ b/xorg-server/glamor/glamor_segment.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "glamor_priv.h"
+
+Bool
+glamor_poly_segment_nf(DrawablePtr drawable, GCPtr gc, int nseg,
+ xSegment *seg)
+{
+ return FALSE;
+}
+
+void
+glamor_poly_segment(DrawablePtr drawable, GCPtr gc, int nseg,
+ xSegment *seg)
+{
+ if (glamor_poly_segment_nf(drawable, gc, nseg, seg))
+ return;
+ miPolySegment(drawable, gc, nseg, seg);
+}
diff --git a/xorg-server/glamor/glamor_transform.c b/xorg-server/glamor/glamor_transform.c
new file mode 100644
index 000000000..d6ba56421
--- /dev/null
+++ b/xorg-server/glamor/glamor_transform.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "glamor_priv.h"
+#include "glamor_transform.h"
+
+
+/*
+ * Set up rendering to target the specified drawable, computing an
+ * appropriate transform for the vertex shader to convert
+ * drawable-relative coordinates into pixmap-relative coordinates. If
+ * requested, the offset from pixmap origin coordinates back to window
+ * system coordinates will be returned in *p_off_x, *p_off_y so that
+ * clipping computations can be adjusted as appropriate
+ */
+
+void
+glamor_set_destination_drawable(DrawablePtr drawable,
+ int box_x,
+ int box_y,
+ Bool do_drawable_translate,
+ Bool center_offset,
+ GLint matrix_uniform_location,
+ int *p_off_x,
+ int *p_off_y)
+{
+ PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
+ int off_x, off_y;
+ BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y);
+ int w = box->x2 - box->x1;
+ int h = box->y2 - box->y1;
+ float scale_x = 2.0f / (float) w;
+ float scale_y = 2.0f / (float) h;
+ float center_adjust = 0.0f;
+
+ glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
+
+ off_x -= box->x1;
+ off_y -= box->y1;
+
+ if (p_off_x) {
+ *p_off_x = off_x;
+ *p_off_y = off_y;
+ }
+
+ /* A tricky computation to find the right value for the two linear functions
+ * that transform rendering coordinates to pixmap coordinates
+ *
+ * pixmap_x = render_x + drawable->x + off_x
+ * pixmap_y = render_y + drawable->y + off_y
+ *
+ * gl_x = pixmap_x * 2 / width - 1
+ * gl_y = pixmap_y * 2 / height - 1
+ *
+ * gl_x = (render_x + drawable->x + off_x) * 2 / width - 1
+ *
+ * gl_x = (render_x) * 2 / width + (drawable->x + off_x) * 2 / width - 1
+ *
+ * I'll think about yInverted later, when I have some way to test
+ */
+
+ if (do_drawable_translate) {
+ off_x += drawable->x;
+ off_y += drawable->y;
+ }
+
+ /*
+ * To get GL_POINTS drawn in the right spot, we need to adjust the
+ * coordinates by 1/2 a pixel.
+ */
+ if (center_offset)
+ center_adjust = 0.5f;
+
+ glUniform4f(matrix_uniform_location,
+ scale_x, (off_x + center_adjust) * scale_x - 1.0f,
+ scale_y, (off_y + center_adjust) * scale_y - 1.0f);
+
+ glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo_at(pixmap_priv, box_x, box_y),
+ 0, 0, w, h);
+}
+
+/*
+ * Set up for solid rendering to the specified pixmap using alu, fg and planemask
+ * from the specified GC. Load the target color into the specified uniform
+ */
+
+void
+glamor_set_color(PixmapPtr pixmap,
+ CARD32 pixel,
+ GLint uniform)
+{
+ float color[4];
+
+ glamor_get_rgba_from_pixel(pixel,
+ &color[0], &color[1], &color[2], &color[3],
+ format_for_pixmap(pixmap));
+
+ glUniform4fv(uniform, 1, color);
+}
+
+Bool
+glamor_set_solid(PixmapPtr pixmap,
+ GCPtr gc,
+ Bool use_alu,
+ GLint uniform)
+{
+ CARD32 pixel;
+ int alu = use_alu ? gc->alu : GXcopy;
+
+ if (!glamor_set_planemask(pixmap, gc->planemask))
+ return FALSE;
+
+ pixel = gc->fgPixel;
+
+ if (!glamor_set_alu(pixmap->drawable.pScreen, alu)) {
+ switch (gc->alu) {
+ case GXclear:
+ pixel = 0;
+ break;
+ case GXcopyInverted:
+ pixel = ~pixel;
+ break;
+ case GXset:
+ pixel = ~0 & gc->planemask;
+ break;
+ default:
+ return FALSE;
+ }
+ }
+ glamor_set_color(pixmap, gc->fgPixel, uniform);
+
+ return TRUE;
+}
+
+Bool
+glamor_set_texture(PixmapPtr pixmap,
+ PixmapPtr texture,
+ int off_x,
+ int off_y,
+ GLint offset_uniform,
+ GLint size_uniform)
+{
+ glamor_pixmap_private *texture_priv;
+
+ texture_priv = glamor_get_pixmap_private(texture);
+
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(texture_priv))
+ return FALSE;
+
+ if (texture_priv->type == GLAMOR_TEXTURE_LARGE)
+ return FALSE;
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture_priv->base.fbo->tex);
+
+ glUniform2f(offset_uniform, off_x, off_y);
+ glUniform2f(size_uniform, texture->drawable.width, texture->drawable.height);
+ return TRUE;
+}
+
+Bool
+glamor_set_tiled(PixmapPtr pixmap,
+ GCPtr gc,
+ GLint offset_uniform,
+ GLint size_uniform)
+{
+ if (!glamor_set_alu(pixmap->drawable.pScreen, gc->alu))
+ return FALSE;
+
+ if (!glamor_set_planemask(pixmap, gc->planemask))
+ return FALSE;
+
+ return glamor_set_texture(pixmap,
+ gc->tile.pixmap,
+ -gc->patOrg.x,
+ -gc->patOrg.y,
+ offset_uniform,
+ size_uniform);
+}
+
+Bool
+glamor_set_stippled(PixmapPtr pixmap,
+ GCPtr gc,
+ GLint fg_uniform,
+ GLint offset_uniform,
+ GLint size_uniform)
+{
+ if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform))
+ return FALSE;
+
+ if (!glamor_set_texture(pixmap, gc->stipple, gc->patOrg.x, gc->patOrg.y, offset_uniform, size_uniform))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/xorg-server/glamor/glamor_transform.h b/xorg-server/glamor/glamor_transform.h
new file mode 100644
index 000000000..36b789af8
--- /dev/null
+++ b/xorg-server/glamor/glamor_transform.h
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#ifndef _GLAMOR_TRANSFORM_H_
+#define _GLAMOR_TRANSFORM_H_
+
+void
+glamor_set_destination_drawable(DrawablePtr drawable,
+ int box_x,
+ int box_y,
+ Bool do_drawable_translate,
+ Bool center_offset,
+ GLint matrix_uniform_location,
+ int *p_off_x,
+ int *p_off_y);
+
+void
+glamor_set_color(PixmapPtr pixmap,
+ CARD32 pixel,
+ GLint uniform);
+
+Bool
+glamor_set_texture(PixmapPtr pixmap,
+ PixmapPtr texture,
+ int off_x,
+ int off_y,
+ GLint offset_uniform,
+ GLint size_uniform);
+
+Bool
+glamor_set_solid(PixmapPtr pixmap,
+ GCPtr gc,
+ Bool use_alu,
+ GLint uniform);
+
+Bool
+glamor_set_tiled(PixmapPtr pixmap,
+ GCPtr gc,
+ GLint offset_uniform,
+ GLint size_uniform);
+
+Bool
+glamor_set_stippled(PixmapPtr pixmap,
+ GCPtr gc,
+ GLint fg_uniform,
+ GLint offset_uniform,
+ GLint size_uniform);
+
+/*
+ * Vertex shader bits that transform X coordinates to pixmap
+ * coordinates using the matrix computed above
+ */
+
+#define GLAMOR_DECLARE_MATRIX "uniform vec4 v_matrix;\n"
+#define GLAMOR_X_POS(x) #x " *v_matrix.x + v_matrix.y"
+#define GLAMOR_Y_POS(y) #y " *v_matrix.z + v_matrix.w"
+#if 0
+#define GLAMOR_POS(dst,src) \
+ " " #dst ".x = " #src ".x * v_matrix.x + v_matrix.y;\n" \
+ " " #dst ".y = " #src ".y * v_matrix.z + v_matrix.w;\n" \
+ " " #dst ".z = 0.0;\n" \
+ " " #dst ".w = 1.0;\n"
+#endif
+#define GLAMOR_POS(dst,src) \
+ " " #dst ".xy = " #src ".xy * v_matrix.xz + v_matrix.yw;\n" \
+ " " #dst ".zw = vec2(0.0,1.0);\n"
+
+#endif /* _GLAMOR_TRANSFORM_H_ */
diff --git a/xorg-server/glamor/glamor_trapezoid.c b/xorg-server/glamor/glamor_trapezoid.c
index 969ab68bc..c76b8bb2a 100644
--- a/xorg-server/glamor/glamor_trapezoid.c
+++ b/xorg-server/glamor/glamor_trapezoid.c
@@ -637,8 +637,6 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
vb = glamor_get_vbo_space(screen, vert_size, &vbo_offset);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
-
/* Set the vertex pointer. */
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
GL_FALSE, glamor_priv->vb_stride,
@@ -977,7 +975,6 @@ _glamor_trapezoids_with_shader(CARD8 op,
ret = TRUE;
TRAPEZOID_RESET_GL:
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
@@ -1415,8 +1412,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale));
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
/* Now draw the Trapezoid mask. */
glUseProgram(trapezoid_prog);
@@ -1562,7 +1557,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
}
}
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_BLEND);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
diff --git a/xorg-server/glamor/glamor_vbo.c b/xorg-server/glamor/glamor_vbo.c
index 5e98bfe47..2731692d6 100644
--- a/xorg-server/glamor/glamor_vbo.c
+++ b/xorg-server/glamor/glamor_vbo.c
@@ -96,7 +96,7 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset)
*vbo_offset = (void *)(uintptr_t)glamor_priv->vbo_offset;
data = glamor_priv->vb + glamor_priv->vbo_offset;
glamor_priv->vbo_offset += size;
- } else if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+ } else if (glamor_priv->has_map_buffer_range) {
if (glamor_priv->vbo_size < glamor_priv->vbo_offset + size) {
glamor_priv->vbo_size = MAX(GLAMOR_VBO_SIZE, size);
glamor_priv->vbo_offset = 0;
@@ -147,7 +147,7 @@ glamor_put_vbo_space(ScreenPtr screen)
* persistent mapping, so we can leave it around until we
* reach the end of the buffer.
*/
- } else if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
+ } else if (glamor_priv->has_map_buffer_range) {
glUnmapBuffer(GL_ARRAY_BUFFER);
} else {
glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
@@ -179,7 +179,7 @@ glamor_fini_vbo(ScreenPtr screen)
glamor_get_context(glamor_priv);
glDeleteBuffers(1, &glamor_priv->vbo);
- if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP)
+ if (!glamor_priv->has_map_buffer_range)
free(glamor_priv->vb);
glamor_put_context(glamor_priv);