diff options
Diffstat (limited to 'gfx/skia/skia/src/core/SkDataTable.cpp')
-rw-r--r-- | gfx/skia/skia/src/core/SkDataTable.cpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/core/SkDataTable.cpp b/gfx/skia/skia/src/core/SkDataTable.cpp new file mode 100644 index 0000000000..d15e65b473 --- /dev/null +++ b/gfx/skia/skia/src/core/SkDataTable.cpp @@ -0,0 +1,136 @@ +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "include/core/SkDataTable.h" + +#include "include/core/SkRefCnt.h" +#include "include/private/base/SkAssert.h" +#include "include/private/base/SkMalloc.h" +#include "include/private/base/SkOnce.h" + +#include <cstring> + +static void malloc_freeproc(void* context) { + sk_free(context); +} + +// Makes empty table +SkDataTable::SkDataTable() { + fCount = 0; + fElemSize = 0; // 0 signals that we use fDir instead of fElems + fU.fDir = nullptr; + fFreeProc = nullptr; + fFreeProcContext = nullptr; +} + +SkDataTable::SkDataTable(const void* array, size_t elemSize, int count, + FreeProc proc, void* context) { + SkASSERT(count > 0); + + fCount = count; + fElemSize = elemSize; // non-zero signals we use fElems instead of fDir + fU.fElems = (const char*)array; + fFreeProc = proc; + fFreeProcContext = context; +} + +SkDataTable::SkDataTable(const Dir* dir, int count, FreeProc proc, void* ctx) { + SkASSERT(count > 0); + + fCount = count; + fElemSize = 0; // 0 signals that we use fDir instead of fElems + fU.fDir = dir; + fFreeProc = proc; + fFreeProcContext = ctx; +} + +SkDataTable::~SkDataTable() { + if (fFreeProc) { + fFreeProc(fFreeProcContext); + } +} + +size_t SkDataTable::atSize(int index) const { + SkASSERT((unsigned)index < (unsigned)fCount); + + if (fElemSize) { + return fElemSize; + } else { + return fU.fDir[index].fSize; + } +} + +const void* SkDataTable::at(int index, size_t* size) const { + SkASSERT((unsigned)index < (unsigned)fCount); + + if (fElemSize) { + if (size) { + *size = fElemSize; + } + return fU.fElems + index * fElemSize; + } else { + if (size) { + *size = fU.fDir[index].fSize; + } + return fU.fDir[index].fPtr; + } +} + +/////////////////////////////////////////////////////////////////////////////// + +sk_sp<SkDataTable> SkDataTable::MakeEmpty() { + static SkDataTable* singleton; + static SkOnce once; + once([]{ singleton = new SkDataTable(); }); + return sk_ref_sp(singleton); +} + +sk_sp<SkDataTable> SkDataTable::MakeCopyArrays(const void * const * ptrs, + const size_t sizes[], int count) { + if (count <= 0) { + return SkDataTable::MakeEmpty(); + } + + size_t dataSize = 0; + for (int i = 0; i < count; ++i) { + dataSize += sizes[i]; + } + + size_t bufferSize = count * sizeof(Dir) + dataSize; + void* buffer = sk_malloc_throw(bufferSize); + + Dir* dir = (Dir*)buffer; + char* elem = (char*)(dir + count); + for (int i = 0; i < count; ++i) { + dir[i].fPtr = elem; + dir[i].fSize = sizes[i]; + memcpy(elem, ptrs[i], sizes[i]); + elem += sizes[i]; + } + + return sk_sp<SkDataTable>(new SkDataTable(dir, count, malloc_freeproc, buffer)); +} + +sk_sp<SkDataTable> SkDataTable::MakeCopyArray(const void* array, size_t elemSize, int count) { + if (count <= 0) { + return SkDataTable::MakeEmpty(); + } + + size_t bufferSize = elemSize * count; + void* buffer = sk_malloc_throw(bufferSize); + memcpy(buffer, array, bufferSize); + + return sk_sp<SkDataTable>(new SkDataTable(buffer, elemSize, count, malloc_freeproc, buffer)); +} + +sk_sp<SkDataTable> SkDataTable::MakeArrayProc(const void* array, size_t elemSize, int count, + FreeProc proc, void* ctx) { + if (count <= 0) { + return SkDataTable::MakeEmpty(); + } + return sk_sp<SkDataTable>(new SkDataTable(array, elemSize, count, proc, ctx)); +} |