1964dec3948721808491b21b4ff4ff41a466443ecBrian Osman/* 2964dec3948721808491b21b4ff4ff41a466443ecBrian Osman * Copyright 2016 Google Inc. 3964dec3948721808491b21b4ff4ff41a466443ecBrian Osman * 4964dec3948721808491b21b4ff4ff41a466443ecBrian Osman * Use of this source code is governed by a BSD-style license that can be 5964dec3948721808491b21b4ff4ff41a466443ecBrian Osman * found in the LICENSE file. 6964dec3948721808491b21b4ff4ff41a466443ecBrian Osman */ 7964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 8964dec3948721808491b21b4ff4ff41a466443ecBrian Osman#include "GrSRGBEffect.h" 9964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 10964dec3948721808491b21b4ff4ff41a466443ecBrian Osman#include "GrFragmentProcessor.h" 11964dec3948721808491b21b4ff4ff41a466443ecBrian Osman#include "GrProcessor.h" 12964dec3948721808491b21b4ff4ff41a466443ecBrian Osman#include "glsl/GrGLSLFragmentProcessor.h" 13964dec3948721808491b21b4ff4ff41a466443ecBrian Osman#include "glsl/GrGLSLFragmentShaderBuilder.h" 14964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 15964dec3948721808491b21b4ff4ff41a466443ecBrian Osmanclass GrGLSRGBEffect : public GrGLSLFragmentProcessor { 16964dec3948721808491b21b4ff4ff41a466443ecBrian Osmanpublic: 17964dec3948721808491b21b4ff4ff41a466443ecBrian Osman void emitCode(EmitArgs& args) override { 18964dec3948721808491b21b4ff4ff41a466443ecBrian Osman const GrSRGBEffect& srgbe = args.fFp.cast<GrSRGBEffect>(); 19964dec3948721808491b21b4ff4ff41a466443ecBrian Osman GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 20964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 21964dec3948721808491b21b4ff4ff41a466443ecBrian Osman SkString srgbFuncName; 22964dec3948721808491b21b4ff4ff41a466443ecBrian Osman static const GrShaderVar gSrgbArgs[] = { 23964dec3948721808491b21b4ff4ff41a466443ecBrian Osman GrShaderVar("x", kFloat_GrSLType), 24964dec3948721808491b21b4ff4ff41a466443ecBrian Osman }; 25964dec3948721808491b21b4ff4ff41a466443ecBrian Osman switch (srgbe.mode()) { 26964dec3948721808491b21b4ff4ff41a466443ecBrian Osman case GrSRGBEffect::Mode::kLinearToSRGB: 27964dec3948721808491b21b4ff4ff41a466443ecBrian Osman fragBuilder->emitFunction(kFloat_GrSLType, 28964dec3948721808491b21b4ff4ff41a466443ecBrian Osman "linear_to_srgb", 29964dec3948721808491b21b4ff4ff41a466443ecBrian Osman SK_ARRAY_COUNT(gSrgbArgs), 30964dec3948721808491b21b4ff4ff41a466443ecBrian Osman gSrgbArgs, 31964dec3948721808491b21b4ff4ff41a466443ecBrian Osman "return (x <= 0.0031308) ? (x * 12.92) " 32964dec3948721808491b21b4ff4ff41a466443ecBrian Osman ": (1.055 * pow(x, 0.416666667) - 0.055);", 33964dec3948721808491b21b4ff4ff41a466443ecBrian Osman &srgbFuncName); 34964dec3948721808491b21b4ff4ff41a466443ecBrian Osman break; 35964dec3948721808491b21b4ff4ff41a466443ecBrian Osman case GrSRGBEffect::Mode::kSRGBToLinear: 36964dec3948721808491b21b4ff4ff41a466443ecBrian Osman fragBuilder->emitFunction(kFloat_GrSLType, 37964dec3948721808491b21b4ff4ff41a466443ecBrian Osman "srgb_to_linear", 38964dec3948721808491b21b4ff4ff41a466443ecBrian Osman SK_ARRAY_COUNT(gSrgbArgs), 39964dec3948721808491b21b4ff4ff41a466443ecBrian Osman gSrgbArgs, 40964dec3948721808491b21b4ff4ff41a466443ecBrian Osman "return (x <= 0.04045) ? (x / 12.92) " 41964dec3948721808491b21b4ff4ff41a466443ecBrian Osman ": pow((x + 0.055) / 1.055, 2.4);", 42964dec3948721808491b21b4ff4ff41a466443ecBrian Osman &srgbFuncName); 43964dec3948721808491b21b4ff4ff41a466443ecBrian Osman break; 44964dec3948721808491b21b4ff4ff41a466443ecBrian Osman } 45964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 46964dec3948721808491b21b4ff4ff41a466443ecBrian Osman if (nullptr == args.fInputColor) { 47964dec3948721808491b21b4ff4ff41a466443ecBrian Osman args.fInputColor = "vec4(1)"; 48964dec3948721808491b21b4ff4ff41a466443ecBrian Osman } 49964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 50964dec3948721808491b21b4ff4ff41a466443ecBrian Osman fragBuilder->codeAppendf("%s = vec4(%s(%s.r), %s(%s.g), %s(%s.b), %s.a);", 51964dec3948721808491b21b4ff4ff41a466443ecBrian Osman args.fOutputColor, 52964dec3948721808491b21b4ff4ff41a466443ecBrian Osman srgbFuncName.c_str(), args.fInputColor, 53964dec3948721808491b21b4ff4ff41a466443ecBrian Osman srgbFuncName.c_str(), args.fInputColor, 54964dec3948721808491b21b4ff4ff41a466443ecBrian Osman srgbFuncName.c_str(), args.fInputColor, 55964dec3948721808491b21b4ff4ff41a466443ecBrian Osman args.fInputColor); 56964dec3948721808491b21b4ff4ff41a466443ecBrian Osman } 57964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 58964dec3948721808491b21b4ff4ff41a466443ecBrian Osman static inline void GenKey(const GrProcessor& processor, const GrShaderCaps&, 59964dec3948721808491b21b4ff4ff41a466443ecBrian Osman GrProcessorKeyBuilder* b) { 60964dec3948721808491b21b4ff4ff41a466443ecBrian Osman const GrSRGBEffect& srgbe = processor.cast<GrSRGBEffect>(); 61964dec3948721808491b21b4ff4ff41a466443ecBrian Osman uint32_t key = static_cast<uint32_t>(srgbe.mode()); 62964dec3948721808491b21b4ff4ff41a466443ecBrian Osman b->add32(key); 63964dec3948721808491b21b4ff4ff41a466443ecBrian Osman } 64964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 65964dec3948721808491b21b4ff4ff41a466443ecBrian Osmanprivate: 66964dec3948721808491b21b4ff4ff41a466443ecBrian Osman typedef GrGLSLFragmentProcessor INHERITED; 67964dec3948721808491b21b4ff4ff41a466443ecBrian Osman}; 68964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 69964dec3948721808491b21b4ff4ff41a466443ecBrian Osman/////////////////////////////////////////////////////////////////////////////// 70964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 71964dec3948721808491b21b4ff4ff41a466443ecBrian OsmanGrSRGBEffect::GrSRGBEffect(Mode mode) 72587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon : INHERITED(kPreservesOpaqueInput_OptimizationFlag | 73587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon kConstantOutputForConstantInput_OptimizationFlag) 74587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon , fMode(mode) { 75964dec3948721808491b21b4ff4ff41a466443ecBrian Osman this->initClassID<GrSRGBEffect>(); 76964dec3948721808491b21b4ff4ff41a466443ecBrian Osman} 77964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 78964dec3948721808491b21b4ff4ff41a466443ecBrian Osmanbool GrSRGBEffect::onIsEqual(const GrFragmentProcessor& s) const { 79964dec3948721808491b21b4ff4ff41a466443ecBrian Osman const GrSRGBEffect& other = s.cast<GrSRGBEffect>(); 80964dec3948721808491b21b4ff4ff41a466443ecBrian Osman return other.fMode == fMode; 81964dec3948721808491b21b4ff4ff41a466443ecBrian Osman} 82964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 83587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomonstatic inline float srgb_to_linear(float srgb) { 84587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon return (srgb <= 0.04045f) ? srgb / 12.92f : powf((srgb + 0.055f) / 1.055f, 2.4f); 85587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon} 86587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomonstatic inline float linear_to_srgb(float linear) { 87587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon return (linear <= 0.0031308) ? linear * 12.92f : 1.055f * powf(linear, 1.f / 2.4f) - 0.055f; 88587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon} 89587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon 90587e08f361ee3e775a6bbc6dca761dbba82e422cBrian SalomonGrColor4f GrSRGBEffect::constantOutputForConstantInput(GrColor4f input) const { 91587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon switch (fMode) { 92587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon case Mode::kLinearToSRGB: 93587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon return GrColor4f(linear_to_srgb(input.fRGBA[0]), linear_to_srgb(input.fRGBA[1]), 94587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon linear_to_srgb(input.fRGBA[2]), input.fRGBA[3]); 95587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon case Mode::kSRGBToLinear: 96587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon return GrColor4f(srgb_to_linear(input.fRGBA[0]), srgb_to_linear(input.fRGBA[1]), 97587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon srgb_to_linear(input.fRGBA[2]), input.fRGBA[3]); 98587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon } 99587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon SkFAIL("Unexpected mode"); 100587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon return GrColor4f::TransparentBlack(); 101587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon} 102587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon 103964dec3948721808491b21b4ff4ff41a466443ecBrian Osman/////////////////////////////////////////////////////////////////////////////// 104964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 105964dec3948721808491b21b4ff4ff41a466443ecBrian OsmanGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSRGBEffect); 106964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 1076f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#if GR_TEST_UTILS 108964dec3948721808491b21b4ff4ff41a466443ecBrian Osmansk_sp<GrFragmentProcessor> GrSRGBEffect::TestCreate(GrProcessorTestData* d) { 109964dec3948721808491b21b4ff4ff41a466443ecBrian Osman Mode testMode = static_cast<Mode>(d->fRandom->nextRangeU(0, 1)); 110964dec3948721808491b21b4ff4ff41a466443ecBrian Osman return sk_sp<GrFragmentProcessor>(new GrSRGBEffect(testMode)); 111964dec3948721808491b21b4ff4ff41a466443ecBrian Osman} 1126f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#endif 113964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 114964dec3948721808491b21b4ff4ff41a466443ecBrian Osman/////////////////////////////////////////////////////////////////////////////// 115964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 116964dec3948721808491b21b4ff4ff41a466443ecBrian Osmanvoid GrSRGBEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, 117964dec3948721808491b21b4ff4ff41a466443ecBrian Osman GrProcessorKeyBuilder* b) const { 118964dec3948721808491b21b4ff4ff41a466443ecBrian Osman GrGLSRGBEffect::GenKey(*this, caps, b); 119964dec3948721808491b21b4ff4ff41a466443ecBrian Osman} 120964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 121964dec3948721808491b21b4ff4ff41a466443ecBrian OsmanGrGLSLFragmentProcessor* GrSRGBEffect::onCreateGLSLInstance() const { 122964dec3948721808491b21b4ff4ff41a466443ecBrian Osman return new GrGLSRGBEffect(); 123964dec3948721808491b21b4ff4ff41a466443ecBrian Osman} 124964dec3948721808491b21b4ff4ff41a466443ecBrian Osman 125964dec3948721808491b21b4ff4ff41a466443ecBrian Osmansk_sp<GrFragmentProcessor> GrSRGBEffect::Make(Mode mode) { 126964dec3948721808491b21b4ff4ff41a466443ecBrian Osman return sk_sp<GrFragmentProcessor>(new GrSRGBEffect(mode)); 127964dec3948721808491b21b4ff4ff41a466443ecBrian Osman} 128