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

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2006 The Android Open Source Project
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8
michael@0 9
michael@0 10 #ifndef SkDescriptor_DEFINED
michael@0 11 #define SkDescriptor_DEFINED
michael@0 12
michael@0 13 #include "SkChecksum.h"
michael@0 14 #include "SkTypes.h"
michael@0 15
michael@0 16 class SkDescriptor : SkNoncopyable {
michael@0 17 public:
michael@0 18 static size_t ComputeOverhead(int entryCount) {
michael@0 19 SkASSERT(entryCount >= 0);
michael@0 20 return sizeof(SkDescriptor) + entryCount * sizeof(Entry);
michael@0 21 }
michael@0 22
michael@0 23 static SkDescriptor* Alloc(size_t length) {
michael@0 24 SkASSERT(SkAlign4(length) == length);
michael@0 25 SkDescriptor* desc = (SkDescriptor*)sk_malloc_throw(length);
michael@0 26 return desc;
michael@0 27 }
michael@0 28
michael@0 29 static void Free(SkDescriptor* desc) {
michael@0 30 sk_free(desc);
michael@0 31 }
michael@0 32
michael@0 33 void init() {
michael@0 34 fLength = sizeof(SkDescriptor);
michael@0 35 fCount = 0;
michael@0 36 }
michael@0 37
michael@0 38 uint32_t getLength() const { return fLength; }
michael@0 39
michael@0 40 void* addEntry(uint32_t tag, uint32_t length, const void* data = NULL) {
michael@0 41 SkASSERT(tag);
michael@0 42 SkASSERT(SkAlign4(length) == length);
michael@0 43 SkASSERT(this->findEntry(tag, NULL) == NULL);
michael@0 44
michael@0 45 Entry* entry = (Entry*)((char*)this + fLength);
michael@0 46 entry->fTag = tag;
michael@0 47 entry->fLen = length;
michael@0 48 if (data) {
michael@0 49 memcpy(entry + 1, data, length);
michael@0 50 }
michael@0 51
michael@0 52 fCount += 1;
michael@0 53 fLength += sizeof(Entry) + length;
michael@0 54 return (entry + 1); // return its data
michael@0 55 }
michael@0 56
michael@0 57 void computeChecksum() {
michael@0 58 fChecksum = SkDescriptor::ComputeChecksum(this);
michael@0 59 }
michael@0 60
michael@0 61 #ifdef SK_DEBUG
michael@0 62 void assertChecksum() const {
michael@0 63 SkASSERT(SkDescriptor::ComputeChecksum(this) == fChecksum);
michael@0 64 }
michael@0 65 #endif
michael@0 66
michael@0 67 const void* findEntry(uint32_t tag, uint32_t* length) const {
michael@0 68 const Entry* entry = (const Entry*)(this + 1);
michael@0 69 int count = fCount;
michael@0 70
michael@0 71 while (--count >= 0) {
michael@0 72 if (entry->fTag == tag) {
michael@0 73 if (length) {
michael@0 74 *length = entry->fLen;
michael@0 75 }
michael@0 76 return entry + 1;
michael@0 77 }
michael@0 78 entry = (const Entry*)((const char*)(entry + 1) + entry->fLen);
michael@0 79 }
michael@0 80 return NULL;
michael@0 81 }
michael@0 82
michael@0 83 SkDescriptor* copy() const {
michael@0 84 SkDescriptor* desc = SkDescriptor::Alloc(fLength);
michael@0 85 memcpy(desc, this, fLength);
michael@0 86 return desc;
michael@0 87 }
michael@0 88
michael@0 89 bool equals(const SkDescriptor& other) const {
michael@0 90 // probe to see if we have a good checksum algo
michael@0 91 // SkASSERT(a.fChecksum != b.fChecksum || memcmp(&a, &b, a.fLength) == 0);
michael@0 92
michael@0 93 // the first value we should look at is the checksum, so this loop
michael@0 94 // should terminate early if they descriptors are different.
michael@0 95 // NOTE: if we wrote a sentinel value at the end of each, we chould
michael@0 96 // remove the aa < stop test in the loop...
michael@0 97 const uint32_t* aa = (const uint32_t*)this;
michael@0 98 const uint32_t* bb = (const uint32_t*)&other;
michael@0 99 const uint32_t* stop = (const uint32_t*)((const char*)aa + fLength);
michael@0 100 do {
michael@0 101 if (*aa++ != *bb++)
michael@0 102 return false;
michael@0 103 } while (aa < stop);
michael@0 104 return true;
michael@0 105 }
michael@0 106
michael@0 107 uint32_t getChecksum() const { return fChecksum; }
michael@0 108
michael@0 109 struct Entry {
michael@0 110 uint32_t fTag;
michael@0 111 uint32_t fLen;
michael@0 112 };
michael@0 113
michael@0 114 #ifdef SK_DEBUG
michael@0 115 uint32_t getCount() const { return fCount; }
michael@0 116 #endif
michael@0 117
michael@0 118 private:
michael@0 119 uint32_t fChecksum; // must be first
michael@0 120 uint32_t fLength; // must be second
michael@0 121 uint32_t fCount;
michael@0 122
michael@0 123 static uint32_t ComputeChecksum(const SkDescriptor* desc) {
michael@0 124 const uint32_t* ptr = (const uint32_t*)desc + 1; // skip the checksum field
michael@0 125 size_t len = desc->fLength - sizeof(uint32_t);
michael@0 126 return SkChecksum::Compute(ptr, len);
michael@0 127 }
michael@0 128
michael@0 129 // private so no one can create one except our factories
michael@0 130 SkDescriptor() {}
michael@0 131 };
michael@0 132
michael@0 133 #include "SkScalerContext.h"
michael@0 134
michael@0 135 class SkAutoDescriptor : SkNoncopyable {
michael@0 136 public:
michael@0 137 SkAutoDescriptor(size_t size) {
michael@0 138 if (size <= sizeof(fStorage)) {
michael@0 139 fDesc = (SkDescriptor*)(void*)fStorage;
michael@0 140 } else {
michael@0 141 fDesc = SkDescriptor::Alloc(size);
michael@0 142 }
michael@0 143 }
michael@0 144
michael@0 145 ~SkAutoDescriptor() {
michael@0 146 if (fDesc != (SkDescriptor*)(void*)fStorage) {
michael@0 147 SkDescriptor::Free(fDesc);
michael@0 148 }
michael@0 149 }
michael@0 150
michael@0 151 SkDescriptor* getDesc() const { return fDesc; }
michael@0 152 private:
michael@0 153 enum {
michael@0 154 kStorageSize = sizeof(SkDescriptor)
michael@0 155 + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContext::Rec) // for rec
michael@0 156 + sizeof(SkDescriptor::Entry) + sizeof(void*) // for typeface
michael@0 157 + 32 // slop for occational small extras
michael@0 158 };
michael@0 159 SkDescriptor* fDesc;
michael@0 160 uint32_t fStorage[(kStorageSize + 3) >> 2];
michael@0 161 };
michael@0 162 #define SkAutoDescriptor(...) SK_REQUIRE_LOCAL_VAR(SkAutoDescriptor)
michael@0 163
michael@0 164
michael@0 165 #endif

mercurial