1f461a8fdf642ba713dcdfb217534652df1eac278krajcevski/* 2f461a8fdf642ba713dcdfb217534652df1eac278krajcevski * Copyright 2014 Google Inc. 3f461a8fdf642ba713dcdfb217534652df1eac278krajcevski * 4f461a8fdf642ba713dcdfb217534652df1eac278krajcevski * Use of this source code is governed by a BSD-style license that can be 5f461a8fdf642ba713dcdfb217534652df1eac278krajcevski * found in the LICENSE file. 6f461a8fdf642ba713dcdfb217534652df1eac278krajcevski */ 7f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 8f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "GrDitherEffect.h" 9f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 10f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "gl/GrGLEffect.h" 11f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "gl/GrGLSL.h" 12f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "GrTBackendEffectFactory.h" 13f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 14f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "SkRect.h" 15f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 16f461a8fdf642ba713dcdfb217534652df1eac278krajcevski////////////////////////////////////////////////////////////////////////////// 17f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 18f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiclass GLDitherEffect; 19f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 20f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiclass DitherEffect : public GrEffect { 21f461a8fdf642ba713dcdfb217534652df1eac278krajcevskipublic: 22f461a8fdf642ba713dcdfb217534652df1eac278krajcevski static GrEffectRef* Create() { 23f461a8fdf642ba713dcdfb217534652df1eac278krajcevski return CreateEffectRef(AutoEffectUnref(SkNEW(DitherEffect))); 24f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 25f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 26f461a8fdf642ba713dcdfb217534652df1eac278krajcevski virtual ~DitherEffect() {}; 27f461a8fdf642ba713dcdfb217534652df1eac278krajcevski static const char* Name() { return "Dither"; } 28f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 29f461a8fdf642ba713dcdfb217534652df1eac278krajcevski typedef GLDitherEffect GLEffect; 30f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 31f461a8fdf642ba713dcdfb217534652df1eac278krajcevski virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; 32f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 33f461a8fdf642ba713dcdfb217534652df1eac278krajcevski virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { 34f461a8fdf642ba713dcdfb217534652df1eac278krajcevski return GrTBackendEffectFactory<DitherEffect>::getInstance(); 35f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 36f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 37f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiprivate: 38f461a8fdf642ba713dcdfb217534652df1eac278krajcevski DitherEffect() { 39f461a8fdf642ba713dcdfb217534652df1eac278krajcevski this->setWillReadFragmentPosition(); 40f461a8fdf642ba713dcdfb217534652df1eac278krajcevski } 41f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 42f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // All dither effects are equal 43f461a8fdf642ba713dcdfb217534652df1eac278krajcevski virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE { return true; } 44f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 45f461a8fdf642ba713dcdfb217534652df1eac278krajcevski GR_DECLARE_EFFECT_TEST; 46f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 47f461a8fdf642ba713dcdfb217534652df1eac278krajcevski typedef GrEffect INHERITED; 48f461a8fdf642ba713dcdfb217534652df1eac278krajcevski}; 49f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 50f461a8fdf642ba713dcdfb217534652df1eac278krajcevskivoid DitherEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { 51f461a8fdf642ba713dcdfb217534652df1eac278krajcevski *validFlags = 0; 52f461a8fdf642ba713dcdfb217534652df1eac278krajcevski} 53f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 54f461a8fdf642ba713dcdfb217534652df1eac278krajcevski////////////////////////////////////////////////////////////////////////////// 55f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 56f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiGR_DEFINE_EFFECT_TEST(DitherEffect); 57f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 58f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiGrEffectRef* DitherEffect::TestCreate(SkRandom*, 59f461a8fdf642ba713dcdfb217534652df1eac278krajcevski GrContext*, 60f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const GrDrawTargetCaps&, 61f461a8fdf642ba713dcdfb217534652df1eac278krajcevski GrTexture*[]) { 62f461a8fdf642ba713dcdfb217534652df1eac278krajcevski return DitherEffect::Create(); 63f461a8fdf642ba713dcdfb217534652df1eac278krajcevski} 64f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 65f461a8fdf642ba713dcdfb217534652df1eac278krajcevski////////////////////////////////////////////////////////////////////////////// 66f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 67f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiclass GLDitherEffect : public GrGLEffect { 68f461a8fdf642ba713dcdfb217534652df1eac278krajcevskipublic: 69f461a8fdf642ba713dcdfb217534652df1eac278krajcevski GLDitherEffect(const GrBackendEffectFactory&, const GrDrawEffect&); 70f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 71f461a8fdf642ba713dcdfb217534652df1eac278krajcevski virtual void emitCode(GrGLShaderBuilder* builder, 72f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const GrDrawEffect& drawEffect, 73f461a8fdf642ba713dcdfb217534652df1eac278krajcevski EffectKey key, 74f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const char* outputColor, 75f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const char* inputColor, 76f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const TransformedCoordsArray&, 77f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const TextureSamplerArray&) SK_OVERRIDE; 78f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 79f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiprivate: 80f461a8fdf642ba713dcdfb217534652df1eac278krajcevski typedef GrGLEffect INHERITED; 81f461a8fdf642ba713dcdfb217534652df1eac278krajcevski}; 82f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 83f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiGLDitherEffect::GLDitherEffect(const GrBackendEffectFactory& factory, 84f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const GrDrawEffect& drawEffect) 85f461a8fdf642ba713dcdfb217534652df1eac278krajcevski : INHERITED (factory) { 86f461a8fdf642ba713dcdfb217534652df1eac278krajcevski} 87f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 88f461a8fdf642ba713dcdfb217534652df1eac278krajcevskivoid GLDitherEffect::emitCode(GrGLShaderBuilder* builder, 89f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const GrDrawEffect& drawEffect, 90f461a8fdf642ba713dcdfb217534652df1eac278krajcevski EffectKey key, 91f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const char* outputColor, 92f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const char* inputColor, 93f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const TransformedCoordsArray&, 94f461a8fdf642ba713dcdfb217534652df1eac278krajcevski const TextureSamplerArray& samplers) { 95f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // Generate a random number based on the fragment position. For this 96f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // random number generator, we use the "GLSL rand" function 97f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // that seems to be floating around on the internet. It works under 98f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // the assumption that sin(<big number>) oscillates with high frequency 99f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // and sampling it will generate "randomness". Since we're using this 100f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // for rendering and not cryptography it should be OK. 101f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 102f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // For each channel c, add the random offset to the pixel to either bump 103f461a8fdf642ba713dcdfb217534652df1eac278krajcevski // it up or let it remain constant during quantization. 104f461a8fdf642ba713dcdfb217534652df1eac278krajcevski builder->fsCodeAppendf("\t\tfloat r = " 105160a52ba217012ed73c240f6d67b3bbf2b4879d6bsalomon "fract(sin(dot(%s ,vec2(12.9898,78.233))) * 43758.5453);\n", 106f461a8fdf642ba713dcdfb217534652df1eac278krajcevski builder->fragmentPosition()); 107aed7007e9e3ee4cdf733bf2f53531fdcd0531b25krajcevski builder->fsCodeAppendf("\t\t%s = (1.0/255.0) * vec4(r, r, r, r) + %s;\n", 108f461a8fdf642ba713dcdfb217534652df1eac278krajcevski outputColor, GrGLSLExpr4(inputColor).c_str()); 109f461a8fdf642ba713dcdfb217534652df1eac278krajcevski} 110f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 111f461a8fdf642ba713dcdfb217534652df1eac278krajcevski////////////////////////////////////////////////////////////////////////////// 112f461a8fdf642ba713dcdfb217534652df1eac278krajcevski 113f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiGrEffectRef* GrDitherEffect::Create() { 114f461a8fdf642ba713dcdfb217534652df1eac278krajcevski return DitherEffect::Create(); 115f461a8fdf642ba713dcdfb217534652df1eac278krajcevski} 116