Bug 9749 - Drawing smooth lines with 6.5.2 is quite slow comparing to with 3.3
Summary: Drawing smooth lines with 6.5.2 is quite slow comparing to with 3.3
Status: RESOLVED WONTFIX
Alias: None
Product: Mesa
Classification: Unclassified
Component: Mesa core (show other bugs)
Version: 6.5
Hardware: x86 (IA32) Linux (All)
: high normal
Assignee: mesa-dev
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-01-23 16:22 UTC by Lixing Fang
Modified: 2011-01-11 17:47 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments

Description Lixing Fang 2007-01-23 16:22:38 UTC
When glEnable(GL_LINE_SMOOTH) is used, drawing 100000 random antialiased lines
with Mesa-6.5.2 (it takes about 51 second) is quite slow comparing doing the
same with Mesa-3.3 (which takes 7 seconds). Here is my GLUT test program:

------------------------------------------------------------------------
#include <GL/glut.h>
#include "stdlib.h"

static double linewidth = 1.0;
static double r = 0.627451;
static double g = 0.627451;
static double b = 0.627451;
static double a = 1.0;
static double p1[3];
static double p2[3];
static int vport[4] = { 0, 0, 513, 626 };
static float view[6] = { 0.0, 11.0, 0.0, 11.0, -100.0, 10.0 };

void init(void)
{
   glEnable (GL_LINE_SMOOTH);
   glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
   glLineWidth ( linewidth );
   glDisable( GL_LIGHTING );
}

void display(void)
{
   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

   int i, k;
   for( i=0; i<100000; i++ ) {
      for( k=0; k<3; k++ ) {
         p1[k] = 1+(int)(10.0*rand()/(RAND_MAX+1.0));
         p2[k] = 1+(int)(10.0*rand()/(RAND_MAX+1.0));
      }

      glBegin( GL_LINES );
      glColor4d( r, g, b, a );
      glVertex3dv( p1 );
      glColor4d( r, g, b, a );
      glVertex3dv( p2 );
      glEnd();
   }

   p1[0] = 1.0; p1[1] = 0.5; p1[2] = 0.0;
   p2[0] = 10.0; p2[1] = 0.5; p2[2] = 0.0;
   glBegin( GL_LINES );
   glColor4d( r, g, b, a );
   glVertex3dv( p1 );
   glColor4d( r, g, b, a );
   glVertex3dv( p2 );
   glEnd();

   glFlush();
}

void reshape(int w, int h)
{
  glDrawBuffer( GL_BACK );
  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  glViewport( vport[0], vport[1], vport[2], vport[3] );
  glOrtho( view[0], view[1], view[2], view[3], view[4], view[5] );
}

int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize (vport[2], vport[3]);
   glutCreateWindow (argv[0]);
   init();
   glutReshapeFunc (reshape);
   glutDisplayFunc (display);
   glutMainLoop();
   return 0;
}
------------------------------------------------------------------------


I had looked into this problem a while and found that the time consuming in
Mesa-6.5.2 mainly comes from function compute_coveragef() in file
/Mesa-6.5.2/src/mesa/swrast/s_aaline.c. I made following changes to try to use
the RGBA coverage calculation in Mesa-3.3 in file /Mesa-3.3/src/lnaatemp.h:

- Edit src/mesa/swrast/s_aaline.c, line 483, just before line
    "#define NAME(x) aa_ci_##x"
  - Add following function:
---------------------------------------------------------------------------------
static void 
plot_mae(GLcontext *ctx, struct LineInfo *line, int ix, int iy, GLfloat coverage)
{
   if (coverage == 0.0)
      return;

   const GLfloat fx = (GLfloat) ix;
   const GLfloat fy = (GLfloat) iy;
   const GLuint i = line->span.end;

   line->span.end++;
   line->span.array->coverage[i] = coverage;
   line->span.array->x[i] = ix;
   line->span.array->y[i] = iy;

   line->span.array->rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane);
   line->span.array->rgba[i][GCOMP] = solve_plane_chan(fx, fy, line->gPlane);
   line->span.array->rgba[i][BCOMP] = solve_plane_chan(fx, fy, line->bPlane);
   line->span.array->rgba[i][ACOMP] = solve_plane_chan(fx, fy, line->aPlane);

   if (line->span.end == MAX_WIDTH) {
      _swrast_write_rgba_span(ctx, &(line->span));
      line->span.end = 0;
   }
}
---------------------------------------------------------------------------------
- Edit src/mesa/swrast/s_aalinetemp.h, line 309
  - Replace line 
      "segment(ctx, &line, NAME(plot), 0.0, 1.0);" 
    with following codes:
---------------------------------------------------------------------------------
#if defined(DO_RGBA)
      GLfloat halfWidth = line.halfWidth;
      GLint dx = line.dx;
      GLint dy = line.dy;
      GLint xStep, yStep;
      GLfloat fr, fg, fb, fa;
      GLfloat dfr, dfg, dfb, dfa;
      GLfloat d255 = 1.0F / 255;

      fr = (v0->color[0]) * d255;
      fg = (v0->color[1]) * d255;
      fb = (v0->color[2]) * d255;
      fa = (v0->color[3]) * d255;

      if (dx < 0) {
         xStep = -1;
         dx = -dx;
      }
      else {
         xStep = 1;
      }

      if (dy < 0) {
         yStep = -1;
         dy = -dy;
      }
      else {
         yStep = 1;
      }

      if (dx > dy) {
         GLint ii;
         GLint x = (GLint) line.x0;
         GLfloat y = line.y0;
         const GLfloat invDx = 1.0F / dx;
         GLfloat yStep = (line.y1 - y) * invDx;

         dfr = ((v1->color[0]) * d255 - fr) * invDx;
         dfg = ((v1->color[1]) * d255 - fg) * invDx;
         dfb = ((v1->color[2]) * d255 - fb) * invDx;
         dfa = ((v1->color[3]) * d255 - fa) * invDx;

         for (ii = 0; ii < dx; ii++) {
            GLfloat yTop = y + halfWidth;
            GLfloat yBot = y - halfWidth;
            GLint yTopi = (GLint) yTop;
            GLint yBoti = (GLint) yBot;
            GLint iy;
            GLfloat alpha = fa;
            GLfloat coverage;

            ASSERT(yBoti <= yTopi);
            {
               coverage = (GLfloat) (alpha * (1.0F - (yBot - yBoti)));
               plot_mae(ctx, &line, x, yBoti, coverage);
               yBoti++;

               coverage = (GLfloat) (alpha * (yTop - yTopi));
               plot_mae(ctx, &line, x, yTopi, coverage);
               yTopi--;

               coverage = alpha;
               for (iy = yBoti; iy <= yTopi; iy++) {
                  plot_mae(ctx, &line, x, iy, coverage);
               }
            }

            x += xStep;
            y += yStep;
            fr += dfr;
            fg += dfg;
            fb += dfb;
            fa += dfa;
         }
      }
      else {
         GLint ii;
         GLint y = (GLint) line.y0;
         GLfloat x = line.x0;
         const GLfloat invDy = 1.0F / dy;
         GLfloat xStep = (line.x1 - x) * invDy;

         dfr = ((v1->color[0]) * d255 - fr) * invDy;
         dfg = ((v1->color[1]) * d255 - fg) * invDy;
         dfb = ((v1->color[2]) * d255 - fb) * invDy;
         dfa = ((v1->color[3]) * d255 - fa) * invDy;

         for (ii = 0; ii < dy; ii++) {
            GLfloat xRight = x + halfWidth;
            GLfloat xLeft = x - halfWidth;
            GLint xRighti = (GLint) xRight;
            GLint xLefti = (GLint) xLeft;
            GLint ix;
            GLfloat alpha = fa;
            GLfloat coverage;

            ASSERT(xLefti < xRight);
            {
               coverage = (GLfloat) (alpha * (1.0F - (xLeft - xLefti)));
               plot_mae(ctx, &line, xLefti, y, coverage);
               xLefti++;

               coverage = (GLfloat) (alpha * (xRight - xRighti));
               plot_mae(ctx, &line, xRighti, y, coverage);
               xRighti--;

               coverage = alpha;
               for (ix = xLefti; ix <= xRighti; ix++) {
                  plot_mae(ctx, &line, ix, y, coverage);
               }
            }

            x += xStep;
            y += yStep;
            fr += dfr;
            fg += dfg;
            fb += dfb;
            fa += dfa;
         }
      }
#else
      segment(ctx, &line, NAME(plot), 0.0, 1.0);
#endif
---------------------------------------------------------------------------------

The result is positive. After the changes drawing 100000 smooth lines with 6.5.2
takes about 7 seconds. Sure I shoule consider about Depth, Fog, and so on. But
it's clear that function compute_coveragef() slows down drawing smooth lines.
Maybe smooth line quality in 6.5.2 is much better. Smooth lines quality with 3.3
is acceptable for me.

Maybe there is a need in latest Mesa to balance quality and drawing speed for
smooth lines.

Thanks,

Lixing
Comment 1 Ian Romanick 2011-01-11 17:47:50 UTC
It seems unlikely that effort will be put into optimizing smoothing line drawing in the software rasterizer... especially since this bug has been sitting here for 4 years.


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.