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
830ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/builders/GrGLProgramBuilder.h"
9f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "GrDitherEffect.h"
10f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
11b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h"
12f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "gl/GrGLSL.h"
13b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrTBackendProcessorFactory.h"
14f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
15f461a8fdf642ba713dcdfb217534652df1eac278krajcevski#include "SkRect.h"
16f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
17f461a8fdf642ba713dcdfb217534652df1eac278krajcevski//////////////////////////////////////////////////////////////////////////////
18f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
19f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiclass GLDitherEffect;
20f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
21b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass DitherEffect : public GrFragmentProcessor {
22f461a8fdf642ba713dcdfb217534652df1eac278krajcevskipublic:
23b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    static GrFragmentProcessor* Create() {
24b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        GR_CREATE_STATIC_FRAGMENT_PROCESSOR(gDitherEffect, DitherEffect, ())
2555fad7af61c21d502acb9891d631e8aa29e3628cbsalomon        return SkRef(gDitherEffect);
26f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    }
27f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
28f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    virtual ~DitherEffect() {};
29f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    static const char* Name() { return "Dither"; }
30f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
31b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GLDitherEffect GLProcessor;
32f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
33f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
34f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
35b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
36b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        return GrTBackendFragmentProcessorFactory<DitherEffect>::getInstance();
37f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    }
38f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
39f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiprivate:
40f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    DitherEffect() {
41f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        this->setWillReadFragmentPosition();
42f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    }
43f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
44f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // All dither effects are equal
45b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; }
46f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
47b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
48f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
49b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrFragmentProcessor INHERITED;
50f461a8fdf642ba713dcdfb217534652df1eac278krajcevski};
51f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
52f461a8fdf642ba713dcdfb217534652df1eac278krajcevskivoid DitherEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
53f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    *validFlags = 0;
54f461a8fdf642ba713dcdfb217534652df1eac278krajcevski}
55f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
56f461a8fdf642ba713dcdfb217534652df1eac278krajcevski//////////////////////////////////////////////////////////////////////////////
57f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
58b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(DitherEffect);
59f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
60b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* DitherEffect::TestCreate(SkRandom*,
61b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                              GrContext*,
62b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                              const GrDrawTargetCaps&,
63b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                              GrTexture*[]) {
64f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    return DitherEffect::Create();
65f461a8fdf642ba713dcdfb217534652df1eac278krajcevski}
66f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
67f461a8fdf642ba713dcdfb217534652df1eac278krajcevski//////////////////////////////////////////////////////////////////////////////
68f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
69b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GLDitherEffect : public GrGLFragmentProcessor {
70f461a8fdf642ba713dcdfb217534652df1eac278krajcevskipublic:
71b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    GLDitherEffect(const GrBackendProcessorFactory&, const GrProcessor&);
72f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
7330ba436f04e61d4505fb854d5fc56079636e0788joshualitt    virtual void emitCode(GrGLProgramBuilder* builder,
74b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrFragmentProcessor& fp,
75b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                          const GrProcessorKey& key,
76f461a8fdf642ba713dcdfb217534652df1eac278krajcevski                          const char* outputColor,
77f461a8fdf642ba713dcdfb217534652df1eac278krajcevski                          const char* inputColor,
78f461a8fdf642ba713dcdfb217534652df1eac278krajcevski                          const TransformedCoordsArray&,
79f461a8fdf642ba713dcdfb217534652df1eac278krajcevski                          const TextureSamplerArray&) SK_OVERRIDE;
80f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
81f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiprivate:
82b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    typedef GrGLFragmentProcessor INHERITED;
83f461a8fdf642ba713dcdfb217534652df1eac278krajcevski};
84f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
85b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGLDitherEffect::GLDitherEffect(const GrBackendProcessorFactory& factory,
86b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                               const GrProcessor&)
87f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    : INHERITED (factory) {
88f461a8fdf642ba713dcdfb217534652df1eac278krajcevski}
89f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
9030ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GLDitherEffect::emitCode(GrGLProgramBuilder* builder,
91b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                              const GrFragmentProcessor& fp,
92b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                              const GrProcessorKey& key,
93f461a8fdf642ba713dcdfb217534652df1eac278krajcevski                              const char* outputColor,
94f461a8fdf642ba713dcdfb217534652df1eac278krajcevski                              const char* inputColor,
95f461a8fdf642ba713dcdfb217534652df1eac278krajcevski                              const TransformedCoordsArray&,
96f461a8fdf642ba713dcdfb217534652df1eac278krajcevski                              const TextureSamplerArray& samplers) {
9730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
98f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // Generate a random number based on the fragment position. For this
99f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // random number generator, we use the "GLSL rand" function
100f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // that seems to be floating around on the internet. It works under
101f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // the assumption that sin(<big number>) oscillates with high frequency
102f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // and sampling it will generate "randomness". Since we're using this
103f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // for rendering and not cryptography it should be OK.
104f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
105f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // For each channel c, add the random offset to the pixel to either bump
106f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    // it up or let it remain constant during quantization.
10730ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\t\tfloat r = "
10822900008fb89afe4687a40db8737553ee0e55621bsalomon                           "fract(sin(dot(%s.xy ,vec2(12.9898,78.233))) * 43758.5453);\n",
10930ba436f04e61d4505fb854d5fc56079636e0788joshualitt                           fsBuilder->fragmentPosition());
11030ba436f04e61d4505fb854d5fc56079636e0788joshualitt    fsBuilder->codeAppendf("\t\t%s = (1.0/255.0) * vec4(r, r, r, r) + %s;\n",
111f461a8fdf642ba713dcdfb217534652df1eac278krajcevski                           outputColor, GrGLSLExpr4(inputColor).c_str());
112f461a8fdf642ba713dcdfb217534652df1eac278krajcevski}
113f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
114f461a8fdf642ba713dcdfb217534652df1eac278krajcevski//////////////////////////////////////////////////////////////////////////////
115f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
116b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrDitherEffect::Create() { return DitherEffect::Create(); }
117