Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2013 Google Inc. | |
|
Stephen White
2014/03/25 17:10:14
Nit: 2014.
| |
| 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 "SkValidateImageFilter.h" | |
| 9 #include "SkReadBuffer.h" | |
| 10 #include "SkWriteBuffer.h" | |
| 11 #include "SkColorPriv.h" | |
| 12 #if SK_SUPPORT_GPU | |
| 13 #include "GrContext.h" | |
| 14 #include "GrCoordTransform.h" | |
| 15 #include "gl/GrGLEffect.h" | |
| 16 #include "GrTBackendEffectFactory.h" | |
| 17 #endif | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 void validatePMColor(const SkBitmap* src, SkBitmap* dst, const SkIRect& bounds) { | |
|
Stephen White
2014/03/25 17:10:14
Nit: "src" should be a const ref, according to ski
| |
| 22 for (int y = bounds.top(); y < bounds.bottom(); ++y) { | |
| 23 const SkPMColor* srcPtr = src->getAddr32(bounds.left(), y); | |
| 24 SkPMColor* dstPtr = dst->getAddr32(bounds.left(), y); | |
| 25 for (int x = bounds.left(); x < bounds.right(); ++x, ++srcPtr) { | |
| 26 SkPMColor srcColor = *srcPtr; | |
| 27 unsigned a = SkGetPackedA32(srcColor); | |
| 28 unsigned r = SkGetPackedR32(srcColor); | |
| 29 unsigned g = SkGetPackedG32(srcColor); | |
| 30 unsigned b = SkGetPackedB32(srcColor); | |
| 31 *dstPtr++ = SkPackARGB32(a, SkTMin(r, a), SkTMin(g, a), SkTMin(b, a) ); | |
| 32 } | |
| 33 } | |
| 34 } | |
| 35 | |
| 36 } // end namespace | |
| 37 | |
| 38 /////////////////////////////////////////////////////////////////////////////// | |
| 39 | |
| 40 SkValidateImageFilter::SkValidateImageFilter(SkImageFilter* input) | |
| 41 : INHERITED(input) | |
| 42 { | |
| 43 } | |
| 44 | |
| 45 SkValidateImageFilter::~SkValidateImageFilter() { | |
| 46 } | |
| 47 | |
| 48 SkValidateImageFilter::SkValidateImageFilter(SkReadBuffer& buffer) | |
| 49 : INHERITED(1, buffer) | |
| 50 { | |
| 51 } | |
| 52 | |
| 53 void SkValidateImageFilter::flatten(SkWriteBuffer& buffer) const { | |
| 54 this->INHERITED::flatten(buffer); | |
| 55 } | |
| 56 | |
| 57 bool SkValidateImageFilter::onFilterImage(Proxy* proxy, | |
| 58 const SkBitmap& src, | |
| 59 const Context& ctx, | |
| 60 SkBitmap* dst, | |
| 61 SkIPoint* offset) const { | |
| 62 SkBitmap source = src; | |
| 63 SkImageFilter* input = getInput(0); | |
| 64 SkIPoint sourceOffset = SkIPoint::Make(0, 0); | |
| 65 if ((!input || !input->filterImage(proxy, src, ctx, &source, &sourceOffset)) ) { | |
| 66 return false; | |
| 67 } | |
| 68 | |
| 69 SkIRect bounds; | |
| 70 if (!this->applyCropRect(ctx, source, sourceOffset, &bounds)) { | |
| 71 return false; | |
| 72 } | |
| 73 | |
| 74 SkAutoLockPixels alp(source); | |
| 75 if (!source.getPixels()) { | |
| 76 return false; | |
| 77 } | |
| 78 | |
| 79 dst->setConfig(src.config(), bounds.width(), bounds.height()); | |
| 80 dst->allocPixels(); | |
| 81 if (!dst->getPixels()) { | |
| 82 return false; | |
| 83 } | |
| 84 | |
| 85 // Make sure none of the RGB components are larger than A | |
| 86 validatePMColor(&source, dst, bounds); | |
| 87 | |
| 88 offset->fX = bounds.left(); | |
| 89 offset->fY = bounds.top(); | |
| 90 return true; | |
| 91 } | |
| 92 | |
| 93 /////////////////////////////////////////////////////////////////////////////// | |
| 94 | |
| 95 #if SK_SUPPORT_GPU | |
| 96 class GrGLValidateEffect : public GrGLEffect { | |
| 97 public: | |
| 98 GrGLValidateEffect(const GrBackendEffectFactory& factory, | |
| 99 const GrDrawEffect& drawEffect); | |
| 100 virtual ~GrGLValidateEffect(); | |
| 101 | |
| 102 virtual void emitCode(GrGLShaderBuilder*, | |
| 103 const GrDrawEffect&, | |
| 104 EffectKey, | |
| 105 const char* outputColor, | |
| 106 const char* inputColor, | |
| 107 const TransformedCoordsArray&, | |
| 108 const TextureSamplerArray&) SK_OVERRIDE; | |
| 109 | |
| 110 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&); | |
| 111 | |
| 112 private: | |
| 113 typedef GrGLEffect INHERITED; | |
| 114 }; | |
| 115 | |
| 116 /////////////////////////////////////////////////////////////////////////////// | |
| 117 | |
| 118 class GrValidateEffect : public GrEffect { | |
| 119 public: | |
| 120 static GrEffectRef* Create(GrTexture* color) { | |
|
Stephen White
2014/03/25 17:10:14
Same here.
| |
| 121 AutoEffectUnref effect(SkNEW_ARGS(GrValidateEffect, (color))); | |
| 122 return CreateEffectRef(effect); | |
| 123 } | |
| 124 | |
| 125 virtual ~GrValidateEffect(); | |
| 126 | |
| 127 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | |
| 128 | |
| 129 typedef GrGLValidateEffect GLEffect; | |
| 130 static const char* Name() { return "Validate"; } | |
| 131 | |
| 132 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE; | |
| 133 | |
| 134 private: | |
| 135 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; | |
| 136 | |
| 137 GrValidateEffect(GrTexture* color); | |
| 138 | |
| 139 GR_DECLARE_EFFECT_TEST; | |
| 140 | |
| 141 GrCoordTransform fColorTransform; | |
| 142 GrTextureAccess fColorAccess; | |
| 143 | |
| 144 typedef GrEffect INHERITED; | |
| 145 }; | |
| 146 | |
| 147 bool SkValidateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, co nst Context& ctx, | |
| 148 SkBitmap* result, SkIPoint* offset) c onst { | |
| 149 SkBitmap source = src; | |
| 150 SkImageFilter* input = getInput(0); | |
| 151 SkIPoint sourceOffset = SkIPoint::Make(0, 0); | |
| 152 if (!input || !input->getInputResultGPU(proxy, src, ctx, &source, &sourceOff set)) { | |
| 153 return false; | |
| 154 } | |
| 155 | |
| 156 SkIRect bounds; | |
| 157 if (!this->applyCropRect(ctx, source, sourceOffset, &bounds)) { | |
| 158 return false; | |
| 159 } | |
| 160 | |
| 161 GrTexture* color = source.getTexture(); | |
|
Stephen White
2014/03/25 17:10:14
Nit: maybe call this sourceTexture instead.
| |
| 162 GrContext* context = color->getContext(); | |
| 163 | |
| 164 GrTextureDesc desc; | |
| 165 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; | |
| 166 desc.fWidth = bounds.width(); | |
| 167 desc.fHeight = bounds.height(); | |
| 168 desc.fConfig = kSkia8888_GrPixelConfig; | |
| 169 | |
| 170 GrAutoScratchTexture ast(context, desc); | |
| 171 SkAutoTUnref<GrTexture> dst(ast.detach()); | |
| 172 | |
| 173 GrContext::AutoRenderTarget art(context, dst->asRenderTarget()); | |
| 174 | |
| 175 GrPaint paint; | |
| 176 paint.addColorEffect(GrValidateEffect::Create(color))->unref(); | |
| 177 | |
| 178 SkIRect colorBounds = bounds; | |
| 179 colorBounds.offset(-sourceOffset); | |
| 180 GrContext::AutoMatrix am; | |
| 181 am.setIdentity(context); | |
| 182 SkMatrix matrix; | |
| 183 matrix.setTranslate(-SkIntToScalar(colorBounds.x()), | |
| 184 -SkIntToScalar(colorBounds.y())); | |
| 185 context->concatMatrix(matrix); | |
| 186 context->drawRect(paint, SkRect::Make(colorBounds)); | |
| 187 offset->fX = bounds.left(); | |
| 188 offset->fY = bounds.top(); | |
| 189 WrapTexture(dst, bounds.width(), bounds.height(), result); | |
| 190 return true; | |
| 191 } | |
| 192 | |
| 193 /////////////////////////////////////////////////////////////////////////////// | |
| 194 | |
| 195 GrValidateEffect::GrValidateEffect(GrTexture* color) | |
| 196 : fColorTransform(kLocal_GrCoordSet, color), | |
| 197 fColorAccess(color) { | |
| 198 this->addCoordTransform(&fColorTransform); | |
| 199 this->addTextureAccess(&fColorAccess); | |
| 200 } | |
| 201 | |
| 202 GrValidateEffect::~GrValidateEffect() { | |
| 203 } | |
| 204 | |
| 205 bool GrValidateEffect::onIsEqual(const GrEffect&) const { | |
| 206 return true; | |
| 207 } | |
| 208 | |
| 209 const GrBackendEffectFactory& GrValidateEffect::getFactory() const { | |
| 210 return GrTBackendEffectFactory<GrValidateEffect>::getInstance(); | |
| 211 } | |
| 212 | |
| 213 void GrValidateEffect::getConstantColorComponents(GrColor* color, uint32_t* vali dFlags) const { | |
| 214 *validFlags = 0; | |
| 215 } | |
| 216 | |
| 217 /////////////////////////////////////////////////////////////////////////////// | |
| 218 | |
| 219 GR_DEFINE_EFFECT_TEST(GrValidateEffect); | |
| 220 | |
| 221 GrEffectRef* GrValidateEffect::TestCreate(SkRandom* random, | |
| 222 GrContext*, | |
| 223 const GrDrawTargetCaps&, | |
| 224 GrTexture* textures[]) { | |
| 225 int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : | |
| 226 GrEffectUnitTest::kAlphaTextureIdx; | |
| 227 return GrValidateEffect::Create(textures[texIdx]); | |
| 228 } | |
| 229 | |
| 230 /////////////////////////////////////////////////////////////////////////////// | |
| 231 | |
| 232 GrGLValidateEffect::GrGLValidateEffect(const GrBackendEffectFactory& factory, | |
| 233 const GrDrawEffect& drawEffect) | |
| 234 : INHERITED(factory) { | |
| 235 } | |
| 236 | |
| 237 GrGLValidateEffect::~GrGLValidateEffect() { | |
| 238 } | |
| 239 | |
| 240 void GrGLValidateEffect::emitCode(GrGLShaderBuilder* builder, | |
| 241 const GrDrawEffect&, | |
| 242 EffectKey key, | |
| 243 const char* outputColor, | |
| 244 const char* inputColor, | |
| 245 const TransformedCoordsArray& coords, | |
| 246 const TextureSamplerArray& samplers) { | |
| 247 const char* color = "col"; | |
| 248 | |
| 249 // Get input color | |
| 250 builder->fsCodeAppendf("\t\tvec4 %s = ", color); | |
| 251 builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].typ e()); | |
| 252 builder->fsCodeAppend(";\n"); | |
| 253 | |
| 254 // Make sure none of the RGB components are larger than A | |
| 255 builder->fsCodeAppendf("%s = vec4(min(%s.rgb, %s.a), %s.a);\n", | |
| 256 outputColor, color, color, color); | |
| 257 } | |
| 258 | |
| 259 GrGLEffect::EffectKey GrGLValidateEffect::GenKey(const GrDrawEffect& drawEffect, | |
| 260 const GrGLCaps&) { | |
| 261 return 0; | |
| 262 } | |
| 263 #endif | |
| OLD | NEW |