diff options
Diffstat (limited to 'xorg-server/glamor')
-rw-r--r-- | xorg-server/glamor/Makefile.am | 5 | ||||
-rw-r--r-- | xorg-server/glamor/glamor.c | 32 | ||||
-rw-r--r-- | xorg-server/glamor/glamor.h | 7 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_core.c | 45 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_fbo.c | 3 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_fill.c | 3 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_glyphs.c | 2 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_gradient.c | 60 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_largepixmap.c | 10 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_pixmap.c | 14 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_points.c | 129 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_polyops.c | 82 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_priv.h | 65 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_program.c | 394 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_program.h | 94 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_render.c | 29 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_segment.c | 39 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_transform.c | 215 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_transform.h | 87 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_trapezoid.c | 6 | ||||
-rw-r--r-- | xorg-server/glamor/glamor_vbo.c | 6 |
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, ®ion, &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, ®ion, &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); |