michael@0: /* michael@0: * Copyright 2012 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #ifndef GrConfigConversionEffect_DEFINED michael@0: #define GrConfigConversionEffect_DEFINED michael@0: michael@0: #include "GrSingleTextureEffect.h" michael@0: michael@0: class GrEffectStage; michael@0: class GrGLConfigConversionEffect; michael@0: michael@0: /** michael@0: * This class is used to perform config conversions. Clients may want to read/write data that is michael@0: * unpremultiplied. Also on some systems reading/writing BGRA or RGBA is faster. In those cases we michael@0: * read/write using the faster path and perform an R/B swap in the shader if the client data is in michael@0: * the slower config. michael@0: */ michael@0: class GrConfigConversionEffect : public GrSingleTextureEffect { michael@0: public: michael@0: /** michael@0: * The PM->UPM or UPM->PM conversions to apply. michael@0: */ michael@0: enum PMConversion { michael@0: kNone_PMConversion = 0, michael@0: kMulByAlpha_RoundUp_PMConversion, michael@0: kMulByAlpha_RoundDown_PMConversion, michael@0: kDivByAlpha_RoundUp_PMConversion, michael@0: kDivByAlpha_RoundDown_PMConversion, michael@0: michael@0: kPMConversionCnt michael@0: }; michael@0: michael@0: // Installs an effect in the GrEffectStage to perform a config conversion. michael@0: static const GrEffectRef* Create(GrTexture*, michael@0: bool swapRedAndBlue, michael@0: PMConversion pmConversion, michael@0: const SkMatrix& matrix); michael@0: michael@0: static const char* Name() { return "Config Conversion"; } michael@0: typedef GrGLConfigConversionEffect GLEffect; michael@0: michael@0: virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; michael@0: michael@0: virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; michael@0: michael@0: bool swapsRedAndBlue() const { return fSwapRedAndBlue; } michael@0: PMConversion pmConversion() const { return fPMConversion; } michael@0: michael@0: // This function determines whether it is possible to choose PM->UPM and UPM->PM conversions michael@0: // for which in any PM->UPM->PM->UPM sequence the two UPM values are the same. This means that michael@0: // if pixels are read back to a UPM buffer, written back to PM to the GPU, and read back again michael@0: // both reads will produce the same result. This test is quite expensive and should not be run michael@0: // multiple times for a given context. michael@0: static void TestForPreservingPMConversions(GrContext* context, michael@0: PMConversion* PMToUPMRule, michael@0: PMConversion* UPMToPMRule); michael@0: michael@0: private: michael@0: GrConfigConversionEffect(GrTexture*, michael@0: bool swapRedAndBlue, michael@0: PMConversion pmConversion, michael@0: const SkMatrix& matrix); michael@0: michael@0: virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; michael@0: michael@0: bool fSwapRedAndBlue; michael@0: PMConversion fPMConversion; michael@0: michael@0: GR_DECLARE_EFFECT_TEST; michael@0: michael@0: typedef GrSingleTextureEffect INHERITED; michael@0: }; michael@0: michael@0: #endif