LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/sksl - SkSLMemoryLayout.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 45 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 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 SKIASL_MEMORYLAYOUT
       9             : #define SKIASL_MEMORYLAYOUT
      10             : 
      11             : #include "ir/SkSLType.h"
      12             : 
      13             : namespace SkSL {
      14             : 
      15             : class MemoryLayout {
      16             : public:
      17             :     enum Standard {
      18             :         k140_Standard,
      19             :         k430_Standard
      20             :     };
      21             : 
      22           0 :     MemoryLayout(Standard std)
      23           0 :     : fStd(std) {}
      24             : 
      25           0 :     static size_t vector_alignment(size_t componentSize, int columns) {
      26           0 :         return componentSize * (columns + columns % 2);
      27             :     }
      28             : 
      29             :     /**
      30             :      * Rounds up to the nearest multiple of 16 if in std140, otherwise returns the parameter
      31             :      * unchanged (std140 requires various things to be rounded up to the nearest multiple of 16,
      32             :      * std430 does not).
      33             :      */
      34           0 :     size_t roundUpIfNeeded(size_t raw) const {
      35           0 :         switch (fStd) {
      36           0 :             case k140_Standard: return (raw + 15) & ~15;
      37           0 :             case k430_Standard: return raw;
      38             :         }
      39           0 :         ABORT("unreachable");
      40             :     }
      41             : 
      42             :     /**
      43             :      * Returns a type's required alignment when used as a standalone variable.
      44             :      */
      45           0 :     size_t alignment(const Type& type) const {
      46             :         // See OpenGL Spec 7.6.2.2 Standard Uniform Block Layout
      47           0 :         switch (type.kind()) {
      48             :             case Type::kScalar_Kind:
      49           0 :                 return this->size(type);
      50             :             case Type::kVector_Kind:
      51           0 :                 return vector_alignment(this->size(type.componentType()), type.columns());
      52             :             case Type::kMatrix_Kind:
      53           0 :                 return this->roundUpIfNeeded(vector_alignment(this->size(type.componentType()),
      54           0 :                                                               type.rows()));
      55             :             case Type::kArray_Kind:
      56           0 :                 return this->roundUpIfNeeded(this->alignment(type.componentType()));
      57             :             case Type::kStruct_Kind: {
      58           0 :                 size_t result = 0;
      59           0 :                 for (const auto& f : type.fields()) {
      60           0 :                     size_t alignment = this->alignment(*f.fType);
      61           0 :                     if (alignment > result) {
      62           0 :                         result = alignment;
      63             :                     }
      64             :                 }
      65           0 :                 return this->roundUpIfNeeded(result);
      66             :             }
      67             :             default:
      68           0 :                 ABORT("cannot determine size of type %s", type.name().c_str());
      69             :         }
      70             :     }
      71             : 
      72             :     /**
      73             :      * For matrices and arrays, returns the number of bytes from the start of one entry (row, in
      74             :      * the case of matrices) to the start of the next.
      75             :      */
      76           0 :     size_t stride(const Type& type) const {
      77           0 :         switch (type.kind()) {
      78             :             case Type::kMatrix_Kind: // fall through
      79             :             case Type::kArray_Kind:
      80           0 :                 return this->alignment(type);
      81             :             default:
      82           0 :                 ABORT("type does not have a stride");
      83             :         }
      84             :     }
      85             : 
      86             :     /**
      87             :      * Returns the size of a type in bytes.
      88             :      */
      89           0 :     size_t size(const Type& type) const {
      90           0 :         switch (type.kind()) {
      91             :             case Type::kScalar_Kind:
      92           0 :                 if (type.name() == "bool") {
      93           0 :                     return 1;
      94             :                 }
      95             :                 // FIXME need to take precision into account, once we figure out how we want to
      96             :                 // handle it...
      97           0 :                 return 4;
      98             :             case Type::kVector_Kind:
      99           0 :                 return type.columns() * this->size(type.componentType());
     100             :             case Type::kMatrix_Kind: // fall through
     101             :             case Type::kArray_Kind:
     102           0 :                 return type.columns() * this->stride(type);
     103             :             case Type::kStruct_Kind: {
     104           0 :                 size_t total = 0;
     105           0 :                 for (const auto& f : type.fields()) {
     106           0 :                     size_t alignment = this->alignment(*f.fType);
     107           0 :                     if (total % alignment != 0) {
     108           0 :                         total += alignment - total % alignment;
     109             :                     }
     110           0 :                     ASSERT(total % alignment == 0);
     111           0 :                     total += this->size(*f.fType);
     112             :                 }
     113           0 :                 size_t alignment = this->alignment(type);
     114           0 :                 ASSERT(!type.fields().size() ||
     115             :                        (0 == alignment % this->alignment(*type.fields()[0].fType)));
     116           0 :                 return (total + alignment - 1) & ~(alignment - 1);
     117             :             }
     118             :             default:
     119           0 :                 ABORT("cannot determine size of type %s", type.name().c_str());
     120             :         }
     121             :     }
     122             : 
     123             :     const Standard fStd;
     124             : };
     125             : 
     126             : } // namespace
     127             : 
     128             : #endif

Generated by: LCOV version 1.13