SkDataTable.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  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. #include "include/core/SkData.h"
  8. #include "include/core/SkDataTable.h"
  9. #include "include/private/SkOnce.h"
  10. static void malloc_freeproc(void* context) {
  11. sk_free(context);
  12. }
  13. // Makes empty table
  14. SkDataTable::SkDataTable() {
  15. fCount = 0;
  16. fElemSize = 0; // 0 signals that we use fDir instead of fElems
  17. fU.fDir = nullptr;
  18. fFreeProc = nullptr;
  19. fFreeProcContext = nullptr;
  20. }
  21. SkDataTable::SkDataTable(const void* array, size_t elemSize, int count,
  22. FreeProc proc, void* context) {
  23. SkASSERT(count > 0);
  24. fCount = count;
  25. fElemSize = elemSize; // non-zero signals we use fElems instead of fDir
  26. fU.fElems = (const char*)array;
  27. fFreeProc = proc;
  28. fFreeProcContext = context;
  29. }
  30. SkDataTable::SkDataTable(const Dir* dir, int count, FreeProc proc, void* ctx) {
  31. SkASSERT(count > 0);
  32. fCount = count;
  33. fElemSize = 0; // 0 signals that we use fDir instead of fElems
  34. fU.fDir = dir;
  35. fFreeProc = proc;
  36. fFreeProcContext = ctx;
  37. }
  38. SkDataTable::~SkDataTable() {
  39. if (fFreeProc) {
  40. fFreeProc(fFreeProcContext);
  41. }
  42. }
  43. size_t SkDataTable::atSize(int index) const {
  44. SkASSERT((unsigned)index < (unsigned)fCount);
  45. if (fElemSize) {
  46. return fElemSize;
  47. } else {
  48. return fU.fDir[index].fSize;
  49. }
  50. }
  51. const void* SkDataTable::at(int index, size_t* size) const {
  52. SkASSERT((unsigned)index < (unsigned)fCount);
  53. if (fElemSize) {
  54. if (size) {
  55. *size = fElemSize;
  56. }
  57. return fU.fElems + index * fElemSize;
  58. } else {
  59. if (size) {
  60. *size = fU.fDir[index].fSize;
  61. }
  62. return fU.fDir[index].fPtr;
  63. }
  64. }
  65. ///////////////////////////////////////////////////////////////////////////////
  66. sk_sp<SkDataTable> SkDataTable::MakeEmpty() {
  67. static SkDataTable* singleton;
  68. static SkOnce once;
  69. once([]{ singleton = new SkDataTable(); });
  70. return sk_ref_sp(singleton);
  71. }
  72. sk_sp<SkDataTable> SkDataTable::MakeCopyArrays(const void * const * ptrs,
  73. const size_t sizes[], int count) {
  74. if (count <= 0) {
  75. return SkDataTable::MakeEmpty();
  76. }
  77. size_t dataSize = 0;
  78. for (int i = 0; i < count; ++i) {
  79. dataSize += sizes[i];
  80. }
  81. size_t bufferSize = count * sizeof(Dir) + dataSize;
  82. void* buffer = sk_malloc_throw(bufferSize);
  83. Dir* dir = (Dir*)buffer;
  84. char* elem = (char*)(dir + count);
  85. for (int i = 0; i < count; ++i) {
  86. dir[i].fPtr = elem;
  87. dir[i].fSize = sizes[i];
  88. memcpy(elem, ptrs[i], sizes[i]);
  89. elem += sizes[i];
  90. }
  91. return sk_sp<SkDataTable>(new SkDataTable(dir, count, malloc_freeproc, buffer));
  92. }
  93. sk_sp<SkDataTable> SkDataTable::MakeCopyArray(const void* array, size_t elemSize, int count) {
  94. if (count <= 0) {
  95. return SkDataTable::MakeEmpty();
  96. }
  97. size_t bufferSize = elemSize * count;
  98. void* buffer = sk_malloc_throw(bufferSize);
  99. memcpy(buffer, array, bufferSize);
  100. return sk_sp<SkDataTable>(new SkDataTable(buffer, elemSize, count, malloc_freeproc, buffer));
  101. }
  102. sk_sp<SkDataTable> SkDataTable::MakeArrayProc(const void* array, size_t elemSize, int count,
  103. FreeProc proc, void* ctx) {
  104. if (count <= 0) {
  105. return SkDataTable::MakeEmpty();
  106. }
  107. return sk_sp<SkDataTable>(new SkDataTable(array, elemSize, count, proc, ctx));
  108. }