Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions | Protected Attributes | List of all members
SkGradientBaseShader Class Referenceabstract

#include <SkGradientBaseShader.h>

Inheritance diagram for SkGradientBaseShader:
SkShaderBase SkShader SkFlattenable SkRefCnt SkRefCntBase SkConicalGradient SkLinearGradient SkRadialGradient SkSweepGradient

Classes

struct  Descriptor
 
class  DescriptorScope
 

Public Types

using Interpolation = SkGradientShader::Interpolation
 
- Public Types inherited from SkShaderBase
enum class  ShaderType { M }
 
enum class  GradientType { kNone , M }
 
enum  Flags { kOpaqueAlpha_Flag = 1 << 0 }
 
- Public Types inherited from SkFlattenable
enum  Type {
  kSkColorFilter_Type , kSkBlender_Type , kSkDrawable_Type , kSkDrawLooper_Type ,
  kSkImageFilter_Type , kSkMaskFilter_Type , kSkPathEffect_Type , kSkShader_Type
}
 
typedef sk_sp< SkFlattenable >(* Factory) (SkReadBuffer &)
 

Public Member Functions

 SkGradientBaseShader (const Descriptor &desc, const SkMatrix &ptsToUnit)
 
 ~SkGradientBaseShader () override
 
ShaderType type () const final
 
bool isOpaque () const override
 
bool interpolateInPremul () const
 
const SkMatrixgetGradientMatrix () const
 
int getColorCount () const
 
const float * getPositions () const
 
const InterpolationgetInterpolation () const
 
SkScalar getPos (int i) const
 
SkColor getLegacyColor (int i) const
 
bool colorsAreOpaque () const
 
SkTileMode getTileMode () const
 
const SkBitmapcachedBitmap () const
 
void setCachedBitmap (SkBitmap b) const
 
- Public Member Functions inherited from SkShaderBase
 ~SkShaderBase () override
 
sk_sp< SkShadermakeInvertAlpha () const
 
sk_sp< SkShadermakeWithCTM (const SkMatrix &) const
 
virtual bool isConstant () const
 
virtual GradientType asGradient (GradientInfo *info=nullptr, SkMatrix *localMatrix=nullptr) const
 
ContextmakeContext (const ContextRec &, SkArenaAlloc *) const
 
bool asLuminanceColor (SkColor4f *) const
 
bool appendRootStages (const SkStageRec &rec, const SkMatrix &ctm) const
 
virtual SkImageonIsAImage (SkMatrix *, SkTileMode[2]) const
 
virtual SkRuntimeEffectasRuntimeEffect () const
 
Type getFlattenableType () const override
 
virtual sk_sp< SkShadermakeAsALocalMatrixShader (SkMatrix *localMatrix) const
 
- Public Member Functions inherited from SkShader
SkImageisAImage (SkMatrix *localMatrix, SkTileMode xy[2]) const
 
bool isAImage () const
 
sk_sp< SkShadermakeWithLocalMatrix (const SkMatrix &) const
 
sk_sp< SkShadermakeWithColorFilter (sk_sp< SkColorFilter >) const
 
sk_sp< SkShadermakeWithWorkingColorSpace (sk_sp< SkColorSpace >) const
 
- Public Member Functions inherited from SkFlattenable
 SkFlattenable ()
 
virtual Factory getFactory () const =0
 
virtual const char * getTypeName () const =0
 
sk_sp< SkDataserialize (const SkSerialProcs *=nullptr) const
 
size_t serialize (void *memory, size_t memory_size, const SkSerialProcs *=nullptr) const
 
- Public Member Functions inherited from SkRefCntBase
 SkRefCntBase ()
 
virtual ~SkRefCntBase ()
 
bool unique () const
 
void ref () const
 
void unref () const
 

Static Public Member Functions

static bool ValidGradient (const SkColor4f colors[], int count, SkTileMode tileMode, const Interpolation &interpolation)
 
static sk_sp< SkShaderMakeDegenerateGradient (const SkColor4f colors[], const SkScalar pos[], int colorCount, sk_sp< SkColorSpace > colorSpace, SkTileMode mode)
 
static void AppendGradientFillStages (SkRasterPipeline *p, SkArenaAlloc *alloc, const SkPMColor4f *colors, const SkScalar *positions, int count)
 
static void AppendInterpolatedToDstStages (SkRasterPipeline *p, SkArenaAlloc *alloc, bool colorsAreOpaque, const Interpolation &interpolation, const SkColorSpace *intermediateColorSpace, const SkColorSpace *dstColorSpace)
 
- Static Public Member Functions inherited from SkShaderBase
static Type GetFlattenableType ()
 
static sk_sp< SkShaderBaseDeserialize (const void *data, size_t size, const SkDeserialProcs *procs=nullptr)
 
static void RegisterFlattenables ()
 
static SkMatrix ConcatLocalMatrices (const SkMatrix &parentLM, const SkMatrix &childLM)
 
- Static Public Member Functions inherited from SkFlattenable
static Factory NameToFactory (const char name[])
 
static const char * FactoryToName (Factory)
 
static void Register (const char name[], Factory)
 
static sk_sp< SkFlattenableDeserialize (Type, const void *data, size_t length, const SkDeserialProcs *procs=nullptr)
 

Public Attributes

SkColor4ffColors
 
SkScalarfPositions
 
int fColorCount
 
sk_sp< SkColorSpacefColorSpace
 
Interpolation fInterpolation
 
bool fFirstStopIsImplicit
 
bool fLastStopIsImplicit
 

Static Public Attributes

static constexpr SkScalar kDegenerateThreshold = SK_Scalar1 / (1 << 15)
 

Protected Member Functions

void flatten (SkWriteBuffer &) const override
 
void commonAsAGradient (GradientInfo *) const
 
bool onAsLuminanceColor (SkColor4f *) const override
 
bool appendStages (const SkStageRec &, const SkShaders::MatrixRec &) const override
 
virtual void appendGradientStages (SkArenaAlloc *alloc, SkRasterPipeline *tPipeline, SkRasterPipeline *postPipeline) const =0
 
- Protected Member Functions inherited from SkShaderBase
 SkShaderBase ()
 
void flatten (SkWriteBuffer &) const override
 

Protected Attributes

const SkMatrix fPtsToUnit
 
SkTileMode fTileMode
 

Detailed Description

Definition at line 35 of file SkGradientBaseShader.h.

Member Typedef Documentation

◆ Interpolation

Definition at line 37 of file SkGradientBaseShader.h.

Constructor & Destructor Documentation

◆ SkGradientBaseShader()

SkGradientBaseShader::SkGradientBaseShader ( const Descriptor desc,
const SkMatrix ptsToUnit 
)

Definition at line 178 of file SkGradientBaseShader.cpp.

179 : fPtsToUnit(ptsToUnit)
180 , fColorSpace(desc.fColorSpace ? desc.fColorSpace : SkColorSpace::MakeSRGB())
183 , fColorsAreOpaque(true) {
184 fPtsToUnit.getType(); // Precache so reads are threadsafe.
185 SkASSERT(desc.fColorCount > 1);
186
187 fInterpolation = desc.fInterpolation;
188
189 SkASSERT((unsigned)desc.fTileMode < kSkTileModeCount);
190 fTileMode = desc.fTileMode;
191
192 /* Note: we let the caller skip the first and/or last position.
193 i.e. pos[0] = 0.3, pos[1] = 0.7
194 In these cases, we insert entries to ensure that the final data
195 will be bracketed by [0, 1].
196 i.e. our_pos[0] = 0, our_pos[1] = 0.3, our_pos[2] = 0.7, our_pos[3] = 1
197
198 Thus colorCount (the caller's value, and fColorCount (our value) may
199 differ by up to 2. In the above example:
200 colorCount = 2
201 fColorCount = 4
202 */
203 fColorCount = desc.fColorCount;
204 // check if we need to add in start and/or end position/colors
205 if (desc.fPositions) {
206 fFirstStopIsImplicit = desc.fPositions[0] != 0;
207 fLastStopIsImplicit = desc.fPositions[desc.fColorCount - 1] != SK_Scalar1;
209 }
210
211 size_t storageSize =
212 fColorCount * (sizeof(SkColor4f) + (desc.fPositions ? sizeof(SkScalar) : 0));
213 fColors = reinterpret_cast<SkColor4f*>(fStorage.reset(storageSize));
214 fPositions = desc.fPositions ? reinterpret_cast<SkScalar*>(fColors + fColorCount) : nullptr;
215
216 // Now copy over the colors, adding the duplicates at t=0 and t=1 as needed
219 *colors++ = desc.fColors[0];
220 }
221 for (int i = 0; i < desc.fColorCount; ++i) {
222 colors[i] = desc.fColors[i];
223 fColorsAreOpaque = fColorsAreOpaque && (desc.fColors[i].fA == 1);
224 }
226 colors += desc.fColorCount;
227 *colors = desc.fColors[desc.fColorCount - 1];
228 }
229
230 if (desc.fPositions) {
231 SkScalar prev = 0;
232 SkScalar* positions = fPositions;
233 *positions++ = prev; // force the first pos to 0
234
235 int startIndex = fFirstStopIsImplicit ? 0 : 1;
236 int count = desc.fColorCount + fLastStopIsImplicit;
237
238 bool uniformStops = true;
239 const SkScalar uniformStep = desc.fPositions[startIndex] - prev;
240 for (int i = startIndex; i < count; i++) {
241 // Pin the last value to 1.0, and make sure pos is monotonic.
242 auto curr = (i == desc.fColorCount) ? 1 : SkTPin(desc.fPositions[i], prev, 1.0f);
243 uniformStops &= SkScalarNearlyEqual(uniformStep, curr - prev);
244
245 *positions++ = prev = curr;
246 }
247
248 // If the stops are uniform, treat them as implicit.
249 if (uniformStops) {
250 fPositions = nullptr;
251 }
252 }
253}
int count
static float prev(float f)
#define SkASSERT(cond)
Definition SkAssert.h:116
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkScalar.h:107
#define SK_Scalar1
Definition SkScalar.h:18
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition SkTPin.h:19
static constexpr int kSkTileModeCount
Definition SkTileMode.h:39
sk_sp< SkColorSpace > fColorSpace
TypeMask getType() const
Definition SkMatrix.h:207
T * reset(size_t count)
float SkScalar
Definition extension.cpp:12
PODArray< SkColor > colors
Definition SkRecords.h:276

◆ ~SkGradientBaseShader()

SkGradientBaseShader::~SkGradientBaseShader ( )
override

Definition at line 255 of file SkGradientBaseShader.cpp.

255{}

Member Function Documentation

◆ AppendGradientFillStages()

void SkGradientBaseShader::AppendGradientFillStages ( SkRasterPipeline p,
SkArenaAlloc alloc,
const SkPMColor4f colors,
const SkScalar positions,
int  count 
)
static

Definition at line 324 of file SkGradientBaseShader.cpp.

328 {
329 // The two-stop case with stops at 0 and 1.
330 if (count == 2 && positions == nullptr) {
331 const SkPMColor4f c_l = pmColors[0], c_r = pmColors[1];
332
333 // See F and B below.
335 (skvx::float4::Load(c_r.vec()) - skvx::float4::Load(c_l.vec())).store(ctx->f);
336 (skvx::float4::Load(c_l.vec())).store(ctx->b);
337
338 p->append(SkRasterPipelineOp::evenly_spaced_2_stop_gradient, ctx);
339 } else {
340 auto* ctx = alloc->make<SkRasterPipeline_GradientCtx>();
341
342 // Note: In order to handle clamps in search, the search assumes a stop conceptully placed
343 // at -inf. Therefore, the max number of stops is fColorCount+1.
344 for (int i = 0; i < 4; i++) {
345 // Allocate at least at for the AVX2 gather from a YMM register.
346 ctx->fs[i] = alloc->makeArray<float>(std::max(count + 1, 8));
347 ctx->bs[i] = alloc->makeArray<float>(std::max(count + 1, 8));
348 }
349
350 if (positions == nullptr) {
351 // Handle evenly distributed stops.
352
353 size_t stopCount = count;
354 float gapCount = stopCount - 1;
355
356 SkPMColor4f c_l = pmColors[0];
357 for (size_t i = 0; i < stopCount - 1; i++) {
358 SkPMColor4f c_r = pmColors[i + 1];
359 init_stop_evenly(ctx, gapCount, i, c_l, c_r);
360 c_l = c_r;
361 }
362 add_const_color(ctx, stopCount - 1, c_l);
363
364 ctx->stopCount = stopCount;
365 p->append(SkRasterPipelineOp::evenly_spaced_gradient, ctx);
366 } else {
367 // Handle arbitrary stops.
368
369 ctx->ts = alloc->makeArray<float>(count + 1);
370
371 // Remove the default stops inserted by SkGradientBaseShader::SkGradientBaseShader
372 // because they are naturally handled by the search method.
373 int firstStop;
374 int lastStop;
375 if (count > 2) {
376 firstStop = pmColors[0] != pmColors[1] ? 0 : 1;
377 lastStop = pmColors[count - 2] != pmColors[count - 1] ? count - 1 : count - 2;
378 } else {
379 firstStop = 0;
380 lastStop = 1;
381 }
382
383 size_t stopCount = 0;
384 float t_l = positions[firstStop];
385 SkPMColor4f c_l = pmColors[firstStop];
386 add_const_color(ctx, stopCount++, c_l);
387 // N.B. lastStop is the index of the last stop, not one after.
388 for (int i = firstStop; i < lastStop; i++) {
389 float t_r = positions[i + 1];
390 SkPMColor4f c_r = pmColors[i + 1];
391 SkASSERT(t_l <= t_r);
392 if (t_l < t_r) {
393 float c_scale = sk_ieee_float_divide(1, t_r - t_l);
394 if (SkIsFinite(c_scale)) {
395 init_stop_pos(ctx, stopCount, t_l, c_scale, c_l, c_r);
396 stopCount += 1;
397 }
398 }
399 t_l = t_r;
400 c_l = c_r;
401 }
402
403 ctx->ts[stopCount] = t_l;
404 add_const_color(ctx, stopCount++, c_l);
405
406 ctx->stopCount = stopCount;
407 p->append(SkRasterPipelineOp::gradient, ctx);
408 }
409 }
410}
float c_scale
static bool SkIsFinite(T x, Pack... values)
static constexpr float sk_ieee_float_divide(float numer, float denom)
static void add_const_color(SkRasterPipeline_GradientCtx *ctx, size_t stop, SkPMColor4f color)
static void init_stop_evenly(SkRasterPipeline_GradientCtx *ctx, float gapCount, size_t stop, SkPMColor4f c_l, SkPMColor4f c_r)
static void init_stop_pos(SkRasterPipeline_GradientCtx *ctx, size_t stop, float t_l, float c_scale, SkPMColor4f c_l, SkPMColor4f c_r)
SI void store(P *ptr, const T &val)
T * makeArray(size_t count)
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
const float * vec() const
Definition SkColor.h:308
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)
Definition SkVx.h:109

◆ appendGradientStages()

virtual void SkGradientBaseShader::appendGradientStages ( SkArenaAlloc alloc,
SkRasterPipeline tPipeline,
SkRasterPipeline postPipeline 
) const
protectedpure virtual

◆ AppendInterpolatedToDstStages()

void SkGradientBaseShader::AppendInterpolatedToDstStages ( SkRasterPipeline p,
SkArenaAlloc alloc,
bool  colorsAreOpaque,
const Interpolation interpolation,
const SkColorSpace intermediateColorSpace,
const SkColorSpace dstColorSpace 
)
static

Definition at line 412 of file SkGradientBaseShader.cpp.

417 {
419 bool colorIsPremul = static_cast<bool>(interpolation.fInPremul);
420
421 // If we interpolated premul colors in any of the special color spaces, we need to unpremul
422 if (colorIsPremul && !colorsAreOpaque) {
423 switch (interpolation.fColorSpace) {
424 case ColorSpace::kLab:
425 case ColorSpace::kOKLab:
426 case ColorSpace::kOKLabGamutMap:
427 p->append(SkRasterPipelineOp::unpremul);
428 colorIsPremul = false;
429 break;
430 case ColorSpace::kLCH:
431 case ColorSpace::kOKLCH:
432 case ColorSpace::kOKLCHGamutMap:
433 case ColorSpace::kHSL:
434 case ColorSpace::kHWB:
435 p->append(SkRasterPipelineOp::unpremul_polar);
436 colorIsPremul = false;
437 break;
438 default:
439 break;
440 }
441 }
442
443 // Convert colors in exotic spaces back to their intermediate SkColorSpace
444 switch (interpolation.fColorSpace) {
445 case ColorSpace::kLab: p->append(SkRasterPipelineOp::css_lab_to_xyz); break;
446 case ColorSpace::kOKLab: p->append(SkRasterPipelineOp::css_oklab_to_linear_srgb); break;
447 case ColorSpace::kOKLabGamutMap:
448 p->append(SkRasterPipelineOp::css_oklab_gamut_map_to_linear_srgb);
449 break;
450 case ColorSpace::kLCH: p->append(SkRasterPipelineOp::css_hcl_to_lab);
451 p->append(SkRasterPipelineOp::css_lab_to_xyz); break;
452 case ColorSpace::kOKLCH: p->append(SkRasterPipelineOp::css_hcl_to_lab);
453 p->append(SkRasterPipelineOp::css_oklab_to_linear_srgb); break;
454 case ColorSpace::kOKLCHGamutMap:
455 p->append(SkRasterPipelineOp::css_hcl_to_lab);
456 p->append(SkRasterPipelineOp::css_oklab_gamut_map_to_linear_srgb);
457 break;
458 case ColorSpace::kHSL: p->append(SkRasterPipelineOp::css_hsl_to_srgb); break;
459 case ColorSpace::kHWB: p->append(SkRasterPipelineOp::css_hwb_to_srgb); break;
460 default: break;
461 }
462
463 // Now transform from intermediate to destination color space.
464 // See comments in GrGradientShader.cpp about the decisions here.
465 if (!dstColorSpace) {
466 dstColorSpace = sk_srgb_singleton();
467 }
468 SkAlphaType intermediateAlphaType = colorIsPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType;
469 // TODO(skia:13108): Get dst alpha type correctly
470 SkAlphaType dstAlphaType = kPremul_SkAlphaType;
471
472 if (colorsAreOpaque) {
473 intermediateAlphaType = dstAlphaType = kUnpremul_SkAlphaType;
474 }
475
477 intermediateColorSpace, intermediateAlphaType, dstColorSpace, dstAlphaType)
478 ->apply(p);
479}
kUnpremul_SkAlphaType
SkAlphaType
Definition SkAlphaType.h:26
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
SkColorSpace * sk_srgb_singleton()
static bool apply(Pass *pass, SkRecord *record)
ColorSpace
Definition image.h:16

◆ appendStages()

bool SkGradientBaseShader::appendStages ( const SkStageRec ,
const SkShaders::MatrixRec  
) const
overrideprotectedvirtual

Adds stages to implement this shader. To ensure that the correct input coords are present in r,g MatrixRec::apply() must be called (unless the shader doesn't require it's input coords). The default impl creates shadercontext and calls that (not very efficient).

Implements SkShaderBase.

Definition at line 481 of file SkGradientBaseShader.cpp.

482 {
483 SkRasterPipeline* p = rec.fPipeline;
484 SkArenaAlloc* alloc = rec.fAlloc;
485 SkRasterPipeline_DecalTileCtx* decal_ctx = nullptr;
486
487 std::optional<SkShaders::MatrixRec> newMRec = mRec.apply(rec, fPtsToUnit);
488 if (!newMRec.has_value()) {
489 return false;
490 }
491
492 SkRasterPipeline_<256> postPipeline;
493
494 this->appendGradientStages(alloc, p, &postPipeline);
495
496 switch (fTileMode) {
498 p->append(SkRasterPipelineOp::mirror_x_1);
499 break;
501 p->append(SkRasterPipelineOp::repeat_x_1);
502 break;
504 decal_ctx = alloc->make<SkRasterPipeline_DecalTileCtx>();
505 decal_ctx->limit_x = SkBits2Float(SkFloat2Bits(1.0f) + 1);
506 // reuse mask + limit_x stage, or create a custom decal_1 that just stores the mask
507 p->append(SkRasterPipelineOp::decal_x, decal_ctx);
508 [[fallthrough]];
509
511 if (!fPositions) {
512 // We clamp only when the stops are evenly spaced.
513 // If not, there may be hard stops, and clamping ruins hard stops at 0 and/or 1.
514 // In that case, we must make sure we're using the general "gradient" stage,
515 // which is the only stage that will correctly handle unclamped t.
516 p->append(SkRasterPipelineOp::clamp_x_1);
517 }
518 break;
519 }
520
521 // Transform all of the colors to destination color space, possibly premultiplied
522 SkColor4fXformer xformedColors(this, rec.fDstCS);
524 xformedColors.fColors.begin(),
525 xformedColors.fPositions,
526 xformedColors.fColors.size());
527 AppendInterpolatedToDstStages(p, alloc, fColorsAreOpaque, fInterpolation,
528 xformedColors.fIntermediateColorSpace.get(), rec.fDstCS);
529
530 if (decal_ctx) {
531 p->append(SkRasterPipelineOp::check_decal_mask, decal_ctx);
532 }
533
534 p->extend(postPipeline);
535
536 return true;
537}
static float SkBits2Float(uint32_t bits)
Definition SkFloatBits.h:48
static uint32_t SkFloat2Bits(float value)
Definition SkFloatBits.h:41
virtual void appendGradientStages(SkArenaAlloc *alloc, SkRasterPipeline *tPipeline, SkRasterPipeline *postPipeline) const =0
static void AppendGradientFillStages(SkRasterPipeline *p, SkArenaAlloc *alloc, const SkPMColor4f *colors, const SkScalar *positions, int count)
static void AppendInterpolatedToDstStages(SkRasterPipeline *p, SkArenaAlloc *alloc, bool colorsAreOpaque, const Interpolation &interpolation, const SkColorSpace *intermediateColorSpace, const SkColorSpace *dstColorSpace)

◆ cachedBitmap()

const SkBitmap & SkGradientBaseShader::cachedBitmap ( ) const
inline

Definition at line 152 of file SkGradientBaseShader.h.

152{ return fColorsAndOffsetsBitmap; }

◆ colorsAreOpaque()

bool SkGradientBaseShader::colorsAreOpaque ( ) const
inline

Definition at line 148 of file SkGradientBaseShader.h.

148{ return fColorsAreOpaque; }

◆ commonAsAGradient()

void SkGradientBaseShader::commonAsAGradient ( GradientInfo info) const
protected

Definition at line 924 of file SkGradientBaseShader.cpp.

924 {
925 if (info) {
926 if (info->fColorCount >= fColorCount) {
927 if (info->fColors) {
928 for (int i = 0; i < fColorCount; ++i) {
929 info->fColors[i] = this->getLegacyColor(i);
930 }
931 }
932 if (info->fColorOffsets) {
933 for (int i = 0; i < fColorCount; ++i) {
934 info->fColorOffsets[i] = this->getPos(i);
935 }
936 }
937 }
938 info->fColorCount = fColorCount;
939 info->fTileMode = fTileMode;
940
941 info->fGradientFlags =
943 }
944}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
SkColor getLegacyColor(int i) const
SkScalar getPos(int i) const

◆ flatten()

void SkGradientBaseShader::flatten ( SkWriteBuffer ) const
overrideprotectedvirtual

Override this if your subclass needs to record data that it will need to recreate itself from its CreateProc (returned by getFactory()).

DEPRECATED public : will move to protected ... use serialize() instead

Reimplemented from SkFlattenable.

Reimplemented in SkLinearGradient, SkRadialGradient, and SkSweepGradient.

Definition at line 75 of file SkGradientBaseShader.cpp.

75 {
76 uint32_t flags = 0;
77 if (fPositions) {
79 }
80 sk_sp<SkData> colorSpaceData = fColorSpace ? fColorSpace->serialize() : nullptr;
81 if (colorSpaceData) {
83 }
86 }
87 SkASSERT(static_cast<uint32_t>(fTileMode) <= kTileModeMask_GSF);
88 flags |= ((uint32_t)fTileMode << kTileModeShift_GSF);
93
94 buffer.writeUInt(flags);
95
96 // If we injected implicit first/last stops at construction time, omit those when serializing:
97 int colorCount = fColorCount;
98 const SkColor4f* colors = fColors;
99 const SkScalar* positions = fPositions;
101 colorCount--;
102 colors++;
103 if (positions) {
104 positions++;
105 }
106 }
108 colorCount--;
109 }
110
111 buffer.writeColor4fArray(colors, colorCount);
112 if (colorSpaceData) {
113 buffer.writeDataAsByteArray(colorSpaceData.get());
114 }
115 if (positions) {
116 buffer.writeScalarArray(positions, colorCount);
117 }
118}
@ kHasColorSpace_GSF
@ kTileModeShift_GSF
@ kInterpolationColorSpaceMask_GSF
@ kInterpolationColorSpaceShift_GSF
@ kInterpolationHueMethodShift_GSF
@ kHasPosition_GSF
@ kInterpolationInPremul_GSF
@ kInterpolationHueMethodMask_GSF
@ kTileModeMask_GSF
sk_sp< SkData > serialize() const
T * get() const
Definition SkRefCnt.h:303
FlutterSemanticsFlag flags
static const uint8_t buffer[]

◆ getColorCount()

int SkGradientBaseShader::getColorCount ( ) const
inline

Definition at line 81 of file SkGradientBaseShader.h.

81{ return fColorCount; }

◆ getGradientMatrix()

const SkMatrix & SkGradientBaseShader::getGradientMatrix ( ) const
inline

Definition at line 80 of file SkGradientBaseShader.h.

80{ return fPtsToUnit; }

◆ getInterpolation()

const Interpolation & SkGradientBaseShader::getInterpolation ( ) const
inline

Definition at line 83 of file SkGradientBaseShader.h.

83{ return fInterpolation; }

◆ getLegacyColor()

SkColor SkGradientBaseShader::getLegacyColor ( int  i) const
inline

Definition at line 135 of file SkGradientBaseShader.h.

135 {
137 return fColors[i].toSkColor();
138 }

◆ getPos()

SkScalar SkGradientBaseShader::getPos ( int  i) const
inline

Definition at line 130 of file SkGradientBaseShader.h.

130 {
132 return fPositions ? fPositions[i] : SkIntToScalar(i) / (fColorCount - 1);
133 }
#define SkIntToScalar(x)
Definition SkScalar.h:57

◆ getPositions()

const float * SkGradientBaseShader::getPositions ( ) const
inline

Definition at line 82 of file SkGradientBaseShader.h.

82{ return fPositions; }

◆ getTileMode()

SkTileMode SkGradientBaseShader::getTileMode ( ) const
inline

Definition at line 150 of file SkGradientBaseShader.h.

150{ return fTileMode; }

◆ interpolateInPremul()

bool SkGradientBaseShader::interpolateInPremul ( ) const
inline

◆ isOpaque()

bool SkGradientBaseShader::isOpaque ( ) const
overridevirtual

Returns true if the shader is guaranteed to produce only opaque colors, subject to the SkPaint using the shader to apply an opaque alpha value. Subclasses should override this to allow some optimizations.

Reimplemented from SkShader.

Definition at line 539 of file SkGradientBaseShader.cpp.

539 {
540 return fColorsAreOpaque && (this->getTileMode() != SkTileMode::kDecal);
541}
SkTileMode getTileMode() const

◆ MakeDegenerateGradient()

sk_sp< SkShader > SkGradientBaseShader::MakeDegenerateGradient ( const SkColor4f  colors[],
const SkScalar  pos[],
int  colorCount,
sk_sp< SkColorSpace colorSpace,
SkTileMode  mode 
)
static

Definition at line 1027 of file SkGradientBaseShader.cpp.

1031 {
1032 switch (mode) {
1033 case SkTileMode::kDecal:
1034 // normally this would reject the area outside of the interpolation region, so since
1035 // inside region is empty when the radii are equal, the entire draw region is empty
1036 return SkShaders::Empty();
1039 // repeat and mirror are treated the same: the border colors are never visible,
1040 // but approximate the final color as infinite repetitions of the colors, so
1041 // it can be represented as the average color of the gradient.
1042 return SkShaders::Color(average_gradient_color(colors, pos, colorCount),
1043 std::move(colorSpace));
1044 case SkTileMode::kClamp:
1045 // Depending on how the gradient shape degenerates, there may be a more specialized
1046 // fallback representation for the factories to use, but this is a reasonable default.
1047 return SkShaders::Color(colors[colorCount - 1], std::move(colorSpace));
1048 }
1049 SkDEBUGFAIL("Should not be reached");
1050 return nullptr;
1051}
SkPoint pos
#define SkDEBUGFAIL(message)
Definition SkAssert.h:118
static SkColor4f average_gradient_color(const SkColor4f colors[], const SkScalar pos[], int colorCount)

◆ onAsLuminanceColor()

bool SkGradientBaseShader::onAsLuminanceColor ( SkColor4f lum) const
overrideprotectedvirtual

Reimplemented from SkShaderBase.

Definition at line 543 of file SkGradientBaseShader.cpp.

543 {
544 // We just compute an average color. There are several things we could do better:
545 // 1) We already have a different average_gradient_color helper later in this file, that weights
546 // contribution by the relative size of each band.
547 // 2) Colors should be converted to some standard color space! These could be in any space.
548 // 3) Do we want to average in the source space, sRGB, or some linear space?
549 SkColor4f color{0, 0, 0, 1};
550 for (int i = 0; i < fColorCount; ++i) {
551 color.fR += fColors[i].fR;
552 color.fG += fColors[i].fG;
553 color.fB += fColors[i].fB;
554 }
555 const float scale = 1.0f / fColorCount;
556 color.fR *= scale;
557 color.fG *= scale;
558 color.fB *= scale;
559 *lum = color;
560 return true;
561}
SkColor4f color
static float lum(float r, float g, float b)
Definition hsl.cpp:52
const Scalar scale

◆ setCachedBitmap()

void SkGradientBaseShader::setCachedBitmap ( SkBitmap  b) const
inline

Definition at line 153 of file SkGradientBaseShader.h.

153{ fColorsAndOffsetsBitmap = b; }
static bool b

◆ type()

ShaderType SkGradientBaseShader::type ( ) const
inlinefinalvirtual

Implements SkShaderBase.

Definition at line 72 of file SkGradientBaseShader.h.

72{ return ShaderType::kGradientBase; }

◆ ValidGradient()

bool SkGradientBaseShader::ValidGradient ( const SkColor4f  colors[],
int  count,
SkTileMode  tileMode,
const Interpolation interpolation 
)
static

Definition at line 948 of file SkGradientBaseShader.cpp.

951 {
952 return nullptr != colors && count >= 1 && (unsigned)tileMode < kSkTileModeCount &&
953 (unsigned)interpolation.fColorSpace < Interpolation::kColorSpaceCount &&
954 (unsigned)interpolation.fHueMethod < Interpolation::kHueMethodCount;
955}
static constexpr int kColorSpaceCount
static constexpr int kHueMethodCount

Member Data Documentation

◆ fColorCount

int SkGradientBaseShader::fColorCount

Definition at line 142 of file SkGradientBaseShader.h.

◆ fColors

SkColor4f* SkGradientBaseShader::fColors

Definition at line 140 of file SkGradientBaseShader.h.

◆ fColorSpace

sk_sp<SkColorSpace> SkGradientBaseShader::fColorSpace

Definition at line 143 of file SkGradientBaseShader.h.

◆ fFirstStopIsImplicit

bool SkGradientBaseShader::fFirstStopIsImplicit

Definition at line 145 of file SkGradientBaseShader.h.

◆ fInterpolation

Interpolation SkGradientBaseShader::fInterpolation

Definition at line 144 of file SkGradientBaseShader.h.

◆ fLastStopIsImplicit

bool SkGradientBaseShader::fLastStopIsImplicit

Definition at line 146 of file SkGradientBaseShader.h.

◆ fPositions

SkScalar* SkGradientBaseShader::fPositions

Definition at line 141 of file SkGradientBaseShader.h.

◆ fPtsToUnit

const SkMatrix SkGradientBaseShader::fPtsToUnit
protected

Definition at line 113 of file SkGradientBaseShader.h.

◆ fTileMode

SkTileMode SkGradientBaseShader::fTileMode
protected

Definition at line 114 of file SkGradientBaseShader.h.

◆ kDegenerateThreshold

constexpr SkScalar SkGradientBaseShader::kDegenerateThreshold = SK_Scalar1 / (1 << 15)
staticconstexpr

Definition at line 98 of file SkGradientBaseShader.h.


The documentation for this class was generated from the following files: