blob: b5c0145a6cc01355eb8eb5583cdf23ad5056d449 [file] [log] [blame]
rileya@google.com1c6d64b2012-07-27 15:49:05 +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
8#ifndef SkGradientShaderPriv_DEFINED
9#define SkGradientShaderPriv_DEFINED
10
11#include "SkGradientShader.h"
Hal Canary95e3c052017-01-11 12:44:43 -050012
Herb Derby83e939b2017-02-07 14:25:11 -050013#include "SkArenaAlloc.h"
Florin Malitad4e9ec82017-10-25 18:00:26 -040014#include "SkMatrix.h"
Florin Malita4aed1382017-05-25 10:38:07 -040015#include "SkShaderBase.h"
Florin Malita14a8dd72017-11-08 15:46:42 -050016#include "SkTArray.h"
Florin Malita39d71de2017-10-31 11:33:49 -040017#include "SkTemplates.h"
rileya@google.com1c6d64b2012-07-27 15:49:05 +000018
Florin Malitad4e9ec82017-10-25 18:00:26 -040019class SkColorSpace;
Florin Malita39d71de2017-10-31 11:33:49 -040020class SkColorSpaceXformer;
Florin Malitad4e9ec82017-10-25 18:00:26 -040021class SkRasterPipeline;
22class SkReadBuffer;
23class SkWriteBuffer;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000024
Florin Malita4aed1382017-05-25 10:38:07 -040025class SkGradientShaderBase : public SkShaderBase {
rileya@google.com1c6d64b2012-07-27 15:49:05 +000026public:
reed@google.com437d6eb2013-05-23 19:03:05 +000027 struct Descriptor {
28 Descriptor() {
29 sk_bzero(this, sizeof(*this));
30 fTileMode = SkShader::kClamp_TileMode;
31 }
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000032
reedaddf2ed2014-08-11 08:28:24 -070033 const SkMatrix* fLocalMatrix;
brianosmane25d71c2016-09-28 11:27:28 -070034 const SkColor4f* fColors;
brianosmanb9c51372016-09-15 11:09:45 -070035 sk_sp<SkColorSpace> fColorSpace;
reed@google.com437d6eb2013-05-23 19:03:05 +000036 const SkScalar* fPos;
37 int fCount;
38 SkShader::TileMode fTileMode;
commit-bot@chromium.org6c5aea22014-04-22 16:25:15 +000039 uint32_t fGradFlags;
reed9fa60da2014-08-21 07:59:51 -070040
41 void flatten(SkWriteBuffer&) const;
42 };
43
44 class DescriptorScope : public Descriptor {
45 public:
46 DescriptorScope() {}
mtklein88fd0fb2014-12-01 06:56:38 -080047
reed9fa60da2014-08-21 07:59:51 -070048 bool unflatten(SkReadBuffer&);
49
50 // fColors and fPos always point into local memory, so they can be safely mutated
51 //
brianosmane25d71c2016-09-28 11:27:28 -070052 SkColor4f* mutableColors() { return const_cast<SkColor4f*>(fColors); }
reed9fa60da2014-08-21 07:59:51 -070053 SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); }
54
55 private:
Florin Malitaf77db112018-05-10 09:52:27 -040056 SkSTArray<16, SkColor4f, true> fColorStorage;
57 SkSTArray<16, SkScalar , true> fPosStorage;
58 SkMatrix fLocalMatrixStorage;
reed@google.com437d6eb2013-05-23 19:03:05 +000059 };
60
mtkleincc695fe2014-12-10 10:29:19 -080061 SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit);
Brian Salomond3b65972017-03-22 12:05:03 -040062 ~SkGradientShaderBase() override;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000063
mtklein36352bf2015-03-25 18:17:31 -070064 bool isOpaque() const override;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000065
commit-bot@chromium.org6c5aea22014-04-22 16:25:15 +000066 uint32_t getGradFlags() const { return fGradFlags; }
commit-bot@chromium.org53783b02014-04-17 21:09:49 +000067
Michael Ludwig4f94ef62018-09-12 15:22:16 -040068 const SkMatrix& getGradientMatrix() const { return fPtsToUnit; }
69
rileya@google.com1c6d64b2012-07-27 15:49:05 +000070protected:
fmalitabc590c02016-02-22 09:12:33 -080071 class GradientShaderBase4fContext;
72
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000073 SkGradientShaderBase(SkReadBuffer& );
mtklein36352bf2015-03-25 18:17:31 -070074 void flatten(SkWriteBuffer&) const override;
rileya@google.com1c6d64b2012-07-27 15:49:05 +000075
Florin Malita5f379a82017-10-18 16:22:35 -040076 void commonAsAGradient(GradientInfo*) const;
skia.committer@gmail.comd3b28e82014-04-22 03:05:17 +000077
mtklein36352bf2015-03-25 18:17:31 -070078 bool onAsLuminanceColor(SkColor*) const override;
reed8367b8c2014-08-22 08:30:20 -070079
Mike Reed1d8c42e2017-08-29 14:58:19 -040080 bool onAppendStages(const StageRec&) const override;
Mike Kleina3771842017-05-04 19:38:48 -040081
Florin Malita50b20842017-07-29 19:08:28 -040082 virtual void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline,
83 SkRasterPipeline* postPipeline) const = 0;
Mike Kleina3771842017-05-04 19:38:48 -040084
fmalita088e21b2016-10-05 09:28:42 -070085 template <typename T, typename... Args>
Herb Derby83e939b2017-02-07 14:25:11 -050086 static Context* CheckedMakeContext(SkArenaAlloc* alloc, Args&&... args) {
87 auto* ctx = alloc->make<T>(std::forward<Args>(args)...);
fmalita088e21b2016-10-05 09:28:42 -070088 if (!ctx->isValid()) {
fmalita088e21b2016-10-05 09:28:42 -070089 return nullptr;
90 }
91 return ctx;
92 }
93
Florin Malita39d71de2017-10-31 11:33:49 -040094 struct AutoXformColors {
95 AutoXformColors(const SkGradientShaderBase&, SkColorSpaceXformer*);
96
97 SkAutoSTMalloc<8, SkColor> fColors;
98 };
99
Mike Kleina3771842017-05-04 19:38:48 -0400100 const SkMatrix fPtsToUnit;
101 TileMode fTileMode;
Mike Kleina3771842017-05-04 19:38:48 -0400102 uint8_t fGradFlags;
Mike Kleina3771842017-05-04 19:38:48 -0400103
reedf3182eb2015-11-17 08:12:19 -0800104public:
Florin Malitaed6ae562017-10-28 11:06:48 -0400105 SkScalar getPos(int i) const {
106 SkASSERT(i < fColorCount);
107 return fOrigPos ? fOrigPos[i] : SkIntToScalar(i) / (fColorCount - 1);
108 }
109
Florin Malita39d71de2017-10-31 11:33:49 -0400110 SkColor getLegacyColor(int i) const {
111 SkASSERT(i < fColorCount);
Brian Osman9ba9d7d2018-10-26 13:31:32 -0400112 return fOrigColors4f[i].toSkColor();
Florin Malita39d71de2017-10-31 11:33:49 -0400113 }
114
brianosmanb9c51372016-09-15 11:09:45 -0700115 SkColor4f* fOrigColors4f; // original colors, as linear floats
116 SkScalar* fOrigPos; // original positions
117 int fColorCount;
Florin Malita39d71de2017-10-31 11:33:49 -0400118 sk_sp<SkColorSpace> fColorSpace; // color space of gradient stops
reedf3182eb2015-11-17 08:12:19 -0800119
120 bool colorsAreOpaque() const { return fColorsAreOpaque; }
121
fmenozzicd9a1d02016-08-15 07:03:47 -0700122 TileMode getTileMode() const { return fTileMode; }
fmenozzicd9a1d02016-08-15 07:03:47 -0700123
reedf3182eb2015-11-17 08:12:19 -0800124private:
Florin Malita89ab2402017-11-01 10:14:57 -0400125 // Reserve inline space for up to 4 stops.
126 static constexpr size_t kInlineStopCount = 4;
127 static constexpr size_t kInlineStorageSize = (sizeof(SkColor4f) + sizeof(SkScalar))
128 * kInlineStopCount;
129 SkAutoSTMalloc<kInlineStorageSize, uint8_t> fStorage;
130
131 bool fColorsAreOpaque;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000132
Florin Malita4aed1382017-05-25 10:38:07 -0400133 typedef SkShaderBase INHERITED;
rileya@google.com1c6d64b2012-07-27 15:49:05 +0000134};
135
136///////////////////////////////////////////////////////////////////////////////
137
Brian Osman6667fb12018-07-03 16:44:02 -0400138struct SkColor4fXformer {
139 SkColor4fXformer(const SkColor4f* colors, int colorCount, SkColorSpace* src, SkColorSpace* dst);
140
141 const SkColor4f* fColors;
142 SkSTArray<4, SkColor4f, true> fStorage;
143};
144
bsalomon@google.comcf8fb1f2012-08-02 14:03:32 +0000145#endif