Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: src/effects/SkTableColorFilter.cpp

Issue 655913003: Use texture strip atlas for color table filter (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/effects/gradients/SkGradientShader.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 #include "SkBitmap.h" 2 #include "SkBitmap.h"
3 #include "SkTableColorFilter.h" 3 #include "SkTableColorFilter.h"
4 #include "SkColorPriv.h" 4 #include "SkColorPriv.h"
5 #include "SkReadBuffer.h" 5 #include "SkReadBuffer.h"
6 #include "SkWriteBuffer.h" 6 #include "SkWriteBuffer.h"
7 #include "SkUnPreMultiply.h" 7 #include "SkUnPreMultiply.h"
8 #include "SkString.h" 8 #include "SkString.h"
9 9
10 class SkTable_ColorFilter : public SkColorFilter { 10 class SkTable_ColorFilter : public SkColorFilter {
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 } 270 }
271 *table = *fBitmap; 271 *table = *fBitmap;
272 } 272 }
273 return true; 273 return true;
274 } 274 }
275 275
276 #if SK_SUPPORT_GPU 276 #if SK_SUPPORT_GPU
277 277
278 #include "GrFragmentProcessor.h" 278 #include "GrFragmentProcessor.h"
279 #include "GrTBackendProcessorFactory.h" 279 #include "GrTBackendProcessorFactory.h"
280 #include "SkGr.h"
280 #include "gl/GrGLProcessor.h" 281 #include "gl/GrGLProcessor.h"
281 #include "gl/builders/GrGLProgramBuilder.h" 282 #include "gl/builders/GrGLProgramBuilder.h"
robertphillips 2014/10/27 19:35:06 move to before gl includes ?
bsalomon 2014/10/27 19:43:03 Done.
282 #include "SkGr.h" 283 #include "effects/GrTextureStripAtlas.h"
283 284
284 class GLColorTableEffect; 285 class GLColorTableEffect;
285 286
286 class ColorTableEffect : public GrFragmentProcessor { 287 class ColorTableEffect : public GrFragmentProcessor {
287 public: 288 public:
288 static GrFragmentProcessor* Create(GrTexture* texture, unsigned flags) { 289 static GrFragmentProcessor* Create(GrContext* context, SkBitmap bitmap, unsi gned flags);
289 return SkNEW_ARGS(ColorTableEffect, (texture, flags));
290 }
291 290
292 virtual ~ColorTableEffect(); 291 virtual ~ColorTableEffect();
293 292
294 static const char* Name() { return "ColorTable"; } 293 static const char* Name() { return "ColorTable"; }
295 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERR IDE; 294 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERR IDE;
296 295
297 typedef GLColorTableEffect GLProcessor; 296 typedef GLColorTableEffect GLProcessor;
298 297
298 const GrTextureStripAtlas* atlas() const { return fAtlas; }
299 int atlasRow() const { return fRow; }
300
299 private: 301 private:
300 virtual bool onIsEqual(const GrFragmentProcessor&) const SK_OVERRIDE{ return true; } 302 virtual bool onIsEqual(const GrFragmentProcessor&) const SK_OVERRIDE;
301 303
302 virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERR IDE; 304 virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERR IDE;
303 305
304 explicit ColorTableEffect(GrTexture* texture, unsigned flags); 306 ColorTableEffect(GrTexture* texture, GrTextureStripAtlas* atlas, int row, un signed flags);
305 307
306 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 308 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
307 309
308 GrTextureAccess fTextureAccess; 310 GrTextureAccess fTextureAccess;
309 unsigned fFlags; // currently not used in shader code, just to assist 311
310 // onComputeInvariantOutput(). 312 // currently not used in shader code, just to assist onComputeInvariantOutpu t().
313 unsigned fFlags;
314
315 GrTextureStripAtlas* fAtlas;
316 int fRow;
311 317
312 typedef GrFragmentProcessor INHERITED; 318 typedef GrFragmentProcessor INHERITED;
313 }; 319 };
314 320
315 class GLColorTableEffect : public GrGLFragmentProcessor { 321 class GLColorTableEffect : public GrGLFragmentProcessor {
316 public: 322 public:
317 GLColorTableEffect(const GrBackendProcessorFactory&, const GrProcessor&); 323 GLColorTableEffect(const GrBackendProcessorFactory&, const GrProcessor&);
318 324
319 virtual void emitCode(GrGLFPBuilder*, 325 virtual void emitCode(GrGLFPBuilder*,
320 const GrFragmentProcessor&, 326 const GrFragmentProcessor&,
321 const GrProcessorKey&, 327 const GrProcessorKey&,
322 const char* outputColor, 328 const char* outputColor,
323 const char* inputColor, 329 const char* inputColor,
324 const TransformedCoordsArray&, 330 const TransformedCoordsArray&,
325 const TextureSamplerArray&) SK_OVERRIDE; 331 const TextureSamplerArray&) SK_OVERRIDE;
326 332
327 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_O VERRIDE {} 333 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_O VERRIDE;
328 334
329 static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilde r* b) {} 335 static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilde r* b) {}
330 336
331 private: 337 private:
332 338 UniformHandle fRGBAYValuesUni;
333 typedef GrGLFragmentProcessor INHERITED; 339 typedef GrGLFragmentProcessor INHERITED;
334 }; 340 };
335 341
336 GLColorTableEffect::GLColorTableEffect(const GrBackendProcessorFactory& factory, const GrProcessor&) 342 GLColorTableEffect::GLColorTableEffect(const GrBackendProcessorFactory& factory, const GrProcessor&)
337 : INHERITED(factory) { 343 : INHERITED(factory) {
338 } 344 }
339 345
346 void GLColorTableEffect::setData(const GrGLProgramDataManager& pdm, const GrProc essor& proc) {
347 // The textures are organized in a strip where the rows are ordered a, r, g, b.
348 float rgbaYValues[4];
349 const ColorTableEffect& cte = proc.cast<ColorTableEffect>();
350 if (cte.atlas()) {
351 SkScalar yDelta = cte.atlas()->getNormalizedTexelHeight();
352 rgbaYValues[3] = cte.atlas()->getYOffset(cte.atlasRow()) + SK_ScalarHalf * yDelta;
353 rgbaYValues[0] = rgbaYValues[3] + yDelta;
354 rgbaYValues[1] = rgbaYValues[0] + yDelta;
355 rgbaYValues[2] = rgbaYValues[1] + yDelta;
356 } else {
357 rgbaYValues[3] = 0.125;
358 rgbaYValues[0] = 0.375;
359 rgbaYValues[1] = 0.625;
360 rgbaYValues[2] = 0.875;
361 }
362 pdm.set4fv(fRGBAYValuesUni, 1, rgbaYValues);
363 }
364
340 void GLColorTableEffect::emitCode(GrGLFPBuilder* builder, 365 void GLColorTableEffect::emitCode(GrGLFPBuilder* builder,
341 const GrFragmentProcessor&, 366 const GrFragmentProcessor&,
342 const GrProcessorKey&, 367 const GrProcessorKey&,
343 const char* outputColor, 368 const char* outputColor,
344 const char* inputColor, 369 const char* inputColor,
345 const TransformedCoordsArray&, 370 const TransformedCoordsArray&,
346 const TextureSamplerArray& samplers) { 371 const TextureSamplerArray& samplers) {
347 372 const char* yoffsets;
373 fRGBAYValuesUni = builder->addUniform(GrGLFPBuilder::kFragment_Visibility,
374 kVec4f_GrSLType, "yoffsets", &yoffsets );
348 static const float kColorScaleFactor = 255.0f / 256.0f; 375 static const float kColorScaleFactor = 255.0f / 256.0f;
349 static const float kColorOffsetFactor = 1.0f / 512.0f; 376 static const float kColorOffsetFactor = 1.0f / 512.0f;
350 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 377 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
351 if (NULL == inputColor) { 378 if (NULL == inputColor) {
352 // the input color is solid white (all ones). 379 // the input color is solid white (all ones).
353 static const float kMaxValue = kColorScaleFactor + kColorOffsetFactor; 380 static const float kMaxValue = kColorScaleFactor + kColorOffsetFactor;
354 fsBuilder->codeAppendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n", 381 fsBuilder->codeAppendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
355 kMaxValue, kMaxValue, kMaxValue, kMaxValue); 382 kMaxValue, kMaxValue, kMaxValue, kMaxValue);
356 383
357 } else { 384 } else {
358 fsBuilder->codeAppendf("\t\tfloat nonZeroAlpha = max(%s.a, .0001);\n", i nputColor); 385 fsBuilder->codeAppendf("\t\tfloat nonZeroAlpha = max(%s.a, .0001);\n", i nputColor);
359 fsBuilder->codeAppendf("\t\tvec4 coord = vec4(%s.rgb / nonZeroAlpha, non ZeroAlpha);\n", inputColor); 386 fsBuilder->codeAppendf("\t\tvec4 coord = vec4(%s.rgb / nonZeroAlpha, non ZeroAlpha);\n", inputColor);
360 fsBuilder->codeAppendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n ", 387 fsBuilder->codeAppendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n ",
361 kColorScaleFactor, 388 kColorScaleFactor,
362 kColorOffsetFactor, kColorOffsetFactor, 389 kColorOffsetFactor, kColorOffsetFactor,
363 kColorOffsetFactor, kColorOffsetFactor); 390 kColorOffsetFactor, kColorOffsetFactor);
364 } 391 }
365 392
393 SkString coord;
394
366 fsBuilder->codeAppendf("\t\t%s.a = ", outputColor); 395 fsBuilder->codeAppendf("\t\t%s.a = ", outputColor);
367 fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.a, 0.125)"); 396 coord.printf("vec2(coord.a, %s.a)", yoffsets);
397 fsBuilder->appendTextureLookup(samplers[0], coord.c_str());
368 fsBuilder->codeAppend(";\n"); 398 fsBuilder->codeAppend(";\n");
369 399
370 fsBuilder->codeAppendf("\t\t%s.r = ", outputColor); 400 fsBuilder->codeAppendf("\t\t%s.r = ", outputColor);
371 fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.r, 0.375)"); 401 coord.printf("vec2(coord.r, %s.r)", yoffsets);
402 fsBuilder->appendTextureLookup(samplers[0], coord.c_str());
372 fsBuilder->codeAppend(";\n"); 403 fsBuilder->codeAppend(";\n");
373 404
374 fsBuilder->codeAppendf("\t\t%s.g = ", outputColor); 405 fsBuilder->codeAppendf("\t\t%s.g = ", outputColor);
375 fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.g, 0.625)"); 406 coord.printf("vec2(coord.g, %s.g)", yoffsets);
407 fsBuilder->appendTextureLookup(samplers[0], coord.c_str());
376 fsBuilder->codeAppend(";\n"); 408 fsBuilder->codeAppend(";\n");
377 409
378 fsBuilder->codeAppendf("\t\t%s.b = ", outputColor); 410 fsBuilder->codeAppendf("\t\t%s.b = ", outputColor);
379 fsBuilder->appendTextureLookup(samplers[0], "vec2(coord.b, 0.875)"); 411 coord.printf("vec2(coord.b, %s.b)", yoffsets);
412 fsBuilder->appendTextureLookup(samplers[0], coord.c_str());
380 fsBuilder->codeAppend(";\n"); 413 fsBuilder->codeAppend(";\n");
381 414
382 fsBuilder->codeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor); 415 fsBuilder->codeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
383 } 416 }
384 417
385 /////////////////////////////////////////////////////////////////////////////// 418 ///////////////////////////////////////////////////////////////////////////////
419 GrFragmentProcessor* ColorTableEffect::Create(GrContext* context, SkBitmap bitma p, unsigned flags) {
386 420
387 ColorTableEffect::ColorTableEffect(GrTexture* texture, unsigned flags) 421 GrTextureStripAtlas::Desc desc;
422 desc.fWidth = bitmap.width();
423 desc.fHeight = 128;
424 desc.fRowHeight = bitmap.height();
425 desc.fContext = context;
426 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info());
427 GrTextureStripAtlas* atlas = GrTextureStripAtlas::GetAtlas(desc);
428 int row = atlas->lockRow(bitmap);
429 SkAutoTUnref<GrTexture> texture;
430 if (-1 == row) {
431 atlas = NULL;
432 // Passing params=NULL because this effect does no tiling or filtering.
433 texture.reset(GrRefCachedBitmapTexture(context, bitmap, NULL));
434 } else {
435 texture.reset(SkRef(atlas->getTexture()));
436 }
437
438 return SkNEW_ARGS(ColorTableEffect, (texture, atlas, row, flags));
439 }
440
441 ColorTableEffect::ColorTableEffect(GrTexture* texture, GrTextureStripAtlas* atla s, int row,
442 unsigned flags)
388 : fTextureAccess(texture, "a") 443 : fTextureAccess(texture, "a")
389 , fFlags(flags) { 444 , fFlags(flags)
445 , fAtlas(atlas)
446 , fRow(row) {
447
390 this->addTextureAccess(&fTextureAccess); 448 this->addTextureAccess(&fTextureAccess);
391 } 449 }
392 450
393 ColorTableEffect::~ColorTableEffect() { 451 ColorTableEffect::~ColorTableEffect() {
452 if (fAtlas) {
453 fAtlas->unlockRow(fRow);
454 }
394 } 455 }
395 456
396 const GrBackendFragmentProcessorFactory& ColorTableEffect::getFactory() const { 457 const GrBackendFragmentProcessorFactory& ColorTableEffect::getFactory() const {
397 return GrTBackendFragmentProcessorFactory<ColorTableEffect>::getInstance(); 458 return GrTBackendFragmentProcessorFactory<ColorTableEffect>::getInstance();
398 } 459 }
399 460
461 bool ColorTableEffect::onIsEqual(const GrFragmentProcessor& other) const {
462 // For non-atlased instances, the texture (compared by base class) is suffic ient to
463 // differentiate different tables. For atlased instances we ensure they are using the
464 // same row.
465 const ColorTableEffect& that = other.cast<ColorTableEffect>();
466 SkASSERT(SkToBool(fAtlas) == SkToBool(that.fAtlas));
467 // Ok to always do this comparison since both would be -1 if non-atlased.
468 return fRow == that.fRow;
469 }
470
400 void ColorTableEffect::onComputeInvariantOutput(InvariantOutput* inout) const { 471 void ColorTableEffect::onComputeInvariantOutput(InvariantOutput* inout) const {
401 // If we kept the table in the effect then we could actually run known input s through the 472 // If we kept the table in the effect then we could actually run known input s through the
402 // table. 473 // table.
403 uint8_t invalidateFlags = 0; 474 uint8_t invalidateFlags = 0;
404 if (fFlags & SkTable_ColorFilter::kR_Flag) { 475 if (fFlags & SkTable_ColorFilter::kR_Flag) {
405 invalidateFlags |= kR_GrColorComponentFlag; 476 invalidateFlags |= kR_GrColorComponentFlag;
406 } 477 }
407 if (fFlags & SkTable_ColorFilter::kG_Flag) { 478 if (fFlags & SkTable_ColorFilter::kG_Flag) {
408 invalidateFlags |= kG_GrColorComponentFlag; 479 invalidateFlags |= kG_GrColorComponentFlag;
409 } 480 }
410 if (fFlags & SkTable_ColorFilter::kB_Flag) { 481 if (fFlags & SkTable_ColorFilter::kB_Flag) {
411 invalidateFlags |= kB_GrColorComponentFlag; 482 invalidateFlags |= kB_GrColorComponentFlag;
412 } 483 }
413 if (fFlags & SkTable_ColorFilter::kA_Flag) { 484 if (fFlags & SkTable_ColorFilter::kA_Flag) {
414 invalidateFlags |= kA_GrColorComponentFlag; 485 invalidateFlags |= kA_GrColorComponentFlag;
415 } 486 }
416 inout->invalidateComponents(invalidateFlags, InvariantOutput::kWill_ReadInpu t); 487 inout->invalidateComponents(invalidateFlags, InvariantOutput::kWill_ReadInpu t);
417 } 488 }
418 489
419 /////////////////////////////////////////////////////////////////////////////// 490 ///////////////////////////////////////////////////////////////////////////////
420 491
421 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ColorTableEffect); 492 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ColorTableEffect);
422 493
423 GrFragmentProcessor* ColorTableEffect::TestCreate(SkRandom* random, 494 GrFragmentProcessor* ColorTableEffect::TestCreate(SkRandom* random,
424 GrContext* context, 495 GrContext* context,
425 const GrDrawTargetCaps&, 496 const GrDrawTargetCaps&,
426 GrTexture* textures[]) { 497 GrTexture* textures[]) {
427 static unsigned kAllFlags = SkTable_ColorFilter::kR_Flag | SkTable_ColorFilt er::kG_Flag | 498 int flags = 0;
428 SkTable_ColorFilter::kB_Flag | SkTable_ColorFilt er::kA_Flag; 499 uint8_t luts[256][4];
429 return ColorTableEffect::Create(textures[GrProcessorUnitTest::kAlphaTextureI dx], kAllFlags); 500 do {
501 for (int i = 0; i < 4; ++i) {
502 flags |= random->nextBool() ? (1 << i): 0;
503 }
504 } while (!flags);
505 for (int i = 0; i < 4; ++i) {
506 if (flags & (1 << i)) {
507 for (int j = 0; j < 256; ++j) {
508 luts[j][i] = SkToU8(random->nextBits(8));
509 }
510 }
511 }
512 SkAutoTUnref<SkColorFilter> filter(SkTableColorFilter::CreateARGB(
513 (flags & (1 << 0)) ? luts[0] : NULL,
514 (flags & (1 << 1)) ? luts[1] : NULL,
515 (flags & (1 << 2)) ? luts[2] : NULL,
516 (flags & (1 << 3)) ? luts[3] : NULL
517 ));
518 return filter->asFragmentProcessor(context);
430 } 519 }
431 520
432 GrFragmentProcessor* SkTable_ColorFilter::asFragmentProcessor(GrContext* context ) const { 521 GrFragmentProcessor* SkTable_ColorFilter::asFragmentProcessor(GrContext* context ) const {
433 SkBitmap bitmap; 522 SkBitmap bitmap;
434 this->asComponentTable(&bitmap); 523 this->asComponentTable(&bitmap);
435 // passing NULL because this effect does no tiling or filtering. 524
436 SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(context, bitmap, NU LL)); 525 return ColorTableEffect::Create(context, bitmap, fFlags);
437 return texture ? ColorTableEffect::Create(texture, fFlags) : NULL;
438 } 526 }
439 527
440 #endif // SK_SUPPORT_GPU 528 #endif // SK_SUPPORT_GPU
441 529
442 /////////////////////////////////////////////////////////////////////////////// 530 ///////////////////////////////////////////////////////////////////////////////
443 531
444 #ifdef SK_CPU_BENDIAN 532 #ifdef SK_CPU_BENDIAN
445 #else 533 #else
446 #define SK_A32_INDEX (3 - (SK_A32_SHIFT >> 3)) 534 #define SK_A32_INDEX (3 - (SK_A32_SHIFT >> 3))
447 #define SK_R32_INDEX (3 - (SK_R32_SHIFT >> 3)) 535 #define SK_R32_INDEX (3 - (SK_R32_SHIFT >> 3))
(...skipping 10 matching lines...) Expand all
458 SkColorFilter* SkTableColorFilter::CreateARGB(const uint8_t tableA[256], 546 SkColorFilter* SkTableColorFilter::CreateARGB(const uint8_t tableA[256],
459 const uint8_t tableR[256], 547 const uint8_t tableR[256],
460 const uint8_t tableG[256], 548 const uint8_t tableG[256],
461 const uint8_t tableB[256]) { 549 const uint8_t tableB[256]) {
462 return SkNEW_ARGS(SkTable_ColorFilter, (tableA, tableR, tableG, tableB)); 550 return SkNEW_ARGS(SkTable_ColorFilter, (tableA, tableR, tableG, tableB));
463 } 551 }
464 552
465 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkTableColorFilter) 553 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkTableColorFilter)
466 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTable_ColorFilter) 554 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTable_ColorFilter)
467 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 555 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « no previous file | src/effects/gradients/SkGradientShader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698