LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkAntiRun.h (source / functions) Hit Total Coverage
Test: output.info Lines: 75 88 85.2 %
Date: 2017-07-14 16:53:18 Functions: 3 4 75.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             : #ifndef SkAntiRun_DEFINED
      10             : #define SkAntiRun_DEFINED
      11             : 
      12             : #include "SkBlitter.h"
      13             : 
      14             : /** Sparse array of run-length-encoded alpha (supersampling coverage) values.
      15             :     Sparseness allows us to independently compose several paths into the
      16             :     same SkAlphaRuns buffer.
      17             : */
      18             : 
      19             : class SkAlphaRuns {
      20             : public:
      21             :     int16_t*    fRuns;
      22             :     uint8_t*     fAlpha;
      23             : 
      24             :     // Return 0-255 given 0-256
      25       10271 :     static inline SkAlpha CatchOverflow(int alpha) {
      26       10271 :         SkASSERT(alpha >= 0 && alpha <= 256);
      27       10271 :         return alpha - (alpha >> 8);
      28             :     }
      29             : 
      30             :     /// Returns true if the scanline contains only a single run,
      31             :     /// of alpha value 0.
      32        2232 :     bool empty() const {
      33        2232 :         SkASSERT(fRuns[0] > 0);
      34        2232 :         return fAlpha[0] == 0 && fRuns[fRuns[0]] == 0;
      35             :     }
      36             : 
      37             :     /// Reinitialize for a new scanline.
      38             :     void    reset(int width);
      39             : 
      40             :     /**
      41             :      *  Insert into the buffer a run starting at (x-offsetX):
      42             :      *      if startAlpha > 0
      43             :      *          one pixel with value += startAlpha,
      44             :      *              max 255
      45             :      *      if middleCount > 0
      46             :      *          middleCount pixels with value += maxValue
      47             :      *      if stopAlpha > 0
      48             :      *          one pixel with value += stopAlpha
      49             :      *  Returns the offsetX value that should be passed on the next call,
      50             :      *  assuming we're on the same scanline. If the caller is switching
      51             :      *  scanlines, then offsetX should be 0 when this is called.
      52             :      */
      53             :     SK_ALWAYS_INLINE int add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
      54             :                              U8CPU maxValue, int offsetX) {
      55        8542 :         SkASSERT(middleCount >= 0);
      56        8542 :         SkASSERT(x >= 0 && x + (startAlpha != 0) + middleCount + (stopAlpha != 0) <= fWidth);
      57             : 
      58        8542 :         SkASSERT(fRuns[offsetX] >= 0);
      59             : 
      60        8542 :         int16_t*    runs = fRuns + offsetX;
      61        8542 :         uint8_t*    alpha = fAlpha + offsetX;
      62        8542 :         uint8_t*    lastAlpha = alpha;
      63        8542 :         x -= offsetX;
      64             : 
      65        8542 :         if (startAlpha) {
      66        2025 :             SkAlphaRuns::Break(runs, alpha, x, 1);
      67             :             /*  I should be able to just add alpha[x] + startAlpha.
      68             :                 However, if the trailing edge of the previous span and the leading
      69             :                 edge of the current span round to the same super-sampled x value,
      70             :                 I might overflow to 256 with this add, hence the funny subtract (crud).
      71             :             */
      72        2025 :             unsigned tmp = alpha[x] + startAlpha;
      73        2025 :             SkASSERT(tmp <= 256);
      74        2025 :             alpha[x] = SkToU8(tmp - (tmp >> 8));    // was (tmp >> 7), but that seems wrong if we're trying to catch 256
      75             : 
      76        2025 :             runs += x + 1;
      77        2025 :             alpha += x + 1;
      78        2025 :             x = 0;
      79        2025 :             SkDEBUGCODE(this->validate();)
      80             :         }
      81             : 
      82        8542 :         if (middleCount) {
      83        8523 :             SkAlphaRuns::Break(runs, alpha, x, middleCount);
      84        8523 :             alpha += x;
      85        8523 :             runs += x;
      86        8523 :             x = 0;
      87             :             do {
      88        9929 :                 alpha[0] = SkToU8(CatchOverflow(alpha[0] + maxValue));
      89        9929 :                 int n = runs[0];
      90        9929 :                 SkASSERT(n <= middleCount);
      91        9929 :                 alpha += n;
      92        9929 :                 runs += n;
      93        9929 :                 middleCount -= n;
      94        9929 :             } while (middleCount > 0);
      95        8523 :             SkDEBUGCODE(this->validate();)
      96        8523 :             lastAlpha = alpha;
      97             :         }
      98             : 
      99        8542 :         if (stopAlpha) {
     100        2052 :             SkAlphaRuns::Break(runs, alpha, x, 1);
     101        2052 :             alpha += x;
     102        2052 :             alpha[0] = SkToU8(alpha[0] + stopAlpha);
     103        2052 :             SkDEBUGCODE(this->validate();)
     104        2052 :             lastAlpha = alpha;
     105             :         }
     106             : 
     107        8542 :         return SkToS32(lastAlpha - fAlpha);  // new offsetX
     108             :     }
     109             : 
     110             :     SkDEBUGCODE(void assertValid(int y, int maxStep) const;)
     111             :     SkDEBUGCODE(void dump() const;)
     112             : 
     113             :     /**
     114             :      * Break the runs in the buffer at offsets x and x+count, properly
     115             :      * updating the runs to the right and left.
     116             :      *   i.e. from the state AAAABBBB, run-length encoded as A4B4,
     117             :      *   Break(..., 2, 5) would produce AAAABBBB rle as A2A2B3B1.
     118             :      * Allows add() to sum another run to some of the new sub-runs.
     119             :      *   i.e. adding ..CCCCC. would produce AADDEEEB, rle as A2D2E3B1.
     120             :      */
     121       12600 :     static void Break(int16_t runs[], uint8_t alpha[], int x, int count) {
     122       12600 :         SkASSERT(count > 0 && x >= 0);
     123             : 
     124             :         //  SkAlphaRuns::BreakAt(runs, alpha, x);
     125             :         //  SkAlphaRuns::BreakAt(&runs[x], &alpha[x], count);
     126             : 
     127       12600 :         int16_t* next_runs = runs + x;
     128       12600 :         uint8_t*  next_alpha = alpha + x;
     129             : 
     130       19482 :         while (x > 0) {
     131        5597 :             int n = runs[0];
     132        5597 :             SkASSERT(n > 0);
     133             : 
     134        5597 :             if (x < n) {
     135        2156 :                 alpha[x] = alpha[0];
     136        2156 :                 runs[0] = SkToS16(x);
     137        2156 :                 runs[x] = SkToS16(n - x);
     138        2156 :                 break;
     139             :             }
     140        3441 :             runs += n;
     141        3441 :             alpha += n;
     142        3441 :             x -= n;
     143             :         }
     144             : 
     145       12600 :         runs = next_runs;
     146       12600 :         alpha = next_alpha;
     147       12600 :         x = count;
     148             : 
     149             :         for (;;) {
     150       14006 :             int n = runs[0];
     151       14006 :             SkASSERT(n > 0);
     152             : 
     153       14006 :             if (x < n) {
     154        4888 :                 alpha[x] = alpha[0];
     155        4888 :                 runs[0] = SkToS16(x);
     156        4888 :                 runs[x] = SkToS16(n - x);
     157        4888 :                 break;
     158             :             }
     159        9118 :             x -= n;
     160        9118 :             if (x <= 0) {
     161        7712 :                 break;
     162             :             }
     163        1406 :             runs += n;
     164        1406 :             alpha += n;
     165        1406 :         }
     166       12600 :     }
     167             : 
     168             :     /**
     169             :      * Cut (at offset x in the buffer) a run into two shorter runs with
     170             :      * matching alpha values.
     171             :      * Used by the RectClipBlitter to trim a RLE encoding to match the
     172             :      * clipping rectangle.
     173             :      */
     174           0 :     static void BreakAt(int16_t runs[], uint8_t alpha[], int x) {
     175           0 :         while (x > 0) {
     176           0 :             int n = runs[0];
     177           0 :             SkASSERT(n > 0);
     178             : 
     179           0 :             if (x < n) {
     180           0 :                 alpha[x] = alpha[0];
     181           0 :                 runs[0] = SkToS16(x);
     182           0 :                 runs[x] = SkToS16(n - x);
     183           0 :                 break;
     184             :             }
     185           0 :             runs += n;
     186           0 :             alpha += n;
     187           0 :             x -= n;
     188             :         }
     189           0 :     }
     190             : 
     191             : private:
     192             :     SkDEBUGCODE(int fWidth;)
     193             :     SkDEBUGCODE(void validate() const;)
     194             : };
     195             : 
     196             : #endif

Generated by: LCOV version 1.13