| Index: dm/DM.cpp
|
| diff --git a/dm/DM.cpp b/dm/DM.cpp
|
| index ace49076ac74427c58486d13e43ea4acf59aeed1..eba76420d54a0e741f5cc41102cd889003c7b7b1 100644
|
| --- a/dm/DM.cpp
|
| +++ b/dm/DM.cpp
|
| @@ -776,6 +776,10 @@ static ImplicitString is_blacklisted(const char* sink, const char* src,
|
| return "";
|
| }
|
|
|
| +// Even when a Task Sink reports to be non-threadsafe (e.g. GPU), we know things like
|
| +// .png encoding are definitely thread safe. This lets us offload that work to CPU threads.
|
| +static SkTaskGroup gDefinitelyThreadSafeWork;
|
| +
|
| // The finest-grained unit of work we can run: draw a single Src into a single Sink,
|
| // report any errors, and perhaps write out the output: a .png of the bitmap, or a raw stream.
|
| struct Task {
|
| @@ -823,55 +827,63 @@ struct Task {
|
| name, note, log);
|
| return;
|
| }
|
| - SkAutoTDelete<SkStreamAsset> data(stream.detachAsStream());
|
| -
|
| - SkString md5;
|
| - if (!FLAGS_writePath.isEmpty() || !FLAGS_readPath.isEmpty()) {
|
| - SkMD5 hash;
|
| - if (data->getLength()) {
|
| - hash.writeStream(data, data->getLength());
|
| - data->rewind();
|
| - } else {
|
| - // If we're BGRA (Linux, Windows), swizzle over to RGBA (Mac, Android).
|
| - // This helps eliminate multiple 0-pixel-diff hashes on gold.skia.org.
|
| - // (Android's general slow speed breaks the tie arbitrarily in RGBA's favor.)
|
| - // We might consider promoting 565 to RGBA too.
|
| - if (bitmap.colorType() == kBGRA_8888_SkColorType) {
|
| - SkBitmap swizzle;
|
| - SkAssertResult(bitmap.copyTo(&swizzle, kRGBA_8888_SkColorType));
|
| - hash.write(swizzle.getPixels(), swizzle.getSize());
|
| +
|
| + // We're likely switching threads here, so we must capture by value, [=] or [foo,bar].
|
| + SkStreamAsset* data = stream.detachAsStream();
|
| + gDefinitelyThreadSafeWork.add([task,name,bitmap,data]{
|
| + SkAutoTDelete<SkStreamAsset> ownedData(data);
|
| +
|
| + // Why doesn't the copy constructor do this when we have pre-locked pixels?
|
| + bitmap.lockPixels();
|
| +
|
| + SkString md5;
|
| + if (!FLAGS_writePath.isEmpty() || !FLAGS_readPath.isEmpty()) {
|
| + SkMD5 hash;
|
| + if (data->getLength()) {
|
| + hash.writeStream(data, data->getLength());
|
| + data->rewind();
|
| } else {
|
| - hash.write(bitmap.getPixels(), bitmap.getSize());
|
| + // If we're BGRA (Linux, Windows), swizzle over to RGBA (Mac, Android).
|
| + // This helps eliminate multiple 0-pixel-diff hashes on gold.skia.org.
|
| + // (Android's general slow speed breaks the tie arbitrarily in RGBA's favor.)
|
| + // We might consider promoting 565 to RGBA too.
|
| + if (bitmap.colorType() == kBGRA_8888_SkColorType) {
|
| + SkBitmap swizzle;
|
| + SkAssertResult(bitmap.copyTo(&swizzle, kRGBA_8888_SkColorType));
|
| + hash.write(swizzle.getPixels(), swizzle.getSize());
|
| + } else {
|
| + hash.write(bitmap.getPixels(), bitmap.getSize());
|
| + }
|
| + }
|
| + SkMD5::Digest digest;
|
| + hash.finish(digest);
|
| + for (int i = 0; i < 16; i++) {
|
| + md5.appendf("%02x", digest.data[i]);
|
| }
|
| }
|
| - SkMD5::Digest digest;
|
| - hash.finish(digest);
|
| - for (int i = 0; i < 16; i++) {
|
| - md5.appendf("%02x", digest.data[i]);
|
| - }
|
| - }
|
|
|
| - if (!FLAGS_readPath.isEmpty() &&
|
| - !gGold.contains(Gold(task->sink.tag.c_str(), task->src.tag.c_str(),
|
| - task->src.options.c_str(), name, md5))) {
|
| - fail(SkStringPrintf("%s not found for %s %s %s %s in %s",
|
| - md5.c_str(),
|
| - task->sink.tag.c_str(),
|
| - task->src.tag.c_str(),
|
| - task->src.options.c_str(),
|
| - name.c_str(),
|
| - FLAGS_readPath[0]));
|
| - }
|
| + if (!FLAGS_readPath.isEmpty() &&
|
| + !gGold.contains(Gold(task->sink.tag.c_str(), task->src.tag.c_str(),
|
| + task->src.options.c_str(), name, md5))) {
|
| + fail(SkStringPrintf("%s not found for %s %s %s %s in %s",
|
| + md5.c_str(),
|
| + task->sink.tag.c_str(),
|
| + task->src.tag.c_str(),
|
| + task->src.options.c_str(),
|
| + name.c_str(),
|
| + FLAGS_readPath[0]));
|
| + }
|
|
|
| - if (!FLAGS_writePath.isEmpty()) {
|
| - const char* ext = task->sink->fileExtension();
|
| - if (data->getLength()) {
|
| - WriteToDisk(*task, md5, ext, data, data->getLength(), nullptr);
|
| - SkASSERT(bitmap.drawsNothing());
|
| - } else if (!bitmap.drawsNothing()) {
|
| - WriteToDisk(*task, md5, ext, nullptr, 0, &bitmap);
|
| + if (!FLAGS_writePath.isEmpty()) {
|
| + const char* ext = task->sink->fileExtension();
|
| + if (data->getLength()) {
|
| + WriteToDisk(*task, md5, ext, data, data->getLength(), nullptr);
|
| + SkASSERT(bitmap.drawsNothing());
|
| + } else if (!bitmap.drawsNothing()) {
|
| + WriteToDisk(*task, md5, ext, nullptr, 0, &bitmap);
|
| + }
|
| }
|
| - }
|
| + });
|
| }
|
| done(now_ms()-timerStart, task->sink.tag.c_str(), task->src.tag.c_str(), task->src.options.c_str(),
|
| name, note, log);
|
| @@ -1110,6 +1122,8 @@ int dm_main() {
|
| }
|
| }
|
| tg.wait();
|
| + gDefinitelyThreadSafeWork.wait();
|
| +
|
| // At this point we're back in single-threaded land.
|
| sk_tool_utils::release_portable_typefaces();
|
|
|
|
|