OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "DMSrcSink.h" | 8 #include "DMSrcSink.h" |
9 #include "SkAndroidCodec.h" | 9 #include "SkAndroidCodec.h" |
10 #include "SkCodec.h" | 10 #include "SkCodec.h" |
(...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 SkISize size() const override { return fSize; } | 997 SkISize size() const override { return fSize; } |
998 private: | 998 private: |
999 SkISize fSize; | 999 SkISize fSize; |
1000 std::function<Error(SkCanvas*)> fDraw; | 1000 std::function<Error(SkCanvas*)> fDraw; |
1001 }; | 1001 }; |
1002 return sink->draw(ProxySrc(size, draw), bitmap, stream, log); | 1002 return sink->draw(ProxySrc(size, draw), bitmap, stream, log); |
1003 } | 1003 } |
1004 | 1004 |
1005 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 1005 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
1006 | 1006 |
| 1007 DEFINE_bool(check, true, "If true, have most Via- modes fail if they affect the
output."); |
| 1008 |
| 1009 // Is *bitmap identical to what you get drawing src into sink? |
| 1010 static Error check_against_reference(const SkBitmap* bitmap, const Src& src, Sin
k* sink) { |
| 1011 // We can only check raster outputs. |
| 1012 // (Non-raster outputs like .pdf, .skp, .svg may differ but still draw ident
ically.) |
| 1013 if (FLAGS_check && bitmap) { |
| 1014 SkBitmap reference; |
| 1015 SkString log; |
| 1016 Error err = sink->draw(src, &reference, nullptr, &log); |
| 1017 // If we can draw into this Sink via some pipeline, we should be able to
draw directly. |
| 1018 SkASSERT(err.isEmpty()); |
| 1019 if (!err.isEmpty()) { |
| 1020 return err; |
| 1021 } |
| 1022 // The dimensions are a property of the Src only, and so should be ident
ical. |
| 1023 SkASSERT(reference.getSize() == bitmap->getSize()); |
| 1024 if (reference.getSize() != bitmap->getSize()) { |
| 1025 return "Dimensions don't match reference"; |
| 1026 } |
| 1027 // All SkBitmaps in DM are pre-locked and tight, so this comparison is e
asy. |
| 1028 if (0 != memcmp(reference.getPixels(), bitmap->getPixels(), reference.ge
tSize())) { |
| 1029 return "Pixels don't match reference"; |
| 1030 } |
| 1031 } |
| 1032 return ""; |
| 1033 } |
| 1034 |
| 1035 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
| 1036 |
1007 static SkISize auto_compute_translate(SkMatrix* matrix, int srcW, int srcH) { | 1037 static SkISize auto_compute_translate(SkMatrix* matrix, int srcW, int srcH) { |
1008 SkRect bounds = SkRect::MakeIWH(srcW, srcH); | 1038 SkRect bounds = SkRect::MakeIWH(srcW, srcH); |
1009 matrix->mapRect(&bounds); | 1039 matrix->mapRect(&bounds); |
1010 matrix->postTranslate(-bounds.x(), -bounds.y()); | 1040 matrix->postTranslate(-bounds.x(), -bounds.y()); |
1011 return SkISize::Make(SkScalarRoundToInt(bounds.width()), SkScalarRoundToInt(
bounds.height())); | 1041 return SkISize::Make(SkScalarRoundToInt(bounds.width()), SkScalarRoundToInt(
bounds.height())); |
1012 } | 1042 } |
1013 | 1043 |
1014 ViaMatrix::ViaMatrix(SkMatrix matrix, Sink* sink) : Via(sink), fMatrix(matrix) {
} | 1044 ViaMatrix::ViaMatrix(SkMatrix matrix, Sink* sink) : Via(sink), fMatrix(matrix) {
} |
1015 | 1045 |
1016 Error ViaMatrix::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkStr
ing* log) const { | 1046 Error ViaMatrix::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkStr
ing* log) const { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1066 : nullptr); | 1096 : nullptr); |
1067 SkAutoTDelete<SkCanvas> canvas(SkRemote::NewCanvas(cache ? cache : decod
er)); | 1097 SkAutoTDelete<SkCanvas> canvas(SkRemote::NewCanvas(cache ? cache : decod
er)); |
1068 return src.draw(canvas); | 1098 return src.draw(canvas); |
1069 }); | 1099 }); |
1070 } | 1100 } |
1071 | 1101 |
1072 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 1102 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
1073 | 1103 |
1074 Error ViaSerialization::draw( | 1104 Error ViaSerialization::draw( |
1075 const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) cons
t { | 1105 const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) cons
t { |
1076 // Draw the Src directly as a reference. | |
1077 SkBitmap reference; | |
1078 if (bitmap) { | |
1079 Error err = fSink->draw(src, &reference, nullptr, log); | |
1080 if (!err.isEmpty()) { | |
1081 return err; | |
1082 } | |
1083 } | |
1084 | |
1085 // Record our Src into a picture. | 1106 // Record our Src into a picture. |
1086 auto size = src.size(); | 1107 auto size = src.size(); |
1087 SkPictureRecorder recorder; | 1108 SkPictureRecorder recorder; |
1088 Error err = src.draw(recorder.beginRecording(SkIntToScalar(size.width()), | 1109 Error err = src.draw(recorder.beginRecording(SkIntToScalar(size.width()), |
1089 SkIntToScalar(size.height()))); | 1110 SkIntToScalar(size.height()))); |
1090 if (!err.isEmpty()) { | 1111 if (!err.isEmpty()) { |
1091 return err; | 1112 return err; |
1092 } | 1113 } |
1093 SkAutoTUnref<SkPicture> pic(recorder.endRecording()); | 1114 SkAutoTUnref<SkPicture> pic(recorder.endRecording()); |
1094 | 1115 |
1095 // Serialize it and then deserialize it. | 1116 // Serialize it and then deserialize it. |
1096 SkDynamicMemoryWStream wStream; | 1117 SkDynamicMemoryWStream wStream; |
1097 pic->serialize(&wStream); | 1118 pic->serialize(&wStream); |
1098 SkAutoTDelete<SkStream> rStream(wStream.detachAsStream()); | 1119 SkAutoTDelete<SkStream> rStream(wStream.detachAsStream()); |
1099 SkAutoTUnref<SkPicture> deserialized(SkPicture::CreateFromStream(rStream, &l
azy_decode_bitmap)); | 1120 SkAutoTUnref<SkPicture> deserialized(SkPicture::CreateFromStream(rStream, &l
azy_decode_bitmap)); |
1100 | 1121 |
1101 return draw_to_canvas(fSink, bitmap, stream, log, size, [&](SkCanvas* canvas
) { | 1122 return draw_to_canvas(fSink, bitmap, stream, log, size, [&](SkCanvas* canvas
) { |
1102 canvas->drawPicture(deserialized); | 1123 canvas->drawPicture(deserialized); |
1103 // Check against the reference if we have one. | 1124 return check_against_reference(bitmap, src, fSink); |
1104 if (bitmap) { | |
1105 if (reference.getSize() != bitmap->getSize()) { | |
1106 return "Serialized and direct have different dimensions."; | |
1107 } | |
1108 if (0 != memcmp(reference.getPixels(), bitmap->getPixels(), referenc
e.getSize())) { | |
1109 return "Serialized and direct have different pixels."; | |
1110 } | |
1111 } | |
1112 return ""; | |
1113 }); | 1125 }); |
1114 } | 1126 } |
1115 | 1127 |
1116 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 1128 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
1117 | 1129 |
1118 ViaTiles::ViaTiles(int w, int h, SkBBHFactory* factory, Sink* sink) | 1130 ViaTiles::ViaTiles(int w, int h, SkBBHFactory* factory, Sink* sink) |
1119 : Via(sink) | 1131 : Via(sink) |
1120 , fW(w) | 1132 , fW(w) |
1121 , fH(h) | 1133 , fH(h) |
1122 , fFactory(factory) {} | 1134 , fFactory(factory) {} |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 canvas->drawImage(image, SkIntToScalar(i*fW), SkIntToScalar(j*fH
)); | 1174 canvas->drawImage(image, SkIntToScalar(i*fW), SkIntToScalar(j*fH
)); |
1163 } | 1175 } |
1164 } | 1176 } |
1165 surfaces.unrefAll(); | 1177 surfaces.unrefAll(); |
1166 return ""; | 1178 return ""; |
1167 }); | 1179 }); |
1168 } | 1180 } |
1169 | 1181 |
1170 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 1182 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
1171 | 1183 |
| 1184 Error ViaPicture::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkSt
ring* log) const { |
| 1185 auto size = src.size(); |
| 1186 return draw_to_canvas(fSink, bitmap, stream, log, size, [&](SkCanvas* canvas
) -> Error { |
| 1187 SkPictureRecorder recorder; |
| 1188 SkAutoTUnref<SkPicture> pic; |
| 1189 Error err = src.draw(recorder.beginRecording(SkIntToScalar(size.width())
, |
| 1190 SkIntToScalar(size.height()
))); |
| 1191 if (!err.isEmpty()) { |
| 1192 return err; |
| 1193 } |
| 1194 pic.reset(recorder.endRecordingAsPicture()); |
| 1195 canvas->drawPicture(pic); |
| 1196 return check_against_reference(bitmap, src, fSink); |
| 1197 }); |
| 1198 } |
| 1199 |
| 1200 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
| 1201 |
1172 // Draw the Src into two pictures, then draw the second picture into the wrapped
Sink. | 1202 // Draw the Src into two pictures, then draw the second picture into the wrapped
Sink. |
1173 // This tests that any shortcuts we may take while recording that second picture
are legal. | 1203 // This tests that any shortcuts we may take while recording that second picture
are legal. |
1174 Error ViaSecondPicture::draw( | 1204 Error ViaSecondPicture::draw( |
1175 const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) cons
t { | 1205 const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) cons
t { |
1176 auto size = src.size(); | 1206 auto size = src.size(); |
1177 return draw_to_canvas(fSink, bitmap, stream, log, size, [&](SkCanvas* canvas
) -> Error { | 1207 return draw_to_canvas(fSink, bitmap, stream, log, size, [&](SkCanvas* canvas
) -> Error { |
1178 SkPictureRecorder recorder; | 1208 SkPictureRecorder recorder; |
1179 SkAutoTUnref<SkPicture> pic; | 1209 SkAutoTUnref<SkPicture> pic; |
1180 for (int i = 0; i < 2; i++) { | 1210 for (int i = 0; i < 2; i++) { |
1181 Error err = src.draw(recorder.beginRecording(SkIntToScalar(size.widt
h()), | 1211 Error err = src.draw(recorder.beginRecording(SkIntToScalar(size.widt
h()), |
1182 SkIntToScalar(size.heig
ht()))); | 1212 SkIntToScalar(size.heig
ht()))); |
1183 if (!err.isEmpty()) { | 1213 if (!err.isEmpty()) { |
1184 return err; | 1214 return err; |
1185 } | 1215 } |
1186 pic.reset(recorder.endRecordingAsPicture()); | 1216 pic.reset(recorder.endRecordingAsPicture()); |
1187 } | 1217 } |
1188 canvas->drawPicture(pic); | 1218 canvas->drawPicture(pic); |
1189 return ""; | 1219 return check_against_reference(bitmap, src, fSink); |
1190 }); | 1220 }); |
1191 } | 1221 } |
1192 | 1222 |
1193 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 1223 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
1194 | 1224 |
1195 // Draw the Src twice. This can help exercise caching. | 1225 // Draw the Src twice. This can help exercise caching. |
1196 Error ViaTwice::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkStri
ng* log) const { | 1226 Error ViaTwice::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkStri
ng* log) const { |
1197 return draw_to_canvas(fSink, bitmap, stream, log, src.size(), [&](SkCanvas*
canvas) -> Error { | 1227 return draw_to_canvas(fSink, bitmap, stream, log, src.size(), [&](SkCanvas*
canvas) -> Error { |
1198 for (int i = 0; i < 2; i++) { | 1228 for (int i = 0; i < 2; i++) { |
1199 SkAutoCanvasRestore acr(canvas, true/*save now*/); | 1229 SkAutoCanvasRestore acr(canvas, true/*save now*/); |
1200 canvas->clear(SK_ColorTRANSPARENT); | 1230 canvas->clear(SK_ColorTRANSPARENT); |
1201 Error err = src.draw(canvas); | 1231 Error err = src.draw(canvas); |
1202 if (err.isEmpty()) { | 1232 if (err.isEmpty()) { |
1203 return err; | 1233 return err; |
1204 } | 1234 } |
1205 } | 1235 } |
1206 return ""; | 1236 return check_against_reference(bitmap, src, fSink); |
1207 }); | 1237 }); |
1208 } | 1238 } |
1209 | 1239 |
1210 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 1240 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
1211 | 1241 |
1212 // This is like SkRecords::Draw, in that it plays back SkRecords ops into a Canv
as. | 1242 // This is like SkRecords::Draw, in that it plays back SkRecords ops into a Canv
as. |
1213 // Unlike SkRecords::Draw, it builds a single-op sub-picture out of each Draw-ty
pe op. | 1243 // Unlike SkRecords::Draw, it builds a single-op sub-picture out of each Draw-ty
pe op. |
1214 // This is an only-slightly-exaggerated simluation of Blink's Slimming Paint pic
tures. | 1244 // This is an only-slightly-exaggerated simluation of Blink's Slimming Paint pic
tures. |
1215 struct DrawsAsSingletonPictures { | 1245 struct DrawsAsSingletonPictures { |
1216 SkCanvas* fCanvas; | 1246 SkCanvas* fCanvas; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1266 DrawsAsSingletonPictures drawsAsSingletonPictures = { | 1296 DrawsAsSingletonPictures drawsAsSingletonPictures = { |
1267 macroCanvas, | 1297 macroCanvas, |
1268 drawables ? *drawables : empty, | 1298 drawables ? *drawables : empty, |
1269 }; | 1299 }; |
1270 for (int i = 0; i < skr.count(); i++) { | 1300 for (int i = 0; i < skr.count(); i++) { |
1271 skr.visit<void>(i, drawsAsSingletonPictures); | 1301 skr.visit<void>(i, drawsAsSingletonPictures); |
1272 } | 1302 } |
1273 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); | 1303 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); |
1274 | 1304 |
1275 canvas->drawPicture(macroPic); | 1305 canvas->drawPicture(macroPic); |
1276 return ""; | 1306 return check_against_reference(bitmap, src, fSink); |
1277 }); | 1307 }); |
1278 } | 1308 } |
1279 | 1309 |
1280 } // namespace DM | 1310 } // namespace DM |
OLD | NEW |