1 /* 2 * Copyright 2016 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 "SkArenaAlloc.h" 9 #include "SkColorShader.h" 10 #include "SkColorSpace.h" 11 #include "SkColorSpacePriv.h" 12 #include "SkColorSpaceXformSteps.h" 13 #include "SkRasterPipeline.h" 14 #include "SkReadBuffer.h" 15 #include "SkUtils.h" 16 17 SkColorShader::SkColorShader(SkColor c) : fColor(c) {} 18 19 bool SkColorShader::isOpaque() const { 20 return SkColorGetA(fColor) == 255; 21 } 22 23 sk_sp<SkFlattenable> SkColorShader::CreateProc(SkReadBuffer& buffer) { 24 return sk_make_sp<SkColorShader>(buffer.readColor()); 25 } 26 27 void SkColorShader::flatten(SkWriteBuffer& buffer) const { 28 buffer.writeColor(fColor); 29 } 30 31 SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { 32 if (info) { 33 if (info->fColors && info->fColorCount >= 1) { 34 info->fColors[0] = fColor; 35 } 36 info->fColorCount = 1; 37 info->fTileMode = SkShader::kRepeat_TileMode; 38 } 39 return kColor_GradientType; 40 } 41 42 SkColor4Shader::SkColor4Shader(const SkColor4f& color, sk_sp<SkColorSpace> space) 43 : fColorSpace(std::move(space)) 44 , fColor(color) 45 {} 46 47 sk_sp<SkFlattenable> SkColor4Shader::CreateProc(SkReadBuffer& buffer) { 48 SkColor4f color; 49 sk_sp<SkColorSpace> colorSpace; 50 buffer.readColor4f(&color); 51 if (buffer.readBool()) { 52 sk_sp<SkData> data = buffer.readByteArrayAsData(); 53 colorSpace = data ? SkColorSpace::Deserialize(data->data(), data->size()) : nullptr; 54 } 55 return SkShader::MakeColorShader(color, std::move(colorSpace)); 56 } 57 58 void SkColor4Shader::flatten(SkWriteBuffer& buffer) const { 59 buffer.writeColor4f(fColor); 60 sk_sp<SkData> colorSpaceData = fColorSpace ? fColorSpace->serialize() : nullptr; 61 if (colorSpaceData) { 62 buffer.writeBool(true); 63 buffer.writeDataAsByteArray(colorSpaceData.get()); 64 } else { 65 buffer.writeBool(false); 66 } 67 } 68 69 70 sk_sp<SkShader> SkColor4Shader::onMakeColorSpace(SkColorSpaceXformer* xformer) const { 71 SkColor4f color = fColor; 72 SkColorSpaceXformSteps(fColorSpace.get(), kUnpremul_SkAlphaType, 73 xformer->dst().get(), kUnpremul_SkAlphaType).apply(color.vec()); 74 return SkShader::MakeColorShader(color.toSkColor()); 75 } 76 77 sk_sp<SkShader> SkShader::MakeColorShader(const SkColor4f& color, sk_sp<SkColorSpace> space) { 78 if (!SkScalarsAreFinite(color.vec(), 4)) { 79 return nullptr; 80 } 81 return sk_make_sp<SkColor4Shader>(color, std::move(space)); 82 } 83 84 bool SkColorShader::onAppendStages(const StageRec& rec) const { 85 SkColor4f color = SkColor4f::FromColor(fColor); 86 SkColorSpaceXformSteps(sk_srgb_singleton(), kUnpremul_SkAlphaType, 87 rec.fDstCS, kUnpremul_SkAlphaType).apply(color.vec()); 88 rec.fPipeline->append_constant_color(rec.fAlloc, color.premul().vec()); 89 return true; 90 } 91 92 bool SkColor4Shader::onAppendStages(const StageRec& rec) const { 93 SkColor4f color = fColor; 94 SkColorSpaceXformSteps(fColorSpace.get(), kUnpremul_SkAlphaType, 95 rec.fDstCS, kUnpremul_SkAlphaType).apply(color.vec()); 96 rec.fPipeline->append_constant_color(rec.fAlloc, color.premul().vec()); 97 return true; 98 } 99 100 #if SK_SUPPORT_GPU 101 102 #include "GrColorSpaceInfo.h" 103 #include "GrColorSpaceXform.h" 104 #include "SkGr.h" 105 #include "effects/GrConstColorProcessor.h" 106 107 std::unique_ptr<GrFragmentProcessor> SkColorShader::asFragmentProcessor( 108 const GrFPArgs& args) const { 109 SkPMColor4f color = SkColorToPMColor4f(fColor, *args.fDstColorSpaceInfo); 110 return GrConstColorProcessor::Make(color, GrConstColorProcessor::InputMode::kModulateA); 111 } 112 113 std::unique_ptr<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor( 114 const GrFPArgs& args) const { 115 SkColorSpaceXformSteps steps{ fColorSpace.get(), kUnpremul_SkAlphaType, 116 args.fDstColorSpaceInfo->colorSpace(), kUnpremul_SkAlphaType }; 117 SkColor4f color = fColor; 118 steps.apply(color.vec()); 119 return GrConstColorProcessor::Make(color.premul(), 120 GrConstColorProcessor::InputMode::kModulateA); 121 } 122 123 #endif 124