1/* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "ColorCodecBench.h" 9#include "Resources.h" 10#include "SkCodec.h" 11#include "SkCodecPriv.h" 12#include "SkColorSpace_XYZ.h" 13#include "SkColorSpaceXform.h" 14#include "SkCommandLineFlags.h" 15 16DEFINE_bool(xform_only, false, "Only time the color xform, do not include the decode time"); 17DEFINE_bool(srgb, false, "Convert to srgb dst space"); 18DEFINE_bool(nonstd, false, "Convert to non-standard dst space"); 19DEFINE_bool(half, false, "Convert to half floats"); 20 21ColorCodecBench::ColorCodecBench(const char* name, sk_sp<SkData> encoded) 22 : fEncoded(std::move(encoded)) 23{ 24 fName.appendf("Color%s", FLAGS_xform_only ? "Xform" : "Codec"); 25 fName.appendf("_%s", name); 26} 27 28const char* ColorCodecBench::onGetName() { 29 return fName.c_str(); 30} 31 32bool ColorCodecBench::isSuitableFor(Backend backend) { 33 return kNonRendering_Backend == backend; 34} 35 36void ColorCodecBench::decodeAndXform() { 37#ifdef SK_DEBUG 38 SkCodec::Result result = 39#endif 40 SkCodec::MakeFromData(fEncoded)->getPixels(fDstInfo, fDst.get(), fDstInfo.minRowBytes()); 41 SkASSERT(SkCodec::kSuccess == result); 42} 43 44void ColorCodecBench::xformOnly() { 45 std::unique_ptr<SkColorSpaceXform> xform = SkColorSpaceXform::New(fSrcSpace.get(), 46 fDstSpace.get()); 47 SkASSERT(xform); 48 49 void* dst = fDst.get(); 50 void* src = fSrc.get(); 51 for (int y = 0; y < fSrcInfo.height(); y++) { 52 SkAssertResult(xform->apply(select_xform_format(fDstInfo.colorType()), dst, 53 SkColorSpaceXform::kRGBA_8888_ColorFormat, src, 54 fSrcInfo.width(), fDstInfo.alphaType())); 55 dst = SkTAddOffset<void>(dst, fDstInfo.minRowBytes()); 56 src = SkTAddOffset<void>(src, fSrcInfo.minRowBytes()); 57 } 58} 59 60void ColorCodecBench::onDelayedSetup() { 61 std::unique_ptr<SkCodec> codec = SkCodec::MakeFromData(fEncoded); 62 fSrcInfo = codec->getInfo().makeColorType(kRGBA_8888_SkColorType); 63 fDstInfo = fSrcInfo; 64 65 fDstSpace = nullptr; 66 if (FLAGS_srgb) { 67 fDstSpace = SkColorSpace::MakeSRGB(); 68 } else if (FLAGS_nonstd) { 69 SkColorSpaceTransferFn gamma; 70 gamma.fA = 1.0f; 71 gamma.fB = gamma.fC = gamma.fD = gamma.fE = gamma.fF = 0.0f; 72 gamma.fG = 4.0f; 73 SkMatrix44 matrix = SkMatrix44(SkMatrix44::kUninitialized_Constructor); 74 matrix.set3x3(0.30f, 0.31f, 0.28f, 0.32f, 0.33f, 0.29f, 0.27f, 0.30f, 0.30f); 75 fDstSpace = SkColorSpace::MakeRGB(gamma, matrix); 76 } else { 77 sk_sp<SkData> dstData = GetResourceAsData("icc_profiles/HP_ZR30w.icc"); 78 SkASSERT(dstData); 79 fDstSpace = SkColorSpace::MakeICC(dstData->data(), dstData->size()); 80 } 81 SkASSERT(fDstSpace); 82 fDstInfo = fDstInfo.makeColorSpace(fDstSpace); 83 84 if (FLAGS_half) { 85 fDstInfo = fDstInfo.makeColorType(kRGBA_F16_SkColorType); 86 fDstSpace = fDstSpace->makeLinearGamma(); 87 } 88 89 fDst.reset(fDstInfo.computeMinByteSize()); 90 91 if (FLAGS_xform_only) { 92 fSrc.reset(fSrcInfo.computeMinByteSize()); 93 fSrcSpace = codec->getInfo().refColorSpace(); 94 codec->getPixels(fSrcInfo, fSrc.get(), fSrcInfo.minRowBytes()); 95 } 96} 97 98void ColorCodecBench::onDraw(int n, SkCanvas*) { 99 for (int i = 0; i < n; i++) { 100 if (FLAGS_xform_only) { 101 this->xformOnly(); 102 } else { 103 this->decodeAndXform(); 104 } 105 } 106} 107