blob: 4c264e4741acb24ee04c5979a2da4965606fb2bf [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00003 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00004 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00006 */
7
8#ifndef SkShader_DEFINED
9#define SkShader_DEFINED
10
11#include "SkBitmap.h"
Mike Klein987de5b2016-11-17 10:47:39 -050012#include "SkFilterQuality.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000013#include "SkFlattenable.h"
fmalitad0c4e092016-02-22 17:19:04 -080014#include "SkImageInfo.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000015#include "SkMask.h"
16#include "SkMatrix.h"
17#include "SkPaint.h"
bsalomon4beef912014-07-28 13:43:02 -070018#include "../gpu/GrColor.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000019
Herb Derby83e939b2017-02-07 14:25:11 -050020class SkArenaAlloc;
reed3061af42016-01-07 15:47:29 -080021class SkColorFilter;
reed0ccc62d2016-05-04 13:09:39 -070022class SkColorSpace;
reedf1ac1822016-08-01 11:24:14 -070023class SkImage;
reed@android.com8a1c16f2008-12-17 15:59:43 +000024class SkPath;
commit-bot@chromium.orgc5d9bb02014-04-08 15:19:34 +000025class SkPicture;
Mike Kleinb0d10e02016-11-12 10:29:26 -050026class SkRasterPipeline;
rileya@google.com03c1c352012-07-20 20:02:43 +000027class GrContext;
joshualittb0a8a372014-09-23 09:50:21 -070028class GrFragmentProcessor;
reed@android.com8a1c16f2008-12-17 15:59:43 +000029
30/** \class SkShader
reed@google.comad917992011-04-11 19:01:12 +000031 *
reed@google.com880dc472012-05-11 14:47:03 +000032 * Shaders specify the source color(s) for what is being drawn. If a paint
33 * has no shader, then the paint's color is used. If the paint has a
34 * shader, then the shader's color(s) are use instead, but they are
35 * modulated by the paint's alpha. This makes it easy to create a shader
36 * once (e.g. bitmap tiling or gradient) and then change its transparency
37 * w/o having to modify the original shader... only the paint's alpha needs
38 * to be modified.
reed@google.comad917992011-04-11 19:01:12 +000039 */
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +000040class SK_API SkShader : public SkFlattenable {
reed@android.com8a1c16f2008-12-17 15:59:43 +000041public:
Robert Phillips54be5c92017-02-11 01:19:30 +000042 SkShader(const SkMatrix* localMatrix = NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +000043 virtual ~SkShader();
44
reed@google.comad917992011-04-11 19:01:12 +000045 /**
commit-bot@chromium.orgd12de022014-05-09 15:42:07 +000046 * Returns the local matrix.
scroggoc870d492014-07-11 10:42:12 -070047 *
48 * FIXME: This can be incorrect for a Shader with its own local matrix
49 * that is also wrapped via CreateLocalMatrixShader.
commit-bot@chromium.orgd12de022014-05-09 15:42:07 +000050 */
51 const SkMatrix& getLocalMatrix() const { return fLocalMatrix; }
52
reed@android.com8a1c16f2008-12-17 15:59:43 +000053 enum TileMode {
reed@google.com0beaba52012-03-16 14:38:06 +000054 /** replicate the edge color if the shader draws outside of its
55 * original bounds
56 */
57 kClamp_TileMode,
58
59 /** repeat the shader's image horizontally and vertically */
60 kRepeat_TileMode,
61
62 /** repeat the shader's image horizontally and vertically, alternating
63 * mirror images so that adjacent images always seam
64 */
65 kMirror_TileMode,
66
67#if 0
68 /** only draw within the original domain, return 0 everywhere else */
69 kDecal_TileMode,
70#endif
reed19c25f12015-03-15 14:01:21 -070071 };
reed@android.com8a1c16f2008-12-17 15:59:43 +000072
reed19c25f12015-03-15 14:01:21 -070073 enum {
74 kTileModeCount = kMirror_TileMode + 1
reed@android.com8a1c16f2008-12-17 15:59:43 +000075 };
76
77 // override these in your subclass
78
79 enum Flags {
80 //!< set if all of the colors will be opaque
reed4e5a7582016-01-05 05:10:33 -080081 kOpaqueAlpha_Flag = 1 << 0,
reed@android.com5119bdb2009-06-12 21:27:03 +000082
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +000083 /** set if the spans only vary in X (const in Y).
reed@android.com5119bdb2009-06-12 21:27:03 +000084 e.g. an Nx1 bitmap that is being tiled in Y, or a linear-gradient
reed@android.com3c9b2a42009-08-27 19:28:37 +000085 that varies from left-to-right. This flag specifies this for
86 shadeSpan().
reed@android.com5119bdb2009-06-12 21:27:03 +000087 */
reed4e5a7582016-01-05 05:10:33 -080088 kConstInY32_Flag = 1 << 1,
fmalitaca058f52016-02-23 19:02:20 -080089
90 /** hint for the blitter that 4f is the preferred shading mode.
91 */
92 kPrefers4f_Flag = 1 << 2,
reed@android.com8a1c16f2008-12-17 15:59:43 +000093 };
94
reed@google.comad917992011-04-11 19:01:12 +000095 /**
junov@chromium.orgb6e16192011-12-09 15:48:03 +000096 * Returns true if the shader is guaranteed to produce only opaque
97 * colors, subject to the SkPaint using the shader to apply an opaque
98 * alpha value. Subclasses should override this to allow some
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +000099 * optimizations.
junov@chromium.orgb6e16192011-12-09 15:48:03 +0000100 */
101 virtual bool isOpaque() const { return false; }
102
commit-bot@chromium.orge901b6d2014-05-01 19:31:31 +0000103 /**
Mike Kleinb0d10e02016-11-12 10:29:26 -0500104 * Returns true if the shader is guaranteed to produce only a single color.
105 * Subclasses can override this to allow loop-hoisting optimization.
106 */
107 virtual bool isConstant() const { return false; }
108
109 /**
commit-bot@chromium.orge901b6d2014-05-01 19:31:31 +0000110 * ContextRec acts as a parameter bundle for creating Contexts.
111 */
112 struct ContextRec {
fmalitad0c4e092016-02-22 17:19:04 -0800113 enum DstType {
114 kPMColor_DstType, // clients prefer shading into PMColor dest
115 kPM4f_DstType, // clients prefer shading into PM4f dest
116 };
117
118 ContextRec(const SkPaint& paint, const SkMatrix& matrix, const SkMatrix* localM,
Brian Osman11970e52016-12-05 15:26:50 -0500119 DstType dstType, SkColorSpace* dstColorSpace)
reed56263c72015-06-05 11:31:26 -0700120 : fPaint(&paint)
commit-bot@chromium.org80116dc2014-05-06 17:16:03 +0000121 , fMatrix(&matrix)
fmalitad0c4e092016-02-22 17:19:04 -0800122 , fLocalMatrix(localM)
Brian Osman11970e52016-12-05 15:26:50 -0500123 , fPreferredDstType(dstType)
124 , fDstColorSpace(dstColorSpace) {}
commit-bot@chromium.orge901b6d2014-05-01 19:31:31 +0000125
fmalitad0c4e092016-02-22 17:19:04 -0800126 const SkPaint* fPaint; // the current paint associated with the draw
127 const SkMatrix* fMatrix; // the current matrix in the canvas
128 const SkMatrix* fLocalMatrix; // optional local matrix
129 const DstType fPreferredDstType; // the "natural" client dest type
Brian Osman11970e52016-12-05 15:26:50 -0500130 SkColorSpace* fDstColorSpace; // the color space of the dest surface (if any)
commit-bot@chromium.orge901b6d2014-05-01 19:31:31 +0000131 };
132
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000133 class Context : public ::SkNoncopyable {
134 public:
commit-bot@chromium.orge901b6d2014-05-01 19:31:31 +0000135 Context(const SkShader& shader, const ContextRec&);
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000136
137 virtual ~Context();
138
139 /**
140 * Called sometimes before drawing with this shader. Return the type of
141 * alpha your shader will return. The default implementation returns 0.
142 * Your subclass should override if it can (even sometimes) report a
143 * non-zero value, since that will enable various blitters to perform
144 * faster.
145 */
146 virtual uint32_t getFlags() const { return 0; }
147
148 /**
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000149 * Called for each span of the object being drawn. Your subclass should
150 * set the appropriate colors (with premultiplied alpha) that correspond
151 * to the specified device coordinates.
152 */
153 virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
154
reed6d3cef92016-01-22 01:04:29 -0800155 virtual void shadeSpan4f(int x, int y, SkPM4f[], int count);
156
reed58fc94e2016-03-18 12:42:26 -0700157 struct BlitState;
158 typedef void (*BlitBW)(BlitState*,
159 int x, int y, const SkPixmap&, int count);
160 typedef void (*BlitAA)(BlitState*,
161 int x, int y, const SkPixmap&, int count, const SkAlpha[]);
162
reed830dfd82016-03-16 12:29:01 -0700163 struct BlitState {
reed58fc94e2016-03-18 12:42:26 -0700164 // inputs
reed830dfd82016-03-16 12:29:01 -0700165 Context* fCtx;
Mike Reed6a015542016-11-09 10:38:09 -0500166 SkBlendMode fMode;
reed58fc94e2016-03-18 12:42:26 -0700167
168 // outputs
reed830dfd82016-03-16 12:29:01 -0700169 enum { N = 2 };
170 void* fStorage[N];
reed58fc94e2016-03-18 12:42:26 -0700171 BlitBW fBlitBW;
172 BlitAA fBlitAA;
reed830dfd82016-03-16 12:29:01 -0700173 };
reed58fc94e2016-03-18 12:42:26 -0700174
175 // Returns true if one or more of the blitprocs are set in the BlitState
176 bool chooseBlitProcs(const SkImageInfo& info, BlitState* state) {
177 state->fBlitBW = nullptr;
178 state->fBlitAA = nullptr;
179 if (this->onChooseBlitProcs(info, state)) {
180 SkASSERT(state->fBlitBW || state->fBlitAA);
181 return true;
182 }
183 return false;
reed830dfd82016-03-16 12:29:01 -0700184 }
reed58fc94e2016-03-18 12:42:26 -0700185
herbc7a784c2015-12-18 09:52:15 -0800186 /**
187 * The const void* ctx is only const because all the implementations are const.
188 * This can be changed to non-const if a new shade proc needs to change the ctx.
189 */
190 typedef void (*ShadeProc)(const void* ctx, int x, int y, SkPMColor[], int count);
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000191 virtual ShadeProc asAShadeProc(void** ctx);
192
193 /**
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000194 * Similar to shadeSpan, but only returns the alpha-channel for a span.
195 * The default implementation calls shadeSpan() and then extracts the alpha
196 * values from the returned colors.
197 */
198 virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
199
reedcc0e3112014-09-10 10:20:24 -0700200 // Notification from blitter::blitMask in case we need to see the non-alpha channels
201 virtual void set3DMask(const SkMask*) {}
202
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000203 protected:
204 // Reference to shader, so we don't have to dupe information.
205 const SkShader& fShader;
206
207 enum MatrixClass {
208 kLinear_MatrixClass, // no perspective
209 kFixedStepInX_MatrixClass, // fast perspective, need to call fixedStepInX() each
210 // scanline
211 kPerspective_MatrixClass // slow perspective, need to mappoints each pixel
212 };
213 static MatrixClass ComputeMatrixClass(const SkMatrix&);
214
commit-bot@chromium.org80116dc2014-05-06 17:16:03 +0000215 uint8_t getPaintAlpha() const { return fPaintAlpha; }
216 const SkMatrix& getTotalInverse() const { return fTotalInverse; }
217 MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
218 const SkMatrix& getCTM() const { return fCTM; }
reed830dfd82016-03-16 12:29:01 -0700219
reed58fc94e2016-03-18 12:42:26 -0700220 virtual bool onChooseBlitProcs(const SkImageInfo&, BlitState*) { return false; }
reed830dfd82016-03-16 12:29:01 -0700221
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000222 private:
commit-bot@chromium.org80116dc2014-05-06 17:16:03 +0000223 SkMatrix fCTM;
224 SkMatrix fTotalInverse;
225 uint8_t fPaintAlpha;
226 uint8_t fTotalInverseClass;
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000227
228 typedef SkNoncopyable INHERITED;
229 };
reed@google.com7c2f27d2011-03-07 19:29:00 +0000230
reed@google.comad917992011-04-11 19:01:12 +0000231 /**
Herb Derby83e939b2017-02-07 14:25:11 -0500232 * Make a context using the memory provided by the arena.
233 *
234 * @return pointer to context or nullptr if can't be created
reed@google.coma641f3f2012-12-13 22:16:30 +0000235 */
Herb Derby83e939b2017-02-07 14:25:11 -0500236 Context* makeContext(const ContextRec&, SkArenaAlloc*) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000237
Mike Reed627778d2016-09-28 17:13:38 -0400238#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
reed@google.comad917992011-04-11 19:01:12 +0000239 /**
reed0f0af232015-09-08 11:02:04 -0700240 * Returns true if this shader is just a bitmap, and if not null, returns the bitmap,
241 * localMatrix, and tilemodes. If this is not a bitmap, returns false and ignores the
242 * out-parameters.
reed@android.comf2b98d62010-12-20 18:26:13 +0000243 */
reed0f0af232015-09-08 11:02:04 -0700244 bool isABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, TileMode xy[2]) const {
245 return this->onIsABitmap(outTexture, outMatrix, xy);
scroggoff390c92015-09-08 06:24:08 -0700246 }
reed0f0af232015-09-08 11:02:04 -0700247
reedf5822822015-08-19 11:46:38 -0700248 bool isABitmap() const {
249 return this->isABitmap(nullptr, nullptr, nullptr);
250 }
Mike Reed627778d2016-09-28 17:13:38 -0400251#endif
reedf5822822015-08-19 11:46:38 -0700252
vandebo@chromium.orgd3ae7792011-02-24 00:21:06 +0000253 /**
reedf1ac1822016-08-01 11:24:14 -0700254 * Iff this shader is backed by a single SkImage, return its ptr (the caller must ref this
255 * if they want to keep it longer than the lifetime of the shader). If not, return nullptr.
256 */
257 SkImage* isAImage(SkMatrix* localMatrix, TileMode xy[2]) const {
258 return this->onIsAImage(localMatrix, xy);
259 }
260
261 bool isAImage() const {
262 return this->isAImage(nullptr, nullptr) != nullptr;
263 }
264
265 /**
vandebo@chromium.orgd3ae7792011-02-24 00:21:06 +0000266 * If the shader subclass can be represented as a gradient, asAGradient
267 * returns the matching GradientType enum (or kNone_GradientType if it
268 * cannot). Also, if info is not null, asAGradient populates info with
269 * the relevant (see below) parameters for the gradient. fColorCount
270 * is both an input and output parameter. On input, it indicates how
271 * many entries in fColors and fColorOffsets can be used, if they are
272 * non-NULL. After asAGradient has run, fColorCount indicates how
273 * many color-offset pairs there are in the gradient. If there is
274 * insufficient space to store all of the color-offset pairs, fColors
275 * and fColorOffsets will not be altered. fColorOffsets specifies
276 * where on the range of 0 to 1 to transition to the given color.
277 * The meaning of fPoint and fRadius is dependant on the type of gradient.
278 *
279 * None:
280 * info is ignored.
281 * Color:
282 * fColorOffsets[0] is meaningless.
283 * Linear:
284 * fPoint[0] and fPoint[1] are the end-points of the gradient
285 * Radial:
286 * fPoint[0] and fRadius[0] are the center and radius
reed71a6cbf2015-05-04 08:32:51 -0700287 * Conical:
vandebo@chromium.orgd3ae7792011-02-24 00:21:06 +0000288 * fPoint[0] and fRadius[0] are the center and radius of the 1st circle
289 * fPoint[1] and fRadius[1] are the center and radius of the 2nd circle
290 * Sweep:
291 * fPoint[0] is the center of the sweep.
292 */
293
294 enum GradientType {
295 kNone_GradientType,
296 kColor_GradientType,
297 kLinear_GradientType,
298 kRadial_GradientType,
vandebo@chromium.orgd3ae7792011-02-24 00:21:06 +0000299 kSweep_GradientType,
reed@google.com83226972012-06-07 20:26:47 +0000300 kConical_GradientType,
301 kLast_GradientType = kConical_GradientType
vandebo@chromium.orgd3ae7792011-02-24 00:21:06 +0000302 };
303
304 struct GradientInfo {
305 int fColorCount; //!< In-out parameter, specifies passed size
306 // of fColors/fColorOffsets on input, and
307 // actual number of colors/offsets on
308 // output.
309 SkColor* fColors; //!< The colors in the gradient.
310 SkScalar* fColorOffsets; //!< The unit offset for color transitions.
311 SkPoint fPoint[2]; //!< Type specific, see above.
312 SkScalar fRadius[2]; //!< Type specific, see above.
313 TileMode fTileMode; //!< The tile mode used.
reed@google.com3d3a8602013-05-24 14:58:44 +0000314 uint32_t fGradientFlags; //!< see SkGradientShader::Flags
vandebo@chromium.orgd3ae7792011-02-24 00:21:06 +0000315 };
316
317 virtual GradientType asAGradient(GradientInfo* info) const;
318
rileya@google.com03c1c352012-07-20 20:02:43 +0000319 /**
commit-bot@chromium.org79590552014-05-13 18:14:45 +0000320 * If the shader subclass is composed of two shaders, return true, and if rec is not NULL,
321 * fill it out with info about the shader.
commit-bot@chromium.org30558792014-05-14 14:28:34 +0000322 *
323 * These are bare pointers; the ownership and reference count are unchanged.
commit-bot@chromium.org79590552014-05-13 18:14:45 +0000324 */
325
326 struct ComposeRec {
327 const SkShader* fShaderA;
328 const SkShader* fShaderB;
Mike Reed7d954ad2016-10-28 15:42:34 -0400329 SkBlendMode fBlendMode;
commit-bot@chromium.org79590552014-05-13 18:14:45 +0000330 };
331
djsollenc87dd2c2014-11-14 11:11:46 -0800332 virtual bool asACompose(ComposeRec*) const { return false; }
commit-bot@chromium.org79590552014-05-13 18:14:45 +0000333
bungeman06ca8ec2016-06-09 08:01:03 -0700334#if SK_SUPPORT_GPU
brianosman839345d2016-07-22 11:04:53 -0700335 struct AsFPArgs {
Brian Osman9f532a32016-10-19 11:12:09 -0400336 AsFPArgs() {}
brianosman839345d2016-07-22 11:04:53 -0700337 AsFPArgs(GrContext* context,
338 const SkMatrix* viewMatrix,
339 const SkMatrix* localMatrix,
340 SkFilterQuality filterQuality,
Brian Osman61624f02016-12-09 14:51:59 -0500341 SkColorSpace* dstColorSpace)
brianosman839345d2016-07-22 11:04:53 -0700342 : fContext(context)
343 , fViewMatrix(viewMatrix)
344 , fLocalMatrix(localMatrix)
345 , fFilterQuality(filterQuality)
Brian Osman61624f02016-12-09 14:51:59 -0500346 , fDstColorSpace(dstColorSpace) {}
brianosman839345d2016-07-22 11:04:53 -0700347
Brian Osman7b8400d2016-11-08 17:08:54 -0500348 GrContext* fContext;
349 const SkMatrix* fViewMatrix;
350 const SkMatrix* fLocalMatrix;
351 SkFilterQuality fFilterQuality;
352 SkColorSpace* fDstColorSpace;
brianosman839345d2016-07-22 11:04:53 -0700353 };
354
commit-bot@chromium.org79590552014-05-13 18:14:45 +0000355 /**
bsalomonc21b09e2015-08-28 18:46:56 -0700356 * Returns a GrFragmentProcessor that implements the shader for the GPU backend. NULL is
357 * returned if there is no GPU implementation.
bsalomon83d081a2014-07-08 09:56:10 -0700358 *
bsalomonc21b09e2015-08-28 18:46:56 -0700359 * The GPU device does not call SkShader::createContext(), instead we pass the view matrix,
360 * local matrix, and filter quality directly.
bsalomon83d081a2014-07-08 09:56:10 -0700361 *
bsalomonc21b09e2015-08-28 18:46:56 -0700362 * The GrContext may be used by the to create textures that are required by the returned
363 * processor.
bsalomonf1b7a1d2015-09-28 06:26:28 -0700364 *
365 * The returned GrFragmentProcessor should expect an unpremultiplied input color and
366 * produce a premultiplied output.
rileya@google.com03c1c352012-07-20 20:02:43 +0000367 */
brianosman839345d2016-07-22 11:04:53 -0700368 virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const;
bungeman06ca8ec2016-06-09 08:01:03 -0700369#endif
rileya@google.com03c1c352012-07-20 20:02:43 +0000370
reed8367b8c2014-08-22 08:30:20 -0700371 /**
372 * If the shader can represent its "average" luminance in a single color, return true and
373 * if color is not NULL, return that color. If it cannot, return false and ignore the color
374 * parameter.
375 *
376 * Note: if this returns true, the returned color will always be opaque, as only the RGB
377 * components are used to compute luminance.
378 */
379 bool asLuminanceColor(SkColor*) const;
380
reed@android.com8a1c16f2008-12-17 15:59:43 +0000381 //////////////////////////////////////////////////////////////////////////
reedf880e452015-12-30 13:39:41 -0800382 // Methods to create combinations or variants of shaders
reed@android.com8a1c16f2008-12-17 15:59:43 +0000383
commit-bot@chromium.orgce56d962014-05-05 18:39:18 +0000384 /**
reedf880e452015-12-30 13:39:41 -0800385 * Return a shader that will apply the specified localMatrix to this shader.
386 * The specified matrix will be applied before any matrix associated with this shader.
387 */
reed150835e2016-03-10 06:36:49 -0800388 sk_sp<SkShader> makeWithLocalMatrix(const SkMatrix&) const;
reed3061af42016-01-07 15:47:29 -0800389
390 /**
391 * Create a new shader that produces the same colors as invoking this shader and then applying
392 * the colorfilter.
393 */
reedd053ce92016-03-22 10:17:23 -0700394 sk_sp<SkShader> makeWithColorFilter(sk_sp<SkColorFilter>) const;
reeda2b340f2016-02-10 08:53:15 -0800395
reedf880e452015-12-30 13:39:41 -0800396 //////////////////////////////////////////////////////////////////////////
397 // Factory methods for stock shaders
Mike Kleinb0d10e02016-11-12 10:29:26 -0500398
reedf880e452015-12-30 13:39:41 -0800399 /**
commit-bot@chromium.orgce56d962014-05-05 18:39:18 +0000400 * Call this to create a new "empty" shader, that will not draw anything.
401 */
reed8a21c9f2016-03-08 18:50:00 -0800402 static sk_sp<SkShader> MakeEmptyShader();
commit-bot@chromium.orgce56d962014-05-05 18:39:18 +0000403
reed8367b8c2014-08-22 08:30:20 -0700404 /**
405 * Call this to create a new shader that just draws the specified color. This should always
406 * draw the same as a paint with this color (and no shader).
407 */
reed8a21c9f2016-03-08 18:50:00 -0800408 static sk_sp<SkShader> MakeColorShader(SkColor);
reed8367b8c2014-08-22 08:30:20 -0700409
reed0ccc62d2016-05-04 13:09:39 -0700410 /**
411 * Create a shader that draws the specified color (in the specified colorspace).
412 *
413 * This works around the limitation that SkPaint::setColor() only takes byte values, and does
414 * not support specific colorspaces.
415 */
416 static sk_sp<SkShader> MakeColorShader(const SkColor4f&, sk_sp<SkColorSpace>);
417
Mike Reed7d954ad2016-10-28 15:42:34 -0400418 static sk_sp<SkShader> MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader> src, SkBlendMode);
419
reed@android.com8a1c16f2008-12-17 15:59:43 +0000420 /** Call this to create a new shader that will draw with the specified bitmap.
reed@google.com99c114e2012-05-03 20:14:26 +0000421 *
422 * If the bitmap cannot be used (e.g. has no pixels, or its dimensions
423 * exceed implementation limits (currently at 64K - 1)) then SkEmptyShader
424 * may be returned.
425 *
commit-bot@chromium.org91246b92013-12-05 15:43:19 +0000426 * If the src is kA8_Config then that mask will be colorized using the color on
427 * the paint.
428 *
reed@google.com99c114e2012-05-03 20:14:26 +0000429 * @param src The bitmap to use inside the shader
430 * @param tmx The tiling mode to use when sampling the bitmap in the x-direction.
431 * @param tmy The tiling mode to use when sampling the bitmap in the y-direction.
432 * @return Returns a new shader object. Note: this function never returns null.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000433 */
reed8a21c9f2016-03-08 18:50:00 -0800434 static sk_sp<SkShader> MakeBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
435 const SkMatrix* localMatrix = nullptr);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000436
halcanarya5f46e12015-09-08 07:12:25 -0700437 // NOTE: You can create an SkImage Shader with SkImage::newShader().
438
commit-bot@chromium.orgc5d9bb02014-04-08 15:19:34 +0000439 /** Call this to create a new shader that will draw with the specified picture.
440 *
441 * @param src The picture to use inside the shader (if not NULL, its ref count
commit-bot@chromium.org855e88e2014-04-21 19:33:12 +0000442 * is incremented). The SkPicture must not be changed after
443 * successfully creating a picture shader.
commit-bot@chromium.orgc5d9bb02014-04-08 15:19:34 +0000444 * @param tmx The tiling mode to use when sampling the bitmap in the x-direction.
445 * @param tmy The tiling mode to use when sampling the bitmap in the y-direction.
fmalitab5f78262014-08-06 13:07:15 -0700446 * @param tile The tile rectangle in picture coordinates: this represents the subset
447 * (or superset) of the picture used when building a tile. It is not
448 * affected by localMatrix and does not imply scaling (only translation
449 * and cropping). If null, the tile rect is considered equal to the picture
450 * bounds.
commit-bot@chromium.orgc5d9bb02014-04-08 15:19:34 +0000451 * @return Returns a new shader object. Note: this function never returns null.
452 */
reed7fb4f8b2016-03-11 04:33:52 -0800453 static sk_sp<SkShader> MakePictureShader(sk_sp<SkPicture> src, TileMode tmx, TileMode tmy,
reed8a21c9f2016-03-08 18:50:00 -0800454 const SkMatrix* localMatrix, const SkRect* tile);
commit-bot@chromium.orgc5d9bb02014-04-08 15:19:34 +0000455
Ben Wagnera8834bb2016-10-24 11:36:21 -0400456 /**
457 * If this shader can be represented by another shader + a localMatrix, return that shader and
458 * the localMatrix. If not, return nullptr and ignore the localMatrix parameter.
459 */
460 virtual sk_sp<SkShader> makeAsALocalMatrixShader(SkMatrix* localMatrix) const;
commit-bot@chromium.org8fae2132014-05-07 22:26:37 +0000461
robertphillips0a482f42015-01-26 07:00:04 -0800462 SK_TO_STRING_VIRT()
mtklein3b375452016-04-04 14:57:19 -0700463 SK_DEFINE_FLATTENABLE_TYPE(SkShader)
reed320a40d2016-08-02 06:12:06 -0700464 SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
commit-bot@chromium.orgc0b7e102013-10-23 17:06:21 +0000465
Herb Derbyac04fef2017-01-13 17:34:33 -0500466 bool appendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
Mike Klein7a14734d2016-11-29 15:33:39 -0500467 const SkMatrix& ctm, const SkPaint&) const;
Mike Kleinb0d10e02016-11-12 10:29:26 -0500468
reed@android.com8a1c16f2008-12-17 15:59:43 +0000469protected:
mtklein36352bf2015-03-25 18:17:31 -0700470 void flatten(SkWriteBuffer&) const override;
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000471
commit-bot@chromium.orgce56d962014-05-05 18:39:18 +0000472 bool computeTotalInverse(const ContextRec&, SkMatrix* totalInverse) const;
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000473
commit-bot@chromium.orgce56d962014-05-05 18:39:18 +0000474 /**
Herb Derby83e939b2017-02-07 14:25:11 -0500475 * Specialize creating a SkShader context using the supplied allocator.
476 * @return pointer to context owned by the arena allocator.
commit-bot@chromium.orgce56d962014-05-05 18:39:18 +0000477 */
Herb Derby83e939b2017-02-07 14:25:11 -0500478 virtual Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const {
479 return nullptr;
480 }
reed773ceda2016-03-03 18:18:25 -0800481
reed8367b8c2014-08-22 08:30:20 -0700482 virtual bool onAsLuminanceColor(SkColor*) const {
483 return false;
484 }
reed0f0af232015-09-08 11:02:04 -0700485
Mike Reed627778d2016-09-28 17:13:38 -0400486#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
reed0f0af232015-09-08 11:02:04 -0700487 virtual bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode[2]) const {
488 return false;
489 }
Mike Reed627778d2016-09-28 17:13:38 -0400490#endif
reed0f0af232015-09-08 11:02:04 -0700491
reedf1ac1822016-08-01 11:24:14 -0700492 virtual SkImage* onIsAImage(SkMatrix*, TileMode[2]) const {
493 return nullptr;
494 }
495
Herb Derbyac04fef2017-01-13 17:34:33 -0500496 virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
Florin Malita882ccaf2017-01-27 10:51:58 -0500497 const SkMatrix&, const SkPaint&,
Florin Malita9206c762017-01-30 12:08:05 -0500498 const SkMatrix* /*local matrix*/) const;
Mike Kleinb0d10e02016-11-12 10:29:26 -0500499
commit-bot@chromium.orgce56d962014-05-05 18:39:18 +0000500private:
Robert Phillips54be5c92017-02-11 01:19:30 +0000501 // This is essentially const, but not officially so it can be modified in
502 // constructors.
503 SkMatrix fLocalMatrix;
scroggoc870d492014-07-11 10:42:12 -0700504
505 // So the SkLocalMatrixShader can whack fLocalMatrix in its SkReadBuffer constructor.
506 friend class SkLocalMatrixShader;
reed320a40d2016-08-02 06:12:06 -0700507 friend class SkBitmapProcLegacyShader; // for computeTotalInverse()
scroggoc870d492014-07-11 10:42:12 -0700508
reed@android.com8a1c16f2008-12-17 15:59:43 +0000509 typedef SkFlattenable INHERITED;
510};
511
512#endif