/*
|
* Copyright 2006 The Android Open Source Project
|
*
|
* Use of this source code is governed by a BSD-style license that can be
|
* found in the LICENSE file.
|
*/
|
|
#ifndef SkDescriptor_DEFINED
|
#define SkDescriptor_DEFINED
|
|
#include <memory>
|
|
#include "SkMacros.h"
|
#include "SkNoncopyable.h"
|
#include "SkScalerContext.h"
|
|
class SkDescriptor : SkNoncopyable {
|
public:
|
static size_t ComputeOverhead(int entryCount) {
|
SkASSERT(entryCount >= 0);
|
return sizeof(SkDescriptor) + entryCount * sizeof(Entry);
|
}
|
|
static std::unique_ptr<SkDescriptor> Alloc(size_t length);
|
|
// Ensure the unsized delete is called.
|
void operator delete(void* p);
|
void init() {
|
fLength = sizeof(SkDescriptor);
|
fCount = 0;
|
}
|
uint32_t getLength() const { return fLength; }
|
void* addEntry(uint32_t tag, size_t length, const void* data = nullptr);
|
void computeChecksum();
|
|
#ifdef SK_DEBUG
|
void assertChecksum() const {
|
SkASSERT(SkDescriptor::ComputeChecksum(this) == fChecksum);
|
}
|
#endif
|
|
const void* findEntry(uint32_t tag, uint32_t* length) const;
|
|
std::unique_ptr<SkDescriptor> copy() const;
|
|
// This assumes that all memory added has a length that is a multiple of 4. This is checked
|
// by the assert in addEntry.
|
bool operator==(const SkDescriptor& other) const;
|
bool operator!=(const SkDescriptor& other) const { return !(*this == other); }
|
|
uint32_t getChecksum() const { return fChecksum; }
|
|
struct Entry {
|
uint32_t fTag;
|
uint32_t fLen;
|
};
|
|
#ifdef SK_DEBUG
|
uint32_t getCount() const { return fCount; }
|
#endif
|
|
private:
|
// private so no one can create one except our factories
|
SkDescriptor() = default;
|
|
static uint32_t ComputeChecksum(const SkDescriptor* desc);
|
|
uint32_t fChecksum; // must be first
|
uint32_t fLength; // must be second
|
uint32_t fCount;
|
};
|
|
class SkAutoDescriptor : SkNoncopyable {
|
public:
|
SkAutoDescriptor();
|
SkAutoDescriptor(size_t size);
|
SkAutoDescriptor(const SkDescriptor& desc);
|
SkAutoDescriptor(SkAutoDescriptor&&) = delete;
|
SkAutoDescriptor& operator =(SkAutoDescriptor&&) = delete;
|
|
~SkAutoDescriptor();
|
|
void reset(size_t size);
|
void reset(const SkDescriptor& desc);
|
SkDescriptor* getDesc() const { SkASSERT(fDesc); return fDesc; }
|
|
private:
|
void free();
|
static constexpr size_t kStorageSize
|
= sizeof(SkDescriptor)
|
+ sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec) // for rec
|
+ sizeof(SkDescriptor::Entry) + sizeof(void*) // for typeface
|
+ 32; // slop for occasional small extras
|
|
SkDescriptor* fDesc{nullptr};
|
std::aligned_storage<kStorageSize, alignof(uint32_t)>::type fStorage;
|
};
|
|
#endif //SkDescriptor_DEFINED
|