rileya@google.com | 1c6d64b | 2012-07-27 15:49:05 +0000 | [diff] [blame] | 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 | #ifndef SkGradientShaderPriv_DEFINED |
| 9 | #define SkGradientShaderPriv_DEFINED |
| 10 | |
| 11 | #include "SkGradientShader.h" |
Hal Canary | 95e3c05 | 2017-01-11 12:44:43 -0500 | [diff] [blame] | 12 | |
Herb Derby | 83e939b | 2017-02-07 14:25:11 -0500 | [diff] [blame] | 13 | #include "SkArenaAlloc.h" |
Florin Malita | d4e9ec8 | 2017-10-25 18:00:26 -0400 | [diff] [blame] | 14 | #include "SkMatrix.h" |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 15 | #include "SkShaderBase.h" |
Florin Malita | 14a8dd7 | 2017-11-08 15:46:42 -0500 | [diff] [blame] | 16 | #include "SkTArray.h" |
Florin Malita | 39d71de | 2017-10-31 11:33:49 -0400 | [diff] [blame] | 17 | #include "SkTemplates.h" |
rileya@google.com | 1c6d64b | 2012-07-27 15:49:05 +0000 | [diff] [blame] | 18 | |
Florin Malita | d4e9ec8 | 2017-10-25 18:00:26 -0400 | [diff] [blame] | 19 | class SkColorSpace; |
Florin Malita | 39d71de | 2017-10-31 11:33:49 -0400 | [diff] [blame] | 20 | class SkColorSpaceXformer; |
Florin Malita | d4e9ec8 | 2017-10-25 18:00:26 -0400 | [diff] [blame] | 21 | class SkRasterPipeline; |
| 22 | class SkReadBuffer; |
| 23 | class SkWriteBuffer; |
rileya@google.com | 1c6d64b | 2012-07-27 15:49:05 +0000 | [diff] [blame] | 24 | |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 25 | class SkGradientShaderBase : public SkShaderBase { |
rileya@google.com | 1c6d64b | 2012-07-27 15:49:05 +0000 | [diff] [blame] | 26 | public: |
reed@google.com | 437d6eb | 2013-05-23 19:03:05 +0000 | [diff] [blame] | 27 | struct Descriptor { |
| 28 | Descriptor() { |
| 29 | sk_bzero(this, sizeof(*this)); |
| 30 | fTileMode = SkShader::kClamp_TileMode; |
| 31 | } |
skia.committer@gmail.com | 3e2345a | 2013-05-24 07:01:26 +0000 | [diff] [blame] | 32 | |
reed | addf2ed | 2014-08-11 08:28:24 -0700 | [diff] [blame] | 33 | const SkMatrix* fLocalMatrix; |
brianosman | e25d71c | 2016-09-28 11:27:28 -0700 | [diff] [blame] | 34 | const SkColor4f* fColors; |
brianosman | b9c5137 | 2016-09-15 11:09:45 -0700 | [diff] [blame] | 35 | sk_sp<SkColorSpace> fColorSpace; |
reed@google.com | 437d6eb | 2013-05-23 19:03:05 +0000 | [diff] [blame] | 36 | const SkScalar* fPos; |
| 37 | int fCount; |
| 38 | SkShader::TileMode fTileMode; |
commit-bot@chromium.org | 6c5aea2 | 2014-04-22 16:25:15 +0000 | [diff] [blame] | 39 | uint32_t fGradFlags; |
reed | 9fa60da | 2014-08-21 07:59:51 -0700 | [diff] [blame] | 40 | |
| 41 | void flatten(SkWriteBuffer&) const; |
| 42 | }; |
| 43 | |
| 44 | class DescriptorScope : public Descriptor { |
| 45 | public: |
| 46 | DescriptorScope() {} |
mtklein | 88fd0fb | 2014-12-01 06:56:38 -0800 | [diff] [blame] | 47 | |
reed | 9fa60da | 2014-08-21 07:59:51 -0700 | [diff] [blame] | 48 | bool unflatten(SkReadBuffer&); |
| 49 | |
| 50 | // fColors and fPos always point into local memory, so they can be safely mutated |
| 51 | // |
brianosman | e25d71c | 2016-09-28 11:27:28 -0700 | [diff] [blame] | 52 | SkColor4f* mutableColors() { return const_cast<SkColor4f*>(fColors); } |
reed | 9fa60da | 2014-08-21 07:59:51 -0700 | [diff] [blame] | 53 | SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); } |
| 54 | |
| 55 | private: |
Florin Malita | f77db11 | 2018-05-10 09:52:27 -0400 | [diff] [blame] | 56 | SkSTArray<16, SkColor4f, true> fColorStorage; |
| 57 | SkSTArray<16, SkScalar , true> fPosStorage; |
| 58 | SkMatrix fLocalMatrixStorage; |
reed@google.com | 437d6eb | 2013-05-23 19:03:05 +0000 | [diff] [blame] | 59 | }; |
| 60 | |
mtklein | cc695fe | 2014-12-10 10:29:19 -0800 | [diff] [blame] | 61 | SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit); |
Brian Salomon | d3b6597 | 2017-03-22 12:05:03 -0400 | [diff] [blame] | 62 | ~SkGradientShaderBase() override; |
rileya@google.com | 1c6d64b | 2012-07-27 15:49:05 +0000 | [diff] [blame] | 63 | |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 64 | bool isOpaque() const override; |
rileya@google.com | 1c6d64b | 2012-07-27 15:49:05 +0000 | [diff] [blame] | 65 | |
commit-bot@chromium.org | 6c5aea2 | 2014-04-22 16:25:15 +0000 | [diff] [blame] | 66 | uint32_t getGradFlags() const { return fGradFlags; } |
commit-bot@chromium.org | 53783b0 | 2014-04-17 21:09:49 +0000 | [diff] [blame] | 67 | |
Michael Ludwig | 4f94ef6 | 2018-09-12 15:22:16 -0400 | [diff] [blame] | 68 | const SkMatrix& getGradientMatrix() const { return fPtsToUnit; } |
| 69 | |
rileya@google.com | 1c6d64b | 2012-07-27 15:49:05 +0000 | [diff] [blame] | 70 | protected: |
fmalita | bc590c0 | 2016-02-22 09:12:33 -0800 | [diff] [blame] | 71 | class GradientShaderBase4fContext; |
| 72 | |
commit-bot@chromium.org | 8b0e8ac | 2014-01-30 18:58:24 +0000 | [diff] [blame] | 73 | SkGradientShaderBase(SkReadBuffer& ); |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 74 | void flatten(SkWriteBuffer&) const override; |
rileya@google.com | 1c6d64b | 2012-07-27 15:49:05 +0000 | [diff] [blame] | 75 | |
Florin Malita | 5f379a8 | 2017-10-18 16:22:35 -0400 | [diff] [blame] | 76 | void commonAsAGradient(GradientInfo*) const; |
skia.committer@gmail.com | d3b28e8 | 2014-04-22 03:05:17 +0000 | [diff] [blame] | 77 | |
mtklein | 36352bf | 2015-03-25 18:17:31 -0700 | [diff] [blame] | 78 | bool onAsLuminanceColor(SkColor*) const override; |
reed | 8367b8c | 2014-08-22 08:30:20 -0700 | [diff] [blame] | 79 | |
Mike Reed | 1d8c42e | 2017-08-29 14:58:19 -0400 | [diff] [blame] | 80 | bool onAppendStages(const StageRec&) const override; |
Mike Klein | a377184 | 2017-05-04 19:38:48 -0400 | [diff] [blame] | 81 | |
Florin Malita | 50b2084 | 2017-07-29 19:08:28 -0400 | [diff] [blame] | 82 | virtual void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline, |
| 83 | SkRasterPipeline* postPipeline) const = 0; |
Mike Klein | a377184 | 2017-05-04 19:38:48 -0400 | [diff] [blame] | 84 | |
fmalita | 088e21b | 2016-10-05 09:28:42 -0700 | [diff] [blame] | 85 | template <typename T, typename... Args> |
Herb Derby | 83e939b | 2017-02-07 14:25:11 -0500 | [diff] [blame] | 86 | static Context* CheckedMakeContext(SkArenaAlloc* alloc, Args&&... args) { |
| 87 | auto* ctx = alloc->make<T>(std::forward<Args>(args)...); |
fmalita | 088e21b | 2016-10-05 09:28:42 -0700 | [diff] [blame] | 88 | if (!ctx->isValid()) { |
fmalita | 088e21b | 2016-10-05 09:28:42 -0700 | [diff] [blame] | 89 | return nullptr; |
| 90 | } |
| 91 | return ctx; |
| 92 | } |
| 93 | |
Florin Malita | 39d71de | 2017-10-31 11:33:49 -0400 | [diff] [blame] | 94 | struct AutoXformColors { |
| 95 | AutoXformColors(const SkGradientShaderBase&, SkColorSpaceXformer*); |
| 96 | |
| 97 | SkAutoSTMalloc<8, SkColor> fColors; |
| 98 | }; |
| 99 | |
Mike Klein | a377184 | 2017-05-04 19:38:48 -0400 | [diff] [blame] | 100 | const SkMatrix fPtsToUnit; |
| 101 | TileMode fTileMode; |
Mike Klein | a377184 | 2017-05-04 19:38:48 -0400 | [diff] [blame] | 102 | uint8_t fGradFlags; |
Mike Klein | a377184 | 2017-05-04 19:38:48 -0400 | [diff] [blame] | 103 | |
reed | f3182eb | 2015-11-17 08:12:19 -0800 | [diff] [blame] | 104 | public: |
Florin Malita | ed6ae56 | 2017-10-28 11:06:48 -0400 | [diff] [blame] | 105 | SkScalar getPos(int i) const { |
| 106 | SkASSERT(i < fColorCount); |
| 107 | return fOrigPos ? fOrigPos[i] : SkIntToScalar(i) / (fColorCount - 1); |
| 108 | } |
| 109 | |
Florin Malita | 39d71de | 2017-10-31 11:33:49 -0400 | [diff] [blame] | 110 | SkColor getLegacyColor(int i) const { |
| 111 | SkASSERT(i < fColorCount); |
Brian Osman | 9ba9d7d | 2018-10-26 13:31:32 -0400 | [diff] [blame] | 112 | return fOrigColors4f[i].toSkColor(); |
Florin Malita | 39d71de | 2017-10-31 11:33:49 -0400 | [diff] [blame] | 113 | } |
| 114 | |
brianosman | b9c5137 | 2016-09-15 11:09:45 -0700 | [diff] [blame] | 115 | SkColor4f* fOrigColors4f; // original colors, as linear floats |
| 116 | SkScalar* fOrigPos; // original positions |
| 117 | int fColorCount; |
Florin Malita | 39d71de | 2017-10-31 11:33:49 -0400 | [diff] [blame] | 118 | sk_sp<SkColorSpace> fColorSpace; // color space of gradient stops |
reed | f3182eb | 2015-11-17 08:12:19 -0800 | [diff] [blame] | 119 | |
| 120 | bool colorsAreOpaque() const { return fColorsAreOpaque; } |
| 121 | |
fmenozzi | cd9a1d0 | 2016-08-15 07:03:47 -0700 | [diff] [blame] | 122 | TileMode getTileMode() const { return fTileMode; } |
fmenozzi | cd9a1d0 | 2016-08-15 07:03:47 -0700 | [diff] [blame] | 123 | |
reed | f3182eb | 2015-11-17 08:12:19 -0800 | [diff] [blame] | 124 | private: |
Florin Malita | 89ab240 | 2017-11-01 10:14:57 -0400 | [diff] [blame] | 125 | // 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.com | 1c6d64b | 2012-07-27 15:49:05 +0000 | [diff] [blame] | 132 | |
Florin Malita | 4aed138 | 2017-05-25 10:38:07 -0400 | [diff] [blame] | 133 | typedef SkShaderBase INHERITED; |
rileya@google.com | 1c6d64b | 2012-07-27 15:49:05 +0000 | [diff] [blame] | 134 | }; |
| 135 | |
| 136 | /////////////////////////////////////////////////////////////////////////////// |
| 137 | |
Brian Osman | 6667fb1 | 2018-07-03 16:44:02 -0400 | [diff] [blame] | 138 | struct 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.com | cf8fb1f | 2012-08-02 14:03:32 +0000 | [diff] [blame] | 145 | #endif |