gfx/skia/trunk/src/core/SkDescriptor.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/core/SkDescriptor.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,165 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2006 The Android Open Source Project
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +
    1.13 +#ifndef SkDescriptor_DEFINED
    1.14 +#define SkDescriptor_DEFINED
    1.15 +
    1.16 +#include "SkChecksum.h"
    1.17 +#include "SkTypes.h"
    1.18 +
    1.19 +class SkDescriptor : SkNoncopyable {
    1.20 +public:
    1.21 +    static size_t ComputeOverhead(int entryCount) {
    1.22 +        SkASSERT(entryCount >= 0);
    1.23 +        return sizeof(SkDescriptor) + entryCount * sizeof(Entry);
    1.24 +    }
    1.25 +
    1.26 +    static SkDescriptor* Alloc(size_t length) {
    1.27 +        SkASSERT(SkAlign4(length) == length);
    1.28 +        SkDescriptor* desc = (SkDescriptor*)sk_malloc_throw(length);
    1.29 +        return desc;
    1.30 +    }
    1.31 +
    1.32 +    static void Free(SkDescriptor* desc) {
    1.33 +        sk_free(desc);
    1.34 +    }
    1.35 +
    1.36 +    void init() {
    1.37 +        fLength = sizeof(SkDescriptor);
    1.38 +        fCount  = 0;
    1.39 +    }
    1.40 +
    1.41 +    uint32_t getLength() const { return fLength; }
    1.42 +
    1.43 +    void* addEntry(uint32_t tag, uint32_t length, const void* data = NULL) {
    1.44 +        SkASSERT(tag);
    1.45 +        SkASSERT(SkAlign4(length) == length);
    1.46 +        SkASSERT(this->findEntry(tag, NULL) == NULL);
    1.47 +
    1.48 +        Entry*  entry = (Entry*)((char*)this + fLength);
    1.49 +        entry->fTag = tag;
    1.50 +        entry->fLen = length;
    1.51 +        if (data) {
    1.52 +            memcpy(entry + 1, data, length);
    1.53 +        }
    1.54 +
    1.55 +        fCount += 1;
    1.56 +        fLength += sizeof(Entry) + length;
    1.57 +        return (entry + 1); // return its data
    1.58 +    }
    1.59 +
    1.60 +    void computeChecksum() {
    1.61 +        fChecksum = SkDescriptor::ComputeChecksum(this);
    1.62 +    }
    1.63 +
    1.64 +#ifdef SK_DEBUG
    1.65 +    void assertChecksum() const {
    1.66 +        SkASSERT(SkDescriptor::ComputeChecksum(this) == fChecksum);
    1.67 +    }
    1.68 +#endif
    1.69 +
    1.70 +    const void* findEntry(uint32_t tag, uint32_t* length) const {
    1.71 +        const Entry* entry = (const Entry*)(this + 1);
    1.72 +        int          count = fCount;
    1.73 +
    1.74 +        while (--count >= 0) {
    1.75 +            if (entry->fTag == tag) {
    1.76 +                if (length) {
    1.77 +                    *length = entry->fLen;
    1.78 +                }
    1.79 +                return entry + 1;
    1.80 +            }
    1.81 +            entry = (const Entry*)((const char*)(entry + 1) + entry->fLen);
    1.82 +        }
    1.83 +        return NULL;
    1.84 +    }
    1.85 +
    1.86 +    SkDescriptor* copy() const {
    1.87 +        SkDescriptor* desc = SkDescriptor::Alloc(fLength);
    1.88 +        memcpy(desc, this, fLength);
    1.89 +        return desc;
    1.90 +    }
    1.91 +
    1.92 +    bool equals(const SkDescriptor& other) const {
    1.93 +        // probe to see if we have a good checksum algo
    1.94 +//        SkASSERT(a.fChecksum != b.fChecksum || memcmp(&a, &b, a.fLength) == 0);
    1.95 +
    1.96 +        // the first value we should look at is the checksum, so this loop
    1.97 +        // should terminate early if they descriptors are different.
    1.98 +        // NOTE: if we wrote a sentinel value at the end of each, we chould
    1.99 +        //       remove the aa < stop test in the loop...
   1.100 +        const uint32_t* aa = (const uint32_t*)this;
   1.101 +        const uint32_t* bb = (const uint32_t*)&other;
   1.102 +        const uint32_t* stop = (const uint32_t*)((const char*)aa + fLength);
   1.103 +        do {
   1.104 +            if (*aa++ != *bb++)
   1.105 +                return false;
   1.106 +        } while (aa < stop);
   1.107 +        return true;
   1.108 +    }
   1.109 +
   1.110 +    uint32_t getChecksum() const { return fChecksum; }
   1.111 +
   1.112 +    struct Entry {
   1.113 +        uint32_t fTag;
   1.114 +        uint32_t fLen;
   1.115 +    };
   1.116 +
   1.117 +#ifdef SK_DEBUG
   1.118 +    uint32_t getCount() const { return fCount; }
   1.119 +#endif
   1.120 +
   1.121 +private:
   1.122 +    uint32_t fChecksum;  // must be first
   1.123 +    uint32_t fLength;    // must be second
   1.124 +    uint32_t fCount;
   1.125 +
   1.126 +    static uint32_t ComputeChecksum(const SkDescriptor* desc) {
   1.127 +        const uint32_t* ptr = (const uint32_t*)desc + 1; // skip the checksum field
   1.128 +        size_t len = desc->fLength - sizeof(uint32_t);
   1.129 +        return SkChecksum::Compute(ptr, len);
   1.130 +    }
   1.131 +
   1.132 +    // private so no one can create one except our factories
   1.133 +    SkDescriptor() {}
   1.134 +};
   1.135 +
   1.136 +#include "SkScalerContext.h"
   1.137 +
   1.138 +class SkAutoDescriptor : SkNoncopyable {
   1.139 +public:
   1.140 +    SkAutoDescriptor(size_t size) {
   1.141 +        if (size <= sizeof(fStorage)) {
   1.142 +            fDesc = (SkDescriptor*)(void*)fStorage;
   1.143 +        } else {
   1.144 +            fDesc = SkDescriptor::Alloc(size);
   1.145 +        }
   1.146 +    }
   1.147 +
   1.148 +    ~SkAutoDescriptor() {
   1.149 +        if (fDesc != (SkDescriptor*)(void*)fStorage) {
   1.150 +            SkDescriptor::Free(fDesc);
   1.151 +        }
   1.152 +    }
   1.153 +
   1.154 +    SkDescriptor* getDesc() const { return fDesc; }
   1.155 +private:
   1.156 +    enum {
   1.157 +        kStorageSize =  sizeof(SkDescriptor)
   1.158 +                        + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContext::Rec)    // for rec
   1.159 +                        + sizeof(SkDescriptor::Entry) + sizeof(void*)                   // for typeface
   1.160 +                        + 32   // slop for occational small extras
   1.161 +    };
   1.162 +    SkDescriptor*   fDesc;
   1.163 +    uint32_t        fStorage[(kStorageSize + 3) >> 2];
   1.164 +};
   1.165 +#define SkAutoDescriptor(...) SK_REQUIRE_LOCAL_VAR(SkAutoDescriptor)
   1.166 +
   1.167 +
   1.168 +#endif

mercurial