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...) 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...) 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 |