blob: 7ec852e6b010eaa8b861c4051c0343ab5d823545 [file] [log] [blame]
Brian Salomon0c15ae82017-07-19 15:39:56 +00001// This controls the range of values added to color channels
2layout(key) in int rangeType;
Brian Salomonf2290cb2017-07-18 21:13:04 +00003
Brian Salomon0c15ae82017-07-19 15:39:56 +00004@make {
5 static sk_sp<GrFragmentProcessor> Make(GrPixelConfig dstConfig) {
6 int rangeType;
7 switch (dstConfig) {
8 case kGray_8_GrPixelConfig:
9 case kRGBA_8888_GrPixelConfig:
10 case kBGRA_8888_GrPixelConfig:
11 case kSRGBA_8888_GrPixelConfig:
12 case kSBGRA_8888_GrPixelConfig:
13 rangeType = 0;
14 break;
15 case kRGB_565_GrPixelConfig:
16 rangeType = 1;
17 break;
18 case kRGBA_4444_GrPixelConfig:
19 rangeType = 2;
20 break;
21 case kUnknown_GrPixelConfig:
22 case kAlpha_half_GrPixelConfig:
23 case kRGBA_8888_sint_GrPixelConfig:
24 case kRGBA_float_GrPixelConfig:
25 case kRG_float_GrPixelConfig:
26 case kRGBA_half_GrPixelConfig:
27 case kAlpha_8_GrPixelConfig:
28 return nullptr;
29 }
30 return sk_sp<GrFragmentProcessor>(new GrDitherEffect(rangeType));
31 }
32}
33
34void main() {
35 float value;
36 float range;
37 @switch (rangeType) {
38 case 0:
39 range = 1.0 / 255.0;
40 break;
41 case 1:
42 range = 1.0 / 63.0;
43 break;
44 default:
45 // Experimentally this looks better than the expected value of 1/15.
Eric Karle1fc9ac2017-08-07 15:55:13 -070046 range = 1.0 / 15.0;
Brian Salomon0c15ae82017-07-19 15:39:56 +000047 break;
48 }
49 @if (sk_Caps.integerSupport) {
50 // This ordered-dither code is lifted from the cpu backend.
Ethan Nicholasdcba08e2017-08-02 10:52:54 -040051 uint x = uint(sk_FragCoord.x);
52 uint y = uint(sk_FragCoord.y);
Brian Salomon0c15ae82017-07-19 15:39:56 +000053 uint m = (y & 1) << 5 | (x & 1) << 4 |
54 (y & 2) << 2 | (x & 2) << 1 |
55 (y & 4) >> 1 | (x & 4) >> 2;
56 value = float(m) * 1.0 / 64.0 - 63.0 / 128.0;
57 } else {
Eric Karle1fc9ac2017-08-07 15:55:13 -070058 // Simulate the integer effect used above using step/mod. For speed, simulates a 4x4
59 // dither pattern rather than an 8x8 one.
60 float4 modValues = mod(sk_FragCoord.xyxy, float4(2.0, 2.0, 4.0, 4.0));
61 float4 stepValues = step(modValues, float4(1.0, 1.0, 2.0, 2.0));
62 value = dot(stepValues, float4(8.0 / 16.0, 4.0 / 16.0, 2.0 / 16.0, 1.0 / 16.0)) - 15.0 / 32.0;
Brian Salomon0c15ae82017-07-19 15:39:56 +000063 }
64 // For each color channel, add the random offset to the channel value and then clamp
65 // between 0 and alpha to keep the color premultiplied.
Ethan Nicholas5af9ea32017-07-28 15:19:46 -040066 sk_OutColor = float4(clamp(sk_InColor.rgb + value * range, 0, sk_InColor.a), sk_InColor.a);
Ethan Nicholas762466e2017-06-29 10:03:38 -040067}
68
69@test(testData) {
Brian Salomon0c15ae82017-07-19 15:39:56 +000070 float range = testData->fRandom->nextRangeF(0.001f, 0.05f);
71 return sk_sp<GrFragmentProcessor>(new GrDitherEffect(range));
72}