1 /*
2  * Copyright 2012 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 #ifndef GrConfigConversionEffect_DEFINED
9 #define GrConfigConversionEffect_DEFINED
10 
11 #include "GrSingleTextureEffect.h"
12 
13 class GrInvariantOutput;
14 
15 /**
16  * This class is used to perform config conversions. Clients may want to read/write data that is
17  * unpremultiplied.
18  */
19 class GrConfigConversionEffect : public GrSingleTextureEffect {
20 public:
21     /**
22      * The PM->UPM or UPM->PM conversions to apply.
23      */
24     enum PMConversion {
25         kMulByAlpha_RoundUp_PMConversion = 0,
26         kMulByAlpha_RoundDown_PMConversion,
27         kDivByAlpha_RoundUp_PMConversion,
28         kDivByAlpha_RoundDown_PMConversion,
29 
30         kPMConversionCnt
31     };
32 
33     static sk_sp<GrFragmentProcessor> Make(GrTexture*, PMConversion, const SkMatrix&);
34 
35     static sk_sp<GrFragmentProcessor> Make(GrResourceProvider*, sk_sp<GrTextureProxy>,
36                                            PMConversion, const SkMatrix&);
37 
name()38     const char* name() const override { return "Config Conversion"; }
39 
pmConversion()40     PMConversion  pmConversion() const { return fPMConversion; }
41 
42     // This function determines whether it is possible to choose PM->UPM and UPM->PM conversions
43     // for which in any PM->UPM->PM->UPM sequence the two UPM values are the same. This means that
44     // if pixels are read back to a UPM buffer, written back to PM to the GPU, and read back again
45     // both reads will produce the same result. This test is quite expensive and should not be run
46     // multiple times for a given context.
47     static void TestForPreservingPMConversions(GrContext* context,
48                                                PMConversion* PMToUPMRule,
49                                                PMConversion* UPMToPMRule);
50 private:
51     GrConfigConversionEffect(GrTexture*, PMConversion, const SkMatrix& matrix);
52 
53     GrConfigConversionEffect(GrResourceProvider*, sk_sp<GrTextureProxy>,
54                              PMConversion, const SkMatrix& matrix);
55 
56     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
57 
58     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
59 
60     bool onIsEqual(const GrFragmentProcessor&) const override;
61 
62     PMConversion    fPMConversion;
63 
64     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
65 
66     typedef GrSingleTextureEffect INHERITED;
67 };
68 
69 #endif
70