LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkBitmapProcState.h (source / functions) Hit Total Coverage
Test: output.info Lines: 30 35 85.7 %
Date: 2017-07-14 16:53:18 Functions: 11 13 84.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2007 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             : #ifndef SkBitmapProcState_DEFINED
       9             : #define SkBitmapProcState_DEFINED
      10             : 
      11             : #include "SkBitmap.h"
      12             : #include "SkBitmapController.h"
      13             : #include "SkBitmapFilter.h"
      14             : #include "SkBitmapProvider.h"
      15             : #include "SkFloatBits.h"
      16             : #include "SkMatrix.h"
      17             : #include "SkMipMap.h"
      18             : #include "SkPaint.h"
      19             : #include "SkShader.h"
      20             : #include "SkTemplates.h"
      21             : 
      22             : typedef SkFixed3232    SkFractionalInt;
      23             : #define SkScalarToFractionalInt(x)  SkScalarToFixed3232(x)
      24             : #define SkFractionalIntToFixed(x)   SkFixed3232ToFixed(x)
      25             : #define SkFixedToFractionalInt(x)   SkFixedToFixed3232(x)
      26             : #define SkFractionalIntToInt(x)     SkFixed3232ToInt(x)
      27             : 
      28             : class SkPaint;
      29             : 
      30             : struct SkBitmapProcInfo {
      31             :     SkBitmapProcInfo(const SkBitmapProvider&, SkShader::TileMode tmx, SkShader::TileMode tmy);
      32             :     ~SkBitmapProcInfo();
      33             : 
      34             :     const SkBitmapProvider        fProvider;
      35             : 
      36             :     SkPixmap                      fPixmap;
      37             :     SkMatrix                      fInvMatrix;         // This changes based on tile mode.
      38             :     // TODO: combine fInvMatrix and fRealInvMatrix.
      39             :     SkMatrix                      fRealInvMatrix;     // The actual inverse matrix.
      40             :     SkColor                       fPaintColor;
      41             :     SkShader::TileMode            fTileModeX;
      42             :     SkShader::TileMode            fTileModeY;
      43             :     SkFilterQuality               fFilterQuality;
      44             :     SkMatrix::TypeMask            fInvType;
      45             : 
      46             :     bool init(const SkMatrix& inverse, const SkPaint&);
      47             : 
      48             : private:
      49             :     enum {
      50             :         kBMStateSize = 136  // found by inspection. if too small, we will call new/delete
      51             :     };
      52             :     SkAlignedSStorage<kBMStateSize> fBMStateStorage;
      53             :     SkBitmapController::State* fBMState;
      54             : };
      55             : 
      56         141 : struct SkBitmapProcState : public SkBitmapProcInfo {
      57         141 :     SkBitmapProcState(const SkBitmapProvider& prov, SkShader::TileMode tmx, SkShader::TileMode tmy)
      58         141 :         : SkBitmapProcInfo(prov, tmx, tmy) {}
      59             : 
      60         141 :     bool setup(const SkMatrix& inv, const SkPaint& paint) {
      61         141 :         return this->init(inv, paint) && this->chooseProcs();
      62             :     }
      63             : 
      64             :     typedef void (*ShaderProc32)(const void* ctx, int x, int y, SkPMColor[], int count);
      65             : 
      66             :     typedef void (*ShaderProc16)(const void* ctx, int x, int y, uint16_t[], int count);
      67             : 
      68             :     typedef void (*MatrixProc)(const SkBitmapProcState&,
      69             :                                uint32_t bitmapXY[],
      70             :                                int count,
      71             :                                int x, int y);
      72             : 
      73             :     typedef void (*SampleProc32)(const SkBitmapProcState&,
      74             :                                  const uint32_t[],
      75             :                                  int count,
      76             :                                  SkPMColor colors[]);
      77             : 
      78             :     typedef U16CPU (*FixedTileProc)(SkFixed);   // returns 0..0xFFFF
      79             :     typedef U16CPU (*IntTileProc)(int value, int count);   // returns 0..count-1
      80             : 
      81             :     SkMatrix::MapXYProc fInvProc;           // chooseProcs
      82             :     SkFractionalInt     fInvSxFractionalInt;
      83             :     SkFractionalInt     fInvKyFractionalInt;
      84             : 
      85             :     FixedTileProc       fTileProcX;         // chooseProcs
      86             :     FixedTileProc       fTileProcY;         // chooseProcs
      87             :     IntTileProc         fIntTileProcY;      // chooseProcs
      88             :     SkFixed             fFilterOneX;
      89             :     SkFixed             fFilterOneY;
      90             : 
      91             :     SkFixed             fInvSx;             // chooseProcs
      92             :     SkFixed             fInvKy;             // chooseProcs
      93             :     SkPMColor           fPaintPMColor;      // chooseProcs - A8 config
      94             :     uint16_t            fAlphaScale;        // chooseProcs
      95             : 
      96             :     /** Platforms implement this, and can optionally overwrite only the
      97             :         following fields:
      98             : 
      99             :         fShaderProc32
     100             :         fShaderProc16
     101             :         fMatrixProc
     102             :         fSampleProc32
     103             :         fSampleProc32
     104             : 
     105             :         They will already have valid function pointers, so a platform that does
     106             :         not have an accelerated version can just leave that field as is. A valid
     107             :         implementation can do nothing (see SkBitmapProcState_opts_none.cpp)
     108             :      */
     109             :     void platformProcs();
     110             : 
     111             :     /** Given the byte size of the index buffer to be passed to the matrix proc,
     112             :         return the maximum number of resulting pixels that can be computed
     113             :         (i.e. the number of SkPMColor values to be written by the sample proc).
     114             :         This routine takes into account that filtering and scale-vs-affine
     115             :         affect the amount of buffer space needed.
     116             : 
     117             :         Only valid to call after chooseProcs (setContext) has been called. It is
     118             :         safe to call this inside the shader's shadeSpan() method.
     119             :      */
     120             :     int maxCountForBufferSize(size_t bufferSize) const;
     121             : 
     122             :     // If a shader proc is present, then the corresponding matrix/sample procs
     123             :     // are ignored
     124        7820 :     ShaderProc32 getShaderProc32() const { return fShaderProc32; }
     125             :     ShaderProc16 getShaderProc16() const { return fShaderProc16; }
     126             : 
     127             : #ifdef SK_DEBUG
     128             :     MatrixProc getMatrixProc() const;
     129             : #else
     130             :     MatrixProc getMatrixProc() const { return fMatrixProc; }
     131             : #endif
     132        1854 :     SampleProc32 getSampleProc32() const { return fSampleProc32; }
     133             : 
     134             : private:
     135             :     ShaderProc32        fShaderProc32;      // chooseProcs
     136             :     ShaderProc16        fShaderProc16;      // chooseProcs
     137             :     // These are used if the shaderproc is nullptr
     138             :     MatrixProc          fMatrixProc;        // chooseProcs
     139             :     SampleProc32        fSampleProc32;      // chooseProcs
     140             : 
     141             :     MatrixProc chooseMatrixProc(bool trivial_matrix);
     142             :     bool chooseProcs(); // caller must have called init() first (on our base-class)
     143             :     bool chooseScanlineProcs(bool trivialMatrix, bool clampClamp);
     144             :     ShaderProc32 chooseShaderProc32();
     145             : 
     146             :     // Return false if we failed to setup for fast translate (e.g. overflow)
     147             :     bool setupForTranslate();
     148             : 
     149             : #ifdef SK_DEBUG
     150             :     static void DebugMatrixProc(const SkBitmapProcState&,
     151             :                                 uint32_t[], int count, int x, int y);
     152             : #endif
     153             : };
     154             : 
     155             : /*  Macros for packing and unpacking pairs of 16bit values in a 32bit uint.
     156             :     Used to allow access to a stream of uint16_t either one at a time, or
     157             :     2 at a time by unpacking a uint32_t
     158             :  */
     159             : #ifdef SK_CPU_BENDIAN
     160             :     #define PACK_TWO_SHORTS(pri, sec) ((pri) << 16 | (sec))
     161             :     #define UNPACK_PRIMARY_SHORT(packed)    ((uint32_t)(packed) >> 16)
     162             :     #define UNPACK_SECONDARY_SHORT(packed)  ((packed) & 0xFFFF)
     163             : #else
     164             :     #define PACK_TWO_SHORTS(pri, sec) ((pri) | ((sec) << 16))
     165             :     #define UNPACK_PRIMARY_SHORT(packed)    ((packed) & 0xFFFF)
     166             :     #define UNPACK_SECONDARY_SHORT(packed)  ((uint32_t)(packed) >> 16)
     167             : #endif
     168             : 
     169             : #ifdef SK_DEBUG
     170           0 :     static inline uint32_t pack_two_shorts(U16CPU pri, U16CPU sec) {
     171           0 :         SkASSERT((uint16_t)pri == pri);
     172           0 :         SkASSERT((uint16_t)sec == sec);
     173           0 :         return PACK_TWO_SHORTS(pri, sec);
     174             :     }
     175             : #else
     176             :     #define pack_two_shorts(pri, sec)   PACK_TWO_SHORTS(pri, sec)
     177             : #endif
     178             : 
     179             : // These functions are generated via macros, but are exposed here so that
     180             : // platformProcs may test for them by name.
     181             : void S32_opaque_D32_filter_DX(const SkBitmapProcState& s, const uint32_t xy[],
     182             :                               int count, SkPMColor colors[]);
     183             : void S32_alpha_D32_filter_DX(const SkBitmapProcState& s, const uint32_t xy[],
     184             :                              int count, SkPMColor colors[]);
     185             : void S32_opaque_D32_filter_DXDY(const SkBitmapProcState& s,
     186             :                                 const uint32_t xy[], int count, SkPMColor colors[]);
     187             : void S32_alpha_D32_filter_DXDY(const SkBitmapProcState& s,
     188             :                                const uint32_t xy[], int count, SkPMColor colors[]);
     189             : void ClampX_ClampY_filter_scale(const SkBitmapProcState& s, uint32_t xy[],
     190             :                                 int count, int x, int y);
     191             : void ClampX_ClampY_nofilter_scale(const SkBitmapProcState& s, uint32_t xy[],
     192             :                                   int count, int x, int y);
     193             : void ClampX_ClampY_filter_affine(const SkBitmapProcState& s,
     194             :                                  uint32_t xy[], int count, int x, int y);
     195             : void ClampX_ClampY_nofilter_affine(const SkBitmapProcState& s,
     196             :                                    uint32_t xy[], int count, int x, int y);
     197             : 
     198             : // Helper class for mapping the middle of pixel (x, y) into SkFractionalInt bitmap space.
     199             : // Discussion:
     200             : // Overall, this code takes a point in destination space, and uses the center of the pixel
     201             : // at (x, y) to determine the sample point in source space. It then adjusts the pixel by different
     202             : // amounts based in filtering and tiling.
     203             : // This code can be broken into two main cases based on filtering:
     204             : // * no filtering (nearest neighbor) - when using nearest neighbor filtering all tile modes reduce
     205             : // the sampled by one ulp. If a simple point pt lies precisely on XXX.1/2 then it forced down
     206             : // when positive making 1/2 + 1/2 = .999999 instead of 1.0.
     207             : // * filtering - in the filtering case, the code calculates the -1/2 shift for starting the
     208             : // bilerp kernel. There is a twist; there is a big difference between clamp and the other tile
     209             : // modes. In tile and repeat the matrix has been reduced by an additional 1/width and 1/height
     210             : // factor. This maps from destination space to [0, 1) (instead of source space) to allow easy
     211             : // modulo arithmetic. This means that the -1/2 needed by bilerp is actually 1/2 * 1/width for x
     212             : // and 1/2 * 1/height for y. This is what happens when the poorly named fFilterOne{X|Y} is
     213             : // divided by two.
     214             : class SkBitmapProcStateAutoMapper {
     215             : public:
     216        2925 :     SkBitmapProcStateAutoMapper(const SkBitmapProcState& s, int x, int y,
     217        2925 :                                 SkPoint* scalarPoint = nullptr) {
     218             :         SkPoint pt;
     219        8775 :         s.fInvProc(s.fInvMatrix,
     220        2925 :                    SkIntToScalar(x) + SK_ScalarHalf,
     221        5850 :                    SkIntToScalar(y) + SK_ScalarHalf, &pt);
     222             : 
     223             :         SkFixed biasX, biasY;
     224        2925 :         if (s.fFilterQuality == kNone_SkFilterQuality) {
     225             :             // SkFixed epsilon bias to ensure inverse-mapped bitmap coordinates are rounded
     226             :             // consistently WRT geometry.  Note that we only need the bias for positive scales:
     227             :             // for negative scales, the rounding is intrinsically correct.
     228             :             // We scale it to persist SkFractionalInt -> SkFixed conversions.
     229        1579 :             biasX = (s.fInvMatrix.getScaleX() > 0);
     230        1579 :             biasY = (s.fInvMatrix.getScaleY() > 0);
     231             :         } else {
     232        1346 :             biasX = s.fFilterOneX >> 1;
     233        1346 :             biasY = s.fFilterOneY >> 1;
     234             :         }
     235             : 
     236             :         // punt to unsigned for defined underflow behavior
     237        5850 :         fX = (SkFractionalInt)((uint64_t)SkScalarToFractionalInt(pt.x()) -
     238        2925 :                                (uint64_t)SkFixedToFractionalInt(biasX));
     239        5850 :         fY = (SkFractionalInt)((uint64_t)SkScalarToFractionalInt(pt.y()) -
     240        2925 :                                (uint64_t)SkFixedToFractionalInt(biasY));
     241             : 
     242        2925 :         if (scalarPoint) {
     243          83 :             scalarPoint->set(pt.x() - SkFixedToScalar(biasX),
     244         166 :                              pt.y() - SkFixedToScalar(biasY));
     245             :         }
     246        2925 :     }
     247             : 
     248         620 :     SkFractionalInt fractionalIntX() const { return fX; }
     249           0 :     SkFractionalInt fractionalIntY() const { return fY; }
     250             : 
     251         726 :     SkFixed fixedX() const { return SkFractionalIntToFixed(fX); }
     252        1346 :     SkFixed fixedY() const { return SkFractionalIntToFixed(fY); }
     253             : 
     254        1187 :     int intX() const { return SkFractionalIntToInt(fX); }
     255        1579 :     int intY() const { return SkFractionalIntToInt(fY); }
     256             : 
     257             : private:
     258             :     SkFractionalInt fX, fY;
     259             : };
     260             : 
     261             : #endif

Generated by: LCOV version 1.13