aboutsummaryrefslogtreecommitdiffhomepage
path: root/bench/ColorCodecBench.cpp
blob: 1239e1d4fe8209ae2e3e628fdcce532143fd46de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "ColorCodecBench.h"
#include "Resources.h"
#include "SkCodec.h"
#include "SkCodecPriv.h"
#include "SkColorSpace_XYZ.h"
#include "SkColorSpaceXform.h"
#include "SkCommandLineFlags.h"

DEFINE_bool(xform_only, false, "Only time the color xform, do not include the decode time");
DEFINE_bool(srgb,       false, "Convert to srgb dst space");
DEFINE_bool(nonstd,     false, "Convert to non-standard dst space");
DEFINE_bool(half,       false, "Convert to half floats");

ColorCodecBench::ColorCodecBench(const char* name, sk_sp<SkData> encoded)
    : fEncoded(std::move(encoded))
{
    fName.appendf("Color%s", FLAGS_xform_only ? "Xform" : "Codec");
    fName.appendf("_%s", name);
}

const char* ColorCodecBench::onGetName() {
    return fName.c_str();
}

bool ColorCodecBench::isSuitableFor(Backend backend) {
    return kNonRendering_Backend == backend;
}

void ColorCodecBench::decodeAndXform() {
#ifdef SK_DEBUG
    SkCodec::Result result =
#endif
    SkCodec::MakeFromData(fEncoded)->getPixels(fDstInfo, fDst.get(), fDstInfo.minRowBytes());
    SkASSERT(SkCodec::kSuccess == result);
}

void ColorCodecBench::xformOnly() {
    std::unique_ptr<SkColorSpaceXform> xform = SkColorSpaceXform::New(fSrcSpace.get(),
                                                                      fDstSpace.get());
    SkASSERT(xform);

    void* dst = fDst.get();
    void* src = fSrc.get();
    for (int y = 0; y < fSrcInfo.height(); y++) {
        SkAssertResult(xform->apply(select_xform_format(fDstInfo.colorType()), dst,
                                    SkColorSpaceXform::kRGBA_8888_ColorFormat, src,
                                    fSrcInfo.width(), fDstInfo.alphaType()));
        dst = SkTAddOffset<void>(dst, fDstInfo.minRowBytes());
        src = SkTAddOffset<void>(src, fSrcInfo.minRowBytes());
    }
}

void ColorCodecBench::onDelayedSetup() {
    std::unique_ptr<SkCodec> codec = SkCodec::MakeFromData(fEncoded);
    fSrcInfo = codec->getInfo().makeColorType(kRGBA_8888_SkColorType);
    fDstInfo = fSrcInfo;

    fDstSpace = nullptr;
    if (FLAGS_srgb) {
        fDstSpace = SkColorSpace::MakeSRGB();
    } else if (FLAGS_nonstd) {
        SkColorSpaceTransferFn gamma;
        gamma.fA = 1.0f;
        gamma.fB = gamma.fC = gamma.fD = gamma.fE = gamma.fF = 0.0f;
        gamma.fG = 4.0f;
        SkMatrix44 matrix = SkMatrix44(SkMatrix44::kUninitialized_Constructor);
        matrix.set3x3(0.30f, 0.31f, 0.28f, 0.32f, 0.33f, 0.29f, 0.27f, 0.30f, 0.30f);
        fDstSpace = SkColorSpace::MakeRGB(gamma, matrix);
    } else {
        sk_sp<SkData> dstData = SkData::MakeFromFileName(
                GetResourcePath("icc_profiles/HP_ZR30w.icc").c_str());
        SkASSERT(dstData);
        fDstSpace = SkColorSpace::MakeICC(dstData->data(), dstData->size());
    }
    SkASSERT(fDstSpace);
    fDstInfo = fDstInfo.makeColorSpace(fDstSpace);

    if (FLAGS_half) {
        fDstInfo = fDstInfo.makeColorType(kRGBA_F16_SkColorType);
        SkASSERT(SkColorSpace_Base::Type::kXYZ == as_CSB(fDstSpace)->type());
        fDstSpace = static_cast<SkColorSpace_XYZ*>(fDstSpace.get())->makeLinearGamma();
    }

    fDst.reset(fDstInfo.computeMinByteSize());

    if (FLAGS_xform_only) {
        fSrc.reset(fSrcInfo.computeMinByteSize());
        fSrcSpace = codec->getInfo().refColorSpace();
        codec->getPixels(fSrcInfo, fSrc.get(), fSrcInfo.minRowBytes());
    }
}

void ColorCodecBench::onDraw(int n, SkCanvas*) {
    for (int i = 0; i < n; i++) {
        if (FLAGS_xform_only) {
            this->xformOnly();
        } else {
            this->decodeAndXform();
        }
    }
}