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

Unified Diff: src/record/SkRecord.h

Issue 248053008: Proof of adoption in SkRecord::replace. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 8 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
« no previous file with comments | « no previous file | src/record/SkRecordOpts.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/record/SkRecord.h
diff --git a/src/record/SkRecord.h b/src/record/SkRecord.h
index ddf1b3d95fabaf927c45bd7152263699f67a7097..b1e4ae24f8da69b5e60aecad189573dbd448c9fd 100644
--- a/src/record/SkRecord.h
+++ b/src/record/SkRecord.h
@@ -82,20 +82,31 @@ public:
// Replace the i-th command with a new command of type T.
// You are expected to placement new an object of type T onto this pointer.
- // References to the old command remain valid for the life of the SkRecord, but
- // you must destroy the old command. (It's okay to destroy it first before calling replace.)
+ // References to the original command are invalidated.
template <typename T>
T* replace(unsigned i) {
SkASSERT(i < this->count());
+
+ Destroyer destroyer;
+ this->mutate(i, destroyer);
+
fTypes[i] = T::kType;
return fRecords[i].set(this->alloc<T>());
}
- // A mutator that can be used with replace to destroy canvas commands.
- struct Destroyer {
- template <typename T>
- void operator()(T* record) { record->~T(); }
- };
+ // Replace the i-th command with a new command of type T.
+ // You are expected to placement new an object of type T onto this pointer.
+ // You must show proof that you've already adopted the existing command.
+ template <typename T, typename Existing>
+ T* replace(unsigned i, const SkRecords::Adopted<Existing>& proofOfAdoption) {
+ SkASSERT(i < this->count());
+
+ SkASSERT(Existing::kType == fTypes[i]);
+ SkASSERT(proofOfAdoption == fRecords[i].ptr<Existing>());
+
+ fTypes[i] = T::kType;
+ return fRecords[i].set(this->alloc<T>());
+ }
private:
// Implementation notes!
@@ -134,6 +145,11 @@ private:
//
// The cost to append a T into this structure is 1 + sizeof(void*) + sizeof(T).
+ // A mutator that can be used with replace to destroy canvas commands.
+ struct Destroyer {
+ template <typename T>
+ void operator()(T* record) { record->~T(); }
+ };
// Logically the same as SkRecords::Type, but packed into 8 bits.
struct Type8 {
@@ -157,6 +173,10 @@ private:
return ptr;
}
+ // Get the data in fAlloc, assuming it's of type T.
+ template <typename T>
+ T* ptr() const { return (T*)fPtr; }
+
// Visit this record with functor F (see public API above) assuming the record we're
// pointing to has this type.
template <typename F>
@@ -176,9 +196,6 @@ private:
}
private:
- template <typename T>
- T* ptr() const { return (T*)fPtr; }
-
void* fPtr;
};
« no previous file with comments | « no previous file | src/record/SkRecordOpts.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698