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

          Line data    Source code
       1             : /*
       2             :  * Copyright 2016 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             : #ifndef Sk4fGradientPriv_DEFINED
       9             : #define Sk4fGradientPriv_DEFINED
      10             : 
      11             : #include "SkColor.h"
      12             : #include "SkHalf.h"
      13             : #include "SkImageInfo.h"
      14             : #include "SkNx.h"
      15             : #include "SkPM4f.h"
      16             : #include "SkPM4fPriv.h"
      17             : #include "SkUtils.h"
      18             : 
      19             : // Templates shared by various 4f gradient flavors.
      20             : 
      21             : namespace {
      22             : 
      23             : enum class ApplyPremul { True, False };
      24             : 
      25             : enum class DstType {
      26             :     L32,  // Linear 32bit.  Used for both shader/blitter paths.
      27             :     S32,  // SRGB 32bit.  Used for the blitter path only.
      28             :     F16,  // Linear half-float.  Used for blitters only.
      29             :     F32,  // Linear float.  Used for shaders only.
      30             : };
      31             : 
      32             : template <ApplyPremul>
      33             : struct PremulTraits;
      34             : 
      35             : template <>
      36             : struct PremulTraits<ApplyPremul::False> {
      37           0 :     static Sk4f apply(const Sk4f& c) { return c; }
      38             : };
      39             : 
      40             : template <>
      41             : struct PremulTraits<ApplyPremul::True> {
      42           0 :     static Sk4f apply(const Sk4f& c) {
      43           0 :         const float alpha = c[SkPM4f::A];
      44             :         // FIXME: portable swizzle?
      45           0 :         return c * Sk4f(alpha, alpha, alpha, 1);
      46             :     }
      47             : };
      48             : 
      49             : // Struct encapsulating various dest-dependent ops:
      50             : //
      51             : //   - load()       Load a SkPM4f value into Sk4f.  Normally called once per interval
      52             : //                  advance.  Also applies a scale and swizzle suitable for DstType.
      53             : //
      54             : //   - store()      Store one Sk4f to dest.  Optionally handles premul, color space
      55             : //                  conversion, etc.
      56             : //
      57             : //   - store(count) Store the Sk4f value repeatedly to dest, count times.
      58             : //
      59             : //   - store4x()    Store 4 Sk4f values to dest (opportunistic optimization).
      60             : //
      61             : template <DstType, ApplyPremul premul>
      62             : struct DstTraits;
      63             : 
      64             : template <ApplyPremul premul>
      65             : struct DstTraits<DstType::L32, premul> {
      66             :     using PM   = PremulTraits<premul>;
      67             :     using Type = SkPMColor;
      68             : 
      69             :     // For L32, prescaling by 255 saves a per-pixel multiplication when premul is not needed.
      70           0 :     static Sk4f load(const SkPM4f& c) {
      71             :         return premul == ApplyPremul::False
      72           0 :             ? c.to4f_pmorder() * Sk4f(255)
      73           0 :             : c.to4f_pmorder();
      74             :     }
      75             : 
      76           0 :     static void store(const Sk4f& c, Type* dst) {
      77             :         if (premul == ApplyPremul::False) {
      78             :             // c is prescaled by 255, just store.
      79           0 :             SkNx_cast<uint8_t>(c).store(dst);
      80             :         } else {
      81           0 :             *dst = Sk4f_toL32(PM::apply(c));
      82             :         }
      83           0 :     }
      84             : 
      85           0 :     static void store(const Sk4f& c, Type* dst, int n) {
      86             :         Type pmc;
      87           0 :         store(c, &pmc);
      88           0 :         sk_memset32(dst, pmc, n);
      89           0 :     }
      90             : 
      91           0 :     static void store4x(const Sk4f& c0, const Sk4f& c1,
      92             :                         const Sk4f& c2, const Sk4f& c3,
      93             :                         Type* dst) {
      94             :         if (premul == ApplyPremul::False) {
      95             :             Sk4f_ToBytes((uint8_t*)dst, c0, c1, c2, c3);
      96             :         } else {
      97           0 :             store(c0, dst + 0);
      98           0 :             store(c1, dst + 1);
      99           0 :             store(c2, dst + 2);
     100           0 :             store(c3, dst + 3);
     101             :         }
     102           0 :     }
     103             : };
     104             : 
     105             : template <ApplyPremul premul>
     106             : struct DstTraits<DstType::S32, premul> {
     107             :     using PM   = PremulTraits<premul>;
     108             :     using Type = SkPMColor;
     109             : 
     110           0 :     static Sk4f load(const SkPM4f& c) {
     111           0 :         return c.to4f_pmorder();
     112             :     }
     113             : 
     114           0 :     static void store(const Sk4f& c, Type* dst) {
     115             :         // FIXME: this assumes opaque colors.  Handle unpremultiplication.
     116           0 :         *dst = Sk4f_toS32(PM::apply(c));
     117           0 :     }
     118             : 
     119           0 :     static void store(const Sk4f& c, Type* dst, int n) {
     120           0 :         sk_memset32(dst, Sk4f_toS32(PM::apply(c)), n);
     121           0 :     }
     122             : 
     123           0 :     static void store4x(const Sk4f& c0, const Sk4f& c1,
     124             :                         const Sk4f& c2, const Sk4f& c3,
     125             :                         Type* dst) {
     126           0 :         store(c0, dst + 0);
     127           0 :         store(c1, dst + 1);
     128           0 :         store(c2, dst + 2);
     129           0 :         store(c3, dst + 3);
     130           0 :     }
     131             : };
     132             : 
     133             : template <ApplyPremul premul>
     134             : struct DstTraits<DstType::F16, premul> {
     135             :     using PM   = PremulTraits<premul>;
     136             :     using Type = uint64_t;
     137             : 
     138           0 :     static Sk4f load(const SkPM4f& c) {
     139           0 :         return c.to4f();
     140             :     }
     141             : 
     142           0 :     static void store(const Sk4f& c, Type* dst) {
     143           0 :         SkFloatToHalf_finite_ftz(PM::apply(c)).store(dst);
     144           0 :     }
     145             : 
     146           0 :     static void store(const Sk4f& c, Type* dst, int n) {
     147             :         uint64_t color;
     148           0 :         SkFloatToHalf_finite_ftz(PM::apply(c)).store(&color);
     149           0 :         sk_memset64(dst, color, n);
     150           0 :     }
     151             : 
     152           0 :     static void store4x(const Sk4f& c0, const Sk4f& c1,
     153             :                         const Sk4f& c2, const Sk4f& c3,
     154             :                         Type* dst) {
     155           0 :         store(c0, dst + 0);
     156           0 :         store(c1, dst + 1);
     157           0 :         store(c2, dst + 2);
     158           0 :         store(c3, dst + 3);
     159           0 :     }
     160             : };
     161             : 
     162             : template <ApplyPremul premul>
     163             : struct DstTraits<DstType::F32, premul> {
     164             :     using PM   = PremulTraits<premul>;
     165             :     using Type = SkPM4f;
     166             : 
     167           0 :     static Sk4f load(const SkPM4f& c) {
     168           0 :         return c.to4f();
     169             :     }
     170             : 
     171           0 :     static void store(const Sk4f& c, Type* dst) {
     172           0 :         PM::apply(c).store(dst->fVec);
     173           0 :     }
     174             : 
     175           0 :     static void store(const Sk4f& c, Type* dst, int n) {
     176           0 :         const Sk4f pmc = PM::apply(c);
     177           0 :         for (int i = 0; i < n; ++i) {
     178           0 :             pmc.store(dst[i].fVec);
     179             :         }
     180           0 :     }
     181             : 
     182           0 :     static void store4x(const Sk4f& c0, const Sk4f& c1,
     183             :                         const Sk4f& c2, const Sk4f& c3,
     184             :                         Type* dst) {
     185           0 :         store(c0, dst + 0);
     186           0 :         store(c1, dst + 1);
     187           0 :         store(c2, dst + 2);
     188           0 :         store(c3, dst + 3);
     189           0 :     }
     190             : };
     191             : 
     192             : } // anonymous namespace
     193             : 
     194             : #endif // Sk4fGradientPriv_DEFINED

Generated by: LCOV version 1.13