OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2014 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include "GrDitherEffect.h" | |
9 | |
10 #include "gl/GrGLEffect.h" | |
11 #include "gl/GrGLSL.h" | |
12 #include "GrTBackendEffectFactory.h" | |
13 | |
14 #include "SkRect.h" | |
15 | |
16 ////////////////////////////////////////////////////////////////////////////// | |
17 | |
18 class GLDitherEffect; | |
19 | |
20 class DitherEffect : public GrEffect { | |
21 public: | |
22 static GrEffectRef* Create() { | |
23 return CreateEffectRef(AutoEffectUnref(SkNEW(DitherEffect))); | |
24 } | |
25 | |
26 virtual ~DitherEffect() {}; | |
27 static const char* Name() { return "Dither"; } | |
28 | |
29 typedef GLDitherEffect GLEffect; | |
30 | |
31 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE; | |
32 | |
33 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | |
34 return GrTBackendEffectFactory<DitherEffect>::getInstance(); | |
35 } | |
36 | |
37 private: | |
38 DitherEffect() { | |
39 this->setWillReadFragmentPosition(); | |
40 } | |
41 | |
42 // All dither effects are equal | |
43 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE { return true; } | |
44 | |
45 GR_DECLARE_EFFECT_TEST; | |
46 | |
47 typedef GrEffect INHERITED; | |
48 }; | |
49 | |
50 void DitherEffect::getConstantColorComponents(GrColor* color, uint32_t* validFla gs) const { | |
51 *validFlags = 0; | |
52 } | |
53 | |
54 ////////////////////////////////////////////////////////////////////////////// | |
55 | |
56 GR_DEFINE_EFFECT_TEST(DitherEffect); | |
57 | |
58 GrEffectRef* DitherEffect::TestCreate(SkRandom*, | |
59 GrContext*, | |
60 const GrDrawTargetCaps&, | |
61 GrTexture*[]) { | |
62 return DitherEffect::Create(); | |
63 } | |
64 | |
65 ////////////////////////////////////////////////////////////////////////////// | |
66 | |
67 class GLDitherEffect : public GrGLEffect { | |
68 public: | |
69 GLDitherEffect(const GrBackendEffectFactory&, const GrDrawEffect&); | |
70 | |
71 virtual void emitCode(GrGLShaderBuilder* builder, | |
72 const GrDrawEffect& drawEffect, | |
73 EffectKey key, | |
74 const char* outputColor, | |
75 const char* inputColor, | |
76 const TransformedCoordsArray&, | |
77 const TextureSamplerArray&) SK_OVERRIDE; | |
78 | |
79 private: | |
80 typedef GrGLEffect INHERITED; | |
81 }; | |
82 | |
83 GLDitherEffect::GLDitherEffect(const GrBackendEffectFactory& factory, | |
84 const GrDrawEffect& drawEffect) | |
85 : INHERITED (factory) { | |
86 } | |
87 | |
robertphillips
2014/06/11 14:15:50
// for each channel c:
// 1. Compute quantized col
krajcevski
2014/06/11 22:33:18
Done.
| |
88 void GLDitherEffect::emitCode(GrGLShaderBuilder* builder, | |
89 const GrDrawEffect& drawEffect, | |
90 EffectKey key, | |
91 const char* outputColor, | |
92 const char* inputColor, | |
93 const TransformedCoordsArray&, | |
94 const TextureSamplerArray& samplers) { | |
95 // Generate a random number based on the fragment position. | |
96 builder->fsCodeAppendf("\t\tfloat r = " | |
robertphillips
2014/06/11 14:14:32
magic numbers?
egdaniel
2014/06/11 14:26:24
Probably should add a comment to describe it, but
krajcevski
2014/06/11 22:33:18
I added a comment for this.
| |
97 "fract(sin(dot(%s.xy ,vec2(12.9898,78.233))) * 43758. 5453);\n", | |
98 builder->fragmentPosition()); | |
99 | |
100 // For each channel, weight the neighboring pixel values based on thier | |
101 // distance from the input channel | |
robertphillips
2014/06/11 14:14:32
kSuffixes ?
krajcevski
2014/06/11 22:33:18
Done.
| |
102 static const char *suffixes[4] = { "r", "g", "b", "a" }; | |
103 for (int i = 0; i < 4; ++i) { | |
104 builder->fsCodeAppendf("\t\tfloat dithered_%s;\n", suffixes[i]); | |
105 builder->fsCodeAppendf("\t\t{\n"); | |
106 builder->fsCodeAppendf("\t\t\tfloat channel = 255.0f * %s.%s;\n", | |
107 inputColor, suffixes[i]); | |
108 builder->fsCodeAppendf("\t\t\tfloat low = floor(channel);\n"); | |
109 builder->fsCodeAppendf("\t\t\tfloat c = channel-low;\n"); | |
110 builder->fsCodeAppendf("\t\t\tfloat high = low + 1;\n"); | |
111 builder->fsCodeAppendf("\t\t\tfloat t = float(c > r);\n"); | |
112 builder->fsCodeAppendf("\t\t\tdithered_%s = (low*(1-t) + high*t)/255.0f; \n", suffixes[i]); | |
113 builder->fsCodeAppendf("\t\t}\n"); | |
114 } | |
115 | |
116 builder->fsCodeAppendf("\t\t%s = vec4(", outputColor); | |
117 for (int i = 0; i < 4; ++i) { | |
118 builder->fsCodeAppendf("dithered_%s%s", suffixes[i], (i < 3)? ", " : "); \n"); | |
119 } | |
120 } | |
121 | |
122 ////////////////////////////////////////////////////////////////////////////// | |
123 | |
124 GrEffectRef* GrDitherEffect::Create() { | |
125 return DitherEffect::Create(); | |
126 } | |
OLD | NEW |