blob: e80ba8f2b57232d2ea6657921f11fe8cfa4cffd7 [file] [log] [blame]
reed@google.com8c5c7a92013-04-19 20:16:01 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkData.h"
9#include "SkDataTable.h"
bungemanfeb3c1a2016-08-05 06:51:50 -070010#include "SkOnce.h"
reed@google.com8c5c7a92013-04-19 20:16:01 +000011
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000012static void malloc_freeproc(void* context) {
13 sk_free(context);
reed@google.com8c5c7a92013-04-19 20:16:01 +000014}
15
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000016// Makes empty table
17SkDataTable::SkDataTable() {
18 fCount = 0;
19 fElemSize = 0; // 0 signals that we use fDir instead of fElems
halcanary96fcdcc2015-08-27 07:41:13 -070020 fU.fDir = nullptr;
21 fFreeProc = nullptr;
22 fFreeProcContext = nullptr;
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000023}
reed@google.com8c5c7a92013-04-19 20:16:01 +000024
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000025SkDataTable::SkDataTable(const void* array, size_t elemSize, int count,
26 FreeProc proc, void* context) {
27 SkASSERT(count > 0);
rmistry@google.comc9f3b382013-04-22 12:45:30 +000028
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000029 fCount = count;
30 fElemSize = elemSize; // non-zero signals we use fElems instead of fDir
31 fU.fElems = (const char*)array;
32 fFreeProc = proc;
33 fFreeProcContext = context;
34}
35
36SkDataTable::SkDataTable(const Dir* dir, int count, FreeProc proc, void* ctx) {
37 SkASSERT(count > 0);
rmistry@google.comc9f3b382013-04-22 12:45:30 +000038
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000039 fCount = count;
40 fElemSize = 0; // 0 signals that we use fDir instead of fElems
41 fU.fDir = dir;
42 fFreeProc = proc;
43 fFreeProcContext = ctx;
44}
45
46SkDataTable::~SkDataTable() {
47 if (fFreeProc) {
48 fFreeProc(fFreeProcContext);
reed@google.com8c5c7a92013-04-19 20:16:01 +000049 }
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000050}
reed@google.com8c5c7a92013-04-19 20:16:01 +000051
52size_t SkDataTable::atSize(int index) const {
53 SkASSERT((unsigned)index < (unsigned)fCount);
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000054
55 if (fElemSize) {
56 return fElemSize;
57 } else {
58 return fU.fDir[index].fSize;
59 }
reed@google.com8c5c7a92013-04-19 20:16:01 +000060}
61
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000062const void* SkDataTable::at(int index, size_t* size) const {
reed@google.com8c5c7a92013-04-19 20:16:01 +000063 SkASSERT((unsigned)index < (unsigned)fCount);
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000064
65 if (fElemSize) {
66 if (size) {
67 *size = fElemSize;
68 }
69 return fU.fElems + index * fElemSize;
70 } else {
71 if (size) {
72 *size = fU.fDir[index].fSize;
73 }
74 return fU.fDir[index].fPtr;
reed@google.com8c5c7a92013-04-19 20:16:01 +000075 }
reed@google.com8c5c7a92013-04-19 20:16:01 +000076}
77
reed@google.com3cceb9f2013-04-19 20:22:39 +000078///////////////////////////////////////////////////////////////////////////////
79
bungemanfeb3c1a2016-08-05 06:51:50 -070080sk_sp<SkDataTable> SkDataTable::MakeEmpty() {
81 static SkDataTable* singleton;
82 static SkOnce once;
83 once([]{ singleton = new SkDataTable(); });
84 return sk_ref_sp(singleton);
reed@google.com3cceb9f2013-04-19 20:22:39 +000085}
86
bungemanfeb3c1a2016-08-05 06:51:50 -070087sk_sp<SkDataTable> SkDataTable::MakeCopyArrays(const void * const * ptrs,
88 const size_t sizes[], int count) {
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000089 if (count <= 0) {
bungemanfeb3c1a2016-08-05 06:51:50 -070090 return SkDataTable::MakeEmpty();
reed@google.com8c5c7a92013-04-19 20:16:01 +000091 }
92
reed@google.com8c5c7a92013-04-19 20:16:01 +000093 size_t dataSize = 0;
94 for (int i = 0; i < count; ++i) {
95 dataSize += sizes[i];
96 }
97
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000098 size_t bufferSize = count * sizeof(Dir) + dataSize;
reed@google.com8c5c7a92013-04-19 20:16:01 +000099 void* buffer = sk_malloc_throw(bufferSize);
100
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000101 Dir* dir = (Dir*)buffer;
102 char* elem = (char*)(dir + count);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000103 for (int i = 0; i < count; ++i) {
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000104 dir[i].fPtr = elem;
105 dir[i].fSize = sizes[i];
106 memcpy(elem, ptrs[i], sizes[i]);
107 elem += sizes[i];
reed@google.com8c5c7a92013-04-19 20:16:01 +0000108 }
rmistry@google.comc9f3b382013-04-22 12:45:30 +0000109
bungemanfeb3c1a2016-08-05 06:51:50 -0700110 return sk_sp<SkDataTable>(new SkDataTable(dir, count, malloc_freeproc, buffer));
reed@google.com8c5c7a92013-04-19 20:16:01 +0000111}
112
bungemanfeb3c1a2016-08-05 06:51:50 -0700113sk_sp<SkDataTable> SkDataTable::MakeCopyArray(const void* array, size_t elemSize, int count) {
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000114 if (count <= 0) {
bungemanfeb3c1a2016-08-05 06:51:50 -0700115 return SkDataTable::MakeEmpty();
reed@google.com8c5c7a92013-04-19 20:16:01 +0000116 }
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000117
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000118 size_t bufferSize = elemSize * count;
reed@google.com8c5c7a92013-04-19 20:16:01 +0000119 void* buffer = sk_malloc_throw(bufferSize);
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000120 memcpy(buffer, array, bufferSize);
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000121
bungemanfeb3c1a2016-08-05 06:51:50 -0700122 return sk_sp<SkDataTable>(new SkDataTable(buffer, elemSize, count, malloc_freeproc, buffer));
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000123}
124
bungemanfeb3c1a2016-08-05 06:51:50 -0700125sk_sp<SkDataTable> SkDataTable::MakeArrayProc(const void* array, size_t elemSize, int count,
126 FreeProc proc, void* ctx) {
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000127 if (count <= 0) {
bungemanfeb3c1a2016-08-05 06:51:50 -0700128 return SkDataTable::MakeEmpty();
reed@google.com8c5c7a92013-04-19 20:16:01 +0000129 }
bungemanfeb3c1a2016-08-05 06:51:50 -0700130 return sk_sp<SkDataTable>(new SkDataTable(array, elemSize, count, proc, ctx));
reed@google.com8c5c7a92013-04-19 20:16:01 +0000131}