OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2013 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 "SkLumaXfermode.h" |
| 9 #include "SkColorPriv.h" |
| 10 #include "SkFlattenableBuffers.h" |
| 11 #include "SkString.h" |
| 12 |
| 13 #if SK_SUPPORT_GPU |
| 14 #include "gl/GrGLEffect.h" |
| 15 #include "gl/GrGLEffectMatrix.h" |
| 16 #include "GrContext.h" |
| 17 #include "GrTBackendEffectFactory.h" |
| 18 #endif |
| 19 |
| 20 static inline SkPMColor luma_proc(const SkPMColor a, const SkPMColor b) { |
| 21 unsigned luma = SkComputeLuminance(SkGetPackedR32(b), |
| 22 SkGetPackedG32(b), |
| 23 SkGetPackedB32(b)); |
| 24 return SkAlphaMulQ(a, SkAlpha255To256(luma)); |
| 25 } |
| 26 |
| 27 template <typename T> |
| 28 static inline const T* lumaOpA(SkXfermode::Mode mode, |
| 29 const T* src, const T* dst) { |
| 30 return SkXfermode::kSrcIn_Mode == mode ? src : dst; |
| 31 } |
| 32 |
| 33 template <typename T> |
| 34 static inline const T* lumaOpB(SkXfermode::Mode mode, |
| 35 const T* src, const T* dst) { |
| 36 return SkXfermode::kSrcIn_Mode == mode ? dst : src; |
| 37 } |
| 38 |
| 39 SkXfermode* SkLumaMaskXfermode::Create(SkXfermode::Mode mode) { |
| 40 if (kSrcIn_Mode == mode || kDstIn_Mode == mode) { |
| 41 return SkNEW_ARGS(SkLumaMaskXfermode, (mode)); |
| 42 } |
| 43 return NULL; |
| 44 } |
| 45 |
| 46 SkLumaMaskXfermode::SkLumaMaskXfermode(SkXfermode::Mode mode) |
| 47 : fMode(mode) { |
| 48 SkASSERT(kSrcIn_Mode == mode || kDstIn_Mode == mode); |
| 49 } |
| 50 |
| 51 SkLumaMaskXfermode::SkLumaMaskXfermode(SkFlattenableReadBuffer& buffer) |
| 52 : INHERITED(buffer) |
| 53 , fMode((SkXfermode::Mode)buffer.readUInt()) { |
| 54 SkASSERT(kSrcIn_Mode == fMode || kDstIn_Mode == fMode); |
| 55 } |
| 56 |
| 57 void SkLumaMaskXfermode::flatten(SkFlattenableWriteBuffer& buffer) const { |
| 58 INHERITED::flatten(buffer); |
| 59 buffer.writeUInt(fMode); |
| 60 } |
| 61 |
| 62 SkPMColor SkLumaMaskXfermode::xferColor(SkPMColor src, SkPMColor dst) const { |
| 63 const SkPMColor* a = lumaOpA<SkPMColor>(fMode, &src, &dst); |
| 64 const SkPMColor* b = lumaOpB<SkPMColor>(fMode, &src, &dst); |
| 65 return luma_proc(*a, *b); |
| 66 } |
| 67 |
| 68 void SkLumaMaskXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], |
| 69 int count, const SkAlpha aa[]) const { |
| 70 const SkPMColor* a = lumaOpA<SkPMColor>(fMode, src, dst); |
| 71 const SkPMColor* b = lumaOpB<SkPMColor>(fMode, src, dst); |
| 72 |
| 73 if (aa) { |
| 74 for (int i = 0; i < count; ++i) { |
| 75 unsigned cov = aa[i]; |
| 76 if (cov) { |
| 77 unsigned resC = luma_proc(a[i], b[i]); |
| 78 if (cov < 255) { |
| 79 resC = SkAlphaMulQ(resC, SkAlpha255To256(cov)); |
| 80 } |
| 81 dst[i] = resC; |
| 82 } |
| 83 } |
| 84 } else { |
| 85 for (int i = 0; i < count; ++i) { |
| 86 dst[i] = luma_proc(a[i], b[i]); |
| 87 } |
| 88 } |
| 89 } |
| 90 |
| 91 #ifdef SK_DEVELOPER |
| 92 void SkLumaMaskXfermode::toString(SkString* str) const { |
| 93 str->printf("SkLumaMaskXfermode: mode: %s", |
| 94 fMode == kSrcIn_Mode ? "SRC_IN" : "DST_IN"); |
| 95 } |
| 96 #endif |
| 97 |
| 98 #if SK_SUPPORT_GPU |
| 99 ////////////////////////////////////////////////////////////////////////////// |
| 100 |
| 101 class GrGLLumaMaskEffect : public GrGLEffect { |
| 102 public: |
| 103 GrGLLumaMaskEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
| 104 virtual ~GrGLLumaMaskEffect(); |
| 105 |
| 106 virtual void emitCode(GrGLShaderBuilder*, |
| 107 const GrDrawEffect&, |
| 108 EffectKey, |
| 109 const char* outputColor, |
| 110 const char* inputColor, |
| 111 const TextureSamplerArray&) SK_OVERRIDE; |
| 112 |
| 113 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&); |
| 114 |
| 115 private: |
| 116 typedef GrGLEffect INHERITED; |
| 117 }; |
| 118 |
| 119 class GrLumaMaskEffect : public GrEffect { |
| 120 public: |
| 121 static GrEffectRef* Create(SkXfermode::Mode mode) { |
| 122 AutoEffectUnref effect(SkNEW_ARGS(GrLumaMaskEffect, (mode))); |
| 123 return CreateEffectRef(effect); |
| 124 } |
| 125 |
| 126 virtual ~GrLumaMaskEffect(); |
| 127 |
| 128 typedef GrGLLumaMaskEffect GLEffect; |
| 129 static const char* Name() { return "LumaMask"; } |
| 130 |
| 131 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
| 132 virtual void getConstantColorComponents(GrColor*, uint32_t*) const SK_OVERRI
DE; |
| 133 |
| 134 SkXfermode::Mode getMode() const { return fMode; } |
| 135 |
| 136 private: |
| 137 GrLumaMaskEffect(SkXfermode::Mode); |
| 138 |
| 139 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; |
| 140 |
| 141 const SkXfermode::Mode fMode; |
| 142 }; |
| 143 |
| 144 ////////////////////////////////////////////////////////////////////////////// |
| 145 |
| 146 GrGLLumaMaskEffect::GrGLLumaMaskEffect(const GrBackendEffectFactory& factory, |
| 147 const GrDrawEffect&) |
| 148 : INHERITED(factory) { |
| 149 } |
| 150 |
| 151 GrGLLumaMaskEffect::~GrGLLumaMaskEffect() { |
| 152 } |
| 153 |
| 154 void GrGLLumaMaskEffect::emitCode(GrGLShaderBuilder* builder, |
| 155 const GrDrawEffect& effect, |
| 156 EffectKey key, |
| 157 const char* outputColor, |
| 158 const char* inputColor, |
| 159 const TextureSamplerArray& samplers) { |
| 160 |
| 161 const GrLumaMaskEffect& lumaEffect = effect.castEffect<GrLumaMaskEffect>(); |
| 162 const char* dstColor = builder->dstColor(); |
| 163 SkASSERT(NULL != dstColor); |
| 164 if (NULL == inputColor) { |
| 165 inputColor = GrGLSLOnesVecf(4); |
| 166 } |
| 167 |
| 168 const char *opA = lumaOpA<char>(lumaEffect.getMode(), inputColor, dstColor); |
| 169 const char *opB = lumaOpB<char>(lumaEffect.getMode(), inputColor, dstColor); |
| 170 |
| 171 builder->fsCodeAppendf("\t\tfloat luma = dot(vec3(%f, %f, %f), %s.rgb); \n", |
| 172 SK_ITU_BT709_LUM_COEFF_R, |
| 173 SK_ITU_BT709_LUM_COEFF_G, |
| 174 SK_ITU_BT709_LUM_COEFF_B, |
| 175 opB); |
| 176 builder->fsCodeAppendf("\t\t%s = %s * luma;\n", outputColor, opA); |
| 177 } |
| 178 |
| 179 GrGLEffect::EffectKey GrGLLumaMaskEffect::GenKey(const GrDrawEffect& drawEffect, |
| 180 const GrGLCaps&) { |
| 181 const GrLumaMaskEffect& effect = drawEffect.castEffect<GrLumaMaskEffect>(); |
| 182 return (EffectKey)effect.getMode(); |
| 183 } |
| 184 |
| 185 ////////////////////////////////////////////////////////////////////////////// |
| 186 |
| 187 GrLumaMaskEffect::GrLumaMaskEffect(SkXfermode::Mode mode) |
| 188 : fMode(mode) { |
| 189 this->setWillReadDstColor(); |
| 190 } |
| 191 |
| 192 GrLumaMaskEffect::~GrLumaMaskEffect() { |
| 193 } |
| 194 |
| 195 const GrBackendEffectFactory& GrLumaMaskEffect::getFactory() const { |
| 196 return GrTBackendEffectFactory<GrLumaMaskEffect>::getInstance(); |
| 197 } |
| 198 |
| 199 void GrLumaMaskEffect::getConstantColorComponents(GrColor*, uint32_t *validFlags
) const { |
| 200 *validFlags = 0; |
| 201 } |
| 202 |
| 203 bool GrLumaMaskEffect::onIsEqual(const GrEffect& sBase) const { |
| 204 return fMode == CastEffect<GrLumaMaskEffect>(sBase).fMode; |
| 205 } |
| 206 |
| 207 ////////////////////////////////////////////////////////////////////////////// |
| 208 |
| 209 bool SkLumaMaskXfermode::asNewEffectOrCoeff(GrContext*, GrEffectRef** effect, |
| 210 Coeff*, Coeff*, |
| 211 GrTexture* background) const { |
| 212 // No background texture support. |
| 213 if (effect && !background) { |
| 214 *effect = GrLumaMaskEffect::Create(fMode); |
| 215 return true; |
| 216 } |
| 217 |
| 218 return false; |
| 219 } |
| 220 |
| 221 #endif // SK_SUPPORT_GPU |
OLD | NEW |