/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Junyan He * */ /** @file glamor_trapezoid.c * * Trapezoid acceleration implementation */ #include "glamor_priv.h" #ifdef RENDER #include "mipict.h" #include "fbpict.h" #ifdef GLAMOR_TRAPEZOID_SHADER void glamor_init_trapezoid_shader(ScreenPtr screen) { glamor_screen_private *glamor_priv; glamor_gl_dispatch *dispatch; GLint fs_prog, vs_prog; const char *trapezoid_vs = GLAMOR_DEFAULT_PRECISION "attribute vec4 v_position;\n" "attribute vec4 v_texcoord;\n" "varying vec2 source_texture;\n" "\n" "void main()\n" "{\n" " gl_Position = v_position;\n" " source_texture = v_texcoord.xy;\n" "}\n"; /* * Because some GL fill function do not support the MultSample * anti-alias, we need to do the MSAA here. This manner like * pixman, will caculate the value of area in trapezoid dividing * the totol area for each pixel, as follow: | ----+------------------------------------------------------> | | ------------- | / \ | / \ | / \ | / +----------------+ | / |.....\ | | / |......\ | | / |.......\ | | / |........\ | | /-------------------+---------\ | | | | | | | | +----------------+ | \|/ */ const char *trapezoid_fs = GLAMOR_DEFAULT_PRECISION "varying vec2 source_texture; \n" "uniform float x_per_pix; \n" "uniform float y_per_pix; \n" "uniform float trap_top; \n" "uniform float trap_bottom; \n" "uniform float trap_left_x; \n" "uniform float trap_left_y; \n" "uniform float trap_left_slope; \n" "uniform int trap_left_vertical; \n" "uniform float trap_right_x; \n" "uniform float trap_right_y; \n" "uniform float trap_right_slope; \n" "uniform int trap_right_vertical; \n" "\n" "float get_alpha_val() \n" "{ \n" " float x_up_cut_left; \n" " float x_bottom_cut_left; \n" " float x_up_cut_right; \n" " float x_bottom_cut_right; \n" " \n" " if(trap_left_vertical == 1) { \n" " x_up_cut_left = trap_left_x; \n" " x_bottom_cut_left = trap_left_x; \n" " } else { \n" " x_up_cut_left = trap_left_x \n" " + (source_texture.y - y_per_pix/2.0 - trap_left_y) \n" " / trap_left_slope; \n" " x_bottom_cut_left = trap_left_x \n" " + (source_texture.y + y_per_pix/2.0 - trap_left_y) \n" " / trap_left_slope; \n" " } \n" " \n" " if(trap_right_vertical == 1) { \n" " x_up_cut_right = trap_right_x; \n" " x_bottom_cut_right = trap_right_x; \n" " } else { \n" " x_up_cut_right = trap_right_x \n" " + (source_texture.y - y_per_pix/2.0 - trap_right_y) \n" " / trap_right_slope; \n" " x_bottom_cut_right = trap_right_x \n" " + (source_texture.y + y_per_pix/2.0 - trap_right_y) \n" " / trap_right_slope; \n" " } \n" " \n" " if((x_up_cut_left <= source_texture.x - x_per_pix/2.0) && \n" " (x_bottom_cut_left <= source_texture.x - x_per_pix/2.0) && \n" " (x_up_cut_right >= source_texture.x + x_per_pix/2.0) && \n" " (x_bottom_cut_right >= source_texture.x + x_per_pix/2.0) && \n" " (trap_top <= source_texture.y - y_per_pix/2.0) && \n" " (trap_bottom >= source_texture.y + y_per_pix/2.0)) { \n" // The complete inside case. " return 1.0; \n" " } else if((trap_top > source_texture.y + y_per_pix/2.0) || \n" " (trap_bottom < source_texture.y - y_per_pix/2.0)) { \n" // The complete outside. Above the top or Below the bottom. " return 0.0; \n" " } else { \n" " if((x_up_cut_right < source_texture.x - x_per_pix/2.0 && \n" " x_bottom_cut_right < source_texture.x - x_per_pix/2.0) \n" " || (x_up_cut_left > source_texture.x + x_per_pix/2.0 && \n" " x_bottom_cut_left > source_texture.x + x_per_pix/2.0)) { \n" // The complete outside. At Left or Right of the trapezoide. " return 0.0; \n" " } \n" " } \n" // Get here, the pix is partly inside the trapezoid. " { \n" " float percent = 0.0; \n" " float up = (source_texture.y - y_per_pix/2.0) >= trap_top ? \n" " (source_texture.y - y_per_pix/2.0) : trap_top; \n" " float bottom = (source_texture.y + y_per_pix/2.0) <= trap_bottom ? \n" " (source_texture.y + y_per_pix/2.0) : trap_bottom; \n" " float left = source_texture.x - x_per_pix/2.0; \n" " float right = source_texture.x + x_per_pix/2.0; \n" " \n" " percent = (bottom - up) / y_per_pix; \n" " \n" " if(trap_left_vertical == 1) { \n" " if(trap_left_x > source_texture.x - x_per_pix/2.0 && \n" " trap_left_x < source_texture.x + x_per_pix/2.0) \n" " left = trap_left_x; \n" " } \n" " if(trap_right_vertical == 1) { \n" " if(trap_right_x > source_texture.x - x_per_pix/2.0 && \n" " trap_right_x < source_texture.x + x_per_pix/2.0) \n" " right = trap_right_x; \n" " } \n" " if((up >= bottom) || (left >= right)) \n" " return 0.0; \n" " \n" " percent = percent * ((right - left)/x_per_pix); \n" " if(trap_left_vertical == 1 && trap_right_vertical == 1) \n" " return percent; \n" " \n" " if(trap_left_vertical != 1) { \n" " float area; \n" // the slope should never be 0.0 here " float up_x = trap_left_x + (up - trap_left_y)/trap_left_slope; \n" " float bottom_x = trap_left_x + (bottom - trap_left_y)/trap_left_slope; \n" " if(trap_left_slope < 0.0 && up_x > left) { \n" /* case 1 | ----+-------------------------------------> | / | / | +---/--------+ | | /.........| | | /..........| | |/...........| | /............| | /|............| | +------------+ | \|/ */ " float left_y = trap_left_y + trap_left_slope*(left - trap_left_x); \n" " if((up_x > left) && (left_y > up)) { \n" " area = 0.5 * (up_x - left) * (left_y - up); \n" " if(up_x > right) { \n" " float right_y = trap_left_y \n" " + trap_left_slope*(right - trap_left_x); \n" " area = area - 0.5 * (up_x - right) * (right_y - up); \n" " } \n" " if(left_y > bottom) { \n" " area = area - 0.5 * (bottom_x - left) * (left_y - bottom); \n" " } \n" " } else { \n" " area = 0.0; \n" " } \n" " percent = percent * (1.0 - (area/((right-left)*(bottom-up)))); \n" " } else if(trap_left_slope > 0.0 && bottom_x > left) { \n" /* case 2 | ----+-------------------------------------> | \ | \ | +\-----------+ | | \..........| | | \.........| | | \........| | | \.......| | | \......| | +------\-----+ | \ | \ \|/ */ " float right_y = trap_left_y + trap_left_slope*(right - trap_left_x); \n" " if((up_x < right) && (right_y > up)) { \n" " area = 0.5 * (right - up_x) * (right_y - up); \n" " if(up_x < left) { \n" " float left_y = trap_left_y \n" " + trap_left_slope*(left - trap_left_x); \n" " area = area - 0.5 * (left - up_x) * (left_y - up); \n" " } \n" " if(right_y > bottom) { \n" " area = area - 0.5 * (right - bottom_x) * (right_y - bottom); \n" " } \n" " } else { \n" " area = 0.0; \n" " } \n" " percent = percent * (area/((right-left)*(bottom-up))); \n" " } \n" " } \n" " \n" " if(trap_right_vertical != 1) { \n" " float area; \n" // the slope should never be 0.0 here " float up_x = trap_right_x + (up - trap_right_y)/trap_right_slope; \n" " float bottom_x = trap_right_x + (bottom - trap_right_y)/trap_right_slope; \n" " if(trap_right_slope < 0.0 && bottom_x < right) { \n" /* case 3 | ----+-------------------------------------> | / | +--------/---+ | |......./ | | |....../ | | |...../ | | |..../ | | |.../ | | +--/---------+ | / | \|/ */ " float left_y = trap_right_y + trap_right_slope*(left - trap_right_x); \n" " if((up_x > left) && (left_y > up)) { \n" " area = 0.5 * (up_x - left) * (left_y - up); \n" " if(up_x > right) { \n" " float right_y = trap_right_y \n" " + trap_right_slope*(right - trap_right_x); \n" " area = area - 0.5 * (up_x - right) * (right_y - up); \n" " } \n" " if(left_y > bottom) { \n" " area = area - 0.5 * (bottom_x - left) * (left_y - bottom); \n" " } \n" " } else { \n" " area = 0.0; \n" " } \n" " percent = percent * (area/((right-left)*(bottom-up))); \n" " } else if(trap_right_slope > 0.0 && up_x < right) { \n" /* case 4 | ----+-------------------------------------> | \ | +--------\---+ | |.........\ | | |..........\ | | |...........\| | |............\ | |............|\ | +------------+ \ | \ | \|/ */ " float right_y = trap_right_y + trap_right_slope*(right - trap_right_x); \n" " if((up_x < right) && (right_y > up)) { \n" " area = 0.5 * (right - up_x) * (right_y - up); \n" " if(up_x < left) { \n" " float left_y = trap_right_y \n" " + trap_right_slope*(left - trap_right_x); \n" " area = area - 0.5 * (left - up_x) * (left_y - up); \n" " } \n" " if(right_y > bottom) { \n" " area = area - 0.5 * (right - bottom_x) * (right_y - bottom); \n" " } \n" " } else { \n" " area = 0.0; \n" " } \n" " percent = percent * (1.0 - (area/((right-left)*(bottom-up)))); \n" " } \n" " } \n" " \n" " return percent; \n" " } \n" "} \n" "\n" "void main() \n" "{ \n" " float alpha_val = get_alpha_val(); \n" " gl_FragColor = vec4(0.0, 0.0, 0.0, alpha_val); \n" "}\n"; glamor_priv = glamor_get_screen_private(screen); dispatch = glamor_get_dispatch(glamor_priv); glamor_priv->trapezoid_prog = dispatch->glCreateProgram(); vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, trapezoid_vs); fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER, trapezoid_fs); dispatch->glAttachShader(glamor_priv->trapezoid_prog, vs_prog); dispatch->glAttachShader(glamor_priv->trapezoid_prog, fs_prog); dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog, GLAMOR_VERTEX_POS, "v_positionsition"); dispatch->glBindAttribLocation(glamor_priv->trapezoid_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord"); glamor_link_glsl_prog(dispatch, glamor_priv->trapezoid_prog); dispatch->glUseProgram(0); glamor_put_dispatch(glamor_priv); } void glamor_fini_trapezoid_shader(ScreenPtr screen) { glamor_screen_private *glamor_priv; glamor_gl_dispatch *dispatch; glamor_priv = glamor_get_screen_private(screen); dispatch = glamor_get_dispatch(glamor_priv); dispatch->glDeleteProgram(glamor_priv->trapezoid_prog); glamor_put_dispatch(glamor_priv); } static Bool _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, xTrapezoid * traps, int ntrap, BoxRec *bounds) { glamor_screen_private *glamor_priv; glamor_gl_dispatch *dispatch; glamor_pixmap_private *pixmap_priv; PixmapPtr pixmap = NULL; GLint x_per_pix_uniform_location; GLint y_per_pix_uniform_location; GLint trap_top_uniform_location; GLint trap_bottom_uniform_location; GLint trap_left_x_uniform_location; GLint trap_left_y_uniform_location; GLint trap_left_slope_uniform_location; GLint trap_right_x_uniform_location; GLint trap_right_y_uniform_location; GLint trap_right_slope_uniform_location; GLint trap_left_vertical_uniform_location; GLint trap_right_vertical_uniform_location; GLint trapezoid_prog; float width, height; xFixed width_fix, height_fix; GLfloat xscale, yscale; float left_slope, right_slope; xTrapezoid *ptrap; BoxRec one_trap_bound; float vertices[8]; float tex_vertices[8]; float tmp; int i; glamor_priv = glamor_get_screen_private(screen); trapezoid_prog = glamor_priv->trapezoid_prog; pixmap = glamor_get_drawable_pixmap(picture->pDrawable); pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { /* should always have here. */ DEBUGF("GLAMOR_PIXMAP_PRIV_HAS_FBO check failed, fallback\n"); return FALSE; } /* First, clear all to zero */ if (!glamor_solid(pixmap, 0, 0, pixmap_priv->container->drawable.width, pixmap_priv->container->drawable.height, GXclear, 0xFFFFFFFF, 0)) { DEBUGF("glamor_solid failed, fallback\n"); return FALSE; } dispatch = glamor_get_dispatch(glamor_priv); /* Bind all the uniform vars .*/ x_per_pix_uniform_location = dispatch->glGetUniformLocation(trapezoid_prog, "x_per_pix"); y_per_pix_uniform_location = dispatch->glGetUniformLocation(trapezoid_prog, "y_per_pix"); trap_top_uniform_location = dispatch->glGetUniformLocation(trapezoid_prog, "trap_top"); trap_bottom_uniform_location = dispatch->glGetUniformLocation(trapezoid_prog, "trap_bottom"); trap_left_x_uniform_location = dispatch->glGetUniformLocation(trapezoid_prog, "trap_left_x"); trap_left_y_uniform_location = dispatch->glGetUniformLocation(trapezoid_prog, "trap_left_y"); trap_left_slope_uniform_location = dispatch->glGetUniformLocation(trapezoid_prog, "trap_left_slope"); trap_left_vertical_uniform_location = dispatch->glGetUniformLocation(trapezoid_prog, "trap_left_vertical"); trap_right_x_uniform_location = dispatch->glGetUniformLocation(trapezoid_prog, "trap_right_x"); trap_right_y_uniform_location = dispatch->glGetUniformLocation(trapezoid_prog, "trap_right_y"); trap_right_slope_uniform_location = dispatch->glGetUniformLocation(trapezoid_prog, "trap_right_slope"); trap_right_vertical_uniform_location = dispatch->glGetUniformLocation(trapezoid_prog, "trap_right_vertical"); glamor_set_destination_pixmap_priv_nc(pixmap_priv); pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale)); width = (float)(bounds->x2 - bounds->x1); height = (float)(bounds->y2 - bounds->y1); width_fix = IntToxFixed((bounds->x2 - bounds->x1)); height_fix = IntToxFixed((bounds->y2 - bounds->y1)); dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); /* Now draw the Trapezoid mask. */ dispatch->glUseProgram(trapezoid_prog); dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 0, vertices); dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 0, tex_vertices); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glEnable(GL_BLEND); dispatch->glBlendFunc(GL_ONE, GL_ONE); for (i = 0; i < ntrap; i++) { ptrap = traps + i; DEBUGF("--- The parameter of xTrapezoid is:\ntop: %d 0x%x\tbottom: %d 0x%x\n" "left: p1 (%d 0x%x, %d 0x%x)\tp2 (%d 0x%x, %d 0x%x)\n" "right: p1 (%d 0x%x, %d 0x%x)\tp2 (%d 0x%x, %d 0x%x)\n", xFixedToInt(ptrap->top), ptrap->top, xFixedToInt(ptrap->bottom), ptrap->bottom, xFixedToInt(ptrap->left.p1.x), ptrap->left.p1.x, xFixedToInt(ptrap->left.p1.y), ptrap->left.p1.y, xFixedToInt(ptrap->left.p2.x), ptrap->left.p2.x, xFixedToInt(ptrap->left.p2.y), ptrap->left.p2.y, xFixedToInt(ptrap->right.p1.x), ptrap->right.p1.x, xFixedToInt(ptrap->right.p1.y), ptrap->right.p1.y, xFixedToInt(ptrap->right.p2.x), ptrap->right.p2.x, xFixedToInt(ptrap->right.p2.y), ptrap->right.p2.y); miTrapezoidBounds(1, ptrap, &one_trap_bound); glamor_set_tcoords_tri_strip((pixmap_priv->container->drawable.width), (pixmap_priv->container->drawable.height), (one_trap_bound.x1), (one_trap_bound.y1), (one_trap_bound.x2), (one_trap_bound.y2), glamor_priv->yInverted, tex_vertices); /* Need to rebase. */ one_trap_bound.x1 -= bounds->x1; one_trap_bound.x2 -= bounds->x1; one_trap_bound.y1 -= bounds->y1; one_trap_bound.y2 -= bounds->y1; glamor_set_normalize_vcoords_tri_strip(xscale, yscale, one_trap_bound.x1, one_trap_bound.y1, one_trap_bound.x2, one_trap_bound.y2, glamor_priv->yInverted, vertices); DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f," "rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0], vertices[1], vertices[2], vertices[3], vertices[4], vertices[5], vertices[6], vertices[7]); DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f," "rightbottom: %f X %f, leftbottom : %f X %f\n", tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3], tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]); if (ptrap->left.p1.x == ptrap->left.p2.x) { left_slope = 0.0; dispatch->glUniform1i(trap_left_vertical_uniform_location, 1); } else { left_slope = ((float)(ptrap->left.p1.y - ptrap->left.p2.y)) / ((float)(ptrap->left.p1.x - ptrap->left.p2.x)); dispatch->glUniform1i(trap_left_vertical_uniform_location, 0); } dispatch->glUniform1f(trap_left_slope_uniform_location, left_slope); if (ptrap->right.p1.x == ptrap->right.p2.x) { right_slope = 0.0; dispatch->glUniform1i(trap_right_vertical_uniform_location, 1); } else { right_slope = ((float)(ptrap->right.p1.y - ptrap->right.p2.y)) / ((float)(ptrap->right.p1.x - ptrap->right.p2.x)); dispatch->glUniform1i(trap_right_vertical_uniform_location, 0); } dispatch->glUniform1f(trap_right_slope_uniform_location, right_slope); dispatch->glUniform1f(x_per_pix_uniform_location, ((float)width_fix) / (65536 * width)); dispatch->glUniform1f(y_per_pix_uniform_location, ((float)height_fix) / (65536 * height)); dispatch->glUniform1f(trap_top_uniform_location, ((float)ptrap->top) / 65536); dispatch->glUniform1f(trap_bottom_uniform_location, ((float)ptrap->bottom) / 65536); dispatch->glUniform1f(trap_left_x_uniform_location, ((float)ptrap->left.p1.x) / 65536); dispatch->glUniform1f(trap_left_y_uniform_location, ((float)ptrap->left.p1.y) / 65536); dispatch->glUniform1f(trap_right_x_uniform_location, ((float)ptrap->right.p1.x) / 65536); dispatch->glUniform1f(trap_right_y_uniform_location, ((float)ptrap->right.p1.y) / 65536); DEBUGF("x_per_pix = %f, y_per_pix = %f, trap_top = %f, trap_bottom = %f, " "trap_left_x = %f, trap_left_y = %f, left_slope = %f, " "trap_right_x = %f, trap_right_y = %f, right_slope = %f\n", ((float)width_fix) / (65536*width), ((float)height_fix) / (65536*height), ((float)ptrap->top) / 65536, ((float)ptrap->bottom) / 65536, ((float)ptrap->left.p1.x) / 65536, ((float)ptrap->left.p1.y) / 65536, left_slope, ((float)ptrap->right.p1.x) / 65536, ((float)ptrap->right.p1.y) / 65536, right_slope); /* Now rendering. */ dispatch->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } dispatch->glBindBuffer(GL_ARRAY_BUFFER, 0); dispatch->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); dispatch->glBlendFunc(GL_ONE, GL_ZERO); dispatch->glDisable(GL_BLEND); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glUseProgram(0); glamor_put_dispatch(glamor_priv); return TRUE; } #endif /*GLAMOR_TRAPEZOID_SHADER */ /** * Creates an appropriate picture for temp mask use. */ static PicturePtr glamor_create_mask_picture(ScreenPtr screen, PicturePtr dst, PictFormatPtr pict_format, CARD16 width, CARD16 height, int gpu) { PixmapPtr pixmap; PicturePtr picture; int error; if (!pict_format) { if (dst->polyEdge == PolyEdgeSharp) pict_format = PictureMatchFormat(screen, 1, PICT_a1); else pict_format = PictureMatchFormat(screen, 8, PICT_a8); if (!pict_format) return 0; } if (gpu) { pixmap = glamor_create_pixmap(screen, width, height, pict_format->depth, 0); } else { pixmap = glamor_create_pixmap(screen, 0, 0, pict_format->depth, GLAMOR_CREATE_PIXMAP_CPU); } if (!pixmap) return 0; picture = CreatePicture(0, &pixmap->drawable, pict_format, 0, 0, serverClient, &error); glamor_destroy_pixmap(pixmap); return picture; } /** * glamor_trapezoids will first try to create a trapezoid mask using shader, * if failed, miTrapezoids will generate trapezoid mask accumulating in * system memory. */ static Bool _glamor_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid * traps, Bool fallback) { ScreenPtr screen = dst->pDrawable->pScreen; BoxRec bounds; PicturePtr picture; INT16 x_dst, y_dst; INT16 x_rel, y_rel; int width, height, stride; PixmapPtr pixmap; pixman_image_t *image = NULL; int ret = 0; /* If a mask format wasn't provided, we get to choose, but behavior should * be as if there was no temporary mask the traps were accumulated into. */ if (!mask_format) { if (dst->polyEdge == PolyEdgeSharp) mask_format = PictureMatchFormat(screen, 1, PICT_a1); else mask_format = PictureMatchFormat(screen, 8, PICT_a8); for (; ntrap; ntrap--, traps++) glamor_trapezoids(op, src, dst, mask_format, x_src, y_src, 1, traps); return TRUE; } miTrapezoidBounds(ntrap, traps, &bounds); DEBUGF("The bounds for all traps is: bounds.x1 = %d, bounds.x2 = %d, " "bounds.y1 = %d, bounds.y2 = %d\n", bounds.x1, bounds.x2, bounds.y1, bounds.y2); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return TRUE; x_dst = traps[0].left.p1.x >> 16; y_dst = traps[0].left.p1.y >> 16; width = bounds.x2 - bounds.x1; height = bounds.y2 - bounds.y1; stride = PixmapBytePad(width, mask_format->depth); #ifdef GLAMOR_TRAPEZOID_SHADER picture = glamor_create_mask_picture(screen, dst, mask_format, width, height, 1); if (!picture) return TRUE; ret = _glamor_generate_trapezoid_with_shader(screen, picture, traps, ntrap, &bounds); if (!ret) FreePicture(picture, 0); #endif if (!ret) { DEBUGF("Fallback to sw rasterize of trapezoid\n"); picture = glamor_create_mask_picture(screen, dst, mask_format, width, height, 0); if (!picture) return TRUE; image = pixman_image_create_bits(picture->format, width, height, NULL, stride); if (!image) { FreePicture(picture, 0); return TRUE; } for (; ntrap; ntrap--, traps++) pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps, -bounds.x1, -bounds.y1); pixmap = glamor_get_drawable_pixmap(picture->pDrawable); screen->ModifyPixmapHeader(pixmap, width, height, mask_format->depth, BitsPerPixel(mask_format->depth), PixmapBytePad(width, mask_format->depth), pixman_image_get_data(image)); } x_rel = bounds.x1 + x_src - x_dst; y_rel = bounds.y1 + y_src - y_dst; DEBUGF("x_src = %d, y_src = %d, x_dst = %d, y_dst = %d, " "x_rel = %d, y_rel = %d\n", x_src, y_src, x_dst, y_dst, x_rel, y_rel); CompositePicture(op, src, picture, dst, x_rel, y_rel, 0, 0, bounds.x1, bounds.y1, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); if (image) pixman_image_unref(image); FreePicture(picture, 0); return TRUE; } void glamor_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid * traps) { DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap); _glamor_trapezoids(op, src, dst, mask_format, x_src, y_src, ntrap, traps, TRUE); } Bool glamor_trapezoids_nf(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid * traps) { DEBUGF("x_src = %d, y_src = %d, ntrap = %d\n", x_src, y_src, ntrap); return _glamor_trapezoids(op, src, dst, mask_format, x_src, y_src, ntrap, traps, FALSE); } #endif /* RENDER */