Bug 91858 - Various rounding errors in miComputeEllipseSpans() with large radius
Summary: Various rounding errors in miComputeEllipseSpans() with large radius
Status: RESOLVED MOVED
Alias: None
Product: xorg
Classification: Unclassified
Component: Server/General (show other bugs)
Version: unspecified
Hardware: Other All
: medium normal
Assignee: Xorg Project Team
QA Contact: Xorg Project Team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-09-03 07:30 UTC by Olivier Fourdan
Modified: 2018-12-13 22:32 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments
Patch I sent to the devel list some time ago (1.37 KB, patch)
2015-09-03 07:30 UTC, Olivier Fourdan
no flags Details | Splinter Review

Description Olivier Fourdan 2015-09-03 07:30:00 UTC
Created attachment 118058 [details] [review]
Patch I sent to the devel list some time ago

This issue is probably as old as the implementation itself, so sorry in advance if this has been discussed before, I haven't found any trace of that (there is bug 13378 but it's a different issue apparently)

When using large values for width/height (> 5000) arcs, the values of inx and outx in miComputeEllipseSpans() gets so close that the spans lw and rw get down to 0, meaning that no 
pixel will be drawn on screen.

lines 566 to 578 in mi/miarc.c from miComputeEllipseSpans()

        span->lx = ICEIL(xorg - outx);
        span->lw = ICEIL(xorg - inx) - span->lx;
        span->rx = ICEIL(xorg + inx);
        span->rw = ICEIL(xorg + outx) - span->rx;

The same issue does not occur with the miZeroArc* routines, but unfortunately those only work wither with circles or else ellipses of size < 800.

I won't pretend I fully understand this code, far from it, so also copying Keith as he co-authored this code and understands this a lot more than I ever will.

Attaching a patch I sent to the devel ML as an RFC a few months ago, that's a hack that does slightly help in some case but is by no mean a definitive perfect solution (not even sure there's such thing as a perfect solution).

With this patch, even if there is no more missing pixels close to the vertical tangent of the ellipse, some "sawtooth" effects can be observed in place sometimes and there can still be a few missing pixels close to the horizontal tangents.

There is also another ugly issue when using a line width > 1 the border close the vertical tangent can become insanely large - To reproduce, try with linewidth=5 in XSetLineAttributes() with the following example.

My patch does not address that.

I was wondering if we could reduce the precision somehow with large values to avoid these side effects on limits, but, err, I haven't found yet (and I've already got some headaches with this, so I'm eager to get some more fresh ideas, thus this RFC patch/bug...)

Following is a simple reproducer to play with.

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/X.h>

int main(int argc, char *argv[])
{
  Window root_window, win;
  Display* display;
  unsigned long white_pixel, black_pixel;
  int screen_num;
  int j;
  GC gc;
  XEvent e;

  display = XOpenDisplay(NULL);
  if (display == NULL) {
    fprintf(stderr, "Cannot connect to X server %s\n", ":0");
    return -1;
  }
  screen_num = DefaultScreen(display);
  root_window = RootWindow(display, screen_num);
  white_pixel = WhitePixel(display, screen_num);
  black_pixel = BlackPixel(display, screen_num);
  gc = DefaultGC(display, screen_num);
  XSetLineAttributes(display, gc, 1, LineSolid, CapNotLast, JoinMiter);
  win = XCreateSimpleWindow(display, RootWindow(display, screen_num),
                            0, 0, 1024, 1024, 1,
                            black_pixel, white_pixel);
  XSelectInput(display, win, ExposureMask | KeyPressMask);
  XMapWindow(display, win);
  while (1) {
    XNextEvent(display, &e);
    if (e.type == Expose) {
      XSelectInput(display, win, ExposureMask | KeyPressMask);
      for (j = 0; j < 10000; j += 100)
        XDrawArc(display, win, gc,
                 5 + j / 10, j / 2 - (10000 - 1024 / 2),
                 19999, 20000 - j,
                 175 * 64, 10 * 64);
    }
  }

  XCloseDisplay(display);
  return 0;
}
Comment 1 GitLab Migration User 2018-12-13 22:32:53 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/xorg/xserver/issues/481.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.