180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkDescriptor_DEFINED 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkDescriptor_DEFINED 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkChecksum.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTypes.h" 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkDescriptor : SkNoncopyable { 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static size_t ComputeOverhead(int entryCount) { 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(entryCount >= 0); 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return sizeof(SkDescriptor) + entryCount * sizeof(Entry); 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static SkDescriptor* Alloc(size_t length) { 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(SkAlign4(length) == length); 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDescriptor* desc = (SkDescriptor*)sk_malloc_throw(length); 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return desc; 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static void Free(SkDescriptor* desc) { 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sk_free(desc); 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void init() { 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fLength = sizeof(SkDescriptor); 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCount = 0; 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t getLength() const { return fLength; } 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* addEntry(uint32_t tag, uint32_t length, const void* data = NULL) { 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(tag); 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(SkAlign4(length) == length); 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(this->findEntry(tag, NULL) == NULL); 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Entry* entry = (Entry*)((char*)this + fLength); 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru entry->fTag = tag; 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru entry->fLen = length; 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (data) { 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(entry + 1, data, length); 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCount += 1; 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fLength += sizeof(Entry) + length; 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return (entry + 1); // return its data 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void computeChecksum() { 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fChecksum = SkDescriptor::ComputeChecksum(this); 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void assertChecksum() const { 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(SkDescriptor::ComputeChecksum(this) == fChecksum); 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const void* findEntry(uint32_t tag, uint32_t* length) const { 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const Entry* entry = (const Entry*)(this + 1); 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int count = fCount; 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (--count >= 0) { 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (entry->fTag == tag) { 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (length) { 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *length = entry->fLen; 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return entry + 1; 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru entry = (const Entry*)((const char*)(entry + 1) + entry->fLen); 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDescriptor* copy() const { 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDescriptor* desc = SkDescriptor::Alloc(fLength); 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(desc, this, fLength); 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return desc; 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool equals(const SkDescriptor& other) const { 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // probe to see if we have a good checksum algo 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// SkASSERT(a.fChecksum != b.fChecksum || memcmp(&a, &b, a.fLength) == 0); 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the first value we should look at is the checksum, so this loop 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // should terminate early if they descriptors are different. 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // NOTE: if we wrote a sentinel value at the end of each, we chould 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // remove the aa < stop test in the loop... 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint32_t* aa = (const uint32_t*)this; 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint32_t* bb = (const uint32_t*)&other; 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint32_t* stop = (const uint32_t*)((const char*)aa + fLength); 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (*aa++ != *bb++) 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (aa < stop); 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t getChecksum() const { return fChecksum; } 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct Entry { 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t fTag; 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t fLen; 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t getCount() const { return fCount; } 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t fChecksum; // must be first 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t fLength; // must be second 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t fCount; 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static uint32_t ComputeChecksum(const SkDescriptor* desc) { 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint32_t* ptr = (const uint32_t*)desc + 1; // skip the checksum field 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t len = desc->fLength - sizeof(uint32_t); 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkChecksum::Compute(ptr, len); 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // private so no one can create one except our factories 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDescriptor() {} 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkScalerContext.h" 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkAutoDescriptor : SkNoncopyable { 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoDescriptor(size_t size) { 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (size <= sizeof(fStorage)) { 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDesc = (SkDescriptor*)(void*)fStorage; 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDesc = SkDescriptor::Alloc(size); 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ~SkAutoDescriptor() { 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fDesc != (SkDescriptor*)(void*)fStorage) { 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDescriptor::Free(fDesc); 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDescriptor* getDesc() const { return fDesc; } 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru enum { 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kStorageSize = sizeof(SkDescriptor) 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContext::Rec) // for rec 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru + sizeof(SkDescriptor::Entry) + sizeof(void*) // for typeface 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru + 32 // slop for occational small extras 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDescriptor* fDesc; 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t fStorage[(kStorageSize + 3) >> 2]; 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 162910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#define SkAutoDescriptor(...) SK_REQUIRE_LOCAL_VAR(SkAutoDescriptor) 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 166