1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819 |
- /*
- * 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 <junyan.he@linux.intel.com>
- *
- */
- /** @file glamor_trapezoid.c
- *
- * Trapezoid acceleration implementation
- */
- #include "glamor_priv.h"
- #ifdef RENDER
- #include "mipict.h"
- #include "fbpict.h"
- static xFixed
- _glamor_linefixedX(xLineFixed *l, xFixed y, Bool ceil)
- {
- xFixed dx = l->p2.x - l->p1.x;
- xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx;
- xFixed dy = l->p2.y - l->p1.y;
- if (ceil)
- ex += (dy - 1);
- return l->p1.x + (xFixed) (ex / dy);
- }
- static xFixed
- _glamor_linefixedY(xLineFixed *l, xFixed x, Bool ceil)
- {
- xFixed dy = l->p2.y - l->p1.y;
- xFixed_32_32 ey = (xFixed_32_32) (x - l->p1.x) * dy;
- xFixed dx = l->p2.x - l->p1.x;
- if (ceil)
- ey += (dx - 1);
- return l->p1.y + (xFixed) (ey / dx);
- }
- #ifdef GLAMOR_TRAPEZOID_SHADER
- #define GLAMOR_VERTEX_TOP_BOTTOM (GLAMOR_VERTEX_SOURCE + 1)
- #define GLAMOR_VERTEX_LEFT_PARAM (GLAMOR_VERTEX_SOURCE + 2)
- #define GLAMOR_VERTEX_RIGHT_PARAM (GLAMOR_VERTEX_SOURCE + 3)
- #define DEBUG_CLIP_VTX 0
- #define POINT_INSIDE_CLIP_RECT(point, rect) \
- (point[0] >= IntToxFixed(rect->x1) \
- && point[0] <= IntToxFixed(rect->x2) \
- && point[1] >= IntToxFixed(rect->y1) \
- && point[1] <= IntToxFixed(rect->y2))
- static xFixed
- _glamor_lines_crossfixedY(xLineFixed *l, xLineFixed *r)
- {
- xFixed dx1 = l->p2.x - l->p1.x;
- xFixed dx2 = r->p2.x - r->p1.x;
- xFixed dy1 = l->p2.y - l->p1.y;
- xFixed dy2 = r->p2.y - r->p1.y;
- xFixed_32_32 tmp = (xFixed_32_32) dy2 * dy1;
- xFixed_32_32 dividend1 = (tmp >> 32) * (l->p1.x - r->p1.x);
- xFixed_32_32 dividend2;
- xFixed_32_32 dividend3;
- xFixed_32_32 divisor;
- tmp = (xFixed_32_32) dx1 *dy2;
- dividend2 = (tmp >> 32) * l->p1.y;
- tmp = (xFixed_32_32) dy1 *dx2;
- dividend3 = (tmp >> 32) * r->p1.y;
- divisor = ((xFixed_32_32) dx1 * (xFixed_32_32) dy2
- - (xFixed_32_32) dy1 * (xFixed_32_32) dx2) >> 32;
- if (divisor)
- return (xFixed) ((dividend2 - dividend1 - dividend3) / divisor);
- return 0xFFFFFFFF;
- }
- static Bool
- point_inside_trapezoid(int point[2], xTrapezoid *trap, xFixed cut_y)
- {
- int ret = TRUE;
- int tmp;
- if (point[1] > trap->bottom) {
- ret = FALSE;
- if (DEBUG_CLIP_VTX) {
- ErrorF("Out of Trap bottom, point[1] = %d(0x%x)), "
- "bottom = %d(0x%x)\n",
- (unsigned int) xFixedToInt(point[1]), point[1],
- (unsigned int) xFixedToInt(trap->bottom),
- (unsigned int) trap->bottom);
- }
- return ret;
- }
- if (point[1] < trap->top) {
- ret = FALSE;
- if (DEBUG_CLIP_VTX) {
- ErrorF("Out of Trap top, point[1] = %d(0x%x)), "
- "top = %d(0x%x)\n",
- (unsigned int) xFixedToInt(point[1]), point[1],
- (unsigned int) xFixedToInt(trap->top),
- (unsigned int) trap->top);
- }
- return ret;
- }
- tmp = _glamor_linefixedX(&trap->left, point[1], FALSE);
- if (point[0] < tmp) {
- ret = FALSE;
- if (abs(cut_y - trap->top) < pixman_fixed_1_minus_e &&
- abs(point[1] - trap->top) < pixman_fixed_1_minus_e &&
- tmp - point[0] < pixman_fixed_1_minus_e) {
- ret = TRUE;
- }
- else if (abs(cut_y - trap->bottom) < pixman_fixed_1_minus_e &&
- point[1] - trap->bottom < pixman_fixed_1_minus_e &&
- tmp - point[0] < pixman_fixed_1_minus_e) {
- ret = TRUE;
- }
- if (DEBUG_CLIP_VTX && !ret) {
- ErrorF("Out of Trap left, point[0] = %d(0x%x)), "
- "left = %d(0x%x)\n",
- (unsigned int) xFixedToInt(point[0]), point[0],
- (unsigned int) xFixedToInt(tmp), (unsigned int) tmp);
- }
- if (!ret)
- return ret;
- }
- tmp = _glamor_linefixedX(&trap->right, point[1], TRUE);
- if (point[0] > tmp) {
- ret = FALSE;
- if (abs(cut_y - trap->top) < pixman_fixed_1_minus_e &&
- abs(point[1] - trap->top) < pixman_fixed_1_minus_e &&
- point[0] - tmp < pixman_fixed_1_minus_e) {
- ret = TRUE;
- }
- else if (abs(cut_y - trap->bottom) < pixman_fixed_1_minus_e &&
- abs(point[1] - trap->bottom) < pixman_fixed_1_minus_e &&
- point[0] - tmp < pixman_fixed_1_minus_e) {
- ret = TRUE;
- }
- if (DEBUG_CLIP_VTX && !ret) {
- ErrorF("Out of Trap right, point[0] = %d(0x%x)), "
- "right = %d(0x%x)\n",
- (unsigned int) xFixedToInt(point[0]), point[0],
- (unsigned int) xFixedToInt(tmp), (unsigned int) tmp);
- }
- if (!ret)
- return ret;
- }
- return ret;
- }
- static void
- glamor_emit_composite_vert(ScreenPtr screen,
- float *vb,
- const float *src_coords,
- const float *mask_coords,
- const float *dst_coords, int i)
- {
- glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- int j = 0;
- vb += i * glamor_priv->vb_stride / sizeof(float);
- vb[j++] = dst_coords[i * 2 + 0];
- vb[j++] = dst_coords[i * 2 + 1];
- if (glamor_priv->has_source_coords) {
- vb[j++] = src_coords[i * 2 + 0];
- vb[j++] = src_coords[i * 2 + 1];
- }
- if (glamor_priv->has_mask_coords) {
- vb[j++] = mask_coords[i * 2 + 0];
- vb[j++] = mask_coords[i * 2 + 1];
- }
- glamor_priv->render_nr_verts++;
- }
- static void
- glamor_emit_composite_triangle(ScreenPtr screen,
- float *vb,
- const float *src_coords,
- const float *mask_coords,
- const float *dst_coords)
- {
- glamor_emit_composite_vert(screen, vb,
- src_coords, mask_coords, dst_coords, 0);
- glamor_emit_composite_vert(screen, vb,
- src_coords, mask_coords, dst_coords, 1);
- glamor_emit_composite_vert(screen, vb,
- src_coords, mask_coords, dst_coords, 2);
- }
- static void
- glamor_flush_composite_triangles(ScreenPtr screen)
- {
- glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- glamor_make_current(glamor_priv);
- glamor_put_vbo_space(screen);
- if (!glamor_priv->render_nr_verts)
- return;
- glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts);
- }
- static Bool
- _glamor_clip_trapezoid_vertex(xTrapezoid *trap, BoxPtr pbox,
- int vertex[6], int *num)
- {
- xFixed edge_cross_y = 0xFFFFFFFF;
- int tl[2];
- int bl[2];
- int tr[2];
- int br[2];
- int left_cut_top[2];
- int left_cut_left[2];
- int left_cut_right[2];
- int left_cut_bottom[2];
- int right_cut_top[2];
- int right_cut_left[2];
- int right_cut_right[2];
- int right_cut_bottom[2];
- int tmp[2];
- int tmp_vtx[20 * 2];
- float tmp_vtx_slope[20];
- BoxRec trap_bound;
- int i = 0;
- int vertex_num = 0;
- if (DEBUG_CLIP_VTX) {
- ErrorF
- ("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(trap->top), (unsigned int) trap->top,
- xFixedToInt(trap->bottom), (unsigned int) trap->bottom,
- xFixedToInt(trap->left.p1.x), (unsigned int) trap->left.p1.x,
- xFixedToInt(trap->left.p1.y), (unsigned int) trap->left.p1.y,
- xFixedToInt(trap->left.p2.x), (unsigned int) trap->left.p2.x,
- xFixedToInt(trap->left.p2.y), (unsigned int) trap->left.p2.y,
- xFixedToInt(trap->right.p1.x), (unsigned int) trap->right.p1.x,
- xFixedToInt(trap->right.p1.y), (unsigned int) trap->right.p1.y,
- xFixedToInt(trap->right.p2.x), (unsigned int) trap->right.p2.x,
- xFixedToInt(trap->right.p2.y), (unsigned int) trap->right.p2.y);
- }
- miTrapezoidBounds(1, trap, &trap_bound);
- if (DEBUG_CLIP_VTX)
- ErrorF("The bounds for this traps is: bounds.x1 = %d, bounds.x2 = %d, "
- "bounds.y1 = %d, bounds.y2 = %d\n", trap_bound.x1, trap_bound.x2,
- trap_bound.y1, trap_bound.y2);
- if (trap_bound.x1 > pbox->x2 || trap_bound.x2 < pbox->x1)
- return FALSE;
- if (trap_bound.y1 > pbox->y2 || trap_bound.y2 < pbox->y1)
- return FALSE;
- #define IS_TRAP_EDGE_VERTICAL(edge) \
- (edge->p1.x == edge->p2.x)
- #define CACULATE_CUT_VERTEX(vtx, cal_x, ceil, vh_edge, edge) \
- do { \
- if(cal_x) { \
- vtx[1] = (vh_edge); \
- vtx[0] = (_glamor_linefixedX( \
- edge, vh_edge, ceil)); \
- if(DEBUG_CLIP_VTX) \
- ErrorF("The intersection point of line y=%d and " \
- "line of p1:(%d,%d) -- p2 (%d,%d) " \
- "is (%d, %d)\n", \
- xFixedToInt(vh_edge), \
- xFixedToInt(edge->p1.x), \
- xFixedToInt(edge->p1.y), \
- xFixedToInt(edge->p2.x), \
- xFixedToInt(edge->p2.y), \
- xFixedToInt(vtx[0]), \
- xFixedToInt(vtx[1])); \
- } else { \
- vtx[0] = (vh_edge); \
- vtx[1] = (_glamor_linefixedY( \
- edge, vh_edge, ceil)); \
- if(DEBUG_CLIP_VTX) \
- ErrorF("The intersection point of line x=%d and " \
- "line of p1:(%d,%d) -- p2 (%d,%d) " \
- "is (%d, %d)\n", \
- xFixedToInt(vh_edge), \
- xFixedToInt(edge->p1.x), \
- xFixedToInt(edge->p1.y), \
- xFixedToInt(edge->p2.x), \
- xFixedToInt(edge->p2.y), \
- xFixedToInt(vtx[0]), \
- xFixedToInt(vtx[1])); \
- } \
- } while(0)
- #define ADD_VERTEX_IF_INSIDE(vtx) \
- if(POINT_INSIDE_CLIP_RECT(vtx, pbox) \
- && point_inside_trapezoid(vtx, trap, edge_cross_y)){ \
- tmp_vtx[vertex_num] = xFixedToInt(vtx[0]); \
- tmp_vtx[vertex_num + 1] = xFixedToInt(vtx[1]); \
- vertex_num += 2; \
- if(DEBUG_CLIP_VTX) \
- ErrorF("@ Point: (%d, %d) is inside " \
- "the Rect and Trapezoid\n", \
- xFixedToInt(vtx[0]), \
- xFixedToInt(vtx[1])); \
- } else if(DEBUG_CLIP_VTX){ \
- ErrorF("X Point: (%d, %d) is outside " \
- "the Rect and Trapezoid\t", \
- xFixedToInt(vtx[0]), \
- xFixedToInt(vtx[1])); \
- if(POINT_INSIDE_CLIP_RECT(vtx, pbox)) \
- ErrorF("The Point is outside " \
- "the Trapezoid\n"); \
- else \
- ErrorF("The Point is outside " \
- "the Rect\n"); \
- }
- /*Trap's right edge cut right edge. */
- if ((!IS_TRAP_EDGE_VERTICAL((&trap->left))) ||
- (!IS_TRAP_EDGE_VERTICAL((&trap->right)))) {
- edge_cross_y = _glamor_lines_crossfixedY((&trap->left), (&trap->right));
- if (DEBUG_CLIP_VTX) {
- ErrorF("Trap's left edge cut right edge at %d(0x%x), "
- "trap_top = %x, trap_bottom = %x\n",
- xFixedToInt(edge_cross_y), edge_cross_y,
- (unsigned int) trap->top, (unsigned int) trap->bottom);
- }
- }
- /*Trap's TopLeft, BottomLeft, TopRight and BottomRight. */
- CACULATE_CUT_VERTEX(tl, 1, FALSE, trap->top, (&trap->left));
- CACULATE_CUT_VERTEX(bl, 1, FALSE, trap->bottom, (&trap->left));
- CACULATE_CUT_VERTEX(tr, 1, TRUE, trap->top, (&trap->right));
- CACULATE_CUT_VERTEX(br, 1, TRUE, trap->bottom, (&trap->right));
- if (DEBUG_CLIP_VTX)
- ErrorF("Trap's TopLeft, BottomLeft, TopRight and BottomRight\n");
- if (DEBUG_CLIP_VTX)
- ErrorF("Caculate the vertex of trapezoid:\n"
- " (%3d, %3d)-------------------------(%3d, %3d)\n"
- " / \\ \n"
- " / \\ \n"
- " / \\ \n"
- " (%3d, %3d)---------------------------------(%3d, %3d)\n"
- "Clip with rect:\n"
- " (%3d, %3d)------------------------(%3d, %3d) \n"
- " | | \n"
- " | | \n"
- " | | \n"
- " (%3d, %3d)------------------------(%3d, %3d) \n",
- xFixedToInt(tl[0]), xFixedToInt(tl[1]), xFixedToInt(tr[0]),
- xFixedToInt(tr[1]), xFixedToInt(bl[0]), xFixedToInt(bl[1]),
- xFixedToInt(br[0]), xFixedToInt(br[1]),
- pbox->x1, pbox->y1, pbox->x2, pbox->y1, pbox->x1, pbox->y2,
- pbox->x2, pbox->y2);
- ADD_VERTEX_IF_INSIDE(tl);
- ADD_VERTEX_IF_INSIDE(bl);
- ADD_VERTEX_IF_INSIDE(tr);
- ADD_VERTEX_IF_INSIDE(br);
- /*Trap's left edge cut Rect. */
- if (DEBUG_CLIP_VTX)
- ErrorF("Trap's left edge cut Rect\n");
- CACULATE_CUT_VERTEX(left_cut_top, 1, FALSE, IntToxFixed(pbox->y1),
- (&trap->left));
- ADD_VERTEX_IF_INSIDE(left_cut_top);
- if (!IS_TRAP_EDGE_VERTICAL((&trap->left))) {
- CACULATE_CUT_VERTEX(left_cut_left, 0, FALSE, IntToxFixed(pbox->x1),
- (&trap->left));
- ADD_VERTEX_IF_INSIDE(left_cut_left);
- }
- CACULATE_CUT_VERTEX(left_cut_bottom, 1, FALSE, IntToxFixed(pbox->y2),
- (&trap->left));
- ADD_VERTEX_IF_INSIDE(left_cut_bottom);
- if (!IS_TRAP_EDGE_VERTICAL((&trap->left))) {
- CACULATE_CUT_VERTEX(left_cut_right, 0, FALSE, IntToxFixed(pbox->x2),
- (&trap->left));
- ADD_VERTEX_IF_INSIDE(left_cut_right);
- }
- /*Trap's right edge cut Rect. */
- if (DEBUG_CLIP_VTX)
- ErrorF("Trap's right edge cut Rect\n");
- CACULATE_CUT_VERTEX(right_cut_top, 1, TRUE, IntToxFixed(pbox->y1),
- (&trap->right));
- ADD_VERTEX_IF_INSIDE(right_cut_top);
- if (!IS_TRAP_EDGE_VERTICAL((&trap->right))) {
- CACULATE_CUT_VERTEX(right_cut_left, 0, TRUE, IntToxFixed(pbox->x1),
- (&trap->right));
- ADD_VERTEX_IF_INSIDE(right_cut_left);
- }
- CACULATE_CUT_VERTEX(right_cut_bottom, 1, TRUE, IntToxFixed(pbox->y2),
- (&trap->right));
- ADD_VERTEX_IF_INSIDE(right_cut_bottom);
- if (!IS_TRAP_EDGE_VERTICAL((&trap->right))) {
- CACULATE_CUT_VERTEX(right_cut_right, 0, TRUE, IntToxFixed(pbox->x2),
- (&trap->right));
- ADD_VERTEX_IF_INSIDE(right_cut_right);
- }
- /* Trap's top cut Left and Right of rect. */
- if (DEBUG_CLIP_VTX)
- ErrorF("Trap's top cut Left and Right of rect\n");
- tmp[0] = IntToxFixed(pbox->x1);
- tmp[1] = trap->top;
- ADD_VERTEX_IF_INSIDE(tmp);
- tmp[0] = IntToxFixed(pbox->x2);
- tmp[1] = trap->top;
- ADD_VERTEX_IF_INSIDE(tmp);
- /* Trap's bottom cut Left and Right of rect. */
- if (DEBUG_CLIP_VTX)
- ErrorF("Trap's bottom cut Left and Right of rect\n");
- tmp[0] = IntToxFixed(pbox->x1);
- tmp[1] = trap->bottom;
- ADD_VERTEX_IF_INSIDE(tmp);
- tmp[0] = IntToxFixed(pbox->x2);
- tmp[1] = trap->bottom;
- ADD_VERTEX_IF_INSIDE(tmp);
- /* The orginal 4 vertex of rect. */
- if (DEBUG_CLIP_VTX)
- ErrorF("The orginal 4 vertex of rect\n");
- tmp[0] = IntToxFixed(pbox->x1);
- tmp[1] = IntToxFixed(pbox->y1);
- ADD_VERTEX_IF_INSIDE(tmp);
- tmp[0] = IntToxFixed(pbox->x1);
- tmp[1] = IntToxFixed(pbox->y2);
- ADD_VERTEX_IF_INSIDE(tmp);
- tmp[0] = IntToxFixed(pbox->x2);
- tmp[1] = IntToxFixed(pbox->y2);
- ADD_VERTEX_IF_INSIDE(tmp);
- tmp[0] = IntToxFixed(pbox->x2);
- tmp[1] = IntToxFixed(pbox->y1);
- ADD_VERTEX_IF_INSIDE(tmp);
- if (DEBUG_CLIP_VTX) {
- ErrorF("\nThe candidate vertex number is %d\n", vertex_num / 2);
- for (i = 0; i < vertex_num / 2; i++) {
- ErrorF("(%d, %d) ", tmp_vtx[2 * i], tmp_vtx[2 * i + 1]);
- }
- ErrorF("\n");
- }
- /* Sort the vertex by X and then Y. */
- for (i = 0; i < vertex_num / 2; i++) {
- int j;
- for (j = 0; j < vertex_num / 2 - i - 1; j++) {
- if (tmp_vtx[2 * j] > tmp_vtx[2 * (j + 1)]
- || (tmp_vtx[2 * j] == tmp_vtx[2 * (j + 1)]
- && tmp_vtx[2 * j + 1] > tmp_vtx[2 * (j + 1) + 1])) {
- tmp[0] = tmp_vtx[2 * j];
- tmp[1] = tmp_vtx[2 * j + 1];
- tmp_vtx[2 * j] = tmp_vtx[2 * (j + 1)];
- tmp_vtx[2 * j + 1] = tmp_vtx[2 * (j + 1) + 1];
- tmp_vtx[2 * (j + 1)] = tmp[0];
- tmp_vtx[2 * (j + 1) + 1] = tmp[1];
- }
- }
- }
- if (DEBUG_CLIP_VTX) {
- ErrorF("\nAfter sort vertex number is:\n");
- for (i = 0; i < vertex_num / 2; i++) {
- ErrorF("(%d, %d) ", tmp_vtx[2 * i], tmp_vtx[2 * i + 1]);
- }
- ErrorF("\n");
- }
- memset(vertex, -1, 2 * 6);
- *num = 0;
- for (i = 0; i < vertex_num / 2; i++) {
- if (*num > 0 && vertex[2 * (*num - 1)] == tmp_vtx[2 * i]
- && vertex[2 * (*num - 1) + 1] == tmp_vtx[2 * i + 1]) {
- /*same vertex. */
- if (DEBUG_CLIP_VTX)
- ErrorF("X Point:(%d, %d) discard\n",
- tmp_vtx[2 * i], tmp_vtx[2 * i + 1]);
- continue;
- }
- (*num)++;
- if (*num > 6) {
- if (DEBUG_CLIP_VTX)
- FatalError("Trapezoid clip with Rect can never have vtx"
- "number bigger than 6\n");
- else {
- ErrorF("Trapezoid clip with Rect can never have vtx"
- "number bigger than 6\n");
- *num = 6;
- break;
- }
- }
- vertex[2 * (*num - 1)] = tmp_vtx[2 * i];
- vertex[2 * (*num - 1) + 1] = tmp_vtx[2 * i + 1];
- if (DEBUG_CLIP_VTX)
- ErrorF("@ Point:(%d, %d) select, num now is %d\n",
- tmp_vtx[2 * i], tmp_vtx[2 * i + 1], *num);
- }
- /* Now we need to arrange the vtx in the polygon's counter-clockwise
- order. We first select the left and top point as the start point and
- sort every vtx by the slope from vtx to the start vtx. */
- for (i = 1; i < *num; i++) {
- tmp_vtx_slope[i] = (vertex[2 * i] != vertex[0] ?
- (float) (vertex[2 * i + 1] -
- vertex[1]) / (float) (vertex[2 * i] -
- vertex[0])
- : (float) INT_MAX);
- }
- if (DEBUG_CLIP_VTX) {
- ErrorF("\nvtx number: %d, VTX and slope:\n", *num);
- for (i = 0; i < *num; i++) {
- ErrorF("(%d, %d):%f ",
- vertex[2 * i], vertex[2 * i + 1], tmp_vtx_slope[i]);
- }
- ErrorF("\n");
- }
- /* Sort the vertex by slope. */
- for (i = 0; i < *num - 1; i++) {
- int j;
- float tmp_slope;
- for (j = 1; j < *num - i - 1; j++) {
- if (tmp_vtx_slope[j] < tmp_vtx_slope[j + 1]) {
- tmp_slope = tmp_vtx_slope[j];
- tmp_vtx_slope[j] = tmp_vtx_slope[j + 1];
- tmp_vtx_slope[j + 1] = tmp_slope;
- tmp[0] = vertex[2 * j];
- tmp[1] = vertex[2 * j + 1];
- vertex[2 * j] = vertex[2 * (j + 1)];
- vertex[2 * j + 1] = vertex[2 * (j + 1) + 1];
- vertex[2 * (j + 1)] = tmp[0];
- vertex[2 * (j + 1) + 1] = tmp[1];
- }
- }
- }
- if (DEBUG_CLIP_VTX) {
- ErrorF("\nBefore return, vtx number: %d, VTX and slope:\n", *num);
- for (i = 0; i < *num; i++) {
- ErrorF("(%d, %d):%f ",
- vertex[2 * i], vertex[2 * i + 1], tmp_vtx_slope[i]);
- }
- ErrorF("\n");
- }
- return TRUE;
- }
- static void *
- glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
- {
- glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- int stride;
- int vert_size;
- char *vbo_offset;
- void *vb;
- glamor_priv->render_nr_verts = 0;
- /* For GLAMOR_VERTEX_POS */
- glamor_priv->vb_stride = 2 * sizeof(float);
- /* For GLAMOR_GLAMOR_VERTEX_SOURCE */
- glamor_priv->vb_stride += 2 * sizeof(float);
- /* For GLAMOR_VERTEX_TOP_BOTTOM */
- glamor_priv->vb_stride += 2 * sizeof(float);
- /* For GLAMOR_VERTEX_LEFT_PARAM */
- glamor_priv->vb_stride += 4 * sizeof(float);
- /* For GLAMOR_VERTEX_RIGHT_PARAM */
- glamor_priv->vb_stride += 4 * sizeof(float);
- vert_size = n_verts * glamor_priv->vb_stride;
- glamor_make_current(glamor_priv);
- glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
- glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
- glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
- vb = glamor_get_vbo_space(screen, vert_size, &vbo_offset);
- /* Set the vertex pointer. */
- glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
- GL_FALSE, glamor_priv->vb_stride,
- vbo_offset);
- glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
- stride = 2;
- glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
- GL_FALSE, glamor_priv->vb_stride,
- vbo_offset + stride * sizeof(float));
- glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- stride += 2;
- glVertexAttribPointer(GLAMOR_VERTEX_TOP_BOTTOM, 2, GL_FLOAT,
- GL_FALSE, glamor_priv->vb_stride,
- vbo_offset + stride * sizeof(float));
- glEnableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
- stride += 2;
- glVertexAttribPointer(GLAMOR_VERTEX_LEFT_PARAM, 4, GL_FLOAT,
- GL_FALSE, glamor_priv->vb_stride,
- vbo_offset + stride * sizeof(float));
- glEnableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
- stride += 4;
- glVertexAttribPointer(GLAMOR_VERTEX_RIGHT_PARAM, 4, GL_FLOAT,
- GL_FALSE, glamor_priv->vb_stride,
- vbo_offset + stride * sizeof(float));
- glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
- return vb;
- }
- static Bool
- _glamor_trapezoids_with_shader(CARD8 op,
- PicturePtr src, PicturePtr dst,
- PictFormatPtr mask_format, INT16 x_src,
- INT16 y_src, int ntrap, xTrapezoid * traps)
- {
- ScreenPtr screen = dst->pDrawable->pScreen;
- glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- struct shader_key key;
- glamor_composite_shader *shader = NULL;
- struct blendinfo op_info;
- PictFormatShort saved_source_format = 0;
- PixmapPtr source_pixmap = NULL;
- PixmapPtr dest_pixmap = NULL;
- glamor_pixmap_private *source_pixmap_priv = NULL;
- glamor_pixmap_private *dest_pixmap_priv = NULL;
- glamor_pixmap_private *temp_src_priv = NULL;
- int x_temp_src, y_temp_src;
- int src_width, src_height;
- int source_x_off, source_y_off;
- GLfloat src_xscale = 1, src_yscale = 1;
- int x_dst, y_dst;
- int dest_x_off, dest_y_off;
- GLfloat dst_xscale, dst_yscale;
- BoxRec bounds;
- PicturePtr temp_src = src;
- int vert_stride = 3;
- int ntriangle_per_loop;
- int nclip_rect;
- int mclip_rect;
- int clip_processed;
- int clipped_vtx[6 * 2];
- RegionRec region;
- BoxPtr box = NULL;
- BoxPtr pbox = NULL;
- int traps_count = 0;
- int traps_not_completed = 0;
- xTrapezoid *ptrap = NULL;
- int nbox;
- float src_matrix[9];
- Bool ret = FALSE;
- /* 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);
- /* No area need to render. */
- if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
- return TRUE;
- dest_pixmap = glamor_get_drawable_pixmap(dst->pDrawable);
- dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
- if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)
- || dest_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
- /* Currently. Always fallback to cpu if destination is in CPU memory. */
- ret = FALSE;
- DEBUGF("dst pixmap has no FBO.\n");
- goto TRAPEZOID_OUT;
- }
- if (src->pDrawable) {
- source_pixmap = glamor_get_drawable_pixmap(src->pDrawable);
- source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
- temp_src_priv = source_pixmap_priv;
- if (source_pixmap_priv
- && (source_pixmap_priv->type == GLAMOR_DRM_ONLY
- || source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE)) {
- ret = FALSE;
- goto TRAPEZOID_OUT;
- }
- }
- x_dst = bounds.x1;
- y_dst = bounds.y1;
- src_width = bounds.x2 - bounds.x1;
- src_height = bounds.y2 - bounds.y1;
- x_temp_src = x_src + bounds.x1 - (traps[0].left.p1.x >> 16);
- y_temp_src = y_src + bounds.y1 - (traps[0].left.p1.y >> 16);
- if ((!src->pDrawable && (src->pSourcePict->type != SourcePictTypeSolidFill)) //1. The Gradient case.
- /* 2. Has no fbo but can upload. */
- || (src->pDrawable && !GLAMOR_PIXMAP_PRIV_HAS_FBO(source_pixmap_priv)
- && ((src_width * src_height * 4 <
- source_pixmap->drawable.width * source_pixmap->drawable.height)
- || !glamor_check_fbo_size(glamor_priv,
- source_pixmap->drawable.width,
- source_pixmap->drawable.height)))) {
- if (!glamor_check_fbo_size(glamor_priv, src_width, src_height)) {
- ret = FALSE;
- goto TRAPEZOID_OUT;
- }
- temp_src = glamor_convert_gradient_picture(screen, src,
- x_src, y_src,
- src_width, src_height);
- if (!temp_src) {
- temp_src = src;
- ret = FALSE;
- DEBUGF("Convert gradient picture failed\n");
- goto TRAPEZOID_OUT;
- }
- temp_src_priv =
- glamor_get_pixmap_private((PixmapPtr) temp_src->pDrawable);
- x_temp_src = y_temp_src = 0;
- }
- x_dst += dst->pDrawable->x;
- y_dst += dst->pDrawable->y;
- if (temp_src->pDrawable) {
- x_temp_src += temp_src->pDrawable->x;
- y_temp_src += temp_src->pDrawable->y;
- }
- if (!miComputeCompositeRegion(®ion,
- temp_src, NULL, dst,
- x_temp_src, y_temp_src,
- 0, 0, x_dst, y_dst, src_width, src_height)) {
- DEBUGF("All the regions are clipped out, do nothing\n");
- goto TRAPEZOID_OUT;
- }
- glamor_make_current(glamor_priv);
- box = REGION_RECTS(®ion);
- nbox = REGION_NUM_RECTS(®ion);
- pbox = box;
- ret = glamor_composite_choose_shader(op, temp_src, NULL, dst,
- temp_src_priv, NULL, dest_pixmap_priv,
- &key, &shader, &op_info,
- &saved_source_format);
- if (ret == FALSE) {
- DEBUGF("can not set the shader program for composite\n");
- goto TRAPEZOID_RESET_GL;
- }
- glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
- glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info);
- glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
- glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
- key.mask != SHADER_MASK_SOLID);
- glamor_get_drawable_deltas(dst->pDrawable, dest_pixmap,
- &dest_x_off, &dest_y_off);
- pixmap_priv_get_dest_scale(dest_pixmap_priv, &dst_xscale, &dst_yscale);
- if (glamor_priv->has_source_coords) {
- source_pixmap = glamor_get_drawable_pixmap(temp_src->pDrawable);
- source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
- glamor_get_drawable_deltas(temp_src->pDrawable,
- source_pixmap, &source_x_off, &source_y_off);
- pixmap_priv_get_scale(source_pixmap_priv, &src_xscale, &src_yscale);
- glamor_picture_get_matrixf(temp_src, src_matrix);
- vert_stride += 3;
- }
- if (glamor_priv->has_mask_coords) {
- DEBUGF("Should never have mask coords here!\n");
- ret = FALSE;
- goto TRAPEZOID_RESET_GL;
- }
- /* A trapezoid clip with a rectangle will at most generate a hexagon,
- which can be devided into 4 triangles to render. */
- ntriangle_per_loop =
- (vert_stride * nbox * ntrap * 4) >
- GLAMOR_COMPOSITE_VBO_VERT_CNT ? (GLAMOR_COMPOSITE_VBO_VERT_CNT /
- vert_stride) : nbox * ntrap * 4;
- ntriangle_per_loop = (ntriangle_per_loop / 4) * 4;
- nclip_rect = nbox;
- while (nclip_rect) {
- float *vb;
- mclip_rect = (nclip_rect * ntrap * 4) > ntriangle_per_loop ?
- (ntriangle_per_loop / (4 * ntrap)) : nclip_rect;
- if (!mclip_rect) { /* Maybe too many traps. */
- mclip_rect = 1;
- ptrap = traps;
- traps_count = ntriangle_per_loop / 4;
- traps_not_completed = ntrap - traps_count;
- }
- else {
- traps_count = ntrap;
- ptrap = traps;
- traps_not_completed = 0;
- }
- NTRAPS_LOOP_AGAIN:
- vb = glamor_setup_composite_vbo(screen,
- (mclip_rect * traps_count *
- 4 * vert_stride));
- clip_processed = mclip_rect;
- while (mclip_rect--) {
- while (traps_count--) {
- int vtx_num;
- int i;
- float vertices[3 * 2], source_texcoords[3 * 2];
- DEBUGF
- ("In loop of render trapezoid, nclip_rect = %d, mclip_rect = %d, "
- "clip_processed = %d, traps_count = %d, traps_not_completed = %d\n",
- nclip_rect, mclip_rect, clip_processed, traps_count,
- traps_not_completed);
- if (_glamor_clip_trapezoid_vertex
- (ptrap, pbox, clipped_vtx, &vtx_num)) {
- for (i = 0; i < vtx_num - 2; i++) {
- int clipped_vtx_tmp[3 * 2];
- clipped_vtx_tmp[0] = clipped_vtx[0];
- clipped_vtx_tmp[1] = clipped_vtx[1];
- clipped_vtx_tmp[2] = clipped_vtx[(i + 1) * 2];
- clipped_vtx_tmp[3] = clipped_vtx[(i + 1) * 2 + 1];
- clipped_vtx_tmp[4] = clipped_vtx[(i + 2) * 2];
- clipped_vtx_tmp[5] = clipped_vtx[(i + 2) * 2 + 1];
- glamor_set_normalize_tri_vcoords(dst_xscale, dst_yscale,
- clipped_vtx_tmp,
- glamor_priv->yInverted,
- vertices);
- DEBUGF("vertices of triangle: (%f X %f), (%f X %f), "
- "(%f X %f)\n", vertices[0], vertices[1],
- vertices[2], vertices[3], vertices[4],
- vertices[5]);
- if (key.source != SHADER_SOURCE_SOLID) {
- if (src->transform) {
- glamor_set_transformed_normalize_tri_tcoords
- (source_pixmap_priv, src_matrix, src_xscale,
- src_yscale, clipped_vtx_tmp,
- glamor_priv->yInverted, source_texcoords);
- }
- else {
- glamor_set_normalize_tri_tcoords(src_xscale,
- src_yscale,
- clipped_vtx_tmp,
- glamor_priv->
- yInverted,
- source_texcoords);
- }
- DEBUGF("source_texcoords of triangle: (%f X %f), "
- "(%f X %f), (%f X %f)\n",
- source_texcoords[0], source_texcoords[1],
- source_texcoords[2], source_texcoords[3],
- source_texcoords[4], source_texcoords[5]);
- }
- glamor_emit_composite_triangle(screen, vb,
- source_texcoords,
- NULL, vertices);
- vb += 3 * glamor_priv->vb_stride / sizeof(float);
- }
- }
- ptrap++;
- }
- if (traps_not_completed) { /* one loop of ntraps not completed */
- mclip_rect = 1;
- traps_count = traps_not_completed > (ntriangle_per_loop / 4) ?
- (ntriangle_per_loop / 4) : traps_not_completed;
- traps_not_completed -= traps_count;
- glamor_flush_composite_triangles(screen);
- goto NTRAPS_LOOP_AGAIN;
- }
- else {
- ptrap = traps;
- traps_count = ntrap;
- }
- pbox++;
- }
- glamor_flush_composite_triangles(screen);
- nclip_rect -= clip_processed;
- }
- ret = TRUE;
- TRAPEZOID_RESET_GL:
- glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
- glDisable(GL_BLEND);
- TRAPEZOID_OUT:
- if (box) {
- REGION_UNINIT(dst->pDrawable->pScreen, ®ion);
- }
- if (temp_src != src) {
- FreePicture(temp_src, 0);
- }
- else {
- if (saved_source_format) {
- src->format = saved_source_format;
- }
- }
- return ret;
- }
- void
- glamor_init_trapezoid_shader(ScreenPtr screen)
- {
- glamor_screen_private *glamor_priv;
- GLint fs_prog, vs_prog;
- const char *trapezoid_vs =
- GLAMOR_DEFAULT_PRECISION
- "attribute vec4 v_position;\n"
- "attribute vec2 v_texcoord;\n"
- /* v_top_bottom, v_left_param and v_right_param contain the
- constant value for all the vertex of one rect. Using uniform
- is more suitable but we need to reset the uniform variables
- for every rect rendering and can not use the vbo, which causes
- performance loss. So we set these attributes to same value
- for every vertex of one rect and so it is also a constant in FS */
- "attribute vec2 v_top_bottom;\n"
- "attribute vec4 v_left_param;\n"
- "attribute vec4 v_right_param;\n"
- "\n"
- "varying vec2 source_texture;\n"
- "varying float trap_top;\n"
- "varying float trap_bottom;\n"
- "varying float trap_left_x;\n"
- "varying float trap_left_y;\n"
- "varying float trap_left_slope;\n"
- "varying float trap_left_vertical_f;\n"
- "varying float trap_right_x;\n"
- "varying float trap_right_y;\n"
- "varying float trap_right_slope;\n"
- "varying float trap_right_vertical_f;\n"
- "\n"
- "void main()\n"
- "{\n"
- " gl_Position = v_position;\n"
- " source_texture = v_texcoord.xy;\n"
- " trap_top = v_top_bottom.x;\n"
- " trap_bottom = v_top_bottom.y;\n"
- " \n"
- " trap_left_x = v_left_param.x;\n"
- " trap_left_y = v_left_param.y;\n"
- " trap_left_slope = v_left_param.z;\n"
- " trap_left_vertical_f = v_left_param.w;\n"
- " \n"
- " trap_right_x = v_right_param.x;\n"
- " trap_right_y = v_right_param.y;\n"
- " trap_right_slope = v_right_param.z;\n"
- " trap_right_vertical_f = v_right_param.w;\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"
- "varying float trap_top; \n"
- "varying float trap_bottom; \n"
- "varying float trap_left_x; \n"
- "varying float trap_left_y; \n"
- "varying float trap_left_slope; \n"
- "varying float trap_left_vertical_f; \n"
- "varying float trap_right_x; \n"
- "varying float trap_right_y; \n"
- "varying float trap_right_slope; \n"
- "varying float trap_right_vertical_f; \n"
- "float x_per_pix = 1.0;"
- "float y_per_pix = 1.0;"
- "\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"
- " bool trap_left_vertical;\n"
- " bool trap_right_vertical;\n"
- " if (abs(trap_left_vertical_f - 1.0) <= 0.0001)\n"
- " trap_left_vertical = true;\n"
- " else\n"
- " trap_left_vertical = false;\n"
- " if (abs(trap_right_vertical_f - 1.0) <= 0.0001)\n"
- " trap_right_vertical = true;\n"
- " else\n"
- " trap_right_vertical = false;\n"
- " \n"
- " if(trap_left_vertical == true) { \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 == true) { \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 == true) { \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 == true) { \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 == true && trap_right_vertical == true) \n"
- " return percent; \n"
- " \n"
- " if(trap_left_vertical != true) { \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 != true) { \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);
- glamor_make_current(glamor_priv);
- glamor_priv->trapezoid_prog = glCreateProgram();
- vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, trapezoid_vs);
- fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, trapezoid_fs);
- glAttachShader(glamor_priv->trapezoid_prog, vs_prog);
- glAttachShader(glamor_priv->trapezoid_prog, fs_prog);
- glBindAttribLocation(glamor_priv->trapezoid_prog,
- GLAMOR_VERTEX_POS, "v_positionsition");
- glBindAttribLocation(glamor_priv->trapezoid_prog,
- GLAMOR_VERTEX_SOURCE, "v_texcoord");
- glBindAttribLocation(glamor_priv->trapezoid_prog,
- GLAMOR_VERTEX_TOP_BOTTOM, "v_top_bottom");
- glBindAttribLocation(glamor_priv->trapezoid_prog,
- GLAMOR_VERTEX_LEFT_PARAM, "v_left_param");
- glBindAttribLocation(glamor_priv->trapezoid_prog,
- GLAMOR_VERTEX_RIGHT_PARAM, "v_right_param");
- glamor_link_glsl_prog(screen, glamor_priv->trapezoid_prog, "trapezoid");
- }
- void
- glamor_fini_trapezoid_shader(ScreenPtr screen)
- {
- glamor_screen_private *glamor_priv;
- glamor_priv = glamor_get_screen_private(screen);
- glamor_make_current(glamor_priv);
- glDeleteProgram(glamor_priv->trapezoid_prog);
- }
- static Bool
- _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
- xTrapezoid *traps, int ntrap,
- BoxRec *bounds)
- {
- glamor_screen_private *glamor_priv;
- glamor_pixmap_private *pixmap_priv;
- PixmapPtr pixmap = NULL;
- GLint trapezoid_prog;
- GLfloat xscale, yscale;
- float left_slope, right_slope;
- xTrapezoid *ptrap;
- BoxRec one_trap_bound;
- int nrect_max;
- int i, j;
- float params[4];
- 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)
- || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { /* 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->base.pixmap->drawable.width,
- pixmap_priv->base.pixmap->drawable.height,
- GXclear, 0xFFFFFFFF, 0)) {
- DEBUGF("glamor_solid failed, fallback\n");
- return FALSE;
- }
- glamor_make_current(glamor_priv);
- glamor_set_destination_pixmap_priv_nc(pixmap_priv);
- pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale));
- /* Now draw the Trapezoid mask. */
- glUseProgram(trapezoid_prog);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE);
- nrect_max = GLAMOR_COMPOSITE_VBO_VERT_CNT / (4 * GLAMOR_VERTEX_RIGHT_PARAM);
- for (i = 0; i < ntrap;) {
- float *vertices;
- int mrect;
- int stride;
- mrect = (ntrap - i) > nrect_max ? nrect_max : (ntrap - i);
- vertices = glamor_setup_composite_vbo_for_trapezoid(screen, 4 * mrect);
- stride = glamor_priv->vb_stride / sizeof(float);
- for (j = 0; j < mrect; j++) {
- ptrap = traps + i + j;
- 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);
- vertices += 2;
- glamor_set_tcoords_ext((pixmap_priv->base.pixmap->drawable.width),
- (pixmap_priv->base.pixmap->drawable.height),
- (one_trap_bound.x1), (one_trap_bound.y1),
- (one_trap_bound.x2), (one_trap_bound.y2),
- glamor_priv->yInverted, vertices, stride);
- DEBUGF("tex_vertices --> leftup : %f X %f, rightup: %f X %f,"
- "rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0],
- vertices[1], vertices[1 * stride], vertices[1 * stride + 1],
- vertices[2 * stride], vertices[2 * stride + 1],
- vertices[3 * stride], vertices[3 * stride + 1]);
- /* 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;
- vertices -= 2;
- glamor_set_normalize_vcoords_ext(pixmap_priv, xscale, yscale,
- one_trap_bound.x1,
- one_trap_bound.y1,
- one_trap_bound.x2,
- one_trap_bound.y2,
- glamor_priv->yInverted, vertices,
- stride);
- DEBUGF("vertices --> leftup : %f X %f, rightup: %f X %f,"
- "rightbottom: %f X %f, leftbottom : %f X %f\n", vertices[0],
- vertices[1], vertices[1 * stride], vertices[1 * stride + 1],
- vertices[2 * stride], vertices[2 * stride + 1],
- vertices[3 * stride], vertices[3 * stride + 1]);
- vertices += 4;
- /* Set the top and bottom. */
- params[0] = ((float) ptrap->top) / 65536;
- params[1] = ((float) ptrap->bottom) / 65536;
- glamor_set_const_ext(params, 2, vertices, 4, stride);
- vertices += 2;
- /* Set the left params. */
- params[0] = ((float) ptrap->left.p1.x) / 65536;
- params[1] = ((float) ptrap->left.p1.y) / 65536;
- if (ptrap->left.p1.x == ptrap->left.p2.x) {
- left_slope = 0.0;
- params[3] = 1.0;
- }
- else {
- left_slope = ((float) (ptrap->left.p1.y - ptrap->left.p2.y))
- / ((float) (ptrap->left.p1.x - ptrap->left.p2.x));
- params[3] = 0.0;
- }
- params[2] = left_slope;
- glamor_set_const_ext(params, 4, vertices, 4, stride);
- vertices += 4;
- /* Set the left params. */
- params[0] = ((float) ptrap->right.p1.x) / 65536;
- params[1] = ((float) ptrap->right.p1.y) / 65536;
- if (ptrap->right.p1.x == ptrap->right.p2.x) {
- right_slope = 0.0;
- params[3] = 1.0;
- }
- else {
- right_slope = ((float) (ptrap->right.p1.y - ptrap->right.p2.y))
- / ((float) (ptrap->right.p1.x - ptrap->right.p2.x));
- params[3] = 0.0;
- }
- params[2] = right_slope;
- glamor_set_const_ext(params, 4, vertices, 4, stride);
- vertices += 4;
- DEBUGF("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) 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);
- glamor_priv->render_nr_verts += 4;
- vertices += 3 * stride;
- }
- i += mrect;
- glamor_put_vbo_space(screen);
- /* Now rendering. */
- if (!glamor_priv->render_nr_verts)
- continue;
- if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
- glDrawRangeElements(GL_TRIANGLES, 0,
- glamor_priv->render_nr_verts,
- (glamor_priv->render_nr_verts * 3) / 2,
- GL_UNSIGNED_SHORT, NULL);
- } else {
- glDrawElements(GL_TRIANGLES,
- (glamor_priv->render_nr_verts * 3) / 2,
- GL_UNSIGNED_SHORT, NULL);
- }
- }
- glBlendFunc(GL_ONE, GL_ZERO);
- glDisable(GL_BLEND);
- glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
- glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
- glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
- 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;
- }
- static int
- _glamor_trapezoid_bounds(int ntrap, xTrapezoid *traps, BoxPtr box)
- {
- int has_large_trapezoid = 0;
- box->y1 = MAXSHORT;
- box->y2 = MINSHORT;
- box->x1 = MAXSHORT;
- box->x2 = MINSHORT;
- for (; ntrap; ntrap--, traps++) {
- INT16 x1, y1, x2, y2;
- if (!xTrapezoidValid(traps))
- continue;
- y1 = xFixedToInt(traps->top);
- if (y1 < box->y1)
- box->y1 = y1;
- y2 = xFixedToInt(xFixedCeil(traps->bottom));
- if (y2 > box->y2)
- box->y2 = y2;
- x1 = xFixedToInt(min
- (_glamor_linefixedX(&traps->left, traps->top, FALSE),
- _glamor_linefixedX(&traps->left, traps->bottom,
- FALSE)));
- if (x1 < box->x1)
- box->x1 = x1;
- x2 = xFixedToInt(xFixedCeil
- (max
- (_glamor_linefixedX(&traps->right, traps->top, TRUE),
- _glamor_linefixedX(&traps->right, traps->bottom,
- TRUE))));
- if (x2 > box->x2)
- box->x2 = x2;
- if (!has_large_trapezoid && (x2 - x1) > 256 && (y2 - y1) > 32)
- has_large_trapezoid = 1;
- }
- return has_large_trapezoid;
- }
- /**
- * 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;
- int has_large_trapezoid;
- /* 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;
- }
- has_large_trapezoid = _glamor_trapezoid_bounds(ntrap, traps, &bounds);
- DEBUGF("The bounds for all traps is: bounds.x1 = %d, bounds.x2 = %d, "
- "bounds.y1 = %d, bounds.y2 = %d, ---- ntrap = %d\n", bounds.x1,
- bounds.x2, bounds.y1, bounds.y2, ntrap);
- 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
- /* We seperate the render to two paths.
- Some GL implemetation do not implement the Anti-Alias for triangles
- and polygen's filling. So when the edge is not vertical or horizontal,
- sawtooth will be obvious. The trapezoid is widely used to render wide
- lines and circles. In these case, the line or circle will be divided
- into a large number of small trapezoids to approximate it, so the sawtooth
- at the edge will cause the result not be acceptable.
- When the depth of the mask is 1, there is no Anti-Alias needed, so we
- use the clip logic to generate the result directly(fast path).
- When the depth is not 1, AA is needed and we use a shader to generate
- a temp mask pixmap.
- */
- if (mask_format->depth == 1) {
- ret = _glamor_trapezoids_with_shader(op, src, dst, mask_format,
- x_src, y_src, ntrap, traps);
- if (ret)
- return TRUE;
- }
- else {
- if (has_large_trapezoid || ntrap > 256) {
- /* The shader speed is relative slower than pixman when generating big chunk
- trapezoid mask. We fallback to pixman to improve the performance. */
- ;
- }
- else if (dst->polyMode == PolyModeImprecise) {
- /* The precise mode is that we sample the trapezoid on the centre points of
- an (2*n+1)x(2*n-1) subpixel grid. It is computationally expensive in shader
- and we use inside area ratio to replace it if the polymode == Imprecise. */
- 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 */
|