LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/effects/gradients - SkClampRange.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 103 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2011 Google Inc.
       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             : #include "SkClampRange.h"
       9             : #include "SkMathPriv.h"
      10             : 
      11           0 : static int SkCLZ64(uint64_t value) {
      12           0 :     int count = 0;
      13           0 :     if (value >> 32) {
      14           0 :         value >>= 32;
      15             :     } else {
      16           0 :         count += 32;
      17             :     }
      18           0 :     return count + SkCLZ(SkToU32(value));
      19             : }
      20             : 
      21           0 : static bool sk_64_smul_check(int64_t count, int64_t dx, int64_t* result) {
      22             :     // Do it the slow way until we have some assembly.
      23           0 :     if (dx == std::numeric_limits<int64_t>::min()) {
      24           0 :         return false; // SkTAbs overflow
      25             :     }
      26             : 
      27           0 :     SkASSERT(count >= 0);
      28           0 :     uint64_t ucount = static_cast<uint64_t>(count);
      29           0 :     uint64_t udx = static_cast<uint64_t>(SkTAbs(dx));
      30           0 :     int zeros = SkCLZ64(ucount) + SkCLZ64(udx);
      31             :     // this is a conservative check: it may return false when in fact it would not have overflowed.
      32             :     // Hackers Delight uses 34 as its convervative check, but that is for 32x32 multiplies.
      33             :     // Since we are looking at 64x64 muls, we add 32 to the check.
      34           0 :     if (zeros < (32 + 34)) {
      35           0 :         return false;
      36             :     }
      37           0 :     *result = count * dx;
      38           0 :     return true;
      39             : }
      40             : 
      41           0 : static bool sk_64_sadd_check(int64_t a, int64_t b, int64_t* result) {
      42           0 :     if (a > 0) {
      43           0 :         if (b > std::numeric_limits<int64_t>::max() - a) {
      44           0 :             return false;
      45             :         }
      46             :     } else {
      47           0 :         if (b < std::numeric_limits<int64_t>::min() - a) {
      48           0 :             return false;
      49             :         }
      50             :     }
      51             : 
      52           0 :     *result = a + b;
      53           0 :     return true;
      54             : }
      55             : 
      56             : 
      57             : /*
      58             :  *  returns [0..count] for the number of steps (<= count) for which x0 <= edge
      59             :  *  given each step is followed by x0 += dx
      60             :  */
      61           0 : static int chop(int64_t x0, SkGradFixed edge, int64_t x1, int64_t dx, int count) {
      62           0 :     SkASSERT(dx > 0);
      63           0 :     SkASSERT(count >= 0);
      64             : 
      65           0 :     if (x0 >= edge) {
      66           0 :         return 0;
      67             :     }
      68           0 :     if (x1 <= edge) {
      69           0 :         return count;
      70             :     }
      71           0 :     int64_t n = (edge - x0 + dx - 1) / dx;
      72           0 :     SkASSERT(n >= 0);
      73           0 :     SkASSERT(n <= count);
      74           0 :     return (int)n;
      75             : }
      76             : 
      77           0 : void SkClampRange::initFor1(SkGradFixed fx) {
      78           0 :     fCount0 = fCount1 = fCount2 = 0;
      79           0 :     if (fx <= 0) {
      80           0 :         fCount0 = 1;
      81           0 :     } else if (fx < kFracMax_SkGradFixed) {
      82           0 :         fCount1 = 1;
      83           0 :         fFx1 = fx;
      84             :     } else {
      85           0 :         fCount2 = 1;
      86             :     }
      87           0 : }
      88             : 
      89           0 : void SkClampRange::init(SkGradFixed fx0, SkGradFixed dx0, int count, int v0, int v1) {
      90           0 :     SkASSERT(count > 0);
      91             : 
      92           0 :     fV0 = v0;
      93           0 :     fV1 = v1;
      94             : 
      95             :     // special case 1 == count, as it is slightly common for skia
      96             :     // and avoids us ever calling divide or 64bit multiply
      97           0 :     if (1 == count) {
      98           0 :         this->initFor1(fx0);
      99           0 :         return;
     100             :     }
     101             : 
     102           0 :     int64_t fx = fx0;
     103           0 :     int64_t dx = dx0;
     104             : 
     105             :     // start with ex equal to the last computed value
     106             :     int64_t count_times_dx, ex;
     107           0 :     if (!sk_64_smul_check(count - 1, dx, &count_times_dx) ||
     108           0 :         !sk_64_sadd_check(fx, count_times_dx, &ex)) {
     109             :         // we can't represent the computed end in 32.32, so just draw something (first color)
     110           0 :         fCount1 = fCount2 = 0;
     111           0 :         fCount0 = count;
     112           0 :         return;
     113             :     }
     114             : 
     115           0 :     if ((uint64_t)(fx | ex) <= kFracMax_SkGradFixed) {
     116           0 :         fCount0 = fCount2 = 0;
     117           0 :         fCount1 = count;
     118           0 :         fFx1 = fx0;
     119           0 :         return;
     120             :     }
     121           0 :     if (fx <= 0 && ex <= 0) {
     122           0 :         fCount1 = fCount2 = 0;
     123           0 :         fCount0 = count;
     124           0 :         return;
     125             :     }
     126           0 :     if (fx >= kFracMax_SkGradFixed && ex >= kFracMax_SkGradFixed) {
     127           0 :         fCount0 = fCount1 = 0;
     128           0 :         fCount2 = count;
     129           0 :         return;
     130             :     }
     131             : 
     132             :     // now make ex be 1 past the last computed value
     133           0 :     ex += dx;
     134             : 
     135           0 :     bool doSwap = dx < 0;
     136             : 
     137           0 :     if (doSwap) {
     138           0 :         ex -= dx;
     139           0 :         fx -= dx;
     140           0 :         SkTSwap(fx, ex);
     141           0 :         dx = -dx;
     142             :     }
     143             : 
     144             : 
     145           0 :     fCount0 = chop(fx, 0, ex, dx, count);
     146           0 :     SkASSERT(fCount0 >= 0);
     147           0 :     SkASSERT(fCount0 <= count);
     148           0 :     count -= fCount0;
     149           0 :     fx += fCount0 * dx;
     150           0 :     SkASSERT(fx >= 0);
     151           0 :     SkASSERT(fCount0 == 0 || (fx - dx) < 0);
     152           0 :     fCount1 = chop(fx, kFracMax_SkGradFixed, ex, dx, count);
     153           0 :     SkASSERT(fCount1 >= 0);
     154           0 :     SkASSERT(fCount1 <= count);
     155           0 :     count -= fCount1;
     156           0 :     fCount2 = count;
     157             : 
     158             : #ifdef SK_DEBUG
     159           0 :     fx += fCount1 * dx;
     160           0 :     SkASSERT(fx <= ex);
     161           0 :     if (fCount2 > 0) {
     162           0 :         SkASSERT(fx >= kFracMax_SkGradFixed);
     163           0 :         if (fCount1 > 0) {
     164           0 :             SkASSERT(fx - dx < kFracMax_SkGradFixed);
     165             :         }
     166             :     }
     167             : #endif
     168             : 
     169           0 :     if (doSwap) {
     170           0 :         SkTSwap(fCount0, fCount2);
     171           0 :         SkTSwap(fV0, fV1);
     172           0 :         dx = -dx;
     173             :     }
     174             : 
     175           0 :     if (fCount1 > 0) {
     176           0 :         fFx1 = fx0 + fCount0 * dx;
     177             :     }
     178             : }

Generated by: LCOV version 1.13