Home | History | Annotate | Download | only in effects
      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 GrFragmentStage;
     14 class GrInvariantOutput;
     15 
     16 /**
     17  * This class is used to perform config conversions. Clients may want to read/write data that is
     18  * unpremultiplied. Also on some systems reading/writing BGRA or RGBA is faster. In those cases we
     19  * read/write using the faster path and perform an R/B swap in the shader if the client data is in
     20  * the slower config.
     21  */
     22 class GrConfigConversionEffect : public GrSingleTextureEffect {
     23 public:
     24     /**
     25      * The PM->UPM or UPM->PM conversions to apply.
     26      */
     27     enum PMConversion {
     28         kNone_PMConversion = 0,
     29         kMulByAlpha_RoundUp_PMConversion,
     30         kMulByAlpha_RoundDown_PMConversion,
     31         kDivByAlpha_RoundUp_PMConversion,
     32         kDivByAlpha_RoundDown_PMConversion,
     33 
     34         kPMConversionCnt
     35     };
     36 
     37     static const GrFragmentProcessor* Create(GrTexture*, bool swapRedAndBlue, PMConversion,
     38                                              const SkMatrix&);
     39 
     40     const char* name() const override { return "Config Conversion"; }
     41 
     42     void getGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
     43 
     44     GrGLFragmentProcessor* createGLInstance() const override;
     45 
     46     bool swapsRedAndBlue() const { return fSwapRedAndBlue; }
     47     PMConversion  pmConversion() const { return fPMConversion; }
     48 
     49     // This function determines whether it is possible to choose PM->UPM and UPM->PM conversions
     50     // for which in any PM->UPM->PM->UPM sequence the two UPM values are the same. This means that
     51     // if pixels are read back to a UPM buffer, written back to PM to the GPU, and read back again
     52     // both reads will produce the same result. This test is quite expensive and should not be run
     53     // multiple times for a given context.
     54     static void TestForPreservingPMConversions(GrContext* context,
     55                                                PMConversion* PMToUPMRule,
     56                                                PMConversion* UPMToPMRule);
     57 
     58 private:
     59     GrConfigConversionEffect(GrTexture*,
     60                             bool swapRedAndBlue,
     61                             PMConversion pmConversion,
     62                             const SkMatrix& matrix);
     63 
     64     bool onIsEqual(const GrFragmentProcessor&) const override;
     65 
     66     void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
     67 
     68     bool            fSwapRedAndBlue;
     69     PMConversion    fPMConversion;
     70 
     71     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
     72 
     73     typedef GrSingleTextureEffect INHERITED;
     74 };
     75 
     76 #endif
     77