[poppler] [PATCH v2 2/5] SplashXPathScanner: Reset span state explicitly when advancing line

Albert Astals Cid aacid at kde.org
Wed May 30 07:31:32 UTC 2018


So this saves checking
   (y < yMin || y > yMax)
a few times in exchange of making the code more error prone since now you have 
to remember to actaully call setRow, have you measured this has an actual 
speed improvement impact?

Cheers,
  Albert

El dissabte, 26 de maig de 2018, a les 19:51:21 CEST, Stefan BrĂ¼ns va 
escriure:
> Avoid checking for a line change in each span. The required state reset
> can be done from the call site.
> ---
>  splash/Splash.cc             |  9 +++++++++
>  splash/SplashXPathScanner.cc | 19 ++++++++++---------
>  splash/SplashXPathScanner.h  | 12 ++++++------
>  3 files changed, 25 insertions(+), 15 deletions(-)
> 
> diff --git a/splash/Splash.cc b/splash/Splash.cc
> index d749ab03..1eb907d8 100644
> --- a/splash/Splash.cc
> +++ b/splash/Splash.cc
> @@ -2612,6 +2612,9 @@ SplashError Splash::fillWithPattern(SplashPath *path,
> GBool eo, }
>      } else {
>        for (y = yMinI; y <= yMaxI; ++y) {
> +	if (!scanner->setRow(y)) {
> +          continue;
> +        }
>  	while (scanner->getNextSpan(y, &x0, &x1)) {
>  	  if (clipRes == splashClipAllInside) {
>  	    drawSpan(&pipe, x0, x1, y, gTrue);
> @@ -2736,6 +2739,9 @@ SplashError Splash::xorFill(SplashPath *path, GBool
> eo) {
> 
>      // draw the spans
>      for (y = yMinI; y <= yMaxI; ++y) {
> +      if (!scanner->setRow(y)) {
> +        continue;
> +      }
>        while (scanner->getNextSpan(y, &x0, &x1)) {
>  	if (clipRes == splashClipAllInside) {
>  	  drawSpan(&pipe, x0, x1, y, gTrue);
> @@ -6492,6 +6498,9 @@ SplashError Splash::shadedFill(SplashPath *path, GBool
> hasBBox, } else {
>        SplashClipResult clipRes2;
>        for (y = yMinI; y <= yMaxI; ++y) {
> +        if (!scanner->setRow(y)) {
> +          continue;
> +        }
>          while (scanner->getNextSpan(y, &x0, &x1)) {
>            if (clipRes == splashClipAllInside) {
>              drawSpan(&pipe, x0, x1, y, gTrue);
> diff --git a/splash/SplashXPathScanner.cc b/splash/SplashXPathScanner.cc
> index 1e48e90b..b36f5322 100644
> --- a/splash/SplashXPathScanner.cc
> +++ b/splash/SplashXPathScanner.cc
> @@ -122,7 +122,6 @@ SplashXPathScanner::SplashXPathScanner(SplashXPath
> *xPathA, GBool eoA, allInter = nullptr;
>    inter = nullptr;
>    computeIntersections();
> -  interY = yMin - 1;
>  }
> 
>  SplashXPathScanner::~SplashXPathScanner() {
> @@ -216,14 +215,6 @@ GBool SplashXPathScanner::testSpan(int x0, int x1, int
> y) { GBool SplashXPathScanner::getNextSpan(int y, int *x0, int *x1) {
>    int interEnd, xx0, xx1;
> 
> -  if (y < yMin || y > yMax) {
> -    return gFalse;
> -  }
> -  if (interY != y) {
> -    interY = y;
> -    interIdx = inter[y - yMin];
> -    interCount = 0;
> -  }
>    interEnd = inter[y - yMin + 1];
>    if (interIdx >= interEnd) {
>      return gFalse;
> @@ -246,6 +237,16 @@ GBool SplashXPathScanner::getNextSpan(int y, int *x0,
> int *x1) { return gTrue;
>  }
> 
> +GBool SplashXPathScanner::setRow(int y) {
> +  if (y < yMin || y > yMax) {
> +    return gFalse;
> +  }
> +
> +  interCount = 0;
> +  interIdx = inter[y - yMin];
> +  return gTrue;
> +}
> +
>  void SplashXPathScanner::computeIntersections() {
>    SplashXPathSeg *seg;
>    SplashCoord segXMin, segXMax, segYMin, segYMax, xx0, xx1;
> diff --git a/splash/SplashXPathScanner.h b/splash/SplashXPathScanner.h
> index b6c358d9..99f2c28f 100644
> --- a/splash/SplashXPathScanner.h
> +++ b/splash/SplashXPathScanner.h
> @@ -69,13 +69,14 @@ public:
>    // path.
>    GBool testSpan(int x0, int x1, int y);
> 
> -  // Returns the next span inside the path at <y>.  If <y> is
> -  // different than the previous call to getNextSpan, this returns the
> -  // first span at <y>; otherwise it returns the next span (relative
> -  // to the previous call to getNextSpan).  Returns false if there are
> -  // no more spans at <y>.
> +  // Returns the next span inside the path at <y>.
> +  // Returns false if there are no more spans at <y>.
>    GBool getNextSpan(int y, int *x0, int *x1);
> 
> +  // Sets the current span to the first span at <y>.
> +  // Returns false if the row is outside the path.
> +  GBool setRow(int y);
> +
>    // Renders one anti-aliased line into <aaBuf>.  Returns the min and
>    // max x coordinates with non-zero pixels in <x0> and <x1>.
>    void renderAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y,
> @@ -102,7 +103,6 @@ private:
>    int allInterLen;		// number of intersections in <allInter>
>    int allInterSize;		// size of the <allInter> array
>    int *inter;			// indexes into <allInter> for each y value
> -  int interY;			// current y value - used by getNextSpan
>    int interIdx;			// current index into <inter> - used by
>  				//   getNextSpan
>    int interCount;		// current EO/NZWN counter - used by






More information about the poppler mailing list