| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2013 Google Inc. | 2  * Copyright 2013 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 "SkBitmapDevice.h" | 
|  | 9 #include "SkBitmapSource.h" | 
|  | 10 #include "SkCanvas.h" | 
|  | 11 #include "SkMallocPixelRef.h" | 
| 8 #include "SkOrderedWriteBuffer.h" | 12 #include "SkOrderedWriteBuffer.h" | 
| 9 #include "SkValidatingReadBuffer.h" | 13 #include "SkValidatingReadBuffer.h" | 
|  | 14 #include "SkXfermodeImageFilter.h" | 
| 10 #include "Test.h" | 15 #include "Test.h" | 
| 11 | 16 | 
| 12 static const uint32_t kArraySize = 64; | 17 static const uint32_t kArraySize = 64; | 
| 13 | 18 | 
| 14 template<typename T> | 19 template<typename T> | 
| 15 static void TestAlignment(T* testObj, skiatest::Reporter* reporter) { | 20 static void TestAlignment(T* testObj, skiatest::Reporter* reporter) { | 
| 16     // Test memory read/write functions directly | 21     // Test memory read/write functions directly | 
| 17     unsigned char dataWritten[1024]; | 22     unsigned char dataWritten[1024]; | 
| 18     size_t bytesWrittenToMemory = testObj->writeToMemory(dataWritten); | 23     size_t bytesWrittenToMemory = testObj->writeToMemory(dataWritten); | 
| 19     REPORTER_ASSERT(reporter, SkAlign4(bytesWrittenToMemory) == bytesWrittenToMe
     mory); | 24     REPORTER_ASSERT(reporter, SkAlign4(bytesWrittenToMemory) == bytesWrittenToMe
     mory); | 
| 20     size_t bytesReadFromMemory = testObj->readFromMemory(dataWritten, bytesWritt
     enToMemory); | 25     size_t bytesReadFromMemory = testObj->readFromMemory(dataWritten, bytesWritt
     enToMemory); | 
| 21     REPORTER_ASSERT(reporter, SkAlign4(bytesReadFromMemory) == bytesReadFromMemo
     ry); | 26     REPORTER_ASSERT(reporter, SkAlign4(bytesReadFromMemory) == bytesReadFromMemo
     ry); | 
| 22 } | 27 } | 
| 23 | 28 | 
| 24 template<typename T> struct SerializationUtils { | 29 template<typename T> struct SerializationUtils { | 
|  | 30     // Generic case for flattenables | 
|  | 31     static void Write(SkOrderedWriteBuffer& writer, const T* flattenable) { | 
|  | 32         writer.writeFlattenable(flattenable); | 
|  | 33     } | 
|  | 34     static void Read(SkValidatingReadBuffer& reader, T** flattenable) { | 
|  | 35         *flattenable = (T*)reader.readFlattenable(T::GetFlattenableType()); | 
|  | 36     } | 
| 25 }; | 37 }; | 
| 26 | 38 | 
| 27 template<> struct SerializationUtils<SkMatrix> { | 39 template<> struct SerializationUtils<SkMatrix> { | 
| 28     static void Write(SkOrderedWriteBuffer& writer, const SkMatrix* matrix) { | 40     static void Write(SkOrderedWriteBuffer& writer, const SkMatrix* matrix) { | 
| 29         writer.writeMatrix(*matrix); | 41         writer.writeMatrix(*matrix); | 
| 30     } | 42     } | 
| 31     static void Read(SkValidatingReadBuffer& reader, SkMatrix* matrix) { | 43     static void Read(SkValidatingReadBuffer& reader, SkMatrix* matrix) { | 
| 32         reader.readMatrix(matrix); | 44         reader.readMatrix(matrix); | 
| 33     } | 45     } | 
| 34 }; | 46 }; | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 120     SerializationUtils<T>::Read(buffer2, &obj2); | 132     SerializationUtils<T>::Read(buffer2, &obj2); | 
| 121     const unsigned char* peekAfter = static_cast<const unsigned char*>(buffer2.s
     kip(0)); | 133     const unsigned char* peekAfter = static_cast<const unsigned char*>(buffer2.s
     kip(0)); | 
| 122     // This should have succeeded, since there are enough bytes to read this | 134     // This should have succeeded, since there are enough bytes to read this | 
| 123     REPORTER_ASSERT(reporter, buffer2.validate(true)); | 135     REPORTER_ASSERT(reporter, buffer2.validate(true)); | 
| 124     REPORTER_ASSERT(reporter, static_cast<size_t>(peekAfter - peekBefore) == byt
     esWritten); | 136     REPORTER_ASSERT(reporter, static_cast<size_t>(peekAfter - peekBefore) == byt
     esWritten); | 
| 125 | 137 | 
| 126     TestAlignment(testObj, reporter); | 138     TestAlignment(testObj, reporter); | 
| 127 } | 139 } | 
| 128 | 140 | 
| 129 template<typename T> | 141 template<typename T> | 
|  | 142 static T* TestFlattenableSerialization(T* testObj, bool shouldSucceed, | 
|  | 143                                        skiatest::Reporter* reporter) { | 
|  | 144     SkOrderedWriteBuffer writer(1024); | 
|  | 145     writer.setFlags(SkOrderedWriteBuffer::kValidation_Flag); | 
|  | 146     SerializationUtils<T>::Write(writer, testObj); | 
|  | 147     size_t bytesWritten = writer.bytesWritten(); | 
|  | 148     REPORTER_ASSERT(reporter, SkAlign4(bytesWritten) == bytesWritten); | 
|  | 149 | 
|  | 150     unsigned char dataWritten[1024]; | 
|  | 151     writer.writeToMemory(dataWritten); | 
|  | 152 | 
|  | 153     // Make sure this fails when it should (test with smaller size, but still mu
     ltiple of 4) | 
|  | 154     SkValidatingReadBuffer buffer(dataWritten, bytesWritten - 4); | 
|  | 155     T* obj = NULL; | 
|  | 156     SerializationUtils<T>::Read(buffer, &obj); | 
|  | 157     REPORTER_ASSERT(reporter, !buffer.validate(true)); | 
|  | 158     REPORTER_ASSERT(reporter, NULL == obj); | 
|  | 159 | 
|  | 160     // Make sure this succeeds when it should | 
|  | 161     SkValidatingReadBuffer buffer2(dataWritten, bytesWritten); | 
|  | 162     const unsigned char* peekBefore = static_cast<const unsigned char*>(buffer2.
     skip(0)); | 
|  | 163     T* obj2 = NULL; | 
|  | 164     SerializationUtils<T>::Read(buffer2, &obj2); | 
|  | 165     const unsigned char* peekAfter = static_cast<const unsigned char*>(buffer2.s
     kip(0)); | 
|  | 166     if (shouldSucceed) { | 
|  | 167         // This should have succeeded, since there are enough bytes to read this | 
|  | 168         REPORTER_ASSERT(reporter, buffer2.validate(true)); | 
|  | 169         REPORTER_ASSERT(reporter, static_cast<size_t>(peekAfter - peekBefore) ==
      bytesWritten); | 
|  | 170         REPORTER_ASSERT(reporter, NULL != obj2); | 
|  | 171     } else { | 
|  | 172         // If the deserialization was supposed to fail, make sure it did | 
|  | 173         REPORTER_ASSERT(reporter, !buffer.validate(true)); | 
|  | 174         REPORTER_ASSERT(reporter, NULL == obj2); | 
|  | 175     } | 
|  | 176 | 
|  | 177     return obj2; // Return object to perform further validity tests on it | 
|  | 178 } | 
|  | 179 | 
|  | 180 template<typename T> | 
| 130 static void TestArraySerialization(T* data, skiatest::Reporter* reporter) { | 181 static void TestArraySerialization(T* data, skiatest::Reporter* reporter) { | 
| 131     SkOrderedWriteBuffer writer(1024); | 182     SkOrderedWriteBuffer writer(1024); | 
| 132     writer.setFlags(SkOrderedWriteBuffer::kValidation_Flag); | 183     writer.setFlags(SkOrderedWriteBuffer::kValidation_Flag); | 
| 133     SerializationUtils<T>::Write(writer, data, kArraySize); | 184     SerializationUtils<T>::Write(writer, data, kArraySize); | 
| 134     size_t bytesWritten = writer.bytesWritten(); | 185     size_t bytesWritten = writer.bytesWritten(); | 
| 135     // This should write the length (in 4 bytes) and the array | 186     // This should write the length (in 4 bytes) and the array | 
| 136     REPORTER_ASSERT(reporter, (4 + kArraySize * sizeof(T)) == bytesWritten); | 187     REPORTER_ASSERT(reporter, (4 + kArraySize * sizeof(T)) == bytesWritten); | 
| 137 | 188 | 
| 138     unsigned char dataWritten[1024]; | 189     unsigned char dataWritten[1024]; | 
| 139     writer.writeToMemory(dataWritten); | 190     writer.writeToMemory(dataWritten); | 
| 140 | 191 | 
| 141     // Make sure this fails when it should | 192     // Make sure this fails when it should | 
| 142     SkValidatingReadBuffer buffer(dataWritten, bytesWritten); | 193     SkValidatingReadBuffer buffer(dataWritten, bytesWritten); | 
| 143     T dataRead[kArraySize]; | 194     T dataRead[kArraySize]; | 
| 144     bool success = SerializationUtils<T>::Read(buffer, dataRead, kArraySize / 2)
     ; | 195     bool success = SerializationUtils<T>::Read(buffer, dataRead, kArraySize / 2)
     ; | 
| 145     // This should have failed, since the provided size was too small | 196     // This should have failed, since the provided size was too small | 
| 146     REPORTER_ASSERT(reporter, !success); | 197     REPORTER_ASSERT(reporter, !success); | 
| 147 | 198 | 
| 148     // Make sure this succeeds when it should | 199     // Make sure this succeeds when it should | 
| 149     SkValidatingReadBuffer buffer2(dataWritten, bytesWritten); | 200     SkValidatingReadBuffer buffer2(dataWritten, bytesWritten); | 
| 150     success = SerializationUtils<T>::Read(buffer2, dataRead, kArraySize); | 201     success = SerializationUtils<T>::Read(buffer2, dataRead, kArraySize); | 
| 151     // This should have succeeded, since there are enough bytes to read this | 202     // This should have succeeded, since there are enough bytes to read this | 
| 152     REPORTER_ASSERT(reporter, success); | 203     REPORTER_ASSERT(reporter, success); | 
| 153 } | 204 } | 
| 154 | 205 | 
|  | 206 static void TestBitmapSerialization(const SkBitmap& validBitmap, | 
|  | 207                                     const SkBitmap& invalidBitmap, | 
|  | 208                                     bool shouldSucceed, | 
|  | 209                                     skiatest::Reporter* reporter) { | 
|  | 210     SkBitmapSource validBitmapSource(validBitmap); | 
|  | 211     SkBitmapSource invalidBitmapSource(invalidBitmap); | 
|  | 212     SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(SkXfermode::kSrcOver_Mode))
     ; | 
|  | 213     SkXfermodeImageFilter xfermodeImageFilter(mode, &invalidBitmapSource, &valid
     BitmapSource); | 
|  | 214 | 
|  | 215     SkAutoTUnref<SkImageFilter> deserializedFilter( | 
|  | 216         TestFlattenableSerialization<SkImageFilter>( | 
|  | 217             &xfermodeImageFilter, shouldSucceed, reporter)); | 
|  | 218 | 
|  | 219     // Try to render a small bitmap using the invalid deserialized filter | 
|  | 220     // to make sure we don't crash while trying to render it | 
|  | 221     if (shouldSucceed) { | 
|  | 222         SkBitmap bitmap; | 
|  | 223         bitmap.setConfig(SkBitmap::kARGB_8888_Config, 24, 24); | 
|  | 224         bitmap.allocPixels(); | 
|  | 225         SkBitmapDevice device(bitmap); | 
|  | 226         SkCanvas canvas(&device); | 
|  | 227         canvas.clear(0x00000000); | 
|  | 228         SkPaint paint; | 
|  | 229         paint.setImageFilter(deserializedFilter); | 
|  | 230         canvas.clipRect(SkRect::MakeXYWH(0, 0, SkIntToScalar(24), SkIntToScalar(
     24))); | 
|  | 231         canvas.drawBitmap(bitmap, 0, 0, &paint); | 
|  | 232     } | 
|  | 233 } | 
|  | 234 | 
| 155 static void Tests(skiatest::Reporter* reporter) { | 235 static void Tests(skiatest::Reporter* reporter) { | 
| 156     // Test matrix serialization | 236     // Test matrix serialization | 
| 157     { | 237     { | 
| 158         SkMatrix matrix = SkMatrix::I(); | 238         SkMatrix matrix = SkMatrix::I(); | 
| 159         TestObjectSerialization(&matrix, reporter); | 239         TestObjectSerialization(&matrix, reporter); | 
| 160      } | 240      } | 
| 161 | 241 | 
| 162     // Test path serialization | 242     // Test path serialization | 
| 163     { | 243     { | 
| 164         SkPath path; | 244         SkPath path; | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 205     { | 285     { | 
| 206         SkPoint data[kArraySize] = { {6, 7}, {42, 128} }; | 286         SkPoint data[kArraySize] = { {6, 7}, {42, 128} }; | 
| 207         TestArraySerialization(data, reporter); | 287         TestArraySerialization(data, reporter); | 
| 208     } | 288     } | 
| 209 | 289 | 
| 210     // Test readScalarArray | 290     // Test readScalarArray | 
| 211     { | 291     { | 
| 212         SkScalar data[kArraySize] = { SK_Scalar1, SK_ScalarHalf, SK_ScalarMax }; | 292         SkScalar data[kArraySize] = { SK_Scalar1, SK_ScalarHalf, SK_ScalarMax }; | 
| 213         TestArraySerialization(data, reporter); | 293         TestArraySerialization(data, reporter); | 
| 214     } | 294     } | 
|  | 295 | 
|  | 296     // Test invalid deserializations | 
|  | 297     { | 
|  | 298         SkBitmap validBitmap; | 
|  | 299         validBitmap.setConfig(SkBitmap::kARGB_8888_Config, 256, 256); | 
|  | 300 | 
|  | 301         // Create a bitmap with a really large height | 
|  | 302         SkBitmap invalidBitmap; | 
|  | 303         invalidBitmap.setConfig(SkBitmap::kARGB_8888_Config, 256, 1000000000); | 
|  | 304 | 
|  | 305         // The deserialization should succeed, and the rendering shouldn't crash
     , | 
|  | 306         // even when the device fails to initialize, due to its size | 
|  | 307         TestBitmapSerialization(validBitmap, invalidBitmap, true, reporter); | 
|  | 308 | 
|  | 309         // Create a bitmap with a pixel ref too small | 
|  | 310         SkBitmap invalidBitmap2; | 
|  | 311         invalidBitmap2.setConfig(SkBitmap::kARGB_8888_Config, 256, 256); | 
|  | 312         invalidBitmap2.setPixelRef(SkNEW_ARGS(SkMallocPixelRef, | 
|  | 313             (NULL, 256, NULL)))->unref(); | 
|  | 314 | 
|  | 315         // The deserialization should detect the pixel ref being too small and f
     ail | 
|  | 316         TestBitmapSerialization(validBitmap, invalidBitmap2, false, reporter); | 
|  | 317     } | 
| 215 } | 318 } | 
| 216 | 319 | 
| 217 #include "TestClassDef.h" | 320 #include "TestClassDef.h" | 
| 218 DEFINE_TESTCLASS("Serialization", SerializationClass, Tests) | 321 DEFINE_TESTCLASS("Serialization", SerializationClass, Tests) | 
| OLD | NEW | 
|---|