Add capture snapshot as data to SkWriter32, use it to optimise record->playback.
This is a new way of implementing https://codereview.chromium.org/155863005/
It uses copy on write semantics to return a buffer without copying it, so that record -> playback does not need to copy the buffer.

BUG=skia:2125
R=tomhudson@google.com, mtklein@google.com, reed@google.com, iancottrell@chromium.org

Author: iancottrell@google.com

Review URL: https://codereview.chromium.org/167113003

git-svn-id: http://skia.googlecode.com/svn/trunk@13769 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tests/Writer32Test.cpp b/tests/Writer32Test.cpp
index a471099..f9b6f6a 100644
--- a/tests/Writer32Test.cpp
+++ b/tests/Writer32Test.cpp
@@ -280,3 +280,36 @@
     test_ptr(reporter);
     test_rewind(reporter);
 }
+
+DEF_TEST(Writer32_snapshot, reporter) {
+    int32_t array[] = { 1, 2, 4, 11 };
+    SkSWriter32<sizeof(array) + 4> writer;
+    writer.write(array, sizeof(array));
+    check_contents(reporter, writer, array, sizeof(array));
+    const void* beforeData = writer.contiguousArray();
+    SkAutoDataUnref snapshot(writer.snapshotAsData());
+    // check the snapshot forced a copy of the static data
+    REPORTER_ASSERT(reporter, snapshot->data() != beforeData);
+    REPORTER_ASSERT(reporter, snapshot->size() == writer.bytesWritten());
+}
+
+DEF_TEST(Writer32_snapshot_dynamic, reporter) {
+    int32_t array[] = { 1, 2, 4, 11 };
+    SkWriter32 writer;
+    writer.write(array, sizeof(array));
+    check_contents(reporter, writer, array, sizeof(array));
+    // force a capacity increase so we can test COW behaviour
+    writer.write(array, sizeof(array));
+    writer.rewindToOffset(sizeof(array));
+    const void* beforeData = writer.contiguousArray();
+    SkAutoDataUnref snapshot(writer.snapshotAsData());
+    // check the snapshot still points to the same data as the writer
+    REPORTER_ASSERT(reporter, writer.contiguousArray() == beforeData);
+    REPORTER_ASSERT(reporter, snapshot->data() == beforeData);
+    REPORTER_ASSERT(reporter, snapshot->size() == writer.bytesWritten());
+    // write more data that would fit in the buffer
+    writer.write(array, sizeof(array));
+    // test it triggered COW anyway
+    REPORTER_ASSERT(reporter, writer.contiguousArray() != beforeData);
+}
+