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

Side by Side Diff: src/effects/gradients/SkGradientShader.cpp

Issue 2343253002: Support for color-spaces with multi-stop (texture) gradients (Closed)
Patch Set: Bug fixes Created 4 years, 3 months 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
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "Sk4fLinearGradient.h" 8 #include "Sk4fLinearGradient.h"
9 #include "SkGradientShaderPriv.h" 9 #include "SkGradientShaderPriv.h"
10 #include "SkHalf.h"
10 #include "SkLinearGradient.h" 11 #include "SkLinearGradient.h"
11 #include "SkRadialGradient.h" 12 #include "SkRadialGradient.h"
12 #include "SkTwoPointConicalGradient.h" 13 #include "SkTwoPointConicalGradient.h"
13 #include "SkSweepGradient.h" 14 #include "SkSweepGradient.h"
14 15
15 void SkGradientShaderBase::Descriptor::flatten(SkWriteBuffer& buffer) const { 16 void SkGradientShaderBase::Descriptor::flatten(SkWriteBuffer& buffer) const {
16 buffer.writeColorArray(fColors, fCount); 17 buffer.writeColorArray(fColors, fCount);
17 // TODO: Flatten fColors4f and fColorSpace 18 // TODO: Flatten fColors4f and fColorSpace
18 if (fPos) { 19 if (fPos) {
19 buffer.writeBool(true); 20 buffer.writeBool(true);
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 538
538 if (nextIndex > prevIndex) 539 if (nextIndex > prevIndex)
539 Build32bitCache(cache->fCache32 + prevIndex, cache->fShader.fOri gColors[i-1], 540 Build32bitCache(cache->fCache32 + prevIndex, cache->fShader.fOri gColors[i-1],
540 cache->fShader.fOrigColors[i], nextIndex - prevI ndex + 1, 541 cache->fShader.fOrigColors[i], nextIndex - prevI ndex + 1,
541 cache->fCacheAlpha, cache->fShader.fGradFlags, c ache->fCacheDither); 542 cache->fCacheAlpha, cache->fShader.fGradFlags, c ache->fCacheDither);
542 prevIndex = nextIndex; 543 prevIndex = nextIndex;
543 } 544 }
544 } 545 }
545 } 546 }
546 547
548 void SkGradientShaderBase::initLinearBitmap(SkBitmap* bitmap) const {
Brian Osman 2016/09/20 17:29:53 This is essentially a condensed version of the log
f(malita) 2016/09/21 02:51:35 Kinda feels like we're reinventing a specialized v
Brian Osman 2016/09/21 13:24:18 That sounds like a good idea. Almost looks like I
549 const bool interpInPremul = SkToBool(fGradFlags &
550 SkGradientShader::kInterpolateColorsInP remul_Flag);
551 bitmap->lockPixels();
552 SkHalf* pixelsF16 = reinterpret_cast<SkHalf*>(bitmap->getPixels());
553 uint32_t* pixelsS32 = reinterpret_cast<uint32_t*>(bitmap->getPixels());
554
555 typedef std::function<void(const Sk4f&, int)> pixelWriteFn_t;
556
557 pixelWriteFn_t writeF16Pixel = [&](const Sk4f& x, int index) {
558 Sk4h c = SkFloatToHalf_finite_ftz(x);
559 pixelsF16[4*index+0] = c[0];
560 pixelsF16[4*index+1] = c[1];
561 pixelsF16[4*index+2] = c[2];
562 pixelsF16[4*index+3] = c[3];
563 };
564 pixelWriteFn_t writeS32Pixel = [&](const Sk4f& c, int index) {
565 pixelsS32[index] = Sk4f_toS32(c);
566 };
567
568 pixelWriteFn_t writeSizedPixel =
569 (kRGBA_F16_SkColorType == bitmap->colorType()) ? writeF16Pixel : writeS3 2Pixel;
570 pixelWriteFn_t writeUnpremulPixel = [&](const Sk4f& c, int index) {
571 writeSizedPixel(Sk4f(c[0] * c[3], c[1] * c[3], c[2] * c[3], c[3]), index );
f(malita) 2016/09/21 02:51:35 nit: c * Sk4f(c[3], c[3], c[3], 1)?
Brian Osman 2016/09/21 13:24:18 Duh! I was sure there was a clearer way to write t
572 };
573
574 pixelWriteFn_t writePixel = interpInPremul ? writeSizedPixel : writeUnpremul Pixel;
575
576 int prevIndex = 0;
577 for (int i = 1; i < fColorCount; i++) {
578 int nextIndex = (fColorCount == 2) ? (kCache32Count - 1)
f(malita) 2016/09/21 02:51:35 wouldn't SkFixedToFFFF(fRecs[i].fPos) >> kCache32S
Brian Osman 2016/09/21 13:24:18 I don't think so. The constructor never initialize
f(malita) 2016/09/22 14:05:39 Acknowledged.
579 : SkFixedToFFFF(fRecs[i].fPos) >> kCache32Shift;
580 SkASSERT(nextIndex < kCache32Count);
581
582 if (nextIndex > prevIndex) {
583 Sk4f c0 = Sk4f::Load(fOrigColors4f[i - 1].vec());
584 Sk4f c1 = Sk4f::Load(fOrigColors4f[i].vec());
585 if (interpInPremul) {
586 c0 = Sk4f(c0[0] * c0[3], c0[1] * c0[3], c0[2] * c0[3], c0[3]);
f(malita) 2016/09/21 02:51:35 nit: c0 * Sk4f(c0[3], c0[3], c0[3], 1)?
Brian Osman 2016/09/21 13:24:18 Done.
587 c1 = Sk4f(c1[0] * c1[3], c1[1] * c1[3], c1[2] * c1[3], c1[3]);
f(malita) 2016/09/21 02:51:35 nit: ditto
Brian Osman 2016/09/21 13:24:18 Done.
588 }
589
590 Sk4f step = Sk4f(1.0f / static_cast<float>(nextIndex - prevIndex));
591 Sk4f delta = (c1 - c0) * step;
592
593 for (int curIndex = prevIndex; curIndex <= nextIndex; ++curIndex) {
594 writePixel(c0, curIndex);
595 c0 += delta;
596 }
597 }
598 prevIndex = nextIndex;
599 }
f(malita) 2016/09/21 02:51:35 SkASSERT(prevIndex == kCache32Count - 1)?
Brian Osman 2016/09/21 13:24:18 Done.
600 bitmap->unlockPixels();
601 }
602
547 /* 603 /*
548 * The gradient holds a cache for the most recent value of alpha. Successive 604 * The gradient holds a cache for the most recent value of alpha. Successive
549 * callers with the same alpha value will share the same cache. 605 * callers with the same alpha value will share the same cache.
550 */ 606 */
551 SkGradientShaderBase::GradientShaderCache* SkGradientShaderBase::refCache(U8CPU alpha, 607 SkGradientShaderBase::GradientShaderCache* SkGradientShaderBase::refCache(U8CPU alpha,
552 bool d ither) const { 608 bool d ither) const {
553 SkAutoMutexAcquire ama(fCacheMutex); 609 SkAutoMutexAcquire ama(fCacheMutex);
554 if (!fCache || fCache->getAlpha() != alpha || fCache->getDither() != dither) { 610 if (!fCache || fCache->getAlpha() != alpha || fCache->getDither() != dither) {
555 fCache.reset(new GradientShaderCache(alpha, dither, *this)); 611 fCache.reset(new GradientShaderCache(alpha, dither, *this));
556 } 612 }
557 // Increment the ref counter inside the mutex to ensure the returned pointer is still valid. 613 // Increment the ref counter inside the mutex to ensure the returned pointer is still valid.
558 // Otherwise, the pointer may have been overwritten on a different thread be fore the object's 614 // Otherwise, the pointer may have been overwritten on a different thread be fore the object's
559 // ref count was incremented. 615 // ref count was incremented.
560 fCache.get()->ref(); 616 fCache.get()->ref();
561 return fCache; 617 return fCache;
562 } 618 }
563 619
564 SK_DECLARE_STATIC_MUTEX(gGradientCacheMutex); 620 SK_DECLARE_STATIC_MUTEX(gGradientCacheMutex);
565 /* 621 /*
566 * Because our caller might rebuild the same (logically the same) gradient 622 * Because our caller might rebuild the same (logically the same) gradient
567 * over and over, we'd like to return exactly the same "bitmap" if possible, 623 * over and over, we'd like to return exactly the same "bitmap" if possible,
568 * allowing the client to utilize a cache of our bitmap (e.g. with a GPU). 624 * allowing the client to utilize a cache of our bitmap (e.g. with a GPU).
569 * To do that, we maintain a private cache of built-bitmaps, based on our 625 * To do that, we maintain a private cache of built-bitmaps, based on our
570 * colors and positions. Note: we don't try to flatten the fMapper, so if one 626 * colors and positions. Note: we don't try to flatten the fMapper, so if one
571 * is present, we skip the cache for now. 627 * is present, we skip the cache for now.
572 */ 628 */
573 void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const { 629 void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap,
574 // our caller assumes no external alpha, so we ensure that our cache is 630 GradientBitmapType bitmapType) const {
575 // built with 0xFF 631 // our caller assumes no external alpha, so we ensure that our cache is buil t with 0xFF
576 SkAutoTUnref<GradientShaderCache> cache(this->refCache(0xFF, true)); 632 SkAutoTUnref<GradientShaderCache> cache(this->refCache(0xFF, true));
577 633
578 // build our key: [numColors + colors[] + {positions[]} + flags ] 634 // build our key: [numColors + colors[] + {positions[]} + flags + colorType ]
579 int count = 1 + fColorCount + 1; 635 int count = 1 + fColorCount + 1 + 1;
580 if (fColorCount > 2) { 636 if (fColorCount > 2) {
581 count += fColorCount - 1; // fRecs[].fPos 637 count += fColorCount - 1; // fRecs[].fPos
582 } 638 }
583 639
584 SkAutoSTMalloc<16, int32_t> storage(count); 640 SkAutoSTMalloc<16, int32_t> storage(count);
585 int32_t* buffer = storage.get(); 641 int32_t* buffer = storage.get();
586 642
587 *buffer++ = fColorCount; 643 *buffer++ = fColorCount;
588 memcpy(buffer, fOrigColors, fColorCount * sizeof(SkColor)); 644 memcpy(buffer, fOrigColors, fColorCount * sizeof(SkColor));
589 buffer += fColorCount; 645 buffer += fColorCount;
590 if (fColorCount > 2) { 646 if (fColorCount > 2) {
591 for (int i = 1; i < fColorCount; i++) { 647 for (int i = 1; i < fColorCount; i++) {
592 *buffer++ = fRecs[i].fPos; 648 *buffer++ = fRecs[i].fPos;
593 } 649 }
594 } 650 }
595 *buffer++ = fGradFlags; 651 *buffer++ = fGradFlags;
652 *buffer++ = static_cast<int32_t>(bitmapType);
596 SkASSERT(buffer - storage.get() == count); 653 SkASSERT(buffer - storage.get() == count);
597 654
598 /////////////////////////////////// 655 ///////////////////////////////////
599 656
600 static SkGradientBitmapCache* gCache; 657 static SkGradientBitmapCache* gCache;
601 // each cache cost 1K of RAM, since each bitmap will be 1x256 at 32bpp 658 // each cache cost 1K or 2K of RAM, since each bitmap will be 1x256 at eithe r 32bpp or 64bpp
602 static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32; 659 static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32;
603 SkAutoMutexAcquire ama(gGradientCacheMutex); 660 SkAutoMutexAcquire ama(gGradientCacheMutex);
604 661
605 if (nullptr == gCache) { 662 if (nullptr == gCache) {
606 gCache = new SkGradientBitmapCache(MAX_NUM_CACHED_GRADIENT_BITMAPS); 663 gCache = new SkGradientBitmapCache(MAX_NUM_CACHED_GRADIENT_BITMAPS);
607 } 664 }
608 size_t size = count * sizeof(int32_t); 665 size_t size = count * sizeof(int32_t);
609 666
610 if (!gCache->find(storage.get(), size, bitmap)) { 667 if (!gCache->find(storage.get(), size, bitmap)) {
611 // force our cahce32pixelref to be built 668 if (GradientBitmapType::kLegacy == bitmapType) {
612 (void)cache->getCache32(); 669 // force our cache32pixelref to be built
613 bitmap->setInfo(SkImageInfo::MakeN32Premul(kCache32Count, 1)); 670 (void)cache->getCache32();
614 bitmap->setPixelRef(cache->getCache32PixelRef()); 671 bitmap->setInfo(SkImageInfo::MakeN32Premul(kCache32Count, 1));
672 bitmap->setPixelRef(cache->getCache32PixelRef());
673 } else {
674 // For these cases we use the bitmap cache, but not the GradientShad erCache. So just
Brian Osman 2016/09/20 17:29:54 We talked about not using the bitmap cache (or bit
675 // allocate and populate the bitmap's data directly.
615 676
677 SkImageInfo info;
678 switch (bitmapType) {
679 case GradientBitmapType::kSRGB:
680 info = SkImageInfo::Make(kCache32Count, 1, kRGBA_8888_SkColo rType,
681 kPremul_SkAlphaType,
682 SkColorSpace::NewNamed(SkColorSpace ::kSRGB_Named));
683 break;
684 case GradientBitmapType::kHalfFloat:
685 info = SkImageInfo::Make(kCache32Count, 1, kRGBA_F16_SkColor Type,
686 kPremul_SkAlphaType,
687 SkColorSpace::NewNamed(SkColorSpace ::kSRGB_Named)
688 ->makeLinearGamma());
689 break;
690 default:
691 SkFAIL("Unexpected bitmap type");
692 return;
693 }
694 bitmap->allocPixels(info);
695 initLinearBitmap(bitmap);
f(malita) 2016/09/21 02:51:35 nit: this->
Brian Osman 2016/09/21 13:24:18 Done.
696 }
616 gCache->add(storage.get(), size, *bitmap); 697 gCache->add(storage.get(), size, *bitmap);
617 } 698 }
618 } 699 }
619 700
620 void SkGradientShaderBase::commonAsAGradient(GradientInfo* info, bool flipGrad) const { 701 void SkGradientShaderBase::commonAsAGradient(GradientInfo* info, bool flipGrad) const {
621 if (info) { 702 if (info) {
622 if (info->fColorCount >= fColorCount) { 703 if (info->fColorCount >= fColorCount) {
623 SkColor* colorLoc; 704 SkColor* colorLoc;
624 Rec* recLoc; 705 Rec* recLoc;
625 if (flipGrad && (info->fColors || info->fColorOffsets)) { 706 if (flipGrad && (info->fColors || info->fColorOffsets)) {
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 976 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
896 977
897 /////////////////////////////////////////////////////////////////////////////// 978 ///////////////////////////////////////////////////////////////////////////////
898 979
899 #if SK_SUPPORT_GPU 980 #if SK_SUPPORT_GPU
900 981
901 #include "GrContext.h" 982 #include "GrContext.h"
902 #include "GrInvariantOutput.h" 983 #include "GrInvariantOutput.h"
903 #include "GrTextureStripAtlas.h" 984 #include "GrTextureStripAtlas.h"
904 #include "gl/GrGLContext.h" 985 #include "gl/GrGLContext.h"
986 #include "glsl/GrGLSLColorSpaceXformHelper.h"
905 #include "glsl/GrGLSLFragmentShaderBuilder.h" 987 #include "glsl/GrGLSLFragmentShaderBuilder.h"
906 #include "glsl/GrGLSLProgramDataManager.h" 988 #include "glsl/GrGLSLProgramDataManager.h"
907 #include "glsl/GrGLSLUniformHandler.h" 989 #include "glsl/GrGLSLUniformHandler.h"
908 #include "SkGr.h" 990 #include "SkGr.h"
909 991
910 static inline bool close_to_one_half(const SkFixed& val) { 992 static inline bool close_to_one_half(const SkFixed& val) {
911 return SkScalarNearlyEqual(SkFixedToScalar(val), SK_ScalarHalf); 993 return SkScalarNearlyEqual(SkFixedToScalar(val), SK_ScalarHalf);
912 } 994 }
913 995
914 static inline int color_type_to_color_count(GrGradientEffect::ColorType colorTyp e) { 996 static inline int color_type_to_color_count(GrGradientEffect::ColorType colorTyp e) {
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1106 1188
1107 break; 1189 break;
1108 } 1190 }
1109 1191
1110 case GrGradientEffect::kTexture_ColorType: { 1192 case GrGradientEffect::kTexture_ColorType: {
1111 SkScalar yCoord = e.getYCoord(); 1193 SkScalar yCoord = e.getYCoord();
1112 if (yCoord != fCachedYCoord) { 1194 if (yCoord != fCachedYCoord) {
1113 pdman.set1f(fFSYUni, yCoord); 1195 pdman.set1f(fFSYUni, yCoord);
1114 fCachedYCoord = yCoord; 1196 fCachedYCoord = yCoord;
1115 } 1197 }
1198 if (SkToBool(e.fColorSpaceXform)) {
1199 pdman.setSkMatrix44(fColorSpaceXformUni, e.fColorSpaceXform->src ToDst());
1200 }
1116 break; 1201 break;
1117 } 1202 }
1118 } 1203 }
1119 } 1204 }
1120 1205
1121 uint32_t GrGradientEffect::GLSLProcessor::GenBaseGradientKey(const GrProcessor& processor) { 1206 uint32_t GrGradientEffect::GLSLProcessor::GenBaseGradientKey(const GrProcessor& processor) {
1122 const GrGradientEffect& e = processor.cast<GrGradientEffect>(); 1207 const GrGradientEffect& e = processor.cast<GrGradientEffect>();
1123 1208
1124 uint32_t key = 0; 1209 uint32_t key = 0;
1125 1210
(...skipping 17 matching lines...) Expand all
1143 1228
1144 if (SkShader::TileMode::kClamp_TileMode == e.fTileMode) { 1229 if (SkShader::TileMode::kClamp_TileMode == e.fTileMode) {
1145 key |= kClampTileMode; 1230 key |= kClampTileMode;
1146 } else if (SkShader::TileMode::kRepeat_TileMode == e.fTileMode) { 1231 } else if (SkShader::TileMode::kRepeat_TileMode == e.fTileMode) {
1147 key |= kRepeatTileMode; 1232 key |= kRepeatTileMode;
1148 } else { 1233 } else {
1149 key |= kMirrorTileMode; 1234 key |= kMirrorTileMode;
1150 } 1235 }
1151 #endif 1236 #endif
1152 1237
1238 key |= GrColorSpaceXform::XformKey(e.fColorSpaceXform.get()) << kReservedBit s;
1239
1153 return key; 1240 return key;
1154 } 1241 }
1155 1242
1156 void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBui lder, 1243 void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBui lder,
1157 GrGLSLUniformHandler* uniformHan dler, 1244 GrGLSLUniformHandler* uniformHan dler,
1158 const GrGLSLCaps* glslCaps, 1245 const GrGLSLCaps* glslCaps,
1159 const GrGradientEffect& ge, 1246 const GrGradientEffect& ge,
1160 const char* gradientTValue, 1247 const char* gradientTValue,
1161 const char* outputColor, 1248 const char* outputColor,
1162 const char* inputColor, 1249 const char* inputColor,
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;"); 1411 fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
1325 } 1412 }
1326 1413
1327 fragBuilder->codeAppendf("%s = %s;", outputColor, 1414 fragBuilder->codeAppendf("%s = %s;", outputColor,
1328 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("col orTemp")).c_str()); 1415 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("col orTemp")).c_str());
1329 1416
1330 break; 1417 break;
1331 } 1418 }
1332 1419
1333 case kTexture_ColorType: { 1420 case kTexture_ColorType: {
1421 GrGLSLColorSpaceXformHelper colorSpaceHelper(uniformHandler, ge.fCol orSpaceXform.get(),
Brian Osman 2016/09/20 17:29:54 I *could* have baked the xform into the texture, a
1422 &fColorSpaceXformUni);
1423
1334 const char* fsyuni = uniformHandler->getUniformCStr(fFSYUni); 1424 const char* fsyuni = uniformHandler->getUniformCStr(fFSYUni);
1335 1425
1336 fragBuilder->codeAppendf("vec2 coord = vec2(%s, %s);", gradientTValu e, fsyuni); 1426 fragBuilder->codeAppendf("vec2 coord = vec2(%s, %s);", gradientTValu e, fsyuni);
1337 fragBuilder->codeAppendf("%s = ", outputColor); 1427 fragBuilder->codeAppendf("%s = ", outputColor);
1338 fragBuilder->appendTextureLookupAndModulate(inputColor, texSamplers[ 0], "coord"); 1428 fragBuilder->appendTextureLookupAndModulate(inputColor, texSamplers[ 0], "coord",
1429 kVec2f_GrSLType, &colorS paceHelper);
1339 fragBuilder->codeAppend(";"); 1430 fragBuilder->codeAppend(";");
1340 1431
1341 break; 1432 break;
1342 } 1433 }
1343 } 1434 }
1344 } 1435 }
1345 1436
1346 ///////////////////////////////////////////////////////////////////// 1437 /////////////////////////////////////////////////////////////////////
1347 1438
1348 GrGradientEffect::GrGradientEffect(const CreateArgs& args) { 1439 GrGradientEffect::GrGradientEffect(const CreateArgs& args) {
1349 const SkGradientShaderBase& shader(*args.fShader); 1440 const SkGradientShaderBase& shader(*args.fShader);
1350 1441
1351 fIsOpaque = shader.isOpaque(); 1442 fIsOpaque = shader.isOpaque();
1352 1443
1353 fColorType = this->determineColorType(shader); 1444 fColorType = this->determineColorType(shader);
1445 fColorSpaceXform = std::move(args.fColorSpaceXform);
1354 1446
1355 if (kTexture_ColorType != fColorType) { 1447 if (kTexture_ColorType != fColorType) {
1356 SkASSERT(shader.fOrigColors && shader.fOrigColors4f); 1448 SkASSERT(shader.fOrigColors && shader.fOrigColors4f);
1357 if (args.fGammaCorrect) { 1449 if (args.fGammaCorrect) {
1358 fColors4f = SkTDArray<SkColor4f>(shader.fOrigColors4f, shader.fColor Count); 1450 fColors4f = SkTDArray<SkColor4f>(shader.fOrigColors4f, shader.fColor Count);
1359 fColorSpaceXform = std::move(args.fColorSpaceXform);
1360 } else { 1451 } else {
1361 fColors = SkTDArray<SkColor>(shader.fOrigColors, shader.fColorCount) ; 1452 fColors = SkTDArray<SkColor>(shader.fOrigColors, shader.fColorCount) ;
1362 } 1453 }
1363 1454
1364 #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS 1455 #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
1365 if (shader.fOrigPos) { 1456 if (shader.fOrigPos) {
1366 fPositions = SkTDArray<SkScalar>(shader.fOrigPos, shader.fColorCount ); 1457 fPositions = SkTDArray<SkScalar>(shader.fOrigPos, shader.fColorCount );
1367 } 1458 }
1368 #endif 1459 #endif
1369 } 1460 }
(...skipping 20 matching lines...) Expand all
1390 } 1481 }
1391 1482
1392 fCoordTransform.reset(kCoordSet, *args.fMatrix); 1483 fCoordTransform.reset(kCoordSet, *args.fMatrix);
1393 1484
1394 break; 1485 break;
1395 case kTexture_ColorType: 1486 case kTexture_ColorType:
1396 // doesn't matter how this is set, just be consistent because it is part of the 1487 // doesn't matter how this is set, just be consistent because it is part of the
1397 // effect key. 1488 // effect key.
1398 fPremulType = kBeforeInterp_PremulType; 1489 fPremulType = kBeforeInterp_PremulType;
1399 1490
1491 SkGradientShaderBase::GradientBitmapType bitmapType =
1492 SkGradientShaderBase::GradientBitmapType::kLegacy;
1493 if (args.fGammaCorrect) {
1494 // Try to use F16 if we can
1495 if (args.fContext->caps()->isConfigTexturable(kRGBA_half_GrPixel Config)) {
1496 bitmapType = SkGradientShaderBase::GradientBitmapType::kHalf Float;
1497 } else if (args.fContext->caps()->isConfigTexturable(kSRGBA_8888 _GrPixelConfig)) {
1498 bitmapType = SkGradientShaderBase::GradientBitmapType::kSRGB ;
1499 } else {
1500 // This should never happen, but just fall back to legacy be havior
1501 SkASSERT("Requesting a gamma-correct gradient FP without F16 or sRGB");
1502 }
1503 }
1504
1400 SkBitmap bitmap; 1505 SkBitmap bitmap;
1401 shader.getGradientTableBitmap(&bitmap); 1506 shader.getGradientTableBitmap(&bitmap, bitmapType);
1402 1507
1403 GrTextureStripAtlas::Desc desc; 1508 GrTextureStripAtlas::Desc desc;
1404 desc.fWidth = bitmap.width(); 1509 desc.fWidth = bitmap.width();
1405 desc.fHeight = 32; 1510 desc.fHeight = 32;
1406 desc.fRowHeight = bitmap.height(); 1511 desc.fRowHeight = bitmap.height();
1407 desc.fContext = args.fContext; 1512 desc.fContext = args.fContext;
1408 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *args.fConte xt->caps()); 1513 desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *args.fConte xt->caps());
1409 fAtlas = GrTextureStripAtlas::GetAtlas(desc); 1514 fAtlas = GrTextureStripAtlas::GetAtlas(desc);
1410 SkASSERT(fAtlas); 1515 SkASSERT(fAtlas);
1411 1516
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1508 (*stops)[i] = stop; 1613 (*stops)[i] = stop;
1509 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; 1614 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f;
1510 } 1615 }
1511 } 1616 }
1512 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); 1617 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount));
1513 1618
1514 return outColors; 1619 return outColors;
1515 } 1620 }
1516 1621
1517 #endif 1622 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698