LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkDescriptor.h (source / functions) Hit Total Coverage
Test: output.info Lines: 64 75 85.3 %
Date: 2017-07-14 16:53:18 Functions: 16 20 80.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 SkDescriptor_DEFINED
      10             : #define SkDescriptor_DEFINED
      11             : 
      12             : #include "SkOpts.h"
      13             : #include "SkTypes.h"
      14             : #include <memory>
      15             : 
      16             : class SkDescriptor : SkNoncopyable {
      17             : public:
      18          21 :     static size_t ComputeOverhead(int entryCount) {
      19          21 :         SkASSERT(entryCount >= 0);
      20          21 :         return sizeof(SkDescriptor) + entryCount * sizeof(Entry);
      21             :     }
      22             : 
      23           2 :     static std::unique_ptr<SkDescriptor> Alloc(size_t length) {
      24           2 :         SkASSERT(SkAlign4(length) == length);
      25           2 :         return std::unique_ptr<SkDescriptor>(static_cast<SkDescriptor*>(::operator new (length)));
      26             :     }
      27             : 
      28             :     // Ensure the unsized delete is called.
      29         126 :     void operator delete(void* p) { ::operator delete(p); }
      30             : 
      31          63 :     void init() {
      32          63 :         fLength = sizeof(SkDescriptor);
      33          63 :         fCount  = 0;
      34          63 :     }
      35             : 
      36          63 :     uint32_t getLength() const { return fLength; }
      37             : 
      38          63 :     void* addEntry(uint32_t tag, size_t length, const void* data = nullptr) {
      39          63 :         SkASSERT(tag);
      40          63 :         SkASSERT(SkAlign4(length) == length);
      41          63 :         SkASSERT(this->findEntry(tag, nullptr) == nullptr);
      42             : 
      43          63 :         Entry* entry = (Entry*)((char*)this + fLength);
      44          63 :         entry->fTag = tag;
      45          63 :         entry->fLen = SkToU32(length);
      46          63 :         if (data) {
      47          63 :             memcpy(entry + 1, data, length);
      48             :         }
      49             : 
      50          63 :         fCount += 1;
      51          63 :         fLength = SkToU32(fLength + sizeof(Entry) + length);
      52          63 :         return (entry + 1); // return its data
      53             :     }
      54             : 
      55          63 :     void computeChecksum() {
      56          63 :         fChecksum = SkDescriptor::ComputeChecksum(this);
      57          63 :     }
      58             : 
      59             : #ifdef SK_DEBUG
      60             :     void assertChecksum() const {
      61             :         SkASSERT(SkDescriptor::ComputeChecksum(this) == fChecksum);
      62             :     }
      63             : #endif
      64             : 
      65          86 :     const void* findEntry(uint32_t tag, uint32_t* length) const {
      66          86 :         const Entry* entry = (const Entry*)(this + 1);
      67          86 :         int          count = fCount;
      68             : 
      69          86 :         while (--count >= 0) {
      70          23 :             if (entry->fTag == tag) {
      71          23 :                 if (length) {
      72          21 :                     *length = entry->fLen;
      73             :                 }
      74          23 :                 return entry + 1;
      75             :             }
      76           0 :             entry = (const Entry*)((const char*)(entry + 1) + entry->fLen);
      77             :         }
      78          63 :         return nullptr;
      79             :     }
      80             : 
      81           2 :     std::unique_ptr<SkDescriptor> copy() const {
      82           2 :         std::unique_ptr<SkDescriptor> desc = SkDescriptor::Alloc(fLength);
      83           2 :         memcpy(desc.get(), this, fLength);
      84           2 :         return desc;
      85             :     }
      86             : 
      87          19 :     bool operator==(const SkDescriptor& other) const {
      88             :         // probe to see if we have a good checksum algo
      89             : //        SkASSERT(a.fChecksum != b.fChecksum || memcmp(&a, &b, a.fLength) == 0);
      90             : 
      91             :         // the first value we should look at is the checksum, so this loop
      92             :         // should terminate early if they descriptors are different.
      93             :         // NOTE: if we wrote a sentinel value at the end of each, we chould
      94             :         //       remove the aa < stop test in the loop...
      95          19 :         const uint32_t* aa = (const uint32_t*)this;
      96          19 :         const uint32_t* bb = (const uint32_t*)&other;
      97          19 :         const uint32_t* stop = (const uint32_t*)((const char*)aa + fLength);
      98         323 :         do {
      99         342 :             if (*aa++ != *bb++)
     100           0 :                 return false;
     101         342 :         } while (aa < stop);
     102          19 :         return true;
     103             :     }
     104           0 :     bool operator!=(const SkDescriptor& other) const { return !(*this == other); }
     105             : 
     106           0 :     uint32_t getChecksum() const { return fChecksum; }
     107             : 
     108             :     struct Entry {
     109             :         uint32_t fTag;
     110             :         uint32_t fLen;
     111             :     };
     112             : 
     113             : #ifdef SK_DEBUG
     114             :     uint32_t getCount() const { return fCount; }
     115             : #endif
     116             : 
     117             : private:
     118             :     uint32_t fChecksum;  // must be first
     119             :     uint32_t fLength;    // must be second
     120             :     uint32_t fCount;
     121             : 
     122          63 :     static uint32_t ComputeChecksum(const SkDescriptor* desc) {
     123          63 :         const uint32_t* ptr = (const uint32_t*)desc + 1; // skip the checksum field
     124          63 :         size_t len = desc->fLength - sizeof(uint32_t);
     125          63 :         return SkOpts::hash(ptr, len);
     126             :     }
     127             : 
     128             :     // private so no one can create one except our factories
     129             :     SkDescriptor() {}
     130             : };
     131             : 
     132             : #include "SkScalerContext.h"
     133             : 
     134             : class SkAutoDescriptor : SkNoncopyable {
     135             : public:
     136           0 :     SkAutoDescriptor() : fDesc(nullptr) {}
     137          63 :     SkAutoDescriptor(size_t size) : fDesc(nullptr) { this->reset(size); }
     138           0 :     SkAutoDescriptor(const SkDescriptor& desc) : fDesc(nullptr) {
     139           0 :         size_t size = desc.getLength();
     140           0 :         this->reset(size);
     141           0 :         memcpy(fDesc, &desc, size);
     142           0 :     }
     143             : 
     144          63 :     ~SkAutoDescriptor() { this->free(); }
     145             : 
     146          63 :     void reset(size_t size) {
     147          63 :         this->free();
     148          63 :         if (size <= sizeof(fStorage)) {
     149          63 :             fDesc = (SkDescriptor*)(void*)fStorage;
     150             :         } else {
     151           0 :             fDesc = SkDescriptor::Alloc(size).release();
     152             :         }
     153          63 :     }
     154             : 
     155          63 :     SkDescriptor* getDesc() const { SkASSERT(fDesc); return fDesc; }
     156             : private:
     157         126 :     void free() {
     158         126 :         if (fDesc != (SkDescriptor*)(void*)fStorage) {
     159          63 :             delete fDesc;
     160             :         }
     161         126 :     }
     162             : 
     163             :     enum {
     164             :         kStorageSize =  sizeof(SkDescriptor)
     165             :                         + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContext::Rec)    // for rec
     166             :                         + sizeof(SkDescriptor::Entry) + sizeof(void*)                   // for typeface
     167             :                         + 32   // slop for occational small extras
     168             :     };
     169             :     SkDescriptor*   fDesc;
     170             :     uint32_t        fStorage[(kStorageSize + 3) >> 2];
     171             : };
     172             : #define SkAutoDescriptor(...) SK_REQUIRE_LOCAL_VAR(SkAutoDescriptor)
     173             : 
     174             : 
     175             : #endif

Generated by: LCOV version 1.13