1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version:  6.5.3
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software.
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Antialiased Triangle rasterizers
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/glheader.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/context.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/colormac.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/macros.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/imports.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/state.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_aatriangle.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_context.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_span.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute coefficients of a plane using the X,Y coords of the v0, v1, v2
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * vertices and the given Z values.
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * A point (x,y,z) lies on plane iff a*x+b*y+c*z+d = 0.
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcompute_plane(const GLfloat v0[], const GLfloat v1[], const GLfloat v2[],
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              GLfloat z0, GLfloat z1, GLfloat z2, GLfloat plane[4])
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat px = v1[0] - v0[0];
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat py = v1[1] - v0[1];
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat pz = z1 - z0;
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat qx = v2[0] - v0[0];
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat qy = v2[1] - v0[1];
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat qz = z2 - z0;
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Crossproduct "(a,b,c):= dv1 x dv2" is orthogonal to plane. */
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat a = py * qz - pz * qy;
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat b = pz * qx - px * qz;
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat c = px * qy - py * qx;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Point on the plane = "r*(a,b,c) + w", with fixed "r" depending
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      on the distance of plane from origin and arbitrary "w" parallel
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      to the plane. */
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* The scalar product "(r*(a,b,c)+w)*(a,b,c)" is "r*(a^2+b^2+c^2)",
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      which is equal to "-d" below. */
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat d = -(a * v0[0] + b * v0[1] + c * z0);
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   plane[0] = a;
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   plane[1] = b;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   plane[2] = c;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   plane[3] = d;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute coefficients of a plane with a constant Z value.
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline void
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconstant_plane(GLfloat value, GLfloat plane[4])
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   plane[0] = 0.0;
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   plane[1] = 0.0;
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   plane[2] = -1.0;
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   plane[3] = value;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define CONSTANT_PLANE(VALUE, PLANE)	\
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo {					\
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PLANE[0] = 0.0F;			\
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PLANE[1] = 0.0F;			\
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PLANE[2] = -1.0F;			\
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PLANE[3] = VALUE;			\
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} while (0)
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Solve plane equation for Z at (X,Y).
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLfloat
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsolve_plane(GLfloat x, GLfloat y, const GLfloat plane[4])
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(plane[2] != 0.0F);
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SOLVE_PLANE(X, Y, PLANE) \
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ((PLANE[3] + PLANE[0] * (X) + PLANE[1] * (Y)) / -PLANE[2])
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return 1 / solve_plane().
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLfloat
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsolve_plane_recip(GLfloat x, GLfloat y, const GLfloat plane[4])
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat denom = plane[3] + plane[0] * x + plane[1] * y;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (denom == 0.0F)
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0.0F;
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return -plane[2] / denom;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Solve plane and return clamped GLchan value.
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLchan
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsolve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4])
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if CHAN_TYPE == GL_FLOAT
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return CLAMP(z, 0.0F, CHAN_MAXF);
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (z < 0)
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 0;
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if (z > CHAN_MAX)
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return CHAN_MAX;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (GLchan) IROUND_POS(z);
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLfloat
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgplane_dx(const GLfloat plane[4])
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return -plane[0] / plane[2];
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic inline GLfloat
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgplane_dy(const GLfloat plane[4])
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return -plane[1] / plane[2];
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute how much (area) of the given pixel is inside the triangle.
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Vertices MUST be specified in counter-clockwise order.
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return:  coverage in [0, 1].
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLfloat
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcompute_coveragef(const GLfloat v0[3], const GLfloat v1[3],
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  const GLfloat v2[3], GLint winx, GLint winy)
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Given a position [0,3]x[0,3] return the sub-pixel sample position.
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Contributed by Ray Tice.
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Jitter sample positions -
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * - average should be .5 in x & y for each column
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * - each of the 16 rows and columns should be used once
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * - the rectangle formed by the first four points
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *   should contain the other points
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * - the distrubition should be fairly even in any given direction
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * The pattern drawn below isn't optimal, but it's better than a regular
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * grid.  In the drawing, the center of each subpixel is surrounded by
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * four dots.  The "x" marks the jittered position relative to the
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * subpixel center.
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define POS(a, b) (0.5+a*4+b)/16
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static const GLfloat samples[16][2] = {
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* start with the four corners */
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(0, 2), POS(0, 0) },
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(3, 3), POS(0, 2) },
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(0, 0), POS(3, 1) },
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(3, 1), POS(3, 3) },
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* continue with interior samples */
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(1, 1), POS(0, 1) },
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(2, 0), POS(0, 3) },
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(0, 3), POS(1, 3) },
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(1, 2), POS(1, 0) },
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(2, 3), POS(1, 2) },
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(3, 2), POS(1, 1) },
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(0, 1), POS(2, 2) },
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(1, 0), POS(2, 1) },
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(2, 1), POS(2, 3) },
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(3, 0), POS(2, 0) },
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(1, 3), POS(3, 0) },
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      { POS(2, 2), POS(3, 2) }
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   };
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat x = (GLfloat) winx;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat y = (GLfloat) winy;
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat dx0 = v1[0] - v0[0];
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat dy0 = v1[1] - v0[1];
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat dx1 = v2[0] - v1[0];
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat dy1 = v2[1] - v1[1];
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat dx2 = v0[0] - v2[0];
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLfloat dy2 = v0[1] - v2[1];
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLint stop = 4, i;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLfloat insideCount = 16.0F;
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(dx0 * dy1 - dx1 * dy0 >= 0.0); /* area >= 0.0 */
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < stop; i++) {
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLfloat sx = x + samples[i][0];
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLfloat sy = y + samples[i][1];
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* cross product determines if sample is inside or outside each edge */
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      GLfloat cross = (dx0 * (sy - v0[1]) - dy0 * (sx - v0[0]));
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Check if the sample is exactly on an edge.  If so, let cross be a
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * positive or negative value depending on the direction of the edge.
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (cross == 0.0F)
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         cross = dx0 + dy0;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (cross < 0.0F) {
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* sample point is outside first edge */
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         insideCount -= 1.0F;
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         stop = 16;
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* sample point is inside first edge */
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         cross = (dx1 * (sy - v1[1]) - dy1 * (sx - v1[0]));
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (cross == 0.0F)
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            cross = dx1 + dy1;
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (cross < 0.0F) {
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* sample point is outside second edge */
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            insideCount -= 1.0F;
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            stop = 16;
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else {
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* sample point is inside first and second edges */
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            cross = (dx2 * (sy - v2[1]) -  dy2 * (sx - v2[0]));
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (cross == 0.0F)
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               cross = dx2 + dy2;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (cross < 0.0F) {
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* sample point is outside third edge */
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               insideCount -= 1.0F;
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               stop = 16;
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (stop == 4)
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 1.0F;
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return insideCount * (1.0F / 16.0F);
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgrgba_aa_tri(struct gl_context *ctx,
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    const SWvertex *v0,
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    const SWvertex *v1,
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    const SWvertex *v2)
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DO_Z
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_aatritemp.h"
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orggeneral_aa_tri(struct gl_context *ctx,
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               const SWvertex *v0,
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               const SWvertex *v1,
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               const SWvertex *v2)
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DO_Z
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DO_ATTRIBS
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_aatritemp.h"
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Examine GL state and set swrast->Triangle to an
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * appropriate antialiased triangle rasterizer function.
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_swrast_set_aa_triangle_function(struct gl_context *ctx)
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SWcontext *swrast = SWRAST_CONTEXT(ctx);
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(ctx->Polygon.SmoothFlag);
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx->Texture._EnabledCoordUnits != 0
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       || _swrast_use_fragment_program(ctx)
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       || swrast->_FogEnabled
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       || _mesa_need_secondary_color(ctx)) {
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SWRAST_CONTEXT(ctx)->Triangle = general_aa_tri;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SWRAST_CONTEXT(ctx)->Triangle = rgba_aa_tri;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT(SWRAST_CONTEXT(ctx)->Triangle);
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
313