blob: a4f9f2932c0ce2fd9f3924575146b0c44f5b354e [file] [log] [blame]
rileya@google.com589708b2012-07-26 20:04:23 +00001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/shaders/gradients/SkLinearGradient.h"
Florin Malitad4e9ec82017-10-25 18:00:26 -04009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "src/core/SkReadBuffer.h"
11#include "src/core/SkWriteBuffer.h"
12#include "src/shaders/gradients/Sk4fLinearGradient.h"
rileya@google.com589708b2012-07-26 20:04:23 +000013
mtkleincc695fe2014-12-10 10:29:19 -080014static SkMatrix pts_to_unit_matrix(const SkPoint pts[2]) {
rileya@google.com589708b2012-07-26 20:04:23 +000015 SkVector vec = pts[1] - pts[0];
16 SkScalar mag = vec.length();
17 SkScalar inv = mag ? SkScalarInvert(mag) : 0;
18
19 vec.scale(inv);
mtkleincc695fe2014-12-10 10:29:19 -080020 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;
rileya@google.com589708b2012-07-26 20:04:23 +000025}
26
27///////////////////////////////////////////////////////////////////////////////
28
reedaddf2ed2014-08-11 08:28:24 -070029SkLinearGradient::SkLinearGradient(const SkPoint pts[2], const Descriptor& desc)
mtkleincc695fe2014-12-10 10:29:19 -080030 : SkGradientShaderBase(desc, pts_to_unit_matrix(pts))
rileya@google.com589708b2012-07-26 20:04:23 +000031 , fStart(pts[0])
mtkleincc695fe2014-12-10 10:29:19 -080032 , fEnd(pts[1]) {
rileya@google.com589708b2012-07-26 20:04:23 +000033}
34
reed60c9b582016-04-03 09:11:13 -070035sk_sp<SkFlattenable> SkLinearGradient::CreateProc(SkReadBuffer& buffer) {
reed9fa60da2014-08-21 07:59:51 -070036 DescriptorScope desc;
37 if (!desc.unflatten(buffer)) {
halcanary96fcdcc2015-08-27 07:41:13 -070038 return nullptr;
reed9fa60da2014-08-21 07:59:51 -070039 }
40 SkPoint pts[2];
41 pts[0] = buffer.readPoint();
42 pts[1] = buffer.readPoint();
brianosmane25d71c2016-09-28 11:27:28 -070043 return SkGradientShader::MakeLinear(pts, desc.fColors, std::move(desc.fColorSpace), desc.fPos,
44 desc.fCount, desc.fTileMode, desc.fGradFlags,
45 desc.fLocalMatrix);
reed9fa60da2014-08-21 07:59:51 -070046}
rileya@google.com589708b2012-07-26 20:04:23 +000047
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000048void SkLinearGradient::flatten(SkWriteBuffer& buffer) const {
rileya@google.com589708b2012-07-26 20:04:23 +000049 this->INHERITED::flatten(buffer);
50 buffer.writePoint(fStart);
51 buffer.writePoint(fEnd);
52}
53
Mike Reede92aae62018-10-17 10:21:51 -040054#ifdef SK_ENABLE_LEGACY_SHADERCONTEXT
Florin Malita4aed1382017-05-25 10:38:07 -040055SkShaderBase::Context* SkLinearGradient::onMakeContext(
Herb Derby83e939b2017-02-07 14:25:11 -050056 const ContextRec& rec, SkArenaAlloc* alloc) const
57{
Mike Reed011d1662019-02-28 17:19:25 -050058 // 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
Mike Reedfae8fce2019-04-03 10:27:45 -040067 return fTileMode != SkTileMode::kDecal
Florin Malitaaf2769d2018-04-04 13:46:35 -040068 ? CheckedMakeContext<LinearGradient4fContext>(alloc, *this, rec)
69 : nullptr;
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +000070}
Mike Reede92aae62018-10-17 10:21:51 -040071#endif
Florin Malita47e55a52017-06-06 12:26:54 -040072
Florin Malita50b20842017-07-29 19:08:28 -040073void SkLinearGradient::appendGradientStages(SkArenaAlloc*, SkRasterPipeline*,
74 SkRasterPipeline*) const {
75 // No extra stage needed for linear gradients.
Florin Malitac86e4702017-01-20 08:41:34 -050076}
77
Mike Kleinba9da462020-01-28 14:25:09 -060078bool SkLinearGradient::transformT(skvm::Builder* p, skvm::F32 x, skvm::F32 y, skvm::F32* t) const {
79 // We've baked getting t in x into the matrix, so this is pretty trivial.
80 *t = x;
81 return true;
82}
Mike Klein85754d52020-01-22 10:04:11 -060083
rileya@google.com589708b2012-07-26 20:04:23 +000084SkShader::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
Michael Ludwigafebe162018-09-12 15:24:34 -040093/////////////////////////////////////////////////////////////////////
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +000094
Michael Ludwigafebe162018-09-12 15:24:34 -040095#if SK_SUPPORT_GPU
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +000096
Mike Kleinc0bd9f92019-04-23 12:05:21 -050097#include "src/gpu/gradients/GrGradientShader.h"
Michael Ludwig4f94ef62018-09-12 15:22:16 -040098
Brian Salomonaff329b2017-08-11 09:40:37 -040099std::unique_ptr<GrFragmentProcessor> SkLinearGradient::asFragmentProcessor(
Mike Reede3429e62018-01-19 11:43:34 -0500100 const GrFPArgs& args) const {
Michael Ludwigafebe162018-09-12 15:24:34 -0400101 return GrGradientShader::MakeLinear(*this, args);
rileya@google.comd7cc6512012-07-27 14:00:39 +0000102}
103
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000104#endif