LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkAnalyticEdge.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 74 143 51.7 %
Date: 2017-07-14 16:53:18 Functions: 3 5 60.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2006 The Android Open Source Project
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : 
       9             : #include "SkAnalyticEdge.h"
      10             : #include "SkFDot6.h"
      11             : #include "SkMathPriv.h"
      12             : 
      13             : // This will become a bottleneck for small ovals rendering if we call SkFixedDiv twice here.
      14             : // Therefore, we'll let the outter function compute the slope once and send in the value.
      15             : // Moreover, we'll compute fDY by quickly lookup the inverse table (if possible).
      16        1096 : bool SkAnalyticEdge::updateLine(SkFixed x0, SkFixed y0, SkFixed x1, SkFixed y1, SkFixed slope) {
      17             :     // Since we send in the slope, we can no longer snap y inside this function.
      18             :     // If we don't send in the slope, or we do some more sophisticated snapping, this function
      19             :     // could be a performance bottleneck.
      20        1096 :     SkASSERT(fWinding == 1 || fWinding == -1);
      21        1096 :     SkASSERT(fCurveCount != 0);
      22             : 
      23        1096 :     SkASSERT(y0 <= y1);
      24             : 
      25        1096 :     SkFDot6 dx = SkFixedToFDot6(x1 - x0);
      26        1096 :     SkFDot6 dy = SkFixedToFDot6(y1 - y0);
      27             : 
      28             :     // are we a zero-height line?
      29        1096 :     if (dy == 0) {
      30           2 :         return false;
      31             :     }
      32             : 
      33        1094 :     SkASSERT(slope < SK_MaxS32);
      34             : 
      35        1094 :     SkFDot6     absSlope = SkAbs32(SkFixedToFDot6(slope));
      36        1094 :     fX          = x0;
      37        1094 :     fDX         = slope;
      38        1094 :     fUpperX     = x0;
      39        1094 :     fY          = y0;
      40        1094 :     fUpperY     = y0;
      41        1094 :     fLowerY     = y1;
      42        2188 :     fDY         = (dx == 0 || slope == 0)
      43        2188 :                   ? SK_MaxS32
      44             :                   : absSlope < kInverseTableSize
      45        1096 :                     ? QuickFDot6Inverse::Lookup(absSlope)
      46           2 :                     : SkAbs32(QuickSkFDot6Div(dy, dx));
      47             : 
      48        1094 :     return true;
      49             : }
      50             : 
      51           0 : bool SkAnalyticQuadraticEdge::setQuadratic(const SkPoint pts[3]) {
      52           0 :     fRiteE = nullptr;
      53             : 
      54           0 :     if (!fQEdge.setQuadraticWithoutUpdate(pts, kDefaultAccuracy)) {
      55           0 :         return false;
      56             :     }
      57           0 :     fQEdge.fQx >>= kDefaultAccuracy;
      58           0 :     fQEdge.fQy >>= kDefaultAccuracy;
      59           0 :     fQEdge.fQDx >>= kDefaultAccuracy;
      60           0 :     fQEdge.fQDy >>= kDefaultAccuracy;
      61           0 :     fQEdge.fQDDx >>= kDefaultAccuracy;
      62           0 :     fQEdge.fQDDy >>= kDefaultAccuracy;
      63           0 :     fQEdge.fQLastX >>= kDefaultAccuracy;
      64           0 :     fQEdge.fQLastY >>= kDefaultAccuracy;
      65           0 :     fQEdge.fQy = SnapY(fQEdge.fQy);
      66           0 :     fQEdge.fQLastY = SnapY(fQEdge.fQLastY);
      67             : 
      68           0 :     fWinding = fQEdge.fWinding;
      69           0 :     fCurveCount = fQEdge.fCurveCount;
      70           0 :     fCurveShift = fQEdge.fCurveShift;
      71             : 
      72           0 :     fSnappedX = fQEdge.fQx;
      73           0 :     fSnappedY = fQEdge.fQy;
      74             : 
      75           0 :     return this->updateQuadratic();
      76             : }
      77             : 
      78           0 : bool SkAnalyticQuadraticEdge::updateQuadratic() {
      79           0 :     int     success = 0; // initialize to fail!
      80           0 :     int     count = fCurveCount;
      81           0 :     SkFixed oldx = fQEdge.fQx;
      82           0 :     SkFixed oldy = fQEdge.fQy;
      83           0 :     SkFixed dx = fQEdge.fQDx;
      84           0 :     SkFixed dy = fQEdge.fQDy;
      85             :     SkFixed newx, newy, newSnappedX, newSnappedY;
      86           0 :     int     shift = fCurveShift;
      87             : 
      88           0 :     SkASSERT(count > 0);
      89             : 
      90           0 :     do {
      91             :         SkFixed slope;
      92           0 :         if (--count > 0)
      93             :         {
      94           0 :             newx    = oldx + (dx >> shift);
      95           0 :             newy    = oldy + (dy >> shift);
      96           0 :             if (SkAbs32(dy >> shift) >= SK_Fixed1 * 2) { // only snap when dy is large enough
      97           0 :                 SkFDot6 diffY = SkFixedToFDot6(newy - fSnappedY);
      98           0 :                 slope = diffY ? QuickSkFDot6Div(SkFixedToFDot6(newx - fSnappedX), diffY)
      99             :                               : SK_MaxS32;
     100           0 :                 newSnappedY = SkTMin<SkFixed>(fQEdge.fQLastY, SkFixedRoundToFixed(newy));
     101           0 :                 newSnappedX = newx - SkFixedMul(slope, newy - newSnappedY);
     102             :             } else {
     103           0 :                 newSnappedY = SkTMin(fQEdge.fQLastY, SnapY(newy));
     104           0 :                 newSnappedX = newx;
     105           0 :                 SkFDot6 diffY = SkFixedToFDot6(newSnappedY - fSnappedY);
     106           0 :                 slope = diffY ? QuickSkFDot6Div(SkFixedToFDot6(newx - fSnappedX), diffY)
     107             :                               : SK_MaxS32;
     108             :             }
     109           0 :             dx += fQEdge.fQDDx;
     110           0 :             dy += fQEdge.fQDDy;
     111             :         }
     112             :         else    // last segment
     113             :         {
     114           0 :             newx    = fQEdge.fQLastX;
     115           0 :             newy    = fQEdge.fQLastY;
     116           0 :             newSnappedY = newy;
     117           0 :             newSnappedX = newx;
     118           0 :             SkFDot6 diffY = (newy - fSnappedY) >> 10;
     119           0 :             slope = diffY ? QuickSkFDot6Div((newx - fSnappedX) >> 10, diffY) : SK_MaxS32;
     120             :         }
     121           0 :         if (slope < SK_MaxS32) {
     122           0 :             success = this->updateLine(fSnappedX, fSnappedY, newSnappedX, newSnappedY, slope);
     123             :         }
     124           0 :         oldx = newx;
     125           0 :         oldy = newy;
     126           0 :     } while (count > 0 && !success);
     127             : 
     128           0 :     SkASSERT(newSnappedY <= fQEdge.fQLastY);
     129             : 
     130           0 :     fQEdge.fQx  = newx;
     131           0 :     fQEdge.fQy  = newy;
     132           0 :     fQEdge.fQDx = dx;
     133           0 :     fQEdge.fQDy = dy;
     134           0 :     fSnappedX   = newSnappedX;
     135           0 :     fSnappedY   = newSnappedY;
     136           0 :     fCurveCount = SkToS8(count);
     137           0 :     return success;
     138             : }
     139             : 
     140         186 : bool SkAnalyticCubicEdge::setCubic(const SkPoint pts[4]) {
     141         186 :     fRiteE = nullptr;
     142             : 
     143         186 :     if (!fCEdge.setCubicWithoutUpdate(pts, kDefaultAccuracy)) {
     144           0 :         return false;
     145             :     }
     146             : 
     147         186 :     fCEdge.fCx >>= kDefaultAccuracy;
     148         186 :     fCEdge.fCy >>= kDefaultAccuracy;
     149         186 :     fCEdge.fCDx >>= kDefaultAccuracy;
     150         186 :     fCEdge.fCDy >>= kDefaultAccuracy;
     151         186 :     fCEdge.fCDDx >>= kDefaultAccuracy;
     152         186 :     fCEdge.fCDDy >>= kDefaultAccuracy;
     153         186 :     fCEdge.fCDDDx >>= kDefaultAccuracy;
     154         186 :     fCEdge.fCDDDy >>= kDefaultAccuracy;
     155         186 :     fCEdge.fCLastX >>= kDefaultAccuracy;
     156         186 :     fCEdge.fCLastY >>= kDefaultAccuracy;
     157         186 :     fCEdge.fCy = SnapY(fCEdge.fCy);
     158         186 :     fCEdge.fCLastY = SnapY(fCEdge.fCLastY);
     159             : 
     160         186 :     fWinding = fCEdge.fWinding;
     161         186 :     fCurveCount = fCEdge.fCurveCount;
     162         186 :     fCurveShift = fCEdge.fCurveShift;
     163         186 :     fCubicDShift = fCEdge.fCubicDShift;
     164             : 
     165         186 :     fSnappedY = fCEdge.fCy;
     166             : 
     167         186 :     return this->updateCubic();
     168             : }
     169             : 
     170        1096 : bool SkAnalyticCubicEdge::updateCubic() {
     171             :     int     success;
     172        1096 :     int     count = fCurveCount;
     173        1096 :     SkFixed oldx = fCEdge.fCx;
     174        1096 :     SkFixed oldy = fCEdge.fCy;
     175             :     SkFixed newx, newy;
     176        1096 :     const int ddshift = fCurveShift;
     177        1096 :     const int dshift = fCubicDShift;
     178             : 
     179        1096 :     SkASSERT(count < 0);
     180             : 
     181           0 :     do {
     182        1096 :         if (++count < 0) {
     183         910 :             newx    = oldx + (fCEdge.fCDx >> dshift);
     184         910 :             fCEdge.fCDx    += fCEdge.fCDDx >> ddshift;
     185         910 :             fCEdge.fCDDx   += fCEdge.fCDDDx;
     186             : 
     187         910 :             newy    = oldy + (fCEdge.fCDy >> dshift);
     188         910 :             fCEdge.fCDy    += fCEdge.fCDDy >> ddshift;
     189         910 :             fCEdge.fCDDy   += fCEdge.fCDDDy;
     190             :         }
     191             :         else {    // last segment
     192         186 :             newx    = fCEdge.fCLastX;
     193         186 :             newy    = fCEdge.fCLastY;
     194             :         }
     195             : 
     196             :         // we want to say SkASSERT(oldy <= newy), but our finite fixedpoint
     197             :         // doesn't always achieve that, so we have to explicitly pin it here.
     198        1096 :         if (newy < oldy) {
     199           0 :             newy = oldy;
     200             :         }
     201             : 
     202        1096 :         SkFixed newSnappedY = SnapY(newy);
     203             :         // we want to SkASSERT(snappedNewY <= fCEdge.fCLastY), but our finite fixedpoint
     204             :         // doesn't always achieve that, so we have to explicitly pin it here.
     205        1096 :         if (fCEdge.fCLastY < newSnappedY) {
     206           0 :             newSnappedY = fCEdge.fCLastY;
     207           0 :             count = 0;
     208             :         }
     209             : 
     210        1096 :         SkFixed slope = SkFixedToFDot6(newSnappedY - fSnappedY) == 0
     211        2190 :                         ? SK_MaxS32
     212        1094 :                         : SkFDot6Div(SkFixedToFDot6(newx - oldx),
     213        2190 :                                      SkFixedToFDot6(newSnappedY - fSnappedY));
     214             : 
     215        1096 :         success = this->updateLine(oldx, fSnappedY, newx, newSnappedY, slope);
     216             : 
     217        1096 :         oldx = newx;
     218        1096 :         oldy = newy;
     219        1096 :         fSnappedY = newSnappedY;
     220        1096 :     } while (count < 0 && !success);
     221             : 
     222        1096 :     fCEdge.fCx  = newx;
     223        1096 :     fCEdge.fCy  = newy;
     224        1096 :     fCurveCount = SkToS8(count);
     225        1096 :     return success;
     226             : }

Generated by: LCOV version 1.13