OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |