зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1704750 - Simplify rasterizer edge termination condition. r=kvark
Floating point imprecision can cause the existing test to be unreliable. Just simplify it so it loops around till it overlaps one edge with another. This does a tiny bit more work but will have less chance of exiting earlier than it should. Differential Revision: https://phabricator.services.mozilla.com/D114236
This commit is contained in:
Родитель
59ec919b24
Коммит
4d26cb2ec6
|
@ -880,35 +880,29 @@ static inline void draw_quad_spans(int nump, Point2D p[4], uint32_t z,
|
||||||
// If we're outside the clip rect, we're done.
|
// If we're outside the clip rect, we're done.
|
||||||
if (y > clipRect.y1) break;
|
if (y > clipRect.y1) break;
|
||||||
// Helper to find the next non-duplicate vertex that doesn't loop back.
|
// Helper to find the next non-duplicate vertex that doesn't loop back.
|
||||||
#define STEP_EDGE(e0i, e0, e1i, e1, STEP_POINT, end) \
|
#define STEP_EDGE(y, e0i, e0, e1i, e1, STEP_POINT, end) \
|
||||||
for (;;) { \
|
do { \
|
||||||
/* Set new start of edge to be end of old edge */ \
|
/* Set new start of edge to be end of old edge */ \
|
||||||
e0i = e1i; \
|
e0i = e1i; \
|
||||||
e0 = e1; \
|
e0 = e1; \
|
||||||
/* Set new end of edge to next point */ \
|
/* Set new end of edge to next point */ \
|
||||||
e1i = STEP_POINT(e1i); \
|
e1i = STEP_POINT(e1i); \
|
||||||
e1 = p[e1i]; \
|
e1 = p[e1i]; \
|
||||||
/* If the edge is descending, use it. */ \
|
/* If the edge crossed the end, we're done. */ \
|
||||||
if (e1.y > e0.y) break; \
|
if (e0i == end) return; \
|
||||||
/* If the edge is ascending or crossed the end, we're done. */ \
|
/* Otherwise, it doesn't advance, so keep searching. */ \
|
||||||
if (e1.y < e0.y || e0i == end) return; \
|
} while (y > e1.y)
|
||||||
/* Otherwise, it's a duplicate, so keep searching. */ \
|
|
||||||
}
|
|
||||||
// Check if Y advanced past the end of the left edge
|
// Check if Y advanced past the end of the left edge
|
||||||
if (y > l1.y) {
|
if (y > l1.y) {
|
||||||
// Step to next left edge past Y and reset edge interpolants.
|
// Step to next left edge past Y and reset edge interpolants.
|
||||||
do {
|
STEP_EDGE(y, l0i, l0, l1i, l1, NEXT_POINT, r1i);
|
||||||
STEP_EDGE(l0i, l0, l1i, l1, NEXT_POINT, r1i);
|
|
||||||
} while (y > l1.y);
|
|
||||||
(flipped ? right : left) =
|
(flipped ? right : left) =
|
||||||
Edge(y, l0, l1, interp_outs[l0i], interp_outs[l1i], l1i);
|
Edge(y, l0, l1, interp_outs[l0i], interp_outs[l1i], l1i);
|
||||||
}
|
}
|
||||||
// Check if Y advanced past the end of the right edge
|
// Check if Y advanced past the end of the right edge
|
||||||
if (y > r1.y) {
|
if (y > r1.y) {
|
||||||
// Step to next right edge past Y and reset edge interpolants.
|
// Step to next right edge past Y and reset edge interpolants.
|
||||||
do {
|
STEP_EDGE(y, r0i, r0, r1i, r1, PREV_POINT, l1i);
|
||||||
STEP_EDGE(r0i, r0, r1i, r1, PREV_POINT, l1i);
|
|
||||||
} while (y > r1.y);
|
|
||||||
(flipped ? left : right) =
|
(flipped ? left : right) =
|
||||||
Edge(y, r0, r1, interp_outs[r0i], interp_outs[r1i], r0i);
|
Edge(y, r0, r1, interp_outs[r0i], interp_outs[r1i], r0i);
|
||||||
}
|
}
|
||||||
|
@ -1146,18 +1140,14 @@ static inline void draw_perspective_spans(int nump, Point3D* p,
|
||||||
// Check if Y advanced past the end of the left edge
|
// Check if Y advanced past the end of the left edge
|
||||||
if (y > l1.y) {
|
if (y > l1.y) {
|
||||||
// Step to next left edge past Y and reset edge interpolants.
|
// Step to next left edge past Y and reset edge interpolants.
|
||||||
do {
|
STEP_EDGE(y, l0i, l0, l1i, l1, NEXT_POINT, r1i);
|
||||||
STEP_EDGE(l0i, l0, l1i, l1, NEXT_POINT, r1i);
|
|
||||||
} while (y > l1.y);
|
|
||||||
(flipped ? right : left) =
|
(flipped ? right : left) =
|
||||||
Edge(y, l0, l1, interp_outs[l0i], interp_outs[l1i], l1i);
|
Edge(y, l0, l1, interp_outs[l0i], interp_outs[l1i], l1i);
|
||||||
}
|
}
|
||||||
// Check if Y advanced past the end of the right edge
|
// Check if Y advanced past the end of the right edge
|
||||||
if (y > r1.y) {
|
if (y > r1.y) {
|
||||||
// Step to next right edge past Y and reset edge interpolants.
|
// Step to next right edge past Y and reset edge interpolants.
|
||||||
do {
|
STEP_EDGE(y, r0i, r0, r1i, r1, PREV_POINT, l1i);
|
||||||
STEP_EDGE(r0i, r0, r1i, r1, PREV_POINT, l1i);
|
|
||||||
} while (y > r1.y);
|
|
||||||
(flipped ? left : right) =
|
(flipped ? left : right) =
|
||||||
Edge(y, r0, r1, interp_outs[r0i], interp_outs[r1i], r0i);
|
Edge(y, r0, r1, interp_outs[r0i], interp_outs[r1i], r0i);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче