| 1 | /* | 
|---|
| 2 | * Copyright 2012 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 "src/shaders/gradients/SkLinearGradient.h" | 
|---|
| 9 |  | 
|---|
| 10 | #include "src/core/SkReadBuffer.h" | 
|---|
| 11 | #include "src/core/SkWriteBuffer.h" | 
|---|
| 12 | #include "src/shaders/gradients/Sk4fLinearGradient.h" | 
|---|
| 13 |  | 
|---|
| 14 | static SkMatrix pts_to_unit_matrix(const SkPoint pts[2]) { | 
|---|
| 15 | SkVector    vec = pts[1] - pts[0]; | 
|---|
| 16 | SkScalar    mag = vec.length(); | 
|---|
| 17 | SkScalar    inv = mag ? SkScalarInvert(mag) : 0; | 
|---|
| 18 |  | 
|---|
| 19 | vec.scale(inv); | 
|---|
| 20 | SkMatrix matrix; | 
|---|
| 21 | matrix.setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY); | 
|---|
| 22 | matrix.postTranslate(-pts[0].fX, -pts[0].fY); | 
|---|
| 23 | matrix.postScale(inv, inv); | 
|---|
| 24 | return matrix; | 
|---|
| 25 | } | 
|---|
| 26 |  | 
|---|
| 27 | /////////////////////////////////////////////////////////////////////////////// | 
|---|
| 28 |  | 
|---|
| 29 | SkLinearGradient::SkLinearGradient(const SkPoint pts[2], const Descriptor& desc) | 
|---|
| 30 | : SkGradientShaderBase(desc, pts_to_unit_matrix(pts)) | 
|---|
| 31 | , fStart(pts[0]) | 
|---|
| 32 | , fEnd(pts[1]) { | 
|---|
| 33 | } | 
|---|
| 34 |  | 
|---|
| 35 | sk_sp<SkFlattenable> SkLinearGradient::CreateProc(SkReadBuffer& buffer) { | 
|---|
| 36 | DescriptorScope desc; | 
|---|
| 37 | if (!desc.unflatten(buffer)) { | 
|---|
| 38 | return nullptr; | 
|---|
| 39 | } | 
|---|
| 40 | SkPoint pts[2]; | 
|---|
| 41 | pts[0] = buffer.readPoint(); | 
|---|
| 42 | pts[1] = buffer.readPoint(); | 
|---|
| 43 | return SkGradientShader::MakeLinear(pts, desc.fColors, std::move(desc.fColorSpace), desc.fPos, | 
|---|
| 44 | desc.fCount, desc.fTileMode, desc.fGradFlags, | 
|---|
| 45 | desc.fLocalMatrix); | 
|---|
| 46 | } | 
|---|
| 47 |  | 
|---|
| 48 | void SkLinearGradient::flatten(SkWriteBuffer& buffer) const { | 
|---|
| 49 | this->INHERITED::flatten(buffer); | 
|---|
| 50 | buffer.writePoint(fStart); | 
|---|
| 51 | buffer.writePoint(fEnd); | 
|---|
| 52 | } | 
|---|
| 53 |  | 
|---|
| 54 | #ifdef SK_ENABLE_LEGACY_SHADERCONTEXT | 
|---|
| 55 | SkShaderBase::Context* SkLinearGradient::onMakeContext( | 
|---|
| 56 | const ContextRec& rec, SkArenaAlloc* alloc) const | 
|---|
| 57 | { | 
|---|
| 58 | // make sure our colorspaces are compatible with legacy blits | 
|---|
| 59 | if (!rec.isLegacyCompatible(fColorSpace.get())) { | 
|---|
| 60 | return nullptr; | 
|---|
| 61 | } | 
|---|
| 62 | // Can't use legacy blit if we can't represent our colors as SkColors | 
|---|
| 63 | if (!this->colorsCanConvertToSkColor()) { | 
|---|
| 64 | return nullptr; | 
|---|
| 65 | } | 
|---|
| 66 |  | 
|---|
| 67 | return fTileMode != SkTileMode::kDecal | 
|---|
| 68 | ? CheckedMakeContext<LinearGradient4fContext>(alloc, *this, rec) | 
|---|
| 69 | : nullptr; | 
|---|
| 70 | } | 
|---|
| 71 | #endif | 
|---|
| 72 |  | 
|---|
| 73 | void SkLinearGradient::appendGradientStages(SkArenaAlloc*, SkRasterPipeline*, | 
|---|
| 74 | SkRasterPipeline*) const { | 
|---|
| 75 | // No extra stage needed for linear gradients. | 
|---|
| 76 | } | 
|---|
| 77 |  | 
|---|
| 78 | skvm::F32 SkLinearGradient::transformT(skvm::Builder* p, skvm::Uniforms*, | 
|---|
| 79 | skvm::F32 x, skvm::F32 y, skvm::I32* mask) const { | 
|---|
| 80 | // We've baked getting t in x into the matrix, so this is pretty trivial. | 
|---|
| 81 | return x; | 
|---|
| 82 | } | 
|---|
| 83 |  | 
|---|
| 84 | SkShader::GradientType SkLinearGradient::asAGradient(GradientInfo* info) const { | 
|---|
| 85 | if (info) { | 
|---|
| 86 | commonAsAGradient(info); | 
|---|
| 87 | info->fPoint[0] = fStart; | 
|---|
| 88 | info->fPoint[1] = fEnd; | 
|---|
| 89 | } | 
|---|
| 90 | return kLinear_GradientType; | 
|---|
| 91 | } | 
|---|
| 92 |  | 
|---|
| 93 | ///////////////////////////////////////////////////////////////////// | 
|---|
| 94 |  | 
|---|
| 95 | #if SK_SUPPORT_GPU | 
|---|
| 96 |  | 
|---|
| 97 | #include "src/gpu/gradients/GrGradientShader.h" | 
|---|
| 98 |  | 
|---|
| 99 | std::unique_ptr<GrFragmentProcessor> SkLinearGradient::asFragmentProcessor( | 
|---|
| 100 | const GrFPArgs& args) const { | 
|---|
| 101 | return GrGradientShader::MakeLinear(*this, args); | 
|---|
| 102 | } | 
|---|
| 103 |  | 
|---|
| 104 | #endif | 
|---|
| 105 |  | 
|---|