Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Unified Diff: src/core/SkData.cpp

Issue 15675025: One allocation for an SkData which makes a copy. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Clean Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/core/SkData.cpp
===================================================================
--- src/core/SkData.cpp (revision 9702)
+++ src/core/SkData.cpp (working copy)
@@ -11,19 +11,11 @@
SK_DEFINE_INST_COUNT(SkData)
-SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) {
- fPtr = ptr;
- fSize = size;
- fReleaseProc = proc;
- fReleaseProcContext = context;
-}
+SkData::SkData(const void* ptr, size_t size)
+ : fSize(size)
+ , fPtr(ptr)
+{ }
-SkData::~SkData() {
- if (fReleaseProc) {
- fReleaseProc(fPtr, fSize, fReleaseProcContext);
- }
-}
-
bool SkData::equals(const SkData* other) const {
if (NULL == other) {
return false;
@@ -52,38 +44,42 @@
SkData* SkData::NewEmpty() {
static SkData* gEmptyRef;
if (NULL == gEmptyRef) {
- gEmptyRef = new SkData(NULL, 0, NULL, NULL);
+ gEmptyRef = new SkData(NULL, 0);
}
gEmptyRef->ref();
return gEmptyRef;
}
-// assumes fPtr was allocated via sk_malloc
-static void sk_free_releaseproc(const void* ptr, size_t, void*) {
+/** Assumes ptr was allocated via sk_malloc, ignores the size and context. */
+static void sk_free_releaseproc(const void* ptr, size_t) {
sk_free((void*)ptr);
}
SkData* SkData::NewFromMalloc(const void* data, size_t length) {
- return new SkData(data, length, sk_free_releaseproc, NULL);
+ typedef SkManagedData<SkManagedDataProcs::ReleaseProc, void> SelfType;
+ return new SelfType(data, length, sk_free_releaseproc);
}
+/** Assumes obj was allocated via sk_malloc, ignores context. */
+static void sk_free_deleteproc(const void* obj) {
+ sk_free((void*)obj);
+}
+
SkData* SkData::NewWithCopy(const void* data, size_t length) {
if (0 == length) {
return SkData::NewEmpty();
}
- void* copy = sk_malloc_throw(length); // balanced in sk_free_releaseproc
+ typedef SkManagedData<void, SkManagedDataProcs::DeleterProc> SelfType;
+ size_t total_size = sizeof(SelfType) + length;
+ char* self = reinterpret_cast<char*>(sk_malloc_throw(total_size));
+ char* copy = self + sizeof(SelfType);
memcpy(copy, data, length);
- return new SkData(copy, length, sk_free_releaseproc, NULL);
+ return SelfType::Place(self, copy, length, sk_free_deleteproc);
}
-SkData* SkData::NewWithProc(const void* data, size_t length,
- ReleaseProc proc, void* context) {
- return new SkData(data, length, proc, context);
-}
-
// assumes fPtr was allocated with sk_fmmap
-static void sk_mmap_releaseproc(const void* addr, size_t length, void*) {
+static void sk_mmap_releaseproc(const void* addr, size_t length) {
sk_fmunmap(addr, length);
}
@@ -94,7 +90,7 @@
return NULL;
}
- return SkData::NewWithProc(addr, size, sk_mmap_releaseproc, NULL);
+ return SkData::NewWithProc(addr, size, sk_mmap_releaseproc);
}
SkData* SkData::NewFromFileName(const char path[]) {
@@ -114,14 +110,18 @@
return NULL;
}
- return SkData::NewWithProc(addr, size, sk_mmap_releaseproc, NULL);
+ return SkData::NewWithProc(addr, size, sk_mmap_releaseproc);
}
-// assumes context is a SkData
-static void sk_dataref_releaseproc(const void*, size_t, void* context) {
- SkData* src = reinterpret_cast<SkData*>(context);
- src->unref();
-}
+struct SkAutoUnrefFunctor {
+public:
+ explicit SkAutoUnrefFunctor(SkRefCnt const * ptr) : fPtr(ptr) { }
+ void operator()(const void* ptr, size_t length) const {
+ fPtr->unref();
+ }
+private:
+ SkRefCnt const * fPtr;
+};
SkData* SkData::NewSubset(const SkData* src, size_t offset, size_t length) {
/*
@@ -140,9 +140,9 @@
}
SkASSERT(length > 0);
- src->ref(); // this will be balanced in sk_dataref_releaseproc
- return new SkData(src->bytes() + offset, length, sk_dataref_releaseproc,
- const_cast<SkData*>(src));
+ src->ref(); // this will be balanced in SkAutoUnrefFunctor
+ typedef SkManagedData<SkAutoUnrefFunctor, void> SelfType;
+ return new SelfType(src->bytes() + offset, length, SkAutoUnrefFunctor(src));
}
SkData* SkData::NewWithCString(const char cstr[]) {
@@ -156,25 +156,28 @@
return NewWithCopy(cstr, size);
}
+SkData* SkData::NewUnowned(const void* data, size_t length) {
+ return new SkData(data, length);
+}
+
///////////////////////////////////////////////////////////////////////////////
void SkData::flatten(SkFlattenableWriteBuffer& buffer) const {
buffer.writeByteArray(fPtr, fSize);
}
-SkData::SkData(SkFlattenableReadBuffer& buffer) {
- fSize = buffer.getArrayCount();
- fReleaseProcContext = NULL;
-
- if (fSize > 0) {
- fPtr = sk_malloc_throw(fSize);
- fReleaseProc = sk_free_releaseproc;
- } else {
- fPtr = NULL;
- fReleaseProc = NULL;
+SkFlattenable* SkData::CreateProc(SkFlattenableReadBuffer& buffer) {
+ uint32_t length = buffer.getArrayCount();
+ if (0 == length) {
+ return SkData::NewEmpty();
}
- buffer.readByteArray(const_cast<void*>(fPtr));
+ typedef SkManagedData<void, SkManagedDataProcs::DeleterProc> SelfType;
+ size_t total_size = sizeof(SelfType) + length;
+ char* self = reinterpret_cast<char*>(sk_malloc_throw(total_size));
+ char* copy = self + sizeof(SelfType);
+ buffer.readByteArray(copy);
+ return SelfType::Place(self, copy, length, sk_free_deleteproc);
}
///////////////////////////////////////////////////////////////////////////////

Powered by Google App Engine
This is Rietveld 408576698