Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | List of all members
BenchmarkStream Class Reference

Public Member Functions

 BenchmarkStream ()
 
Benchmarknext ()
 
BenchmarkrawNext ()
 
void fillCurrentOptions (NanoJSONResultsWriter &log) const
 
void fillCurrentMetrics (NanoJSONResultsWriter &log) const
 

Static Public Member Functions

static sk_sp< SkPictureReadPicture (const char *path)
 
static std::unique_ptr< MSKPPlayerReadMSKP (const char *path)
 
static sk_sp< SkPictureReadSVGPicture (const char *path)
 

Detailed Description

Definition at line 792 of file nanobench.cpp.

Constructor & Destructor Documentation

◆ BenchmarkStream()

BenchmarkStream::BenchmarkStream ( )
inline

Definition at line 794 of file nanobench.cpp.

794 : fBenches(BenchRegistry::Head())
795 , fGMs(skiagm::GMRegistry::Head()) {
796 collect_files(FLAGS_skps, ".skp", &fSKPs);
797 collect_files(FLAGS_mskps, ".mskp", &fMSKPs);
798 collect_files(FLAGS_svgs, ".svg", &fSVGs);
799 collect_files(FLAGS_texttraces, ".trace", &fTextBlobTraces);
800
801 if (4 != sscanf(FLAGS_clip[0], "%d,%d,%d,%d",
802 &fClip.fLeft, &fClip.fTop, &fClip.fRight, &fClip.fBottom)) {
803 SkDebugf("Can't parse %s from --clip as an SkIRect.\n", FLAGS_clip[0]);
804 exit(1);
805 }
806
807 for (int i = 0; i < FLAGS_scales.size(); i++) {
808 if (1 != sscanf(FLAGS_scales[i], "%f", &fScales.push_back())) {
809 SkDebugf("Can't parse %s from --scales as an SkScalar.\n", FLAGS_scales[i]);
810 exit(1);
811 }
812 }
813
814 if (2 != sscanf(FLAGS_zoom[0], "%f,%lf", &fZoomMax, &fZoomPeriodMs)) {
815 SkDebugf("Can't parse %s from --zoom as a zoomMax,zoomPeriodMs.\n", FLAGS_zoom[0]);
816 exit(1);
817 }
818
819 // Prepare the images for decoding
820 if (!CommonFlags::CollectImages(FLAGS_images, &fImages)) {
821 exit(1);
822 }
823
824 // Choose the candidate color types for image decoding
825 fColorTypes.push_back(kN32_SkColorType);
826 if (!FLAGS_simpleCodec) {
827 fColorTypes.push_back(kRGB_565_SkColorType);
828 fColorTypes.push_back(kAlpha_8_SkColorType);
829 fColorTypes.push_back(kGray_8_SkColorType);
830 }
831 }
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition: SkColorType.h:21
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition: SkColorType.h:35
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition: SkColorType.h:22
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static const Registry * Head()
Definition: Registry.h:29
bool CollectImages(const CommandLineFlags::StringArray &dir, skia_private::TArray< SkString > *output)
exit(kErrorExitCode)
static void collect_files(const CommandLineFlags::StringArray &paths, const char *ext, TArray< SkString > *list)
Definition: nanobench.cpp:776
int32_t fBottom
larger y-axis bounds
Definition: SkRect.h:36
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:34
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:33
int32_t fRight
larger x-axis bounds
Definition: SkRect.h:35

Member Function Documentation

◆ fillCurrentMetrics()

void BenchmarkStream::fillCurrentMetrics ( NanoJSONResultsWriter log) const
inline

Definition at line 1264 of file nanobench.cpp.

1264 {
1265 if (0 == strcmp(fBenchType, "recording")) {
1266 log.appendMetric("bytes", fSKPBytes);
1267 log.appendMetric("ops", fSKPOps);
1268 }
1269 }

◆ fillCurrentOptions()

void BenchmarkStream::fillCurrentOptions ( NanoJSONResultsWriter log) const
inline

Definition at line 1252 of file nanobench.cpp.

1252 {
1253 log.appendCString("source_type", fSourceType);
1254 log.appendCString("bench_type", fBenchType);
1255 if (0 == strcmp(fSourceType, "skp")) {
1256 log.appendString("clip",
1257 SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop,
1258 fClip.fRight, fClip.fBottom));
1259 SkASSERT_RELEASE(fCurrentScale < fScales.size()); // debugging paranoia
1260 log.appendString("scale", SkStringPrintf("%.2g", fScales[fCurrentScale]));
1261 }
1262 }
#define SkASSERT_RELEASE(cond)
Definition: SkAssert.h:100
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
int size() const
Definition: SkTArray.h:421

◆ next()

Benchmark * BenchmarkStream::next ( )
inline

Definition at line 901 of file nanobench.cpp.

901 {
902 std::unique_ptr<Benchmark> bench;
903 do {
904 bench.reset(this->rawNext());
905 if (!bench) {
906 return nullptr;
907 }
908 } while (CommandLineFlags::ShouldSkip(FLAGS_sourceType, fSourceType) ||
909 CommandLineFlags::ShouldSkip(FLAGS_benchType, fBenchType));
910 return bench.release();
911 }
static void bench(NanoJSONResultsWriter *log, const char *name, int bytes)
Definition: SkSLBench.cpp:285
Benchmark * rawNext()
Definition: nanobench.cpp:913
static bool ShouldSkip(const SkTDArray< const char * > &strings, const char *name)

◆ rawNext()

Benchmark * BenchmarkStream::rawNext ( )
inline

Definition at line 913 of file nanobench.cpp.

913 {
914 if (fBenches) {
915 Benchmark* bench = fBenches->get()(nullptr);
916 fBenches = fBenches->next();
917 fSourceType = "bench";
918 fBenchType = "micro";
919 return bench;
920 }
921
922 while (fGMs) {
923 std::unique_ptr<skiagm::GM> gm = fGMs->get()();
924 if (gm->isBazelOnly()) {
925 // We skip Bazel-only GMs because they might not be regular GMs. The Bazel build
926 // reuses the notion of GMs to replace the notion of DM sources of various kinds,
927 // such as codec sources and image generation sources. See comments in the
928 // skiagm::GM::isBazelOnly function declaration for context.
929 continue;
930 }
931 fGMs = fGMs->next();
932 if (gm->runAsBench()) {
933 fSourceType = "gm";
934 fBenchType = "micro";
935 return new GMBench(std::move(gm));
936 }
937 }
938
939 while (fCurrentTextBlobTrace < fTextBlobTraces.size()) {
940 SkString path = fTextBlobTraces[fCurrentTextBlobTrace++];
942 static constexpr char kEnding[] = ".trace";
943 if (basename.endsWith(kEnding)) {
944 basename.remove(basename.size() - strlen(kEnding), strlen(kEnding));
945 }
946 fSourceType = "texttrace";
947 fBenchType = "micro";
949 SkStringPrintf("SkDiffBench-%s", basename.c_str()),
950 [path](){ return SkStream::MakeFromFile(path.c_str()); });
951 }
952
953 // First add all .skps as RecordingBenches.
954 while (fCurrentRecording < fSKPs.size()) {
955 const SkString& path = fSKPs[fCurrentRecording++];
956 sk_sp<SkPicture> pic = ReadPicture(path.c_str());
957 if (!pic) {
958 continue;
959 }
961 fSourceType = "skp";
962 fBenchType = "recording";
963 fSKPBytes = static_cast<double>(pic->approximateBytesUsed());
964 fSKPOps = pic->approximateOpCount();
965 return new RecordingBench(name.c_str(), pic.get(), FLAGS_bbh);
966 }
967
968 // Add all .skps as DeserializePictureBenchs.
969 while (fCurrentDeserialPicture < fSKPs.size()) {
970 const SkString& path = fSKPs[fCurrentDeserialPicture++];
972 if (!data) {
973 continue;
974 }
976 fSourceType = "skp";
977 fBenchType = "deserial";
978 fSKPBytes = static_cast<double>(data->size());
979 fSKPOps = 0;
980 return new DeserializePictureBench(name.c_str(), std::move(data));
981 }
982
983 // Then once each for each scale as SKPBenches (playback).
984 while (fCurrentScale < fScales.size()) {
985 while (fCurrentSKP < fSKPs.size()) {
986 const SkString& path = fSKPs[fCurrentSKP++];
987 sk_sp<SkPicture> pic = ReadPicture(path.c_str());
988 if (!pic) {
989 continue;
990 }
991
992 if (FLAGS_bbh) {
993 // The SKP we read off disk doesn't have a BBH. Re-record so it grows one.
994 SkRTreeFactory factory;
995 SkPictureRecorder recorder;
996 pic->playback(recorder.beginRecording(pic->cullRect().width(),
997 pic->cullRect().height(),
998 &factory));
999 pic = recorder.finishRecordingAsPicture();
1000 }
1002 fSourceType = "skp";
1003 fBenchType = "playback";
1004 return new SKPBench(name.c_str(), pic.get(), fClip, fScales[fCurrentScale],
1005 FLAGS_loopSKP);
1006 }
1007
1008 while (fCurrentSVG < fSVGs.size()) {
1009 const char* path = fSVGs[fCurrentSVG++].c_str();
1011 fSourceType = "svg";
1012 fBenchType = "playback";
1013 return new SKPBench(SkOSPath::Basename(path).c_str(), pic.get(), fClip,
1014 fScales[fCurrentScale], FLAGS_loopSKP);
1015 }
1016 }
1017
1018 fCurrentSKP = 0;
1019 fCurrentSVG = 0;
1020 fCurrentScale++;
1021 }
1022
1023 // Now loop over each skp again if we have an animation
1024 if (fZoomMax != 1.0f && fZoomPeriodMs > 0) {
1025 while (fCurrentAnimSKP < fSKPs.size()) {
1026 const SkString& path = fSKPs[fCurrentAnimSKP];
1027 sk_sp<SkPicture> pic = ReadPicture(path.c_str());
1028 if (!pic) {
1029 fCurrentAnimSKP++;
1030 continue;
1031 }
1032
1033 fCurrentAnimSKP++;
1036 SKPAnimationBench::MakeZoomAnimation(fZoomMax, fZoomPeriodMs);
1037 return new SKPAnimationBench(name.c_str(), pic.get(), fClip, std::move(animation),
1038 FLAGS_loopSKP);
1039 }
1040 }
1041
1042 // Read all MSKPs as benches
1043 while (fCurrentMSKP < fMSKPs.size()) {
1044 const SkString& path = fMSKPs[fCurrentMSKP++];
1045 std::unique_ptr<MSKPPlayer> player = ReadMSKP(path.c_str());
1046 if (!player) {
1047 continue;
1048 }
1050 fSourceType = "mskp";
1051 fBenchType = "mskp";
1052 return new MSKPBench(std::move(name), std::move(player));
1053 }
1054
1055 for (; fCurrentCodec < fImages.size(); fCurrentCodec++) {
1056 fSourceType = "image";
1057 fBenchType = "skcodec";
1058 const SkString& path = fImages[fCurrentCodec];
1059 if (CommandLineFlags::ShouldSkip(FLAGS_match, path.c_str())) {
1060 continue;
1061 }
1063 std::unique_ptr<SkCodec> codec(SkCodec::MakeFromData(encoded));
1064 if (!codec) {
1065 // Nothing to time.
1066 SkDebugf("Cannot find codec for %s\n", path.c_str());
1067 continue;
1068 }
1069
1070 while (fCurrentColorType < fColorTypes.size()) {
1071 const SkColorType colorType = fColorTypes[fCurrentColorType];
1072
1073 SkAlphaType alphaType = codec->getInfo().alphaType();
1074 if (FLAGS_simpleCodec) {
1075 if (kUnpremul_SkAlphaType == alphaType) {
1076 alphaType = kPremul_SkAlphaType;
1077 }
1078
1079 fCurrentColorType++;
1080 } else {
1081 switch (alphaType) {
1083 // We only need to test one alpha type (opaque).
1084 fCurrentColorType++;
1085 break;
1088 if (0 == fCurrentAlphaType) {
1089 // Test unpremul first.
1090 alphaType = kUnpremul_SkAlphaType;
1091 fCurrentAlphaType++;
1092 } else {
1093 // Test premul.
1094 alphaType = kPremul_SkAlphaType;
1095 fCurrentAlphaType = 0;
1096 fCurrentColorType++;
1097 }
1098 break;
1099 default:
1100 SkASSERT(false);
1101 fCurrentColorType++;
1102 break;
1103 }
1104 }
1105
1106 // Make sure we can decode to this color type and alpha type.
1108 codec->getInfo().makeColorType(colorType).makeAlphaType(alphaType);
1109 const size_t rowBytes = info.minRowBytes();
1110 SkAutoMalloc storage(info.computeByteSize(rowBytes));
1111
1112 const SkCodec::Result result = codec->getPixels(
1113 info, storage.get(), rowBytes);
1114 switch (result) {
1115 case SkCodec::kSuccess:
1117 return new CodecBench(SkOSPath::Basename(path.c_str()),
1118 encoded.get(), colorType, alphaType);
1120 // This is okay. Not all conversions are valid.
1121 break;
1122 default:
1123 // This represents some sort of failure.
1124 SkASSERT(false);
1125 break;
1126 }
1127 }
1128 fCurrentColorType = 0;
1129 }
1130
1131 // Run AndroidCodecBenches
1132 const int sampleSizes[] = { 2, 4, 8 };
1133 for (; fCurrentAndroidCodec < fImages.size(); fCurrentAndroidCodec++) {
1134 fSourceType = "image";
1135 fBenchType = "skandroidcodec";
1136
1137 const SkString& path = fImages[fCurrentAndroidCodec];
1138 if (CommandLineFlags::ShouldSkip(FLAGS_match, path.c_str())) {
1139 continue;
1140 }
1142 std::unique_ptr<SkAndroidCodec> codec(SkAndroidCodec::MakeFromData(encoded));
1143 if (!codec) {
1144 // Nothing to time.
1145 SkDebugf("Cannot find codec for %s\n", path.c_str());
1146 continue;
1147 }
1148
1149 while (fCurrentSampleSize < (int) std::size(sampleSizes)) {
1150 int sampleSize = sampleSizes[fCurrentSampleSize];
1151 fCurrentSampleSize++;
1152 if (10 * sampleSize > std::min(codec->getInfo().width(), codec->getInfo().height())) {
1153 // Avoid benchmarking scaled decodes of already small images.
1154 break;
1155 }
1156
1157 return new AndroidCodecBench(SkOSPath::Basename(path.c_str()),
1158 encoded.get(), sampleSize);
1159 }
1160 fCurrentSampleSize = 0;
1161 }
1162
1163#ifdef SK_ENABLE_ANDROID_UTILS
1164 // Run the BRDBenches
1165 // We intend to create benchmarks that model the use cases in
1166 // android/libraries/social/tiledimage. In this library, an image is decoded in 512x512
1167 // tiles. The image can be translated freely, so the location of a tile may be anywhere in
1168 // the image. For that reason, we will benchmark decodes in five representative locations
1169 // in the image. Additionally, this use case utilizes power of two scaling, so we will
1170 // test on power of two sample sizes. The output tile is always 512x512, so, when a
1171 // sampleSize is used, the size of the subset that is decoded is always
1172 // (sampleSize*512)x(sampleSize*512).
1173 // There are a few good reasons to only test on power of two sample sizes at this time:
1174 // All use cases we are aware of only scale by powers of two.
1175 // PNG decodes use the indicated sampling strategy regardless of the sample size, so
1176 // these tests are sufficient to provide good coverage of our scaling options.
1177 const uint32_t brdSampleSizes[] = { 1, 2, 4, 8, 16 };
1178 const uint32_t minOutputSize = 512;
1179 for (; fCurrentBRDImage < fImages.size(); fCurrentBRDImage++) {
1180 fSourceType = "image";
1181 fBenchType = "BRD";
1182
1183 const SkString& path = fImages[fCurrentBRDImage];
1184 if (CommandLineFlags::ShouldSkip(FLAGS_match, path.c_str())) {
1185 continue;
1186 }
1187
1188 while (fCurrentColorType < fColorTypes.size()) {
1189 while (fCurrentSampleSize < (int) std::size(brdSampleSizes)) {
1190 while (fCurrentSubsetType <= kLastSingle_SubsetType) {
1191
1193 const SkColorType colorType = fColorTypes[fCurrentColorType];
1194 uint32_t sampleSize = brdSampleSizes[fCurrentSampleSize];
1195 int currentSubsetType = fCurrentSubsetType++;
1196
1197 int width = 0;
1198 int height = 0;
1199 if (!valid_brd_bench(encoded, colorType, sampleSize, minOutputSize,
1200 &width, &height)) {
1201 break;
1202 }
1203
1205 SkIRect subset;
1206 const uint32_t subsetSize = sampleSize * minOutputSize;
1207 switch (currentSubsetType) {
1208 case kTopLeft_SubsetType:
1209 basename.append("_TopLeft");
1210 subset = SkIRect::MakeXYWH(0, 0, subsetSize, subsetSize);
1211 break;
1212 case kTopRight_SubsetType:
1213 basename.append("_TopRight");
1214 subset = SkIRect::MakeXYWH(width - subsetSize, 0, subsetSize,
1215 subsetSize);
1216 break;
1217 case kMiddle_SubsetType:
1218 basename.append("_Middle");
1219 subset = SkIRect::MakeXYWH((width - subsetSize) / 2,
1220 (height - subsetSize) / 2, subsetSize, subsetSize);
1221 break;
1222 case kBottomLeft_SubsetType:
1223 basename.append("_BottomLeft");
1224 subset = SkIRect::MakeXYWH(0, height - subsetSize, subsetSize,
1225 subsetSize);
1226 break;
1227 case kBottomRight_SubsetType:
1228 basename.append("_BottomRight");
1229 subset = SkIRect::MakeXYWH(width - subsetSize,
1230 height - subsetSize, subsetSize, subsetSize);
1231 break;
1232 default:
1233 SkASSERT(false);
1234 }
1235
1236 return new BitmapRegionDecoderBench(basename.c_str(), encoded.get(),
1237 colorType, sampleSize, subset);
1238 }
1239 fCurrentSubsetType = 0;
1240 fCurrentSampleSize++;
1241 }
1242 fCurrentSampleSize = 0;
1243 fCurrentColorType++;
1244 }
1245 fCurrentColorType = 0;
1246 }
1247#endif // SK_ENABLE_ANDROID_UTILS
1248
1249 return nullptr;
1250 }
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
kUnpremul_SkAlphaType
SkAlphaType
Definition: SkAlphaType.h:26
@ kOpaque_SkAlphaType
pixel is opaque
Definition: SkAlphaType.h:28
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkColorType
Definition: SkColorType.h:19
Benchmark * CreateDiffCanvasBench(SkString name, std::function< std::unique_ptr< SkStreamAsset >()> dataSrc)
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static std::unique_ptr< MSKPPlayer > ReadMSKP(const char *path)
Definition: nanobench.cpp:849
static sk_sp< SkPicture > ReadSVGPicture(const char *path)
Definition: nanobench.cpp:865
static sk_sp< SkPicture > ReadPicture(const char *path)
Definition: nanobench.cpp:833
static sk_sp< Animation > MakeZoomAnimation(SkScalar zoomMax, double zoomPeriodMs)
static std::unique_ptr< SkAndroidCodec > MakeFromData(sk_sp< SkData >, SkPngChunkReader *=nullptr)
static std::unique_ptr< SkCodec > MakeFromData(sk_sp< SkData >, SkSpan< const SkCodecs::Decoder > decoders, SkPngChunkReader *=nullptr)
Definition: SkCodec.cpp:241
Result
Definition: SkCodec.h:76
@ kInvalidConversion
Definition: SkCodec.h:96
@ kIncompleteInput
Definition: SkCodec.h:84
@ kSuccess
Definition: SkCodec.h:80
static sk_sp< SkData > MakeFromFileName(const char path[])
Definition: SkData.cpp:148
static SkString Basename(const char *fullPath)
Definition: SkOSPath.cpp:23
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPicture()
virtual SkRect cullRect() const =0
virtual void playback(SkCanvas *canvas, AbortCallback *callback=nullptr) const =0
virtual size_t approximateBytesUsed() const =0
virtual int approximateOpCount(bool nested=false) const =0
T * get() const
Definition: SkRefCnt.h:303
const T & get() const
Definition: Registry.h:32
const Registry * next() const
Definition: Registry.h:31
GAsyncResult * result
static float min(float r, float g, float b)
Definition: hsl.cpp:48
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
basename
Definition: malisc.py:23
int32_t height
int32_t width
Definition: SkRect.h:32
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
Definition: SkRect.h:104
constexpr float height() const
Definition: SkRect.h:769
constexpr float width() const
Definition: SkRect.h:762
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63

◆ ReadMSKP()

static std::unique_ptr< MSKPPlayer > BenchmarkStream::ReadMSKP ( const char *  path)
inlinestatic

Definition at line 849 of file nanobench.cpp.

849 {
850 // Not strictly necessary, as it will be checked again later,
851 // but helps to avoid a lot of pointless work if we're going to skip it.
852 if (CommandLineFlags::ShouldSkip(FLAGS_match, SkOSPath::Basename(path).c_str())) {
853 return nullptr;
854 }
855
856 std::unique_ptr<SkStreamSeekable> stream = SkStream::MakeFromFile(path);
857 if (!stream) {
858 SkDebugf("Could not read %s.\n", path);
859 return nullptr;
860 }
861
862 return MSKPPlayer::Make(stream.get());
863 }
static std::unique_ptr< MSKPPlayer > Make(SkStreamSeekable *stream)
Definition: MSKPPlayer.cpp:386
static std::unique_ptr< SkStreamAsset > MakeFromFile(const char path[])
Definition: SkStream.cpp:922

◆ ReadPicture()

static sk_sp< SkPicture > BenchmarkStream::ReadPicture ( const char *  path)
inlinestatic

Definition at line 833 of file nanobench.cpp.

833 {
834 // Not strictly necessary, as it will be checked again later,
835 // but helps to avoid a lot of pointless work if we're going to skip it.
836 if (CommandLineFlags::ShouldSkip(FLAGS_match, SkOSPath::Basename(path).c_str())) {
837 return nullptr;
838 }
839
840 std::unique_ptr<SkStream> stream = SkStream::MakeFromFile(path);
841 if (!stream) {
842 SkDebugf("Could not read %s.\n", path);
843 return nullptr;
844 }
845
846 return SkPicture::MakeFromStream(stream.get());
847 }
static sk_sp< SkPicture > MakeFromStream(SkStream *stream, const SkDeserialProcs *procs=nullptr)
Definition: SkPicture.cpp:147

◆ ReadSVGPicture()

static sk_sp< SkPicture > BenchmarkStream::ReadSVGPicture ( const char *  path)
inlinestatic

Definition at line 865 of file nanobench.cpp.

865 {
866 if (CommandLineFlags::ShouldSkip(FLAGS_match, SkOSPath::Basename(path).c_str())) {
867 return nullptr;
868 }
870 if (!data) {
871 SkDebugf("Could not read %s.\n", path);
872 return nullptr;
873 }
874
875#if defined(SK_ENABLE_SVG)
876 SkMemoryStream stream(std::move(data));
878 .setFontManager(ToolUtils::TestFontMgr())
879 .setTextShapingFactory(SkShapers::BestAvailable())
880 .make(stream);
881 if (!svgDom) {
882 SkDebugf("Could not parse %s.\n", path);
883 return nullptr;
884 }
885
886 // Use the intrinsic SVG size if available, otherwise fall back to a default value.
887 static const SkSize kDefaultContainerSize = SkSize::Make(128, 128);
888 if (svgDom->containerSize().isEmpty()) {
889 svgDom->setContainerSize(kDefaultContainerSize);
890 }
891
892 SkPictureRecorder recorder;
893 svgDom->render(recorder.beginRecording(svgDom->containerSize().width(),
894 svgDom->containerSize().height()));
895 return recorder.finishRecordingAsPicture();
896#else
897 return nullptr;
898#endif // defined(SK_ENABLE_SVG)
899 }
void render(SkCanvas *) const
Definition: SkSVGDOM.cpp:460
void setContainerSize(const SkSize &)
Definition: SkSVGDOM.cpp:497
const SkSize & containerSize() const
Definition: SkSVGDOM.cpp:493
sk_sp< Factory > BestAvailable()
sk_sp< SkFontMgr > TestFontMgr()
DlVertices::Builder Builder
Definition: SkSize.h:52
static constexpr SkSize Make(SkScalar w, SkScalar h)
Definition: SkSize.h:56
bool isEmpty() const
Definition: SkSize.h:71
SkScalar width() const
Definition: SkSize.h:76
SkScalar height() const
Definition: SkSize.h:77

The documentation for this class was generated from the following file: