gfx/skia/trunk/src/core/SkDataTable.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/core/SkDataTable.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,188 @@
     1.4 +/*
     1.5 + * Copyright 2013 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +#include "SkData.h"
    1.12 +#include "SkDataTable.h"
    1.13 +
    1.14 +static void malloc_freeproc(void* context) {
    1.15 +    sk_free(context);
    1.16 +}
    1.17 +
    1.18 +// Makes empty table
    1.19 +SkDataTable::SkDataTable() {
    1.20 +    fCount = 0;
    1.21 +    fElemSize = 0;   // 0 signals that we use fDir instead of fElems
    1.22 +    fU.fDir = NULL;
    1.23 +    fFreeProc = NULL;
    1.24 +    fFreeProcContext = NULL;
    1.25 +}
    1.26 +
    1.27 +SkDataTable::SkDataTable(const void* array, size_t elemSize, int count,
    1.28 +                         FreeProc proc, void* context) {
    1.29 +    SkASSERT(count > 0);
    1.30 +
    1.31 +    fCount = count;
    1.32 +    fElemSize = elemSize;   // non-zero signals we use fElems instead of fDir
    1.33 +    fU.fElems = (const char*)array;
    1.34 +    fFreeProc = proc;
    1.35 +    fFreeProcContext = context;
    1.36 +}
    1.37 +
    1.38 +SkDataTable::SkDataTable(const Dir* dir, int count, FreeProc proc, void* ctx) {
    1.39 +    SkASSERT(count > 0);
    1.40 +
    1.41 +    fCount = count;
    1.42 +    fElemSize = 0;  // 0 signals that we use fDir instead of fElems
    1.43 +    fU.fDir = dir;
    1.44 +    fFreeProc = proc;
    1.45 +    fFreeProcContext = ctx;
    1.46 +}
    1.47 +
    1.48 +SkDataTable::~SkDataTable() {
    1.49 +    if (fFreeProc) {
    1.50 +        fFreeProc(fFreeProcContext);
    1.51 +    }
    1.52 +}
    1.53 +
    1.54 +size_t SkDataTable::atSize(int index) const {
    1.55 +    SkASSERT((unsigned)index < (unsigned)fCount);
    1.56 +
    1.57 +    if (fElemSize) {
    1.58 +        return fElemSize;
    1.59 +    } else {
    1.60 +        return fU.fDir[index].fSize;
    1.61 +    }
    1.62 +}
    1.63 +
    1.64 +const void* SkDataTable::at(int index, size_t* size) const {
    1.65 +    SkASSERT((unsigned)index < (unsigned)fCount);
    1.66 +
    1.67 +    if (fElemSize) {
    1.68 +        if (size) {
    1.69 +            *size = fElemSize;
    1.70 +        }
    1.71 +        return fU.fElems + index * fElemSize;
    1.72 +    } else {
    1.73 +        if (size) {
    1.74 +            *size = fU.fDir[index].fSize;
    1.75 +        }
    1.76 +        return fU.fDir[index].fPtr;
    1.77 +    }
    1.78 +}
    1.79 +
    1.80 +///////////////////////////////////////////////////////////////////////////////
    1.81 +
    1.82 +SkDataTable* SkDataTable::NewEmpty() {
    1.83 +    static SkDataTable* gEmpty;
    1.84 +    if (NULL == gEmpty) {
    1.85 +        gEmpty = SkNEW(SkDataTable);
    1.86 +    }
    1.87 +    gEmpty->ref();
    1.88 +    return gEmpty;
    1.89 +}
    1.90 +
    1.91 +SkDataTable* SkDataTable::NewCopyArrays(const void * const * ptrs,
    1.92 +                                        const size_t sizes[], int count) {
    1.93 +    if (count <= 0) {
    1.94 +        return SkDataTable::NewEmpty();
    1.95 +    }
    1.96 +
    1.97 +    size_t dataSize = 0;
    1.98 +    for (int i = 0; i < count; ++i) {
    1.99 +        dataSize += sizes[i];
   1.100 +    }
   1.101 +
   1.102 +    size_t bufferSize = count * sizeof(Dir) + dataSize;
   1.103 +    void* buffer = sk_malloc_throw(bufferSize);
   1.104 +
   1.105 +    Dir* dir = (Dir*)buffer;
   1.106 +    char* elem = (char*)(dir + count);
   1.107 +    for (int i = 0; i < count; ++i) {
   1.108 +        dir[i].fPtr = elem;
   1.109 +        dir[i].fSize = sizes[i];
   1.110 +        memcpy(elem, ptrs[i], sizes[i]);
   1.111 +        elem += sizes[i];
   1.112 +    }
   1.113 +
   1.114 +    return SkNEW_ARGS(SkDataTable, (dir, count, malloc_freeproc, buffer));
   1.115 +}
   1.116 +
   1.117 +SkDataTable* SkDataTable::NewCopyArray(const void* array, size_t elemSize,
   1.118 +                                       int count) {
   1.119 +    if (count <= 0) {
   1.120 +        return SkDataTable::NewEmpty();
   1.121 +    }
   1.122 +
   1.123 +    size_t bufferSize = elemSize * count;
   1.124 +    void* buffer = sk_malloc_throw(bufferSize);
   1.125 +    memcpy(buffer, array, bufferSize);
   1.126 +
   1.127 +    return SkNEW_ARGS(SkDataTable,
   1.128 +                      (buffer, elemSize, count, malloc_freeproc, buffer));
   1.129 +}
   1.130 +
   1.131 +SkDataTable* SkDataTable::NewArrayProc(const void* array, size_t elemSize,
   1.132 +                                       int count, FreeProc proc, void* ctx) {
   1.133 +    if (count <= 0) {
   1.134 +        return SkDataTable::NewEmpty();
   1.135 +    }
   1.136 +    return SkNEW_ARGS(SkDataTable, (array, elemSize, count, proc, ctx));
   1.137 +}
   1.138 +
   1.139 +///////////////////////////////////////////////////////////////////////////////
   1.140 +
   1.141 +static void chunkalloc_freeproc(void* context) {
   1.142 +    SkDELETE((SkChunkAlloc*)context);
   1.143 +}
   1.144 +
   1.145 +SkDataTableBuilder::SkDataTableBuilder(size_t minChunkSize)
   1.146 +    : fHeap(NULL)
   1.147 +    , fMinChunkSize(minChunkSize) {}
   1.148 +
   1.149 +SkDataTableBuilder::~SkDataTableBuilder() { this->reset(); }
   1.150 +
   1.151 +void SkDataTableBuilder::reset(size_t minChunkSize) {
   1.152 +    fMinChunkSize = minChunkSize;
   1.153 +    fDir.reset();
   1.154 +    if (fHeap) {
   1.155 +        SkDELETE(fHeap);
   1.156 +        fHeap = NULL;
   1.157 +    }
   1.158 +}
   1.159 +
   1.160 +void SkDataTableBuilder::append(const void* src, size_t size) {
   1.161 +    if (NULL == fHeap) {
   1.162 +        fHeap = SkNEW_ARGS(SkChunkAlloc, (fMinChunkSize));
   1.163 +    }
   1.164 +
   1.165 +    void* dst = fHeap->alloc(size, SkChunkAlloc::kThrow_AllocFailType);
   1.166 +    memcpy(dst, src, size);
   1.167 +
   1.168 +    SkDataTable::Dir* dir = fDir.append();
   1.169 +    dir->fPtr = dst;
   1.170 +    dir->fSize = size;
   1.171 +}
   1.172 +
   1.173 +SkDataTable* SkDataTableBuilder::detachDataTable() {
   1.174 +    const int count = fDir.count();
   1.175 +    if (0 == count) {
   1.176 +        return SkDataTable::NewEmpty();
   1.177 +    }
   1.178 +
   1.179 +    // Copy the dir into the heap;
   1.180 +    void* dir = fHeap->alloc(count * sizeof(SkDataTable::Dir),
   1.181 +                             SkChunkAlloc::kThrow_AllocFailType);
   1.182 +    memcpy(dir, fDir.begin(), count * sizeof(SkDataTable::Dir));
   1.183 +
   1.184 +    SkDataTable* table = SkNEW_ARGS(SkDataTable,
   1.185 +                                    ((SkDataTable::Dir*)dir, count,
   1.186 +                                     chunkalloc_freeproc, fHeap));
   1.187 +    // we have to detach our fHeap, since we are giving that to the table
   1.188 +    fHeap = NULL;
   1.189 +    fDir.reset();
   1.190 +    return table;
   1.191 +}

mercurial