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

Side by Side Diff: src/core/SkData.cpp

Issue 560653004: SkData can allocate room for its contents in the same block (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: use real proc address, call destructor when inplace Created 6 years, 3 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkData.h" 8 #include "SkData.h"
9 #include "SkLazyPtr.h" 9 #include "SkLazyPtr.h"
10 #include "SkOSFile.h" 10 #include "SkOSFile.h"
11 #include "SkReadBuffer.h" 11 #include "SkReadBuffer.h"
12 #include "SkWriteBuffer.h" 12 #include "SkWriteBuffer.h"
13 13
14 // Sentinel for when the SkData is inplace new contiguous with its contents. Don 't call!
15 //
16 static void sk_inplace_sentinel_releaseproc(const void*, size_t, void*) {
17 sk_throw();
18 }
19
14 SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) { 20 SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) {
15 fPtr = ptr; 21 fPtr = ptr;
16 fSize = size; 22 fSize = size;
17 fReleaseProc = proc; 23 fReleaseProc = proc;
18 fReleaseProcContext = context; 24 fReleaseProcContext = context;
19 } 25 }
20 26
27 // This constructor means we are inline with our fPtr's contents. Thus we set fP tr
28 // to point right after this. We also set our releaseproc to gInplaceReleaseProc , as a sentinel
bungeman-skia 2014/09/11 15:17:16 update comment from gInplaceReleaseProc?
reed1 2014/09/11 15:28:02 Done.
29 // that we need to handle "delete" ourselves. See internal_displose().
30 //
31 SkData::SkData(size_t size) {
32 fPtr = (char*)(this + 1); // contents are immediately after this
33 fSize = size;
34 fReleaseProc = sk_inplace_sentinel_releaseproc;
35 fReleaseProcContext = NULL;
36 }
37
21 SkData::~SkData() { 38 SkData::~SkData() {
22 if (fReleaseProc) { 39 if (fReleaseProc) {
23 fReleaseProc(fPtr, fSize, fReleaseProcContext); 40 fReleaseProc(fPtr, fSize, fReleaseProcContext);
24 } 41 }
25 } 42 }
26 43
44 void SkData::internal_dispose() const {
45 if (sk_inplace_sentinel_releaseproc == fReleaseProc) {
46 const_cast<SkData*>(this)->fReleaseProc = NULL; // so we don't call i t in our destructor
47
48 this->internal_dispose_restore_refcnt_to_1();
49 this->~SkData(); // explicitly call this for refcnt bookkeeping
50
51 sk_free(const_cast<SkData*>(this));
52 } else {
53 this->internal_dispose_restore_refcnt_to_1();
54 SkDELETE(this);
55 }
56 }
57
27 bool SkData::equals(const SkData* other) const { 58 bool SkData::equals(const SkData* other) const {
28 if (NULL == other) { 59 if (NULL == other) {
29 return false; 60 return false;
30 } 61 }
31 62
32 return fSize == other->fSize && !memcmp(fPtr, other->fPtr, fSize); 63 return fSize == other->fSize && !memcmp(fPtr, other->fPtr, fSize);
33 } 64 }
34 65
35 size_t SkData::copyRange(size_t offset, size_t length, void* buffer) const { 66 size_t SkData::copyRange(size_t offset, size_t length, void* buffer) const {
36 size_t available = fSize; 67 size_t available = fSize;
37 if (offset >= available || 0 == length) { 68 if (offset >= available || 0 == length) {
38 return 0; 69 return 0;
39 } 70 }
40 available -= offset; 71 available -= offset;
41 if (length > available) { 72 if (length > available) {
42 length = available; 73 length = available;
43 } 74 }
44 SkASSERT(length > 0); 75 SkASSERT(length > 0);
45 76
46 memcpy(buffer, this->bytes() + offset, length); 77 memcpy(buffer, this->bytes() + offset, length);
47 return length; 78 return length;
48 } 79 }
49 80
81 SkData* SkData::PrivateNewWithCopy(const void* srcOrNull, size_t length) {
82 if (0 == length) {
83 return SkData::NewEmpty();
84 }
85 char* storage = (char*)sk_malloc_throw(sizeof(SkData) + length);
86 SkData* data = new (storage) SkData(length);
87 if (srcOrNull) {
88 memcpy(data->writable_data(), srcOrNull, length);
89 }
90 return data;
91 }
92
50 /////////////////////////////////////////////////////////////////////////////// 93 ///////////////////////////////////////////////////////////////////////////////
51 94
52 SkData* SkData::NewEmptyImpl() { 95 SkData* SkData::NewEmptyImpl() {
53 return new SkData(NULL, 0, NULL, NULL); 96 return new SkData(NULL, 0, NULL, NULL);
54 } 97 }
98
55 void SkData::DeleteEmpty(SkData* ptr) { SkDELETE(ptr); } 99 void SkData::DeleteEmpty(SkData* ptr) { SkDELETE(ptr); }
56 100
57 SkData* SkData::NewEmpty() { 101 SkData* SkData::NewEmpty() {
58 SK_DECLARE_STATIC_LAZY_PTR(SkData, empty, NewEmptyImpl, DeleteEmpty); 102 SK_DECLARE_STATIC_LAZY_PTR(SkData, empty, NewEmptyImpl, DeleteEmpty);
59 return SkRef(empty.get()); 103 return SkRef(empty.get());
60 } 104 }
61 105
62 // assumes fPtr was allocated via sk_malloc 106 // assumes fPtr was allocated via sk_malloc
63 static void sk_free_releaseproc(const void* ptr, size_t, void*) { 107 static void sk_free_releaseproc(const void* ptr, size_t, void*) {
64 sk_free((void*)ptr); 108 sk_free((void*)ptr);
65 } 109 }
66 110
67 SkData* SkData::NewFromMalloc(const void* data, size_t length) { 111 SkData* SkData::NewFromMalloc(const void* data, size_t length) {
68 return new SkData(data, length, sk_free_releaseproc, NULL); 112 return new SkData(data, length, sk_free_releaseproc, NULL);
69 } 113 }
70 114
71 SkData* SkData::NewWithCopy(const void* data, size_t length) { 115 SkData* SkData::NewWithCopy(const void* src, size_t length) {
72 if (0 == length) { 116 SkASSERT(src);
73 return SkData::NewEmpty(); 117 return PrivateNewWithCopy(src, length);
74 } 118 }
75 119
76 void* copy = sk_malloc_throw(length); // balanced in sk_free_releaseproc 120 SkData* SkData::NewUninitialized(size_t length) {
77 memcpy(copy, data, length); 121 return PrivateNewWithCopy(NULL, length);
78 return new SkData(copy, length, sk_free_releaseproc, NULL);
79 } 122 }
80 123
81 SkData* SkData::NewWithProc(const void* data, size_t length, 124 SkData* SkData::NewWithProc(const void* data, size_t length,
82 ReleaseProc proc, void* context) { 125 ReleaseProc proc, void* context) {
83 return new SkData(data, length, proc, context); 126 return new SkData(data, length, proc, context);
84 } 127 }
85 128
86 // assumes fPtr was allocated with sk_fmmap 129 // assumes fPtr was allocated with sk_fmmap
87 static void sk_mmap_releaseproc(const void* addr, size_t length, void*) { 130 static void sk_mmap_releaseproc(const void* addr, size_t length, void*) {
88 sk_fmunmap(addr, length); 131 sk_fmunmap(addr, length);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 SkData* SkData::NewWithCString(const char cstr[]) { 192 SkData* SkData::NewWithCString(const char cstr[]) {
150 size_t size; 193 size_t size;
151 if (NULL == cstr) { 194 if (NULL == cstr) {
152 cstr = ""; 195 cstr = "";
153 size = 1; 196 size = 1;
154 } else { 197 } else {
155 size = strlen(cstr) + 1; 198 size = strlen(cstr) + 1;
156 } 199 }
157 return NewWithCopy(cstr, size); 200 return NewWithCopy(cstr, size);
158 } 201 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698