GrSRGBEffect.cpp revision cb30bb2cb727e276792812c6390547dba474c831
1269403b032f965ff3847eb982c2f697229dc5a92Svetoslav/*
2269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * Copyright 2016 Google Inc.
3269403b032f965ff3847eb982c2f697229dc5a92Svetoslav *
4269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * Use of this source code is governed by a BSD-style license that can be
5269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * found in the LICENSE file.
6269403b032f965ff3847eb982c2f697229dc5a92Svetoslav */
7269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
8269403b032f965ff3847eb982c2f697229dc5a92Svetoslav#include "GrSRGBEffect.h"
9269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
10269403b032f965ff3847eb982c2f697229dc5a92Svetoslav#include "GrContext.h"
11269403b032f965ff3847eb982c2f697229dc5a92Svetoslav#include "GrFragmentProcessor.h"
12269403b032f965ff3847eb982c2f697229dc5a92Svetoslav#include "GrProcessor.h"
13269403b032f965ff3847eb982c2f697229dc5a92Svetoslav#include "glsl/GrGLSLFragmentProcessor.h"
14269403b032f965ff3847eb982c2f697229dc5a92Svetoslav#include "glsl/GrGLSLFragmentShaderBuilder.h"
15269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
16269403b032f965ff3847eb982c2f697229dc5a92Svetoslavclass GrGLSRGBEffect : public GrGLSLFragmentProcessor {
17a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavpublic:
18269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    void emitCode(EmitArgs& args) override {
1976d7e3ee70c4299b22b1a03505d2b4f108716c75Philip P. Moltmann        const GrSRGBEffect& srgbe = args.fFp.cast<GrSRGBEffect>();
20269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
21269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
22269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        SkString srgbFuncName;
23d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav        static const GrShaderVar gSrgbArgs[] = {
2498963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann            GrShaderVar("x", kFloat_GrSLType),
2598963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann        };
2698963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann        switch (srgbe.mode()) {
2798963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann            case GrSRGBEffect::Mode::kLinearToSRGB:
2898963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann                fragBuilder->emitFunction(kFloat_GrSLType,
29269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                                          "linear_to_srgb",
3098963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann                                          SK_ARRAY_COUNT(gSrgbArgs),
3198963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann                                          gSrgbArgs,
3298963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann                                          "return (x <= 0.0031308) ? (x * 12.92) "
3344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov                                          ": (1.055 * pow(x, 0.416666667) - 0.055);",
3444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov                                          &srgbFuncName);
3544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov                break;
36269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            case GrSRGBEffect::Mode::kSRGBToLinear:
37269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                fragBuilder->emitFunction(kFloat_GrSLType,
38d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav                                          "srgb_to_linear",
39269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                                          SK_ARRAY_COUNT(gSrgbArgs),
40d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav                                          gSrgbArgs,
41269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                                          "return (x <= 0.04045) ? (x / 12.92) "
42269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                                          ": pow((x + 0.055) / 1.055, 2.4);",
4398963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann                                          &srgbFuncName);
44269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                break;
45269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
46269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
47269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        if (nullptr == args.fInputColor) {
48269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            args.fInputColor = "vec4(1)";
4998963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann        }
5098963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann
51269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        fragBuilder->codeAppendf("%s = vec4(%s(%s.r), %s(%s.g), %s(%s.b), %s.a);",
52269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                                    args.fOutputColor,
53269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                                    srgbFuncName.c_str(), args.fInputColor,
54269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                                    srgbFuncName.c_str(), args.fInputColor,
55269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                                    srgbFuncName.c_str(), args.fInputColor,
56269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                                    args.fInputColor);
57269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
58269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
59269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    static inline void GenKey(const GrProcessor& processor, const GrShaderCaps&,
609e9e2e73c6ec7bece20268196dc89ad0c8bafad4Wojciech Staszkiewicz                              GrProcessorKeyBuilder* b) {
61269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        const GrSRGBEffect& srgbe = processor.cast<GrSRGBEffect>();
62269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        uint32_t key = static_cast<uint32_t>(srgbe.mode());
6398963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann        b->add32(key);
642916f658c9a55aa5b08a3bbe3056dbfd78e0e1b0Svet Ganov    }
65269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
66269403b032f965ff3847eb982c2f697229dc5a92Svetoslavprivate:
67bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann    typedef GrGLSLFragmentProcessor INHERITED;
68d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav};
69269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
70269403b032f965ff3847eb982c2f697229dc5a92Svetoslav///////////////////////////////////////////////////////////////////////////////
71269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
72269403b032f965ff3847eb982c2f697229dc5a92SvetoslavGrSRGBEffect::GrSRGBEffect(Mode mode)
73269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        : INHERITED(kPreservesOpaqueInput_OptimizationFlag |
7498963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann                    kConstantOutputForConstantInput_OptimizationFlag)
7598963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann        , fMode(mode) {
76269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    this->initClassID<GrSRGBEffect>();
77269403b032f965ff3847eb982c2f697229dc5a92Svetoslav}
78c6066799ad130140159230d14451b429eb828755Svetoslav
79269403b032f965ff3847eb982c2f697229dc5a92Svetoslavbool GrSRGBEffect::onIsEqual(const GrFragmentProcessor& s) const {
80269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    const GrSRGBEffect& other = s.cast<GrSRGBEffect>();
81269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    return other.fMode == fMode;
82269403b032f965ff3847eb982c2f697229dc5a92Svetoslav}
8344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov
84269403b032f965ff3847eb982c2f697229dc5a92Svetoslavstatic inline float srgb_to_linear(float srgb) {
8598963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann    return (srgb <= 0.04045f) ? srgb / 12.92f : powf((srgb + 0.055f) / 1.055f, 2.4f);
8698963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann}
8798963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmannstatic inline float linear_to_srgb(float linear) {
8898963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann    return (linear <= 0.0031308) ? linear * 12.92f : 1.055f * powf(linear, 1.f / 2.4f) - 0.055f;
8998963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann}
9098963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann
9198963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. MoltmannGrColor4f GrSRGBEffect::constantOutputForConstantInput(GrColor4f input) const {
9298963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann    switch (fMode) {
9398963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann        case Mode::kLinearToSRGB:
9498963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann            return GrColor4f(linear_to_srgb(input.fRGBA[0]), linear_to_srgb(input.fRGBA[1]),
9598963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann                             linear_to_srgb(input.fRGBA[2]), input.fRGBA[3]);
9698963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann        case Mode::kSRGBToLinear:
979186d0cb2bd325d9b52da15dbd513937c1e42caaSvetoslav Ganov            return GrColor4f(srgb_to_linear(input.fRGBA[0]), srgb_to_linear(input.fRGBA[1]),
9825885ecbe4306165872c1b24628e9646778a0535Svet Ganov                             srgb_to_linear(input.fRGBA[2]), input.fRGBA[3]);
999186d0cb2bd325d9b52da15dbd513937c1e42caaSvetoslav Ganov    }
10098963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann    SkFAIL("Unexpected mode");
10125885ecbe4306165872c1b24628e9646778a0535Svet Ganov    return GrColor4f::TransparentBlack();
102269403b032f965ff3847eb982c2f697229dc5a92Svetoslav}
103269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
104269403b032f965ff3847eb982c2f697229dc5a92Svetoslav///////////////////////////////////////////////////////////////////////////////
105269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
106269403b032f965ff3847eb982c2f697229dc5a92SvetoslavGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSRGBEffect);
107d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov
108d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov#if GR_TEST_UTILS
1091c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslavsk_sp<GrFragmentProcessor> GrSRGBEffect::TestCreate(GrProcessorTestData* d) {
1101c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav    Mode testMode = static_cast<Mode>(d->fRandom->nextRangeU(0, 1));
11198963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann    return sk_sp<GrFragmentProcessor>(new GrSRGBEffect(testMode));
11298963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann}
11398963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann#endif
11498963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann
11598963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann///////////////////////////////////////////////////////////////////////////////
11698963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann
11798963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmannvoid GrSRGBEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
11898963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann                                          GrProcessorKeyBuilder* b) const {
11998963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann    GrGLSRGBEffect::GenKey(*this, caps, b);
12098963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann}
12198963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann
12298963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. MoltmannGrGLSLFragmentProcessor* GrSRGBEffect::onCreateGLSLInstance() const {
12398963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann    return new GrGLSRGBEffect();
12498963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann}
12598963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann
12698963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmannsk_sp<GrFragmentProcessor> GrSRGBEffect::Make(Mode mode) {
12798963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann    return sk_sp<GrFragmentProcessor>(new GrSRGBEffect(mode));
12898963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann}
12998963260dc30f1dc3e89dbd0efdfcdc6398d753cPhilip P. Moltmann