| 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;
 | 
|      };
 | 
|  
 | 
| 
 |