aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkBitmapProcShader.cpp229
-rw-r--r--src/core/SkBitmapProcShader.h26
-rw-r--r--src/core/SkColorFilterShader.cpp138
-rw-r--r--src/core/SkColorFilterShader.h60
-rw-r--r--src/core/SkColorShader.cpp339
-rw-r--r--src/core/SkColorShader.h142
-rw-r--r--src/core/SkComposeShader.cpp311
-rw-r--r--src/core/SkComposeShader.h88
-rw-r--r--src/core/SkEmptyShader.h41
-rw-r--r--src/core/SkLightingShader.cpp488
-rw-r--r--src/core/SkLightingShader.h39
-rw-r--r--src/core/SkLocalMatrixShader.cpp110
-rw-r--r--src/core/SkLocalMatrixShader.h75
-rw-r--r--src/core/SkPictureShader.cpp364
-rw-r--r--src/core/SkPictureShader.h79
-rw-r--r--src/core/SkShader.cpp305
-rw-r--r--src/core/SkShaderBase.h303
17 files changed, 0 insertions, 3137 deletions
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
deleted file mode 100644
index e52982354d..0000000000
--- a/src/core/SkBitmapProcShader.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkBitmapProcShader.h"
-
-#include "SkArenaAlloc.h"
-#include "SkBitmapProcState.h"
-#include "SkBitmapProvider.h"
-#include "SkXfermodePriv.h"
-
-static bool only_scale_and_translate(const SkMatrix& matrix) {
- unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
- return (matrix.getType() & ~mask) == 0;
-}
-
-class BitmapProcInfoContext : public SkShaderBase::Context {
-public:
- // The info has been allocated elsewhere, but we are responsible for calling its destructor.
- BitmapProcInfoContext(const SkShaderBase& shader, const SkShaderBase::ContextRec& rec,
- SkBitmapProcInfo* info)
- : INHERITED(shader, rec)
- , fInfo(info)
- {
- fFlags = 0;
- if (fInfo->fPixmap.isOpaque() && (255 == this->getPaintAlpha())) {
- fFlags |= SkShaderBase::kOpaqueAlpha_Flag;
- }
-
- if (1 == fInfo->fPixmap.height() && only_scale_and_translate(this->getTotalInverse())) {
- fFlags |= SkShaderBase::kConstInY32_Flag;
- }
- }
-
- uint32_t getFlags() const override { return fFlags; }
-
-private:
- SkBitmapProcInfo* fInfo;
- uint32_t fFlags;
-
- typedef SkShaderBase::Context INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class BitmapProcShaderContext : public BitmapProcInfoContext {
-public:
- BitmapProcShaderContext(const SkShaderBase& shader, const SkShaderBase::ContextRec& rec,
- SkBitmapProcState* state)
- : INHERITED(shader, rec, state)
- , fState(state)
- {}
-
- void shadeSpan(int x, int y, SkPMColor dstC[], int count) override {
- const SkBitmapProcState& state = *fState;
- if (state.getShaderProc32()) {
- state.getShaderProc32()(&state, x, y, dstC, count);
- return;
- }
-
- const int BUF_MAX = 128;
- uint32_t buffer[BUF_MAX];
- SkBitmapProcState::MatrixProc mproc = state.getMatrixProc();
- SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32();
- const int max = state.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX);
-
- SkASSERT(state.fPixmap.addr());
-
- for (;;) {
- int n = SkTMin(count, max);
- SkASSERT(n > 0 && n < BUF_MAX*2);
- mproc(state, buffer, n, x, y);
- sproc(state, buffer, n, dstC);
-
- if ((count -= n) == 0) {
- break;
- }
- SkASSERT(count > 0);
- x += n;
- dstC += n;
- }
- }
-
- ShadeProc asAShadeProc(void** ctx) override {
- if (fState->getShaderProc32()) {
- *ctx = fState;
- return (ShadeProc)fState->getShaderProc32();
- }
- return nullptr;
- }
-
-private:
- SkBitmapProcState* fState;
-
- typedef BitmapProcInfoContext INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-#include "SkLinearBitmapPipeline.h"
-#include "SkPM4f.h"
-
-class LinearPipelineContext : public BitmapProcInfoContext {
-public:
- LinearPipelineContext(const SkShaderBase& shader, const SkShaderBase::ContextRec& rec,
- SkBitmapProcInfo* info, SkArenaAlloc* alloc)
- : INHERITED(shader, rec, info), fAllocator{alloc}
- {
- // Save things off in case we need to build a blitter pipeline.
- fSrcPixmap = info->fPixmap;
- fAlpha = SkColorGetA(info->fPaintColor) / 255.0f;
- fFilterQuality = info->fFilterQuality;
- fMatrixTypeMask = info->fRealInvMatrix.getType();
-
- fShaderPipeline = alloc->make<SkLinearBitmapPipeline>(
- info->fRealInvMatrix, info->fFilterQuality,
- info->fTileModeX, info->fTileModeY,
- info->fPaintColor,
- info->fPixmap,
- fAllocator);
-
- // To implement the old shadeSpan entry-point, we need to efficiently convert our native
- // floats into SkPMColor. The SkXfermode::D32Procs do exactly that.
- //
- fSrcModeProc = SkXfermode::GetD32Proc(SkBlendMode::kSrc, 0);
- }
-
- void shadeSpan4f(int x, int y, SkPM4f dstC[], int count) override {
- fShaderPipeline->shadeSpan4f(x, y, dstC, count);
- }
-
- void shadeSpan(int x, int y, SkPMColor dstC[], int count) override {
- const int N = 128;
- SkPM4f tmp[N];
-
- while (count > 0) {
- const int n = SkTMin(count, N);
- fShaderPipeline->shadeSpan4f(x, y, tmp, n);
- fSrcModeProc(SkBlendMode::kSrc, dstC, tmp, n, nullptr);
- dstC += n;
- x += n;
- count -= n;
- }
- }
-
- bool onChooseBlitProcs(const SkImageInfo& dstInfo, BlitState* state) override {
- if ((fBlitterPipeline = SkLinearBitmapPipeline::ClonePipelineForBlitting(
- *fShaderPipeline,
- fMatrixTypeMask,
- fFilterQuality, fSrcPixmap,
- fAlpha, state->fMode, dstInfo, fAllocator)))
- {
- state->fStorage[0] = fBlitterPipeline;
- state->fBlitBW = &LinearPipelineContext::ForwardToPipeline;
-
- return true;
- }
-
- return false;
- }
-
- static void ForwardToPipeline(BlitState* state, int x, int y, const SkPixmap& dst, int count) {
- SkLinearBitmapPipeline* pipeline = static_cast<SkLinearBitmapPipeline*>(state->fStorage[0]);
- void* addr = dst.writable_addr32(x, y);
- pipeline->blitSpan(x, y, addr, count);
- }
-
-private:
- // Store the allocator from the context creation incase we are asked to build a blitter.
- SkArenaAlloc* fAllocator;
- SkLinearBitmapPipeline* fShaderPipeline;
- SkLinearBitmapPipeline* fBlitterPipeline;
- SkXfermode::D32Proc fSrcModeProc;
- SkPixmap fSrcPixmap;
- float fAlpha;
- SkMatrix::TypeMask fMatrixTypeMask;
- SkFilterQuality fFilterQuality;
-
- typedef BitmapProcInfoContext INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-static bool choose_linear_pipeline(const SkShaderBase::ContextRec& rec, const SkImageInfo& srcInfo) {
- // If we get here, we can reasonably use either context, respect the caller's preference
- //
- bool needsPremul = srcInfo.alphaType() == kUnpremul_SkAlphaType;
- bool needsSwizzle = srcInfo.bytesPerPixel() == 4 && srcInfo.colorType() != kN32_SkColorType;
- return SkShaderBase::ContextRec::kPM4f_DstType == rec.fPreferredDstType
- || needsPremul || needsSwizzle;
-}
-
-size_t SkBitmapProcLegacyShader::ContextSize(const ContextRec& rec, const SkImageInfo& srcInfo) {
- size_t size0 = sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState);
- size_t size1 = sizeof(LinearPipelineContext) + sizeof(SkBitmapProcInfo);
- size_t s = SkTMax(size0, size1);
- return s;
-}
-
-SkShaderBase::Context* SkBitmapProcLegacyShader::MakeContext(
- const SkShaderBase& shader, TileMode tmx, TileMode tmy,
- const SkBitmapProvider& provider, const ContextRec& rec, SkArenaAlloc* alloc)
-{
- SkMatrix totalInverse;
- // Do this first, so we know the matrix can be inverted.
- if (!shader.computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, &totalInverse)) {
- return nullptr;
- }
-
- // Decide if we can/want to use the new linear pipeline
- bool useLinearPipeline = choose_linear_pipeline(rec, provider.info());
-
- if (useLinearPipeline) {
- SkBitmapProcInfo* info = alloc->make<SkBitmapProcInfo>(provider, tmx, tmy);
- if (!info->init(totalInverse, *rec.fPaint)) {
- return nullptr;
- }
-
- return alloc->make<LinearPipelineContext>(shader, rec, info, alloc);
- } else {
- SkBitmapProcState* state = alloc->make<SkBitmapProcState>(provider, tmx, tmy);
- if (!state->setup(totalInverse, *rec.fPaint)) {
- return nullptr;
- }
- return alloc->make<BitmapProcShaderContext>(shader, rec, state);
- }
-}
diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h
deleted file mode 100644
index 2a2599cb1d..0000000000
--- a/src/core/SkBitmapProcShader.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#ifndef SkBitmapProcShader_DEFINED
-#define SkBitmapProcShader_DEFINED
-
-#include "SkImagePriv.h"
-#include "SkShaderBase.h"
-
-class SkBitmapProvider;
-
-class SkBitmapProcLegacyShader : public SkShaderBase {
-private:
- friend class SkImageShader;
-
- static size_t ContextSize(const ContextRec&, const SkImageInfo& srcInfo);
- static Context* MakeContext(const SkShaderBase&, TileMode tmx, TileMode tmy,
- const SkBitmapProvider&, const ContextRec&, SkArenaAlloc* alloc);
-
- typedef SkShaderBase INHERITED;
-};
-
-#endif
diff --git a/src/core/SkColorFilterShader.cpp b/src/core/SkColorFilterShader.cpp
deleted file mode 100644
index 4798422dfa..0000000000
--- a/src/core/SkColorFilterShader.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkArenaAlloc.h"
-#include "SkColorFilterShader.h"
-#include "SkColorSpaceXformer.h"
-#include "SkReadBuffer.h"
-#include "SkWriteBuffer.h"
-#include "SkShader.h"
-#include "SkString.h"
-
-#if SK_SUPPORT_GPU
-#include "GrFragmentProcessor.h"
-#endif
-
-SkColorFilterShader::SkColorFilterShader(sk_sp<SkShader> shader, sk_sp<SkColorFilter> filter)
- : fShader(std::move(shader))
- , fFilter(std::move(filter))
-{
- SkASSERT(fShader);
- SkASSERT(fFilter);
-}
-
-sk_sp<SkFlattenable> SkColorFilterShader::CreateProc(SkReadBuffer& buffer) {
- auto shader = buffer.readShader();
- auto filter = buffer.readColorFilter();
- if (!shader || !filter) {
- return nullptr;
- }
- return sk_make_sp<SkColorFilterShader>(shader, filter);
-}
-
-void SkColorFilterShader::flatten(SkWriteBuffer& buffer) const {
- buffer.writeFlattenable(fShader.get());
- buffer.writeFlattenable(fFilter.get());
-}
-
-uint32_t SkColorFilterShader::FilterShaderContext::getFlags() const {
- const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader);
-
- uint32_t shaderF = fShaderContext->getFlags();
- uint32_t filterF = filterShader.fFilter->getFlags();
-
- // If the filter does not support a given feature, but sure to clear the corresponding flag
- // in the shader flags.
- //
- if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) {
- shaderF &= ~kOpaqueAlpha_Flag;
- }
- return shaderF;
-}
-
-SkShaderBase::Context* SkColorFilterShader::onMakeContext(const ContextRec& rec,
- SkArenaAlloc* alloc) const {
- auto* shaderContext = as_SB(fShader)->makeContext(rec, alloc);
- if (nullptr == shaderContext) {
- return nullptr;
- }
- return alloc->make<FilterShaderContext>(*this, shaderContext, rec);
-}
-
-sk_sp<SkShader> SkColorFilterShader::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
- return xformer->apply(fShader.get())->makeWithColorFilter(xformer->apply(fFilter.get()));
-}
-
-SkColorFilterShader::FilterShaderContext::FilterShaderContext(
- const SkColorFilterShader& filterShader,
- SkShaderBase::Context* shaderContext,
- const ContextRec& rec)
- : INHERITED(filterShader, rec)
- , fShaderContext(shaderContext)
-{}
-
-void SkColorFilterShader::FilterShaderContext::shadeSpan(int x, int y, SkPMColor result[],
- int count) {
- const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader);
-
- fShaderContext->shadeSpan(x, y, result, count);
- filterShader.fFilter->filterSpan(result, count, result);
-}
-
-void SkColorFilterShader::FilterShaderContext::shadeSpan4f(int x, int y, SkPM4f result[],
- int count) {
- const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader);
-
- fShaderContext->shadeSpan4f(x, y, result, count);
- filterShader.fFilter->filterSpan4f(result, count, result);
-}
-
-#if SK_SUPPORT_GPU
-/////////////////////////////////////////////////////////////////////
-
-sk_sp<GrFragmentProcessor> SkColorFilterShader::asFragmentProcessor(const AsFPArgs& args) const {
-
- sk_sp<GrFragmentProcessor> fp1(as_SB(fShader)->asFragmentProcessor(args));
- if (!fp1) {
- return nullptr;
- }
-
- sk_sp<GrFragmentProcessor> fp2(fFilter->asFragmentProcessor(args.fContext,
- args.fDstColorSpace));
- if (!fp2) {
- return fp1;
- }
-
- sk_sp<GrFragmentProcessor> fpSeries[] = { std::move(fp1), std::move(fp2) };
- return GrFragmentProcessor::RunInSeries(fpSeries, 2);
-}
-#endif
-
-#ifndef SK_IGNORE_TO_STRING
-void SkColorFilterShader::toString(SkString* str) const {
- str->append("SkColorFilterShader: (");
-
- str->append("Shader: ");
- as_SB(fShader)->toString(str);
- str->append(" Filter: ");
- // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added
-
- this->INHERITED::toString(str);
-
- str->append(")");
-}
-#endif
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-sk_sp<SkShader> SkShader::makeWithColorFilter(sk_sp<SkColorFilter> filter) const {
- SkShader* base = const_cast<SkShader*>(this);
- if (!filter) {
- return sk_ref_sp(base);
- }
- return sk_make_sp<SkColorFilterShader>(sk_ref_sp(base), filter);
-}
diff --git a/src/core/SkColorFilterShader.h b/src/core/SkColorFilterShader.h
deleted file mode 100644
index 7f4202158a..0000000000
--- a/src/core/SkColorFilterShader.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkColorFilterShader_DEFINED
-#define SkColorFilterShader_DEFINED
-
-#include "SkColorFilter.h"
-#include "SkShaderBase.h"
-
-class SkArenaAlloc;
-
-class SkColorFilterShader : public SkShaderBase {
-public:
- SkColorFilterShader(sk_sp<SkShader> shader, sk_sp<SkColorFilter> filter);
-
-#if SK_SUPPORT_GPU
- sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
-#endif
-
- class FilterShaderContext : public Context {
- public:
- // Takes ownership of shaderContext and calls its destructor.
- FilterShaderContext(const SkColorFilterShader&, SkShaderBase::Context*, const ContextRec&);
-
- uint32_t getFlags() const override;
-
- void shadeSpan(int x, int y, SkPMColor[], int count) override;
- void shadeSpan4f(int x, int y, SkPM4f[], int count) override;
-
- void set3DMask(const SkMask* mask) override {
- // forward to our proxy
- fShaderContext->set3DMask(mask);
- }
-
- private:
- SkShaderBase::Context* fShaderContext;
-
- typedef Context INHERITED;
- };
-
- SK_TO_STRING_OVERRIDE()
- SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorFilterShader)
-
-protected:
- void flatten(SkWriteBuffer&) const override;
- Context* onMakeContext(const ContextRec&, SkArenaAlloc* alloc) const override;
- sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
-
-private:
- sk_sp<SkShader> fShader;
- sk_sp<SkColorFilter> fFilter;
-
- typedef SkShaderBase INHERITED;
-};
-
-#endif
diff --git a/src/core/SkColorShader.cpp b/src/core/SkColorShader.cpp
deleted file mode 100644
index 32b2c54d71..0000000000
--- a/src/core/SkColorShader.cpp
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkArenaAlloc.h"
-#include "SkColorShader.h"
-#include "SkColorSpace.h"
-#include "SkPM4fPriv.h"
-#include "SkRasterPipeline.h"
-#include "SkReadBuffer.h"
-#include "SkUtils.h"
-
-SkColorShader::SkColorShader(SkColor c) : fColor(c) {}
-
-bool SkColorShader::isOpaque() const {
- return SkColorGetA(fColor) == 255;
-}
-
-sk_sp<SkFlattenable> SkColorShader::CreateProc(SkReadBuffer& buffer) {
- return sk_make_sp<SkColorShader>(buffer.readColor());
-}
-
-void SkColorShader::flatten(SkWriteBuffer& buffer) const {
- buffer.writeColor(fColor);
-}
-
-uint32_t SkColorShader::ColorShaderContext::getFlags() const {
- return fFlags;
-}
-
-SkShaderBase::Context* SkColorShader::onMakeContext(const ContextRec& rec,
- SkArenaAlloc* alloc) const {
- return alloc->make<ColorShaderContext>(*this, rec);
-}
-
-SkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shader,
- const ContextRec& rec)
- : INHERITED(shader, rec)
-{
- SkColor color = shader.fColor;
- unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(rec.fPaint->getAlpha()));
-
- unsigned r = SkColorGetR(color);
- unsigned g = SkColorGetG(color);
- unsigned b = SkColorGetB(color);
-
- if (a != 255) {
- r = SkMulDiv255Round(r, a);
- g = SkMulDiv255Round(g, a);
- b = SkMulDiv255Round(b, a);
- }
- fPMColor = SkPackARGB32(a, r, g, b);
-
- SkColor4f c4 = SkColor4f::FromColor(shader.fColor);
- c4.fA *= rec.fPaint->getAlpha() / 255.0f;
- fPM4f = c4.premul();
-
- fFlags = kConstInY32_Flag;
- if (255 == a) {
- fFlags |= kOpaqueAlpha_Flag;
- }
-}
-
-void SkColorShader::ColorShaderContext::shadeSpan(int x, int y, SkPMColor span[], int count) {
- sk_memset32(span, fPMColor, count);
-}
-
-void SkColorShader::ColorShaderContext::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
- memset(alpha, SkGetPackedA32(fPMColor), count);
-}
-
-void SkColorShader::ColorShaderContext::shadeSpan4f(int x, int y, SkPM4f span[], int count) {
- for (int i = 0; i < count; ++i) {
- span[i] = fPM4f;
- }
-}
-
-SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const {
- if (info) {
- if (info->fColors && info->fColorCount >= 1) {
- info->fColors[0] = fColor;
- }
- info->fColorCount = 1;
- info->fTileMode = SkShader::kRepeat_TileMode;
- }
- return kColor_GradientType;
-}
-
-#if SK_SUPPORT_GPU
-
-#include "SkGr.h"
-#include "effects/GrConstColorProcessor.h"
-sk_sp<GrFragmentProcessor> SkColorShader::asFragmentProcessor(const AsFPArgs& args) const {
- GrColor4f color = SkColorToPremulGrColor4f(fColor, args.fDstColorSpace);
- return GrConstColorProcessor::Make(color, GrConstColorProcessor::kModulateA_InputMode);
-}
-
-#endif
-
-#ifndef SK_IGNORE_TO_STRING
-void SkColorShader::toString(SkString* str) const {
- str->append("SkColorShader: (");
-
- str->append("Color: ");
- str->appendHex(fColor);
-
- this->INHERITED::toString(str);
-
- str->append(")");
-}
-#endif
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-static unsigned unit_to_byte(float unit) {
- SkASSERT(unit >= 0 && unit <= 1);
- return (unsigned)(unit * 255 + 0.5);
-}
-
-static SkColor unit_to_skcolor(const SkColor4f& unit, SkColorSpace* cs) {
- return SkColorSetARGB(unit_to_byte(unit.fA), unit_to_byte(unit.fR),
- unit_to_byte(unit.fG), unit_to_byte(unit.fB));
-}
-
-SkColor4Shader::SkColor4Shader(const SkColor4f& color, sk_sp<SkColorSpace> space)
- : fColorSpace(std::move(space))
- , fColor4(color)
- , fCachedByteColor(unit_to_skcolor(color.pin(), space.get()))
-{}
-
-sk_sp<SkFlattenable> SkColor4Shader::CreateProc(SkReadBuffer& buffer) {
- SkColor4f color;
- buffer.readColor4f(&color);
- if (buffer.readBool()) {
- // TODO how do we unflatten colorspaces
- }
- return SkShader::MakeColorShader(color, nullptr);
-}
-
-void SkColor4Shader::flatten(SkWriteBuffer& buffer) const {
- buffer.writeColor4f(fColor4);
- buffer.writeBool(false); // TODO how do we flatten colorspaces?
-}
-
-uint32_t SkColor4Shader::Color4Context::getFlags() const {
- return fFlags;
-}
-
-SkShaderBase::Context* SkColor4Shader::onMakeContext(const ContextRec& rec,
- SkArenaAlloc* alloc) const {
- return alloc->make<Color4Context>(*this, rec);
-}
-
-SkColor4Shader::Color4Context::Color4Context(const SkColor4Shader& shader,
- const ContextRec& rec)
-: INHERITED(shader, rec)
-{
- SkColor color = shader.fCachedByteColor;
- unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(rec.fPaint->getAlpha()));
-
- unsigned r = SkColorGetR(color);
- unsigned g = SkColorGetG(color);
- unsigned b = SkColorGetB(color);
-
- if (a != 255) {
- r = SkMulDiv255Round(r, a);
- g = SkMulDiv255Round(g, a);
- b = SkMulDiv255Round(b, a);
- }
- fPMColor = SkPackARGB32(a, r, g, b);
-
- SkColor4f c4 = shader.fColor4;
- c4.fA *= rec.fPaint->getAlpha() * (1 / 255.0f);
- fPM4f = c4.premul();
-
- fFlags = kConstInY32_Flag;
- if (255 == a) {
- fFlags |= kOpaqueAlpha_Flag;
- }
-}
-
-void SkColor4Shader::Color4Context::shadeSpan(int x, int y, SkPMColor span[], int count) {
- sk_memset32(span, fPMColor, count);
-}
-
-void SkColor4Shader::Color4Context::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
- memset(alpha, SkGetPackedA32(fPMColor), count);
-}
-
-void SkColor4Shader::Color4Context::shadeSpan4f(int x, int y, SkPM4f span[], int count) {
- for (int i = 0; i < count; ++i) {
- span[i] = fPM4f;
- }
-}
-
-// TODO: do we need an updated version of this method for color4+colorspace?
-SkShader::GradientType SkColor4Shader::asAGradient(GradientInfo* info) const {
- if (info) {
- if (info->fColors && info->fColorCount >= 1) {
- info->fColors[0] = fCachedByteColor;
- }
- info->fColorCount = 1;
- info->fTileMode = SkShader::kRepeat_TileMode;
- }
- return kColor_GradientType;
-}
-
-#if SK_SUPPORT_GPU
-
-#include "SkGr.h"
-#include "effects/GrConstColorProcessor.h"
-#include "GrColorSpaceXform.h"
-sk_sp<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor(const AsFPArgs& args) const {
- sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(fColorSpace.get(),
- args.fDstColorSpace);
- GrColor4f color = GrColor4f::FromSkColor4f(fColor4);
- if (colorSpaceXform) {
- color = colorSpaceXform->apply(color);
- }
- return GrConstColorProcessor::Make(color.premul(), GrConstColorProcessor::kModulateA_InputMode);
-}
-
-#endif
-
-#ifndef SK_IGNORE_TO_STRING
-void SkColor4Shader::toString(SkString* str) const {
- str->append("SkColor4Shader: (");
-
- str->append("RGBA:");
- for (int i = 0; i < 4; ++i) {
- str->appendf(" %g", fColor4.vec()[i]);
- }
- str->append(" )");
-}
-#endif
-
-sk_sp<SkShader> SkColor4Shader::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
- return SkShader::MakeColorShader(xformer->apply(fCachedByteColor));
-}
-
-sk_sp<SkShader> SkShader::MakeColorShader(const SkColor4f& color, sk_sp<SkColorSpace> space) {
- if (!SkScalarsAreFinite(color.vec(), 4)) {
- return nullptr;
- }
- return sk_make_sp<SkColor4Shader>(color, std::move(space));
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-static void D32_BlitBW(SkShaderBase::Context::BlitState* state, int x, int y, const SkPixmap& dst,
- int count) {
- SkXfermode::D32Proc proc = (SkXfermode::D32Proc)state->fStorage[0];
- const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
- proc(state->fMode, dst.writable_addr32(x, y), src, count, nullptr);
-}
-
-static void D32_BlitAA(SkShaderBase::Context::BlitState* state, int x, int y, const SkPixmap& dst,
- int count, const SkAlpha aa[]) {
- SkXfermode::D32Proc proc = (SkXfermode::D32Proc)state->fStorage[0];
- const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
- proc(state->fMode, dst.writable_addr32(x, y), src, count, aa);
-}
-
-static void F16_BlitBW(SkShaderBase::Context::BlitState* state, int x, int y, const SkPixmap& dst,
- int count) {
- SkXfermode::F16Proc proc = (SkXfermode::F16Proc)state->fStorage[0];
- const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
- proc(state->fMode, dst.writable_addr64(x, y), src, count, nullptr);
-}
-
-static void F16_BlitAA(SkShaderBase::Context::BlitState* state, int x, int y, const SkPixmap& dst,
- int count, const SkAlpha aa[]) {
- SkXfermode::F16Proc proc = (SkXfermode::F16Proc)state->fStorage[0];
- const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
- proc(state->fMode, dst.writable_addr64(x, y), src, count, aa);
-}
-
-static bool choose_blitprocs(const SkPM4f* pm4, const SkImageInfo& info,
- SkShaderBase::Context::BlitState* state) {
- uint32_t flags = SkXfermode::kSrcIsSingle_D32Flag;
- if (pm4->a() == 1) {
- flags |= SkXfermode::kSrcIsOpaque_D32Flag;
- }
- switch (info.colorType()) {
- case kN32_SkColorType:
- if (info.gammaCloseToSRGB()) {
- flags |= SkXfermode::kDstIsSRGB_D32Flag;
- }
- state->fStorage[0] = (void*)SkXfermode::GetD32Proc(state->fMode, flags);
- state->fStorage[1] = (void*)pm4;
- state->fBlitBW = D32_BlitBW;
- state->fBlitAA = D32_BlitAA;
- return true;
- case kRGBA_F16_SkColorType:
- state->fStorage[0] = (void*)SkXfermode::GetF16Proc(state->fMode, flags);
- state->fStorage[1] = (void*)pm4;
- state->fBlitBW = F16_BlitBW;
- state->fBlitAA = F16_BlitAA;
- return true;
- default:
- return false;
- }
-}
-
-bool SkColorShader::ColorShaderContext::onChooseBlitProcs(const SkImageInfo& info,
- BlitState* state) {
- return choose_blitprocs(&fPM4f, info, state);
-}
-
-bool SkColor4Shader::Color4Context::onChooseBlitProcs(const SkImageInfo& info, BlitState* state) {
- return choose_blitprocs(&fPM4f, info, state);
-}
-
-bool SkColorShader::onAppendStages(SkRasterPipeline* p,
- SkColorSpace* dst,
- SkArenaAlloc* scratch,
- const SkMatrix&,
- const SkPaint&,
- const SkMatrix*) const {
- auto color = scratch->make<SkPM4f>(SkPM4f_from_SkColor(fColor, dst));
- p->append(SkRasterPipeline::constant_color, color);
- return true;
-}
-
-bool SkColor4Shader::onAppendStages(SkRasterPipeline* p,
- SkColorSpace* dst,
- SkArenaAlloc* scratch,
- const SkMatrix&,
- const SkPaint&,
- const SkMatrix*) const {
- auto color = scratch->make<SkPM4f>(to_colorspace(fColor4, fColorSpace.get(), dst).premul());
- p->append(SkRasterPipeline::constant_color, color);
- return true;
-}
diff --git a/src/core/SkColorShader.h b/src/core/SkColorShader.h
deleted file mode 100644
index 9af83c1163..0000000000
--- a/src/core/SkColorShader.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2007 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkColorShader_DEFINED
-#define SkColorShader_DEFINED
-
-#include "SkColorSpaceXformer.h"
-#include "SkShaderBase.h"
-#include "SkPM4f.h"
-
-/** \class SkColorShader
- A Shader that represents a single color. In general, this effect can be
- accomplished by just using the color field on the paint, but if an
- actual shader object is needed, this provides that feature.
-*/
-class SK_API SkColorShader : public SkShaderBase {
-public:
- /** Create a ColorShader that ignores the color in the paint, and uses the
- specified color. Note: like all shaders, at draw time the paint's alpha
- will be respected, and is applied to the specified color.
- */
- explicit SkColorShader(SkColor c);
-
- bool isOpaque() const override;
- bool isConstant() const override { return true; }
-
- class ColorShaderContext : public Context {
- public:
- ColorShaderContext(const SkColorShader& shader, const ContextRec&);
-
- uint32_t getFlags() const override;
- void shadeSpan(int x, int y, SkPMColor span[], int count) override;
- void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) override;
- void shadeSpan4f(int x, int y, SkPM4f[], int count) override;
-
- protected:
- bool onChooseBlitProcs(const SkImageInfo&, BlitState*) override;
-
- private:
- SkPM4f fPM4f;
- SkPMColor fPMColor;
- uint32_t fFlags;
-
- typedef Context INHERITED;
- };
-
- GradientType asAGradient(GradientInfo* info) const override;
-
-#if SK_SUPPORT_GPU
- sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
-#endif
-
- SK_TO_STRING_OVERRIDE()
- SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorShader)
-
-protected:
- SkColorShader(SkReadBuffer&);
- void flatten(SkWriteBuffer&) const override;
- Context* onMakeContext(const ContextRec&, SkArenaAlloc* storage) const override;
-
- bool onAsLuminanceColor(SkColor* lum) const override {
- *lum = fColor;
- return true;
- }
-
- bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
- const SkMatrix& ctm, const SkPaint&, const SkMatrix*) const override;
-
- sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override {
- return SkShader::MakeColorShader(xformer->apply(fColor));
- }
-
-private:
- SkColor fColor;
-
- typedef SkShaderBase INHERITED;
-};
-
-class SkColor4Shader : public SkShaderBase {
-public:
- SkColor4Shader(const SkColor4f&, sk_sp<SkColorSpace>);
-
- bool isOpaque() const override {
- return SkColorGetA(fCachedByteColor) == 255;
- }
- bool isConstant() const override { return true; }
-
- class Color4Context : public Context {
- public:
- Color4Context(const SkColor4Shader& shader, const ContextRec&);
-
- uint32_t getFlags() const override;
- void shadeSpan(int x, int y, SkPMColor span[], int count) override;
- void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) override;
- void shadeSpan4f(int x, int y, SkPM4f[], int count) override;
-
- protected:
- bool onChooseBlitProcs(const SkImageInfo&, BlitState*) override;
-
- private:
- SkPM4f fPM4f;
- SkPMColor fPMColor;
- uint32_t fFlags;
-
- typedef Context INHERITED;
- };
-
- GradientType asAGradient(GradientInfo* info) const override;
-
-#if SK_SUPPORT_GPU
- sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
-#endif
-
- SK_TO_STRING_OVERRIDE()
- SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorShader)
-
-protected:
- SkColor4Shader(SkReadBuffer&);
- void flatten(SkWriteBuffer&) const override;
- Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
- bool onAsLuminanceColor(SkColor* lum) const override {
- *lum = fCachedByteColor;
- return true;
- }
- bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
- const SkMatrix& ctm, const SkPaint&, const SkMatrix*) const override;
-
- sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
-
-private:
- sk_sp<SkColorSpace> fColorSpace;
- const SkColor4f fColor4;
- const SkColor fCachedByteColor;
-
- typedef SkShaderBase INHERITED;
-};
-
-#endif
diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp
deleted file mode 100644
index 7735494291..0000000000
--- a/src/core/SkComposeShader.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkArenaAlloc.h"
-#include "SkBlendModePriv.h"
-#include "SkComposeShader.h"
-#include "SkColorFilter.h"
-#include "SkColorPriv.h"
-#include "SkColorShader.h"
-#include "SkRasterPipeline.h"
-#include "SkReadBuffer.h"
-#include "SkWriteBuffer.h"
-#include "SkString.h"
-#include "../jumper/SkJumper.h"
-
-sk_sp<SkShader> SkShader::MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader> src,
- SkBlendMode mode) {
- if (!src || !dst) {
- return nullptr;
- }
- if (SkBlendMode::kSrc == mode) {
- return src;
- }
- if (SkBlendMode::kDst == mode) {
- return dst;
- }
- return sk_sp<SkShader>(new SkComposeShader(std::move(dst), std::move(src), mode));
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-class SkAutoAlphaRestore {
-public:
- SkAutoAlphaRestore(SkPaint* paint, uint8_t newAlpha) {
- fAlpha = paint->getAlpha();
- fPaint = paint;
- paint->setAlpha(newAlpha);
- }
-
- ~SkAutoAlphaRestore() {
- fPaint->setAlpha(fAlpha);
- }
-private:
- SkPaint* fPaint;
- uint8_t fAlpha;
-};
-#define SkAutoAlphaRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoAlphaRestore)
-
-sk_sp<SkFlattenable> SkComposeShader::CreateProc(SkReadBuffer& buffer) {
- sk_sp<SkShader> shaderA(buffer.readShader());
- sk_sp<SkShader> shaderB(buffer.readShader());
- SkBlendMode mode;
- if (buffer.isVersionLT(SkReadBuffer::kXfermodeToBlendMode2_Version)) {
- sk_sp<SkXfermode> xfer = buffer.readXfermode();
- mode = xfer ? xfer->blend() : SkBlendMode::kSrcOver;
- } else {
- mode = (SkBlendMode)buffer.read32();
- }
- if (!shaderA || !shaderB) {
- return nullptr;
- }
- return sk_make_sp<SkComposeShader>(std::move(shaderA), std::move(shaderB), mode);
-}
-
-void SkComposeShader::flatten(SkWriteBuffer& buffer) const {
- buffer.writeFlattenable(fShaderA.get());
- buffer.writeFlattenable(fShaderB.get());
- buffer.write32((int)fMode);
-}
-
-SkShaderBase::Context* SkComposeShader::onMakeContext(
- const ContextRec& rec, SkArenaAlloc* alloc) const
-{
- // we preconcat our localMatrix (if any) with the device matrix
- // before calling our sub-shaders
- SkMatrix tmpM;
- tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix());
-
- // Our sub-shaders need to see opaque, so by combining them we don't double-alphatize the
- // result. ComposeShader itself will respect the alpha, and post-apply it after calling the
- // sub-shaders.
- SkPaint opaquePaint(*rec.fPaint);
- opaquePaint.setAlpha(0xFF);
-
- ContextRec newRec(rec);
- newRec.fMatrix = &tmpM;
- newRec.fPaint = &opaquePaint;
-
- SkShaderBase::Context* contextA = as_SB(fShaderA)->makeContext(newRec, alloc);
- SkShaderBase::Context* contextB = as_SB(fShaderB)->makeContext(newRec, alloc);
- if (!contextA || !contextB) {
- return nullptr;
- }
-
- return alloc->make<ComposeShaderContext>(*this, rec, contextA, contextB);
-}
-
-sk_sp<SkShader> SkComposeShader::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
- return SkShader::MakeComposeShader(xformer->apply(fShaderA.get()),
- xformer->apply(fShaderB.get()), fMode);
-}
-
-SkComposeShader::ComposeShaderContext::ComposeShaderContext(
- const SkComposeShader& shader, const ContextRec& rec,
- SkShaderBase::Context* contextA, SkShaderBase::Context* contextB)
- : INHERITED(shader, rec)
- , fShaderContextA(contextA)
- , fShaderContextB(contextB) {}
-
-bool SkComposeShader::asACompose(ComposeRec* rec) const {
- if (rec) {
- rec->fShaderA = fShaderA.get();
- rec->fShaderB = fShaderB.get();
- rec->fBlendMode = fMode;
- }
- return true;
-}
-
-bool SkComposeShader::isRasterPipelineOnly() const {
- return as_SB(fShaderA)->isRasterPipelineOnly() || as_SB(fShaderB)->isRasterPipelineOnly();
-}
-
-bool SkComposeShader::onAppendStages(SkRasterPipeline* pipeline, SkColorSpace* dstCS,
- SkArenaAlloc* alloc, const SkMatrix& ctm,
- const SkPaint& paint, const SkMatrix* localM) const {
- struct Storage {
- float fXY[4 * SkJumper_kMaxStride];
- float fRGBA[4 * SkJumper_kMaxStride];
- float fAlpha;
- };
- auto storage = alloc->make<Storage>();
-
- // We need to save off device x,y (inputs to shader), since after calling fShaderA they
- // will be smashed, and I'll need them again for fShaderB. store_rgba saves off 4 registers
- // even though we only need to save r,g.
- pipeline->append(SkRasterPipeline::store_rgba, storage->fXY);
- if (!as_SB(fShaderB)->appendStages(pipeline, dstCS, alloc, ctm, paint, localM)) { // SRC
- return false;
- }
- // This outputs r,g,b,a, which we'll need later when we apply the mode, but we save it off now
- // since fShaderB will overwrite them.
- pipeline->append(SkRasterPipeline::store_rgba, storage->fRGBA);
- // Now we restore the device x,y for the next shader
- pipeline->append(SkRasterPipeline::load_rgba, storage->fXY);
- if (!as_SB(fShaderA)->appendStages(pipeline, dstCS, alloc, ctm, paint, localM)) { // DST
- return false;
- }
- // We now have our logical 'dst' in r,g,b,a, but we need it in dr,dg,db,da for the mode
- // so we have to shuttle them. If we had a stage the would load_into_dst, then we could
- // reverse the two shader invocations, and avoid this move...
- pipeline->append(SkRasterPipeline::move_src_dst);
- pipeline->append(SkRasterPipeline::load_rgba, storage->fRGBA);
-
- // Idea: should time this, and see if it helps to have custom versions of the overflow modes
- // that do their own clamping, avoiding the overhead of an extra stage.
- SkBlendMode_AppendStages(fMode, pipeline);
- if (SkBlendMode_CanOverflow(fMode)) {
- pipeline->append(SkRasterPipeline::clamp_a);
- }
- return true;
-}
-
-// larger is better (fewer times we have to loop), but we shouldn't
-// take up too much stack-space (each element is 4 bytes)
-#define TMP_COLOR_COUNT 64
-
-void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor result[], int count) {
- auto* shaderContextA = fShaderContextA;
- auto* shaderContextB = fShaderContextB;
- SkBlendMode mode = static_cast<const SkComposeShader&>(fShader).fMode;
- unsigned scale = SkAlpha255To256(this->getPaintAlpha());
-
- SkPMColor tmp[TMP_COLOR_COUNT];
-
- SkXfermode* xfer = SkXfermode::Peek(mode);
- if (nullptr == xfer) { // implied SRC_OVER
- // TODO: when we have a good test-case, should use SkBlitRow::Proc32
- // for these loops
- do {
- int n = count;
- if (n > TMP_COLOR_COUNT) {
- n = TMP_COLOR_COUNT;
- }
-
- shaderContextA->shadeSpan(x, y, result, n);
- shaderContextB->shadeSpan(x, y, tmp, n);
-
- if (256 == scale) {
- for (int i = 0; i < n; i++) {
- result[i] = SkPMSrcOver(tmp[i], result[i]);
- }
- } else {
- for (int i = 0; i < n; i++) {
- result[i] = SkAlphaMulQ(SkPMSrcOver(tmp[i], result[i]),
- scale);
- }
- }
-
- result += n;
- x += n;
- count -= n;
- } while (count > 0);
- } else { // use mode for the composition
- do {
- int n = count;
- if (n > TMP_COLOR_COUNT) {
- n = TMP_COLOR_COUNT;
- }
-
- shaderContextA->shadeSpan(x, y, result, n);
- shaderContextB->shadeSpan(x, y, tmp, n);
- xfer->xfer32(result, tmp, n, nullptr);
-
- if (256 != scale) {
- for (int i = 0; i < n; i++) {
- result[i] = SkAlphaMulQ(result[i], scale);
- }
- }
-
- result += n;
- x += n;
- count -= n;
- } while (count > 0);
- }
-}
-
-void SkComposeShader::ComposeShaderContext::shadeSpan4f(int x, int y, SkPM4f result[], int count) {
- auto* shaderContextA = fShaderContextA;
- auto* shaderContextB = fShaderContextB;
- SkBlendMode mode = static_cast<const SkComposeShader&>(fShader).fMode;
- unsigned alpha = this->getPaintAlpha();
- Sk4f scale(alpha * (1.0f / 255));
-
- SkPM4f tmp[TMP_COLOR_COUNT];
-
- SkXfermodeProc4f xfer = SkXfermode::GetProc4f(mode);
- do {
- int n = SkTMin(count, TMP_COLOR_COUNT);
-
- shaderContextA->shadeSpan4f(x, y, result, n);
- shaderContextB->shadeSpan4f(x, y, tmp, n);
- if (255 == alpha) {
- for (int i = 0; i < n; ++i) {
- result[i] = xfer(tmp[i], result[i]);
- }
- } else {
- for (int i = 0; i < n; ++i) {
- (xfer(tmp[i], result[i]).to4f() * scale).store(result + i);
- }
- }
- result += n;
- x += n;
- count -= n;
- } while (count > 0);
-}
-
-#if SK_SUPPORT_GPU
-
-#include "effects/GrConstColorProcessor.h"
-#include "effects/GrXfermodeFragmentProcessor.h"
-
-/////////////////////////////////////////////////////////////////////
-
-sk_sp<GrFragmentProcessor> SkComposeShader::asFragmentProcessor(const AsFPArgs& args) const {
- switch (fMode) {
- case SkBlendMode::kClear:
- return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(),
- GrConstColorProcessor::kIgnore_InputMode);
- break;
- case SkBlendMode::kSrc:
- return as_SB(fShaderB)->asFragmentProcessor(args);
- break;
- case SkBlendMode::kDst:
- return as_SB(fShaderA)->asFragmentProcessor(args);
- break;
- default:
- sk_sp<GrFragmentProcessor> fpA(as_SB(fShaderA)->asFragmentProcessor(args));
- if (!fpA) {
- return nullptr;
- }
- sk_sp<GrFragmentProcessor> fpB(as_SB(fShaderB)->asFragmentProcessor(args));
- if (!fpB) {
- return nullptr;
- }
- return GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(fpB),
- std::move(fpA), fMode);
- }
-}
-#endif
-
-#ifndef SK_IGNORE_TO_STRING
-void SkComposeShader::toString(SkString* str) const {
- str->append("SkComposeShader: (");
-
- str->append("ShaderA: ");
- as_SB(fShaderA)->toString(str);
- str->append(" ShaderB: ");
- as_SB(fShaderB)->toString(str);
- if (SkBlendMode::kSrcOver != fMode) {
- str->appendf(" Xfermode: %s", SkXfermode::ModeName(fMode));
- }
-
- this->INHERITED::toString(str);
-
- str->append(")");
-}
-#endif
diff --git a/src/core/SkComposeShader.h b/src/core/SkComposeShader.h
deleted file mode 100644
index 8592f3a8ae..0000000000
--- a/src/core/SkComposeShader.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkComposeShader_DEFINED
-#define SkComposeShader_DEFINED
-
-#include "SkShaderBase.h"
-#include "SkBlendMode.h"
-
-class SkColorSpacXformer;
-
-///////////////////////////////////////////////////////////////////////////////////////////
-
-/** \class SkComposeShader
- This subclass of shader returns the composition of two other shaders, combined by
- a xfermode.
-*/
-class SK_API SkComposeShader : public SkShaderBase {
-public:
- /** Create a new compose shader, given shaders A, B, and a combining xfermode mode.
- When the xfermode is called, it will be given the result from shader A as its
- "dst", and the result from shader B as its "src".
- mode->xfer32(sA_result, sB_result, ...)
- @param shaderA The colors from this shader are seen as the "dst" by the xfermode
- @param shaderB The colors from this shader are seen as the "src" by the xfermode
- @param mode The xfermode that combines the colors from the two shaders. If mode
- is null, then SRC_OVER is assumed.
- */
- SkComposeShader(sk_sp<SkShader> sA, sk_sp<SkShader> sB, SkBlendMode mode)
- : fShaderA(std::move(sA))
- , fShaderB(std::move(sB))
- , fMode(mode)
- {}
-
-#if SK_SUPPORT_GPU
- sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
-#endif
-
- class ComposeShaderContext : public Context {
- public:
- // When this object gets destroyed, it will call contextA and contextB's destructor
- // but it will NOT free the memory.
- ComposeShaderContext(const SkComposeShader&, const ContextRec&,
- SkShaderBase::Context* contextA, SkShaderBase::Context* contextB);
-
- void shadeSpan(int x, int y, SkPMColor[], int count) override;
- void shadeSpan4f(int x, int y, SkPM4f[], int count) override;
-
- private:
- SkShaderBase::Context* fShaderContextA;
- SkShaderBase::Context* fShaderContextB;
-
- typedef Context INHERITED;
- };
-
-#ifdef SK_DEBUG
- SkShader* getShaderA() { return fShaderA.get(); }
- SkShader* getShaderB() { return fShaderB.get(); }
-#endif
-
- bool asACompose(ComposeRec* rec) const override;
-
- SK_TO_STRING_OVERRIDE()
- SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeShader)
-
-protected:
- SkComposeShader(SkReadBuffer&);
- void flatten(SkWriteBuffer&) const override;
- Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
- sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
- bool onAppendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*,
- const SkMatrix&, const SkPaint&, const SkMatrix* localM) const override;
-
- bool isRasterPipelineOnly() const final;
-
-private:
- sk_sp<SkShader> fShaderA;
- sk_sp<SkShader> fShaderB;
- SkBlendMode fMode;
-
- typedef SkShaderBase INHERITED;
-};
-
-#endif
diff --git a/src/core/SkEmptyShader.h b/src/core/SkEmptyShader.h
deleted file mode 100644
index c1bcfe0957..0000000000
--- a/src/core/SkEmptyShader.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkEmptyShader_DEFINED
-#define SkEmptyShader_DEFINED
-
-#include "SkShaderBase.h"
-
-// TODO: move this to private, as there is a public factory on SkShader
-
-/**
- * \class SkEmptyShader
- * A Shader that always draws nothing. Its createContext always returns nullptr.
- */
-class SK_API SkEmptyShader : public SkShaderBase {
-public:
- SkEmptyShader() {}
-
- SK_TO_STRING_OVERRIDE()
- SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmptyShader)
-
-protected:
- Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override {
- return nullptr;
- }
-
- void flatten(SkWriteBuffer& buffer) const override {
- // Do nothing.
- // We just don't want to fall through to SkShader::flatten(),
- // which will write data we don't care to serialize or decode.
- }
-
-private:
- typedef SkShaderBase INHERITED;
-};
-
-#endif
diff --git a/src/core/SkLightingShader.cpp b/src/core/SkLightingShader.cpp
deleted file mode 100644
index cdfa528e1e..0000000000
--- a/src/core/SkLightingShader.cpp
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkArenaAlloc.h"
-#include "SkBitmapProcShader.h"
-#include "SkBitmapProcState.h"
-#include "SkColor.h"
-#include "SkColorSpaceXformer.h"
-#include "SkEmptyShader.h"
-#include "SkLightingShader.h"
-#include "SkMathPriv.h"
-#include "SkNormalSource.h"
-#include "SkPoint3.h"
-#include "SkReadBuffer.h"
-#include "SkShaderBase.h"
-#include "SkWriteBuffer.h"
-
-////////////////////////////////////////////////////////////////////////////
-
-/*
- SkLightingShader TODOs:
- support different light types
- support multiple lights
- fix non-opaque diffuse textures
-
- To Test:
- A8 diffuse textures
- down & upsampled draws
-*/
-
-
-
-/** \class SkLightingShaderImpl
- This subclass of shader applies lighting.
-*/
-class SkLightingShaderImpl : public SkShaderBase {
-public:
- /** Create a new lighting shader that uses the provided normal map and
- lights to light the diffuse bitmap.
- @param diffuseShader the shader that provides the diffuse colors
- @param normalSource the source of normals for lighting computation
- @param lights the lights applied to the geometry
- */
- SkLightingShaderImpl(sk_sp<SkShader> diffuseShader,
- sk_sp<SkNormalSource> normalSource,
- sk_sp<SkLights> lights)
- : fDiffuseShader(std::move(diffuseShader))
- , fNormalSource(std::move(normalSource))
- , fLights(std::move(lights)) {}
-
- bool isOpaque() const override;
-
-#if SK_SUPPORT_GPU
- sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
-#endif
-
- class LightingShaderContext : public Context {
- public:
- // The context takes ownership of the context and provider. It will call their destructors
- // and then indirectly free their memory by calling free() on heapAllocated
- LightingShaderContext(const SkLightingShaderImpl&, const ContextRec&,
- SkShaderBase::Context* diffuseContext, SkNormalSource::Provider*,
- void* heapAllocated);
-
- void shadeSpan(int x, int y, SkPMColor[], int count) override;
-
- uint32_t getFlags() const override { return fFlags; }
-
- private:
- SkShaderBase::Context* fDiffuseContext;
- SkNormalSource::Provider* fNormalProvider;
- SkColor fPaintColor;
- uint32_t fFlags;
-
- typedef Context INHERITED;
- };
-
- SK_TO_STRING_OVERRIDE()
- SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingShaderImpl)
-
-protected:
- void flatten(SkWriteBuffer&) const override;
- Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
- sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
-
-private:
- sk_sp<SkShader> fDiffuseShader;
- sk_sp<SkNormalSource> fNormalSource;
- sk_sp<SkLights> fLights;
-
- friend class SkLightingShader;
-
- typedef SkShaderBase INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////
-
-#if SK_SUPPORT_GPU
-
-#include "GrCoordTransform.h"
-#include "GrFragmentProcessor.h"
-#include "glsl/GrGLSLFragmentProcessor.h"
-#include "glsl/GrGLSLFragmentShaderBuilder.h"
-#include "glsl/GrGLSLProgramDataManager.h"
-#include "glsl/GrGLSLUniformHandler.h"
-#include "SkGr.h"
-
-// This FP expects a premul'd color input for its diffuse color. Premul'ing of the paint's color is
-// handled by the asFragmentProcessor() factory, but shaders providing diffuse color must output it
-// premul'd.
-class LightingFP : public GrFragmentProcessor {
-public:
- LightingFP(sk_sp<GrFragmentProcessor> normalFP, sk_sp<SkLights> lights)
- : INHERITED(kPreservesOpaqueInput_OptimizationFlag) {
- // fuse all ambient lights into a single one
- fAmbientColor = lights->ambientLightColor();
- for (int i = 0; i < lights->numLights(); ++i) {
- if (SkLights::Light::kDirectional_LightType == lights->light(i).type()) {
- fDirectionalLights.push_back(lights->light(i));
- // TODO get the handle to the shadow map if there is one
- } else {
- SkDEBUGFAIL("Unimplemented Light Type passed to LightingFP");
- }
- }
-
- this->registerChildProcessor(std::move(normalFP));
- this->initClassID<LightingFP>();
- }
-
- class GLSLLightingFP : public GrGLSLFragmentProcessor {
- public:
- GLSLLightingFP() {
- fAmbientColor.fX = 0.0f;
- }
-
- void emitCode(EmitArgs& args) override {
-
- GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
- GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
- const LightingFP& lightingFP = args.fFp.cast<LightingFP>();
-
- const char *lightDirsUniName = nullptr;
- const char *lightColorsUniName = nullptr;
- if (lightingFP.fDirectionalLights.count() != 0) {
- fLightDirsUni = uniformHandler->addUniformArray(
- kFragment_GrShaderFlag,
- kVec3f_GrSLType,
- kDefault_GrSLPrecision,
- "LightDir",
- lightingFP.fDirectionalLights.count(),
- &lightDirsUniName);
- fLightColorsUni = uniformHandler->addUniformArray(
- kFragment_GrShaderFlag,
- kVec3f_GrSLType,
- kDefault_GrSLPrecision,
- "LightColor",
- lightingFP.fDirectionalLights.count(),
- &lightColorsUniName);
- }
-
- const char* ambientColorUniName = nullptr;
- fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
- kVec3f_GrSLType, kDefault_GrSLPrecision,
- "AmbientColor", &ambientColorUniName);
-
- fragBuilder->codeAppendf("vec4 diffuseColor = %s;", args.fInputColor);
-
- SkString dstNormalName("dstNormal");
- this->emitChild(0, &dstNormalName, args);
-
- fragBuilder->codeAppendf("vec3 normal = %s.xyz;", dstNormalName.c_str());
-
- fragBuilder->codeAppend( "vec3 result = vec3(0.0);");
-
- // diffuse light
- if (lightingFP.fDirectionalLights.count() != 0) {
- fragBuilder->codeAppendf("for (int i = 0; i < %d; i++) {",
- lightingFP.fDirectionalLights.count());
- // TODO: modulate the contribution from each light based on the shadow map
- fragBuilder->codeAppendf(" float NdotL = clamp(dot(normal, %s[i]), 0.0, 1.0);",
- lightDirsUniName);
- fragBuilder->codeAppendf(" result += %s[i]*diffuseColor.rgb*NdotL;",
- lightColorsUniName);
- fragBuilder->codeAppend("}");
- }
-
- // ambient light
- fragBuilder->codeAppendf("result += %s * diffuseColor.rgb;", ambientColorUniName);
-
- // Clamping to alpha (equivalent to an unpremul'd clamp to 1.0)
- fragBuilder->codeAppendf("%s = vec4(clamp(result.rgb, 0.0, diffuseColor.a), "
- "diffuseColor.a);", args.fOutputColor);
- }
-
- static void GenKey(const GrProcessor& proc, const GrShaderCaps&, GrProcessorKeyBuilder* b) {
- const LightingFP& lightingFP = proc.cast<LightingFP>();
- b->add32(lightingFP.fDirectionalLights.count());
- }
-
- protected:
- void onSetData(const GrGLSLProgramDataManager& pdman,
- const GrFragmentProcessor& proc) override {
- const LightingFP& lightingFP = proc.cast<LightingFP>();
-
- const SkTArray<SkLights::Light>& directionalLights = lightingFP.directionalLights();
- if (directionalLights != fDirectionalLights) {
- SkTArray<SkColor3f> lightDirs(directionalLights.count());
- SkTArray<SkVector3> lightColors(directionalLights.count());
- for (const SkLights::Light& light : directionalLights) {
- lightDirs.push_back(light.dir());
- lightColors.push_back(light.color());
- }
-
- pdman.set3fv(fLightDirsUni, directionalLights.count(), &(lightDirs[0].fX));
- pdman.set3fv(fLightColorsUni, directionalLights.count(), &(lightColors[0].fX));
-
- fDirectionalLights = directionalLights;
- }
-
- const SkColor3f& ambientColor = lightingFP.ambientColor();
- if (ambientColor != fAmbientColor) {
- pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX);
- fAmbientColor = ambientColor;
- }
- }
-
- private:
- SkTArray<SkLights::Light> fDirectionalLights;
- GrGLSLProgramDataManager::UniformHandle fLightDirsUni;
- GrGLSLProgramDataManager::UniformHandle fLightColorsUni;
-
- SkColor3f fAmbientColor;
- GrGLSLProgramDataManager::UniformHandle fAmbientColorUni;
- };
-
- void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
- GLSLLightingFP::GenKey(*this, caps, b);
- }
-
- const char* name() const override { return "LightingFP"; }
-
- const SkTArray<SkLights::Light>& directionalLights() const { return fDirectionalLights; }
- const SkColor3f& ambientColor() const { return fAmbientColor; }
-
-private:
- GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLLightingFP; }
-
- bool onIsEqual(const GrFragmentProcessor& proc) const override {
- const LightingFP& lightingFP = proc.cast<LightingFP>();
- return fDirectionalLights == lightingFP.fDirectionalLights &&
- fAmbientColor == lightingFP.fAmbientColor;
- }
-
- SkTArray<SkLights::Light> fDirectionalLights;
- SkColor3f fAmbientColor;
-
- typedef GrFragmentProcessor INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////
-
-sk_sp<GrFragmentProcessor> SkLightingShaderImpl::asFragmentProcessor(const AsFPArgs& args) const {
- sk_sp<GrFragmentProcessor> normalFP(fNormalSource->asFragmentProcessor(args));
- if (!normalFP) {
- return nullptr;
- }
-
- if (fDiffuseShader) {
- sk_sp<GrFragmentProcessor> fpPipeline[] = {
- as_SB(fDiffuseShader)->asFragmentProcessor(args),
- sk_make_sp<LightingFP>(std::move(normalFP), fLights)
- };
- if(!fpPipeline[0]) {
- return nullptr;
- }
-
- sk_sp<GrFragmentProcessor> innerLightFP = GrFragmentProcessor::RunInSeries(fpPipeline, 2);
- // FP is wrapped because paint's alpha needs to be applied to output
- return GrFragmentProcessor::MulOutputByInputAlpha(std::move(innerLightFP));
- } else {
- // FP is wrapped because paint comes in unpremul'd to fragment shader, but LightingFP
- // expects premul'd color.
- return GrFragmentProcessor::PremulInput(sk_make_sp<LightingFP>(std::move(normalFP),
- fLights));
- }
-}
-
-#endif
-
-////////////////////////////////////////////////////////////////////////////
-
-bool SkLightingShaderImpl::isOpaque() const {
- return (fDiffuseShader ? fDiffuseShader->isOpaque() : false);
-}
-
-SkLightingShaderImpl::LightingShaderContext::LightingShaderContext(
- const SkLightingShaderImpl& shader, const ContextRec& rec,
- SkShaderBase::Context* diffuseContext, SkNormalSource::Provider* normalProvider,
- void* heapAllocated)
- : INHERITED(shader, rec)
- , fDiffuseContext(diffuseContext)
- , fNormalProvider(normalProvider) {
- bool isOpaque = shader.isOpaque();
-
- // update fFlags
- uint32_t flags = 0;
- if (isOpaque && (255 == this->getPaintAlpha())) {
- flags |= kOpaqueAlpha_Flag;
- }
-
- fPaintColor = rec.fPaint->getColor();
- fFlags = flags;
-}
-
-static inline SkPMColor convert(SkColor3f color, U8CPU a) {
- if (color.fX <= 0.0f) {
- color.fX = 0.0f;
- } else if (color.fX >= 255.0f) {
- color.fX = 255.0f;
- }
-
- if (color.fY <= 0.0f) {
- color.fY = 0.0f;
- } else if (color.fY >= 255.0f) {
- color.fY = 255.0f;
- }
-
- if (color.fZ <= 0.0f) {
- color.fZ = 0.0f;
- } else if (color.fZ >= 255.0f) {
- color.fZ = 255.0f;
- }
-
- return SkPreMultiplyARGB(a, (int) color.fX, (int) color.fY, (int) color.fZ);
-}
-
-// larger is better (fewer times we have to loop), but we shouldn't
-// take up too much stack-space (each one here costs 16 bytes)
-#define BUFFER_MAX 16
-void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y,
- SkPMColor result[], int count) {
- const SkLightingShaderImpl& lightShader = static_cast<const SkLightingShaderImpl&>(fShader);
-
- SkPMColor diffuse[BUFFER_MAX];
- SkPoint3 normals[BUFFER_MAX];
-
- SkColor diffColor = fPaintColor;
-
- do {
- int n = SkTMin(count, BUFFER_MAX);
-
- fNormalProvider->fillScanLine(x, y, normals, n);
-
- if (fDiffuseContext) {
- fDiffuseContext->shadeSpan(x, y, diffuse, n);
- }
-
- for (int i = 0; i < n; ++i) {
- if (fDiffuseContext) {
- diffColor = SkUnPreMultiply::PMColorToColor(diffuse[i]);
- }
-
- SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f);
-
- // Adding ambient light
- accum.fX += lightShader.fLights->ambientLightColor().fX * SkColorGetR(diffColor);
- accum.fY += lightShader.fLights->ambientLightColor().fY * SkColorGetG(diffColor);
- accum.fZ += lightShader.fLights->ambientLightColor().fZ * SkColorGetB(diffColor);
-
- // This is all done in linear unpremul color space (each component 0..255.0f though)
- for (int l = 0; l < lightShader.fLights->numLights(); ++l) {
- const SkLights::Light& light = lightShader.fLights->light(l);
-
- SkScalar illuminanceScalingFactor = 1.0f;
-
- if (SkLights::Light::kDirectional_LightType == light.type()) {
- illuminanceScalingFactor = normals[i].dot(light.dir());
- if (illuminanceScalingFactor < 0.0f) {
- illuminanceScalingFactor = 0.0f;
- }
- }
-
- accum.fX += light.color().fX * SkColorGetR(diffColor) * illuminanceScalingFactor;
- accum.fY += light.color().fY * SkColorGetG(diffColor) * illuminanceScalingFactor;
- accum.fZ += light.color().fZ * SkColorGetB(diffColor) * illuminanceScalingFactor;
- }
-
- // convert() premultiplies the accumulate color with alpha
- result[i] = convert(accum, SkColorGetA(diffColor));
- }
-
- result += n;
- x += n;
- count -= n;
- } while (count > 0);
-}
-
-////////////////////////////////////////////////////////////////////////////
-
-#ifndef SK_IGNORE_TO_STRING
-void SkLightingShaderImpl::toString(SkString* str) const {
- str->appendf("LightingShader: ()");
-}
-#endif
-
-sk_sp<SkFlattenable> SkLightingShaderImpl::CreateProc(SkReadBuffer& buf) {
-
- // Discarding SkShader flattenable params
- bool hasLocalMatrix = buf.readBool();
- SkAssertResult(!hasLocalMatrix);
-
- sk_sp<SkLights> lights = SkLights::MakeFromBuffer(buf);
-
- sk_sp<SkNormalSource> normalSource(buf.readFlattenable<SkNormalSource>());
-
- bool hasDiffuse = buf.readBool();
- sk_sp<SkShader> diffuseShader = nullptr;
- if (hasDiffuse) {
- diffuseShader = buf.readFlattenable<SkShaderBase>();
- }
-
- return sk_make_sp<SkLightingShaderImpl>(std::move(diffuseShader), std::move(normalSource),
- std::move(lights));
-}
-
-void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const {
- this->INHERITED::flatten(buf);
-
- fLights->flatten(buf);
-
- buf.writeFlattenable(fNormalSource.get());
- buf.writeBool(fDiffuseShader);
- if (fDiffuseShader) {
- buf.writeFlattenable(fDiffuseShader.get());
- }
-}
-
-SkShaderBase::Context* SkLightingShaderImpl::onMakeContext(
- const ContextRec& rec, SkArenaAlloc* alloc) const
-{
- SkShaderBase::Context *diffuseContext = nullptr;
- if (fDiffuseShader) {
- diffuseContext = as_SB(fDiffuseShader)->makeContext(rec, alloc);
- if (!diffuseContext) {
- return nullptr;
- }
- }
-
- SkNormalSource::Provider* normalProvider = fNormalSource->asProvider(rec, alloc);
- if (!normalProvider) {
- return nullptr;
- }
-
- return alloc->make<LightingShaderContext>(*this, rec, diffuseContext, normalProvider, nullptr);
-}
-
-sk_sp<SkShader> SkLightingShaderImpl::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
- sk_sp<SkShader> xformedDiffuseShader =
- fDiffuseShader ? xformer->apply(fDiffuseShader.get()) : nullptr;
- return SkLightingShader::Make(std::move(xformedDiffuseShader), fNormalSource,
- fLights->makeColorSpace(xformer));
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-sk_sp<SkShader> SkLightingShader::Make(sk_sp<SkShader> diffuseShader,
- sk_sp<SkNormalSource> normalSource,
- sk_sp<SkLights> lights) {
- SkASSERT(lights);
- if (!normalSource) {
- normalSource = SkNormalSource::MakeFlat();
- }
-
- return sk_make_sp<SkLightingShaderImpl>(std::move(diffuseShader), std::move(normalSource),
- std::move(lights));
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader)
- SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl)
-SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
-
-///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkLightingShader.h b/src/core/SkLightingShader.h
deleted file mode 100644
index aa90710aa4..0000000000
--- a/src/core/SkLightingShader.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkLightingShader_DEFINED
-#define SkLightingShader_DEFINED
-
-#include "SkLights.h"
-#include "SkShader.h"
-
-class SkBitmap;
-class SkMatrix;
-class SkNormalSource;
-
-class SK_API SkLightingShader {
-public:
- /** Returns a shader that lights the shape, colored by the diffuseShader, using the
- normals from normalSource, with the set of lights provided.
-
- @param diffuseShader the shader that provides the colors. If nullptr, uses the paint's
- color.
- @param normalSource the source for the shape's normals. If nullptr, assumes straight
- up normals (<0,0,1>).
- @param lights the lights applied to the normals
-
- The lighting equation is currently:
- result = (LightColor * dot(Normal, LightDir) + AmbientColor) * DiffuseColor
-
- */
- static sk_sp<SkShader> Make(sk_sp<SkShader> diffuseShader, sk_sp<SkNormalSource> normalSource,
- sk_sp<SkLights> lights);
-
- SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
-};
-
-#endif
diff --git a/src/core/SkLocalMatrixShader.cpp b/src/core/SkLocalMatrixShader.cpp
deleted file mode 100644
index e21e4a84b7..0000000000
--- a/src/core/SkLocalMatrixShader.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkLocalMatrixShader.h"
-
-#if SK_SUPPORT_GPU
-#include "GrFragmentProcessor.h"
-#endif
-
-#if SK_SUPPORT_GPU
-sk_sp<GrFragmentProcessor> SkLocalMatrixShader::asFragmentProcessor(const AsFPArgs& args) const {
- SkMatrix tmp = this->getLocalMatrix();
- if (args.fLocalMatrix) {
- tmp.preConcat(*args.fLocalMatrix);
- }
- return as_SB(fProxyShader)->asFragmentProcessor(AsFPArgs(
- args.fContext, args.fViewMatrix, &tmp, args.fFilterQuality, args.fDstColorSpace));
-}
-#endif
-
-sk_sp<SkFlattenable> SkLocalMatrixShader::CreateProc(SkReadBuffer& buffer) {
- SkMatrix lm;
- buffer.readMatrix(&lm);
- auto baseShader(buffer.readShader());
- if (!baseShader) {
- return nullptr;
- }
- return baseShader->makeWithLocalMatrix(lm);
-}
-
-void SkLocalMatrixShader::flatten(SkWriteBuffer& buffer) const {
- buffer.writeMatrix(this->getLocalMatrix());
- buffer.writeFlattenable(fProxyShader.get());
-}
-
-SkShaderBase::Context* SkLocalMatrixShader::onMakeContext(
- const ContextRec& rec, SkArenaAlloc* alloc) const
-{
- ContextRec newRec(rec);
- SkMatrix tmp;
- if (rec.fLocalMatrix) {
- tmp.setConcat(*rec.fLocalMatrix, this->getLocalMatrix());
- newRec.fLocalMatrix = &tmp;
- } else {
- newRec.fLocalMatrix = &this->getLocalMatrix();
- }
- return as_SB(fProxyShader)->makeContext(newRec, alloc);
-}
-
-SkImage* SkLocalMatrixShader::onIsAImage(SkMatrix* outMatrix, enum TileMode* mode) const {
- SkMatrix imageMatrix;
- SkImage* image = fProxyShader->isAImage(&imageMatrix, mode);
- if (image && outMatrix) {
- // Local matrix must be applied first so it is on the right side of the concat.
- *outMatrix = SkMatrix::Concat(imageMatrix, this->getLocalMatrix());
- }
-
- return image;
-}
-
-bool SkLocalMatrixShader::onAppendStages(SkRasterPipeline* p,
- SkColorSpace* dst,
- SkArenaAlloc* scratch,
- const SkMatrix& ctm,
- const SkPaint& paint,
- const SkMatrix* localM) const {
- SkMatrix tmp;
- if (localM) {
- tmp.setConcat(*localM, this->getLocalMatrix());
- }
- return as_SB(fProxyShader)->appendStages(p, dst, scratch, ctm, paint,
- localM ? &tmp : &this->getLocalMatrix());
-}
-
-#ifndef SK_IGNORE_TO_STRING
-void SkLocalMatrixShader::toString(SkString* str) const {
- str->append("SkLocalMatrixShader: (");
-
- as_SB(fProxyShader)->toString(str);
-
- this->INHERITED::toString(str);
-
- str->append(")");
-}
-#endif
-
-sk_sp<SkShader> SkShader::makeWithLocalMatrix(const SkMatrix& localMatrix) const {
- if (localMatrix.isIdentity()) {
- return sk_ref_sp(const_cast<SkShader*>(this));
- }
-
- const SkMatrix* lm = &localMatrix;
-
- sk_sp<SkShader> baseShader;
- SkMatrix otherLocalMatrix;
- sk_sp<SkShader> proxy(as_SB(this)->makeAsALocalMatrixShader(&otherLocalMatrix));
- if (proxy) {
- otherLocalMatrix.preConcat(localMatrix);
- lm = &otherLocalMatrix;
- baseShader = proxy;
- } else {
- baseShader = sk_ref_sp(const_cast<SkShader*>(this));
- }
-
- return sk_make_sp<SkLocalMatrixShader>(std::move(baseShader), *lm);
-}
diff --git a/src/core/SkLocalMatrixShader.h b/src/core/SkLocalMatrixShader.h
deleted file mode 100644
index 4572e9fe2e..0000000000
--- a/src/core/SkLocalMatrixShader.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkLocalMatrixShader_DEFINED
-#define SkLocalMatrixShader_DEFINED
-
-#include "SkShaderBase.h"
-#include "SkReadBuffer.h"
-#include "SkWriteBuffer.h"
-
-class GrFragmentProcessor;
-class SkArenaAlloc;
-class SkColorSpaceXformer;
-
-class SkLocalMatrixShader : public SkShaderBase {
-public:
- SkLocalMatrixShader(sk_sp<SkShader> proxy, const SkMatrix& localMatrix)
- : INHERITED(&localMatrix)
- , fProxyShader(std::move(proxy))
- {}
-
- GradientType asAGradient(GradientInfo* info) const override {
- return fProxyShader->asAGradient(info);
- }
-
-#if SK_SUPPORT_GPU
- sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
-#endif
-
- sk_sp<SkShader> makeAsALocalMatrixShader(SkMatrix* localMatrix) const override {
- if (localMatrix) {
- *localMatrix = this->getLocalMatrix();
- }
- return fProxyShader;
- }
-
- SK_TO_STRING_OVERRIDE()
- SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLocalMatrixShader)
-
-protected:
- void flatten(SkWriteBuffer&) const override;
-
- Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
-
- SkImage* onIsAImage(SkMatrix* matrix, TileMode* mode) const override;
-
- bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
- const SkMatrix&, const SkPaint&, const SkMatrix*) const override;
-
- sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override {
- return as_SB(fProxyShader)->makeColorSpace(xformer)->makeWithLocalMatrix(
- this->getLocalMatrix());
- }
-
-#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
- bool onIsABitmap(SkBitmap* bitmap, SkMatrix* matrix, TileMode* mode) const override {
- return fProxyShader->isABitmap(bitmap, matrix, mode);
- }
-#endif
-
- bool isRasterPipelineOnly() const final {
- return as_SB(fProxyShader)->isRasterPipelineOnly();
- }
-
-private:
- sk_sp<SkShader> fProxyShader;
-
- typedef SkShaderBase INHERITED;
-};
-
-#endif
diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp
deleted file mode 100644
index d6ee941251..0000000000
--- a/src/core/SkPictureShader.cpp
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkPictureShader.h"
-
-#include "SkArenaAlloc.h"
-#include "SkBitmap.h"
-#include "SkBitmapProcShader.h"
-#include "SkCanvas.h"
-#include "SkColorSpaceXformCanvas.h"
-#include "SkImage.h"
-#include "SkImageShader.h"
-#include "SkMatrixUtils.h"
-#include "SkPicture.h"
-#include "SkPictureImageGenerator.h"
-#include "SkReadBuffer.h"
-#include "SkResourceCache.h"
-
-#if SK_SUPPORT_GPU
-#include "GrContext.h"
-#include "GrCaps.h"
-#include "GrFragmentProcessor.h"
-#endif
-
-namespace {
-static unsigned gBitmapSkaderKeyNamespaceLabel;
-
-struct BitmapShaderKey : public SkResourceCache::Key {
-public:
- BitmapShaderKey(sk_sp<SkColorSpace> colorSpace,
- uint32_t pictureID,
- const SkRect& tile,
- SkShader::TileMode tmx,
- SkShader::TileMode tmy,
- const SkSize& scale,
- const SkMatrix& localMatrix,
- SkTransferFunctionBehavior blendBehavior)
- : fColorSpace(std::move(colorSpace))
- , fPictureID(pictureID)
- , fTile(tile)
- , fTmx(tmx)
- , fTmy(tmy)
- , fScale(scale)
- , fBlendBehavior(blendBehavior) {
-
- for (int i = 0; i < 9; ++i) {
- fLocalMatrixStorage[i] = localMatrix[i];
- }
-
- static const size_t keySize = sizeof(fColorSpace) +
- sizeof(fPictureID) +
- sizeof(fTile) +
- sizeof(fTmx) + sizeof(fTmy) +
- sizeof(fScale) +
- sizeof(fLocalMatrixStorage) +
- sizeof(fBlendBehavior);
- // This better be packed.
- SkASSERT(sizeof(uint32_t) * (&fEndOfStruct - (uint32_t*)&fColorSpace) == keySize);
- this->init(&gBitmapSkaderKeyNamespaceLabel, 0, keySize);
- }
-
-private:
- sk_sp<SkColorSpace> fColorSpace;
- uint32_t fPictureID;
- SkRect fTile;
- SkShader::TileMode fTmx, fTmy;
- SkSize fScale;
- SkScalar fLocalMatrixStorage[9];
- SkTransferFunctionBehavior fBlendBehavior;
-
- SkDEBUGCODE(uint32_t fEndOfStruct;)
-};
-
-struct BitmapShaderRec : public SkResourceCache::Rec {
- BitmapShaderRec(const BitmapShaderKey& key, SkShader* tileShader)
- : fKey(key)
- , fShader(SkRef(tileShader)) {}
-
- BitmapShaderKey fKey;
- sk_sp<SkShader> fShader;
- size_t fBitmapBytes;
-
- const Key& getKey() const override { return fKey; }
- size_t bytesUsed() const override {
- // Just the record overhead -- the actual pixels are accounted by SkImageCacherator.
- return sizeof(fKey) + sizeof(SkImageShader);
- }
- const char* getCategory() const override { return "bitmap-shader"; }
- SkDiscardableMemory* diagnostic_only_getDiscardable() const override { return nullptr; }
-
- static bool Visitor(const SkResourceCache::Rec& baseRec, void* contextShader) {
- const BitmapShaderRec& rec = static_cast<const BitmapShaderRec&>(baseRec);
- sk_sp<SkShader>* result = reinterpret_cast<sk_sp<SkShader>*>(contextShader);
-
- *result = rec.fShader;
-
- // The bitmap shader is backed by an image generator, thus it can always re-generate its
- // pixels if discarded.
- return true;
- }
-};
-
-} // namespace
-
-SkPictureShader::SkPictureShader(sk_sp<SkPicture> picture, TileMode tmx, TileMode tmy,
- const SkMatrix* localMatrix, const SkRect* tile,
- sk_sp<SkColorSpace> colorSpace)
- : INHERITED(localMatrix)
- , fPicture(std::move(picture))
- , fTile(tile ? *tile : fPicture->cullRect())
- , fTmx(tmx)
- , fTmy(tmy)
- , fColorSpace(std::move(colorSpace))
-{}
-
-sk_sp<SkShader> SkPictureShader::Make(sk_sp<SkPicture> picture, TileMode tmx, TileMode tmy,
- const SkMatrix* localMatrix, const SkRect* tile) {
- if (!picture || picture->cullRect().isEmpty() || (tile && tile->isEmpty())) {
- return SkShader::MakeEmptyShader();
- }
- return sk_sp<SkShader>(new SkPictureShader(std::move(picture), tmx, tmy, localMatrix, tile,
- nullptr));
-}
-
-sk_sp<SkFlattenable> SkPictureShader::CreateProc(SkReadBuffer& buffer) {
- SkMatrix lm;
- buffer.readMatrix(&lm);
- TileMode mx = (TileMode)buffer.read32();
- TileMode my = (TileMode)buffer.read32();
- SkRect tile;
- buffer.readRect(&tile);
-
- sk_sp<SkPicture> picture;
-
- if (buffer.isCrossProcess() && SkPicture::PictureIOSecurityPrecautionsEnabled()) {
- if (buffer.isVersionLT(SkReadBuffer::kPictureShaderHasPictureBool_Version)) {
- // Older code blindly serialized pictures. We don't trust them.
- buffer.validate(false);
- return nullptr;
- }
- // Newer code won't serialize pictures in disallow-cross-process-picture mode.
- // Assert that they didn't serialize anything except a false here.
- buffer.validate(!buffer.readBool());
- } else {
- // Old code always serialized the picture. New code writes a 'true' first if it did.
- if (buffer.isVersionLT(SkReadBuffer::kPictureShaderHasPictureBool_Version) ||
- buffer.readBool()) {
- picture = SkPicture::MakeFromBuffer(buffer);
- }
- }
- return SkPictureShader::Make(picture, mx, my, &lm, &tile);
-}
-
-void SkPictureShader::flatten(SkWriteBuffer& buffer) const {
- buffer.writeMatrix(this->getLocalMatrix());
- buffer.write32(fTmx);
- buffer.write32(fTmy);
- buffer.writeRect(fTile);
-
- // The deserialization code won't trust that our serialized picture is safe to deserialize.
- // So write a 'false' telling it that we're not serializing a picture.
- if (buffer.isCrossProcess() && SkPicture::PictureIOSecurityPrecautionsEnabled()) {
- buffer.writeBool(false);
- } else {
- buffer.writeBool(true);
- fPicture->flatten(buffer);
- }
-}
-
-sk_sp<SkShader> SkPictureShader::refBitmapShader(const SkMatrix& viewMatrix, const SkMatrix* localM,
- SkColorSpace* dstColorSpace,
- const int maxTextureSize) const {
- SkASSERT(fPicture && !fPicture->cullRect().isEmpty());
-
- SkMatrix m;
- m.setConcat(viewMatrix, this->getLocalMatrix());
- if (localM) {
- m.preConcat(*localM);
- }
-
- // Use a rotation-invariant scale
- SkPoint scale;
- //
- // TODO: replace this with decomposeScale() -- but beware LayoutTest rebaselines!
- //
- if (!SkDecomposeUpper2x2(m, nullptr, &scale, nullptr)) {
- // Decomposition failed, use an approximation.
- scale.set(SkScalarSqrt(m.getScaleX() * m.getScaleX() + m.getSkewX() * m.getSkewX()),
- SkScalarSqrt(m.getScaleY() * m.getScaleY() + m.getSkewY() * m.getSkewY()));
- }
- SkSize scaledSize = SkSize::Make(SkScalarAbs(scale.x() * fTile.width()),
- SkScalarAbs(scale.y() * fTile.height()));
-
- // Clamp the tile size to about 4M pixels
- static const SkScalar kMaxTileArea = 2048 * 2048;
- SkScalar tileArea = scaledSize.width() * scaledSize.height();
- if (tileArea > kMaxTileArea) {
- SkScalar clampScale = SkScalarSqrt(kMaxTileArea / tileArea);
- scaledSize.set(scaledSize.width() * clampScale,
- scaledSize.height() * clampScale);
- }
-#if SK_SUPPORT_GPU
- // Scale down the tile size if larger than maxTextureSize for GPU Path or it should fail on create texture
- if (maxTextureSize) {
- if (scaledSize.width() > maxTextureSize || scaledSize.height() > maxTextureSize) {
- SkScalar downScale = maxTextureSize / SkMaxScalar(scaledSize.width(), scaledSize.height());
- scaledSize.set(SkScalarFloorToScalar(scaledSize.width() * downScale),
- SkScalarFloorToScalar(scaledSize.height() * downScale));
- }
- }
-#endif
-
-#ifdef SK_SUPPORT_LEGACY_PICTURESHADER_ROUNDING
- const SkISize tileSize = scaledSize.toRound();
-#else
- const SkISize tileSize = scaledSize.toCeil();
-#endif
- if (tileSize.isEmpty()) {
- return SkShader::MakeEmptyShader();
- }
-
- // The actual scale, compensating for rounding & clamping.
- const SkSize tileScale = SkSize::Make(SkIntToScalar(tileSize.width()) / fTile.width(),
- SkIntToScalar(tileSize.height()) / fTile.height());
-
- // |fColorSpace| will only be set when using an SkColorSpaceXformCanvas to do pre-draw xforms.
- // This canvas is strictly for legacy mode. A non-null |dstColorSpace| indicates that we
- // should perform color correct rendering and xform at draw time.
- SkASSERT(!fColorSpace || !dstColorSpace);
- sk_sp<SkColorSpace> keyCS = dstColorSpace ? sk_ref_sp(dstColorSpace) : fColorSpace;
- SkTransferFunctionBehavior blendBehavior = dstColorSpace ? SkTransferFunctionBehavior::kRespect
- : SkTransferFunctionBehavior::kIgnore;
-
- sk_sp<SkShader> tileShader;
- BitmapShaderKey key(std::move(keyCS),
- fPicture->uniqueID(),
- fTile,
- fTmx,
- fTmy,
- tileScale,
- this->getLocalMatrix(),
- blendBehavior);
-
- if (!SkResourceCache::Find(key, BitmapShaderRec::Visitor, &tileShader)) {
- SkMatrix tileMatrix;
- tileMatrix.setRectToRect(fTile, SkRect::MakeIWH(tileSize.width(), tileSize.height()),
- SkMatrix::kFill_ScaleToFit);
-
- sk_sp<SkImage> tileImage = SkImage::MakeFromGenerator(
- SkPictureImageGenerator::Make(tileSize, fPicture, &tileMatrix, nullptr,
- SkImage::BitDepth::kU8, sk_ref_sp(dstColorSpace)));
- if (!tileImage) {
- return nullptr;
- }
-
- if (fColorSpace) {
- tileImage = tileImage->makeColorSpace(fColorSpace, SkTransferFunctionBehavior::kIgnore);
- }
-
- SkMatrix shaderMatrix = this->getLocalMatrix();
- shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height());
- tileShader = tileImage->makeShader(fTmx, fTmy, &shaderMatrix);
-
- SkResourceCache::Add(new BitmapShaderRec(key, tileShader.get()));
- }
-
- return tileShader;
-}
-
-bool SkPictureShader::onAppendStages(SkRasterPipeline* p, SkColorSpace* cs, SkArenaAlloc* alloc,
- const SkMatrix& ctm, const SkPaint& paint,
- const SkMatrix* localMatrix) const {
- // Keep bitmapShader alive by using alloc instead of stack memory
- auto& bitmapShader = *alloc->make<sk_sp<SkShader>>();
- bitmapShader = this->refBitmapShader(ctm, localMatrix, cs);
- return bitmapShader && as_SB(bitmapShader)->appendStages(p, cs, alloc, ctm, paint);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-SkShaderBase::Context* SkPictureShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc)
-const {
- sk_sp<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix, rec.fLocalMatrix,
- rec.fDstColorSpace));
- if (!bitmapShader) {
- return nullptr;
- }
-
- PictureShaderContext* ctx =
- alloc->make<PictureShaderContext>(*this, rec, std::move(bitmapShader), alloc);
- if (nullptr == ctx->fBitmapShaderContext) {
- ctx = nullptr;
- }
- return ctx;
-}
-
-sk_sp<SkShader> SkPictureShader::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
- return sk_sp<SkPictureShader>(new SkPictureShader(fPicture, fTmx, fTmy, &this->getLocalMatrix(),
- &fTile, xformer->dst()));
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-SkPictureShader::PictureShaderContext::PictureShaderContext(
- const SkPictureShader& shader, const ContextRec& rec, sk_sp<SkShader> bitmapShader,
- SkArenaAlloc* alloc)
- : INHERITED(shader, rec)
- , fBitmapShader(std::move(bitmapShader))
-{
- fBitmapShaderContext = as_SB(fBitmapShader)->makeContext(rec, alloc);
- //if fBitmapShaderContext is null, we are invalid
-}
-
-uint32_t SkPictureShader::PictureShaderContext::getFlags() const {
- SkASSERT(fBitmapShaderContext);
- return fBitmapShaderContext->getFlags();
-}
-
-SkShaderBase::Context::ShadeProc SkPictureShader::PictureShaderContext::asAShadeProc(void** ctx) {
- SkASSERT(fBitmapShaderContext);
- return fBitmapShaderContext->asAShadeProc(ctx);
-}
-
-void SkPictureShader::PictureShaderContext::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
- SkASSERT(fBitmapShaderContext);
- fBitmapShaderContext->shadeSpan(x, y, dstC, count);
-}
-
-#ifndef SK_IGNORE_TO_STRING
-void SkPictureShader::toString(SkString* str) const {
- static const char* gTileModeName[SkShader::kTileModeCount] = {
- "clamp", "repeat", "mirror"
- };
-
- str->appendf("PictureShader: [%f:%f:%f:%f] ",
- fPicture->cullRect().fLeft,
- fPicture->cullRect().fTop,
- fPicture->cullRect().fRight,
- fPicture->cullRect().fBottom);
-
- str->appendf("(%s, %s)", gTileModeName[fTmx], gTileModeName[fTmy]);
-
- this->INHERITED::toString(str);
-}
-#endif
-
-#if SK_SUPPORT_GPU
-sk_sp<GrFragmentProcessor> SkPictureShader::asFragmentProcessor(const AsFPArgs& args) const {
- int maxTextureSize = 0;
- if (args.fContext) {
- maxTextureSize = args.fContext->caps()->maxTextureSize();
- }
- sk_sp<SkShader> bitmapShader(this->refBitmapShader(*args.fViewMatrix, args.fLocalMatrix,
- args.fDstColorSpace, maxTextureSize));
- if (!bitmapShader) {
- return nullptr;
- }
- return as_SB(bitmapShader)->asFragmentProcessor(SkShaderBase::AsFPArgs(
- args.fContext, args.fViewMatrix, nullptr, args.fFilterQuality, args.fDstColorSpace));
-}
-#endif
diff --git a/src/core/SkPictureShader.h b/src/core/SkPictureShader.h
deleted file mode 100644
index f7a509f181..0000000000
--- a/src/core/SkPictureShader.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkPictureShader_DEFINED
-#define SkPictureShader_DEFINED
-
-#include "SkShaderBase.h"
-
-class SkArenaAlloc;
-class SkBitmap;
-class SkPicture;
-
-/*
- * An SkPictureShader can be used to draw SkPicture-based patterns.
- *
- * The SkPicture is first rendered into a tile, which is then used to shade the area according
- * to specified tiling rules.
- */
-class SkPictureShader : public SkShaderBase {
-public:
- static sk_sp<SkShader> Make(sk_sp<SkPicture>, TileMode, TileMode, const SkMatrix*,
- const SkRect*);
-
- SK_TO_STRING_OVERRIDE()
- SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureShader)
-
-#if SK_SUPPORT_GPU
- sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
-#endif
-
-protected:
- SkPictureShader(SkReadBuffer&);
- void flatten(SkWriteBuffer&) const override;
- bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
- const SkMatrix&, const SkPaint&, const SkMatrix*) const override;
- Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
- sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
-
-private:
- SkPictureShader(sk_sp<SkPicture>, TileMode, TileMode, const SkMatrix*, const SkRect*,
- sk_sp<SkColorSpace>);
-
- sk_sp<SkShader> refBitmapShader(const SkMatrix&, const SkMatrix* localMatrix,
- SkColorSpace* dstColorSpace,
- const int maxTextureSize = 0) const;
-
- sk_sp<SkPicture> fPicture;
- SkRect fTile;
- TileMode fTmx, fTmy;
-
- class PictureShaderContext : public Context {
- public:
- PictureShaderContext(
- const SkPictureShader&, const ContextRec&, sk_sp<SkShader> bitmapShader, SkArenaAlloc*);
-
- uint32_t getFlags() const override;
-
- ShadeProc asAShadeProc(void** ctx) override;
- void shadeSpan(int x, int y, SkPMColor dstC[], int count) override;
-
- sk_sp<SkShader> fBitmapShader;
- SkShaderBase::Context* fBitmapShaderContext;
- void* fBitmapShaderContextStorage;
-
- typedef Context INHERITED;
- };
-
- // Should never be set by a public constructor. This is only used when onMakeColorSpace()
- // forces a deferred color space xform.
- sk_sp<SkColorSpace> fColorSpace;
-
- typedef SkShaderBase INHERITED;
-};
-
-#endif // SkPictureShader_DEFINED
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
deleted file mode 100644
index d04fbfe4df..0000000000
--- a/src/core/SkShader.cpp
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkArenaAlloc.h"
-#include "SkAtomics.h"
-#include "SkBitmapProcShader.h"
-#include "SkColorShader.h"
-#include "SkEmptyShader.h"
-#include "SkMallocPixelRef.h"
-#include "SkPaint.h"
-#include "SkPicture.h"
-#include "SkPictureShader.h"
-#include "SkPM4fPriv.h"
-#include "SkRasterPipeline.h"
-#include "SkReadBuffer.h"
-#include "SkScalar.h"
-#include "SkShaderBase.h"
-#include "SkTLazy.h"
-#include "SkWriteBuffer.h"
-#include "../jumper/SkJumper.h"
-
-#if SK_SUPPORT_GPU
-#include "GrFragmentProcessor.h"
-#endif
-
-//#define SK_TRACK_SHADER_LIFETIME
-
-#ifdef SK_TRACK_SHADER_LIFETIME
- static int32_t gShaderCounter;
-#endif
-
-static inline void inc_shader_counter() {
-#ifdef SK_TRACK_SHADER_LIFETIME
- int32_t prev = sk_atomic_inc(&gShaderCounter);
- SkDebugf("+++ shader counter %d\n", prev + 1);
-#endif
-}
-static inline void dec_shader_counter() {
-#ifdef SK_TRACK_SHADER_LIFETIME
- int32_t prev = sk_atomic_dec(&gShaderCounter);
- SkDebugf("--- shader counter %d\n", prev - 1);
-#endif
-}
-
-SkShaderBase::SkShaderBase(const SkMatrix* localMatrix)
- : fLocalMatrix(localMatrix ? *localMatrix : SkMatrix::I()) {
- inc_shader_counter();
- // Pre-cache so future calls to fLocalMatrix.getType() are threadsafe.
- (void)fLocalMatrix.getType();
-}
-
-SkShaderBase::~SkShaderBase() {
- dec_shader_counter();
-}
-
-void SkShaderBase::flatten(SkWriteBuffer& buffer) const {
- this->INHERITED::flatten(buffer);
- bool hasLocalM = !fLocalMatrix.isIdentity();
- buffer.writeBool(hasLocalM);
- if (hasLocalM) {
- buffer.writeMatrix(fLocalMatrix);
- }
-}
-
-bool SkShaderBase::computeTotalInverse(const SkMatrix& ctm,
- const SkMatrix* outerLocalMatrix,
- SkMatrix* totalInverse) const {
- SkMatrix total = SkMatrix::Concat(ctm, fLocalMatrix);
- if (outerLocalMatrix) {
- total.preConcat(*outerLocalMatrix);
- }
-
- return total.invert(totalInverse);
-}
-
-bool SkShaderBase::asLuminanceColor(SkColor* colorPtr) const {
- SkColor storage;
- if (nullptr == colorPtr) {
- colorPtr = &storage;
- }
- if (this->onAsLuminanceColor(colorPtr)) {
- *colorPtr = SkColorSetA(*colorPtr, 0xFF); // we only return opaque
- return true;
- }
- return false;
-}
-
-SkShaderBase::Context* SkShaderBase::makeContext(const ContextRec& rec, SkArenaAlloc* alloc) const {
- if (!this->computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, nullptr)) {
- return nullptr;
- }
- return this->onMakeContext(rec, alloc);
-}
-
-SkShaderBase::Context::Context(const SkShaderBase& shader, const ContextRec& rec)
- : fShader(shader), fCTM(*rec.fMatrix)
-{
- // We should never use a context for RP-only shaders.
- SkASSERT(!shader.isRasterPipelineOnly());
-
- // Because the context parameters must be valid at this point, we know that the matrix is
- // invertible.
- SkAssertResult(fShader.computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, &fTotalInverse));
- fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse);
-
- fPaintAlpha = rec.fPaint->getAlpha();
-}
-
-SkShaderBase::Context::~Context() {}
-
-SkShaderBase::Context::ShadeProc SkShaderBase::Context::asAShadeProc(void** ctx) {
- return nullptr;
-}
-
-void SkShaderBase::Context::shadeSpan4f(int x, int y, SkPM4f dst[], int count) {
- const int N = 128;
- SkPMColor tmp[N];
- while (count > 0) {
- int n = SkTMin(count, N);
- this->shadeSpan(x, y, tmp, n);
- for (int i = 0; i < n; ++i) {
- dst[i] = SkPM4f::FromPMColor(tmp[i]);
- }
- dst += n;
- x += n;
- count -= n;
- }
-}
-
-#include "SkColorPriv.h"
-
-#define kTempColorQuadCount 6 // balance between speed (larger) and saving stack-space
-#define kTempColorCount (kTempColorQuadCount << 2)
-
-#ifdef SK_CPU_BENDIAN
- #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3))
-#else
- #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3)
-#endif
-
-void SkShaderBase::Context::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
- SkASSERT(count > 0);
-
- SkPMColor colors[kTempColorCount];
-
- while ((count -= kTempColorCount) >= 0) {
- this->shadeSpan(x, y, colors, kTempColorCount);
- x += kTempColorCount;
-
- const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
- int quads = kTempColorQuadCount;
- do {
- U8CPU a0 = srcA[0];
- U8CPU a1 = srcA[4];
- U8CPU a2 = srcA[8];
- U8CPU a3 = srcA[12];
- srcA += 4*4;
- *alpha++ = SkToU8(a0);
- *alpha++ = SkToU8(a1);
- *alpha++ = SkToU8(a2);
- *alpha++ = SkToU8(a3);
- } while (--quads != 0);
- }
- SkASSERT(count < 0);
- SkASSERT(count + kTempColorCount >= 0);
- if (count += kTempColorCount) {
- this->shadeSpan(x, y, colors, count);
-
- const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
- do {
- *alpha++ = *srcA;
- srcA += 4;
- } while (--count != 0);
- }
-#if 0
- do {
- int n = count;
- if (n > kTempColorCount)
- n = kTempColorCount;
- SkASSERT(n > 0);
-
- this->shadeSpan(x, y, colors, n);
- x += n;
- count -= n;
-
- const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT);
- do {
- *alpha++ = *srcA;
- srcA += 4;
- } while (--n != 0);
- } while (count > 0);
-#endif
-}
-
-SkShaderBase::Context::MatrixClass SkShaderBase::Context::ComputeMatrixClass(const SkMatrix& mat) {
- MatrixClass mc = kLinear_MatrixClass;
-
- if (mat.hasPerspective()) {
- if (mat.isFixedStepInX()) {
- mc = kFixedStepInX_MatrixClass;
- } else {
- mc = kPerspective_MatrixClass;
- }
- }
- return mc;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-const SkMatrix& SkShader::getLocalMatrix() const {
- return as_SB(this)->getLocalMatrix();
-}
-
-#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
-bool SkShader::isABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, TileMode xy[2]) const {
- return as_SB(this)->onIsABitmap(outTexture, outMatrix, xy);
-}
-#endif
-
-SkImage* SkShader::isAImage(SkMatrix* localMatrix, TileMode xy[2]) const {
- return as_SB(this)->onIsAImage(localMatrix, xy);
-}
-
-SkShader::GradientType SkShader::asAGradient(GradientInfo* info) const {
- return kNone_GradientType;
-}
-
-#if SK_SUPPORT_GPU
-sk_sp<GrFragmentProcessor> SkShaderBase::asFragmentProcessor(const AsFPArgs&) const {
- return nullptr;
-}
-#endif
-
-sk_sp<SkShader> SkShader::makeAsALocalMatrixShader(SkMatrix*) const {
- return nullptr;
-}
-
-sk_sp<SkShader> SkShader::MakeEmptyShader() { return sk_make_sp<SkEmptyShader>(); }
-
-sk_sp<SkShader> SkShader::MakeColorShader(SkColor color) { return sk_make_sp<SkColorShader>(color); }
-
-sk_sp<SkShader> SkShader::MakeBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
- const SkMatrix* localMatrix) {
- if (localMatrix && !localMatrix->invert(nullptr)) {
- return nullptr;
- }
- return SkMakeBitmapShader(src, tmx, tmy, localMatrix, kIfMutable_SkCopyPixelsMode);
-}
-
-sk_sp<SkShader> SkShader::MakePictureShader(sk_sp<SkPicture> src, TileMode tmx, TileMode tmy,
- const SkMatrix* localMatrix, const SkRect* tile) {
- if (localMatrix && !localMatrix->invert(nullptr)) {
- return nullptr;
- }
- return SkPictureShader::Make(std::move(src), tmx, tmy, localMatrix, tile);
-}
-
-#ifndef SK_IGNORE_TO_STRING
-void SkShaderBase::toString(SkString* str) const {
- if (!fLocalMatrix.isIdentity()) {
- str->append(" ");
- fLocalMatrix.toString(str);
- }
-}
-#endif
-
-bool SkShaderBase::appendStages(SkRasterPipeline* p,
- SkColorSpace* dstCS,
- SkArenaAlloc* alloc,
- const SkMatrix& ctm,
- const SkPaint& paint,
- const SkMatrix* localM) const {
- return this->onAppendStages(p, dstCS, alloc, ctm, paint, localM);
-}
-
-bool SkShaderBase::onAppendStages(SkRasterPipeline* p,
- SkColorSpace* dstCS,
- SkArenaAlloc* alloc,
- const SkMatrix& ctm,
- const SkPaint& paint,
- const SkMatrix* localM) const {
- return false;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-sk_sp<SkFlattenable> SkEmptyShader::CreateProc(SkReadBuffer&) {
- return SkShader::MakeEmptyShader();
-}
-
-#ifndef SK_IGNORE_TO_STRING
-#include "SkEmptyShader.h"
-
-void SkEmptyShader::toString(SkString* str) const {
- str->append("SkEmptyShader: (");
-
- this->INHERITED::toString(str);
-
- str->append(")");
-}
-#endif
diff --git a/src/core/SkShaderBase.h b/src/core/SkShaderBase.h
deleted file mode 100644
index 895fc6cf05..0000000000
--- a/src/core/SkShaderBase.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkShaderBase_DEFINED
-#define SkShaderBase_DEFINED
-
-#include "SkFilterQuality.h"
-#include "SkMatrix.h"
-#include "SkShader.h"
-
-class GrContext;
-class GrFragmentProcessor;
-class SkArenaAlloc;
-class SkColorSpace;
-class SkColorSpaceXformer;
-class SkImage;
-struct SkImageInfo;
-class SkPaint;
-class SkRasterPipeline;
-
-class SkShaderBase : public SkShader {
-public:
- SkShaderBase(const SkMatrix* localMatrix = nullptr);
-
- ~SkShaderBase() override;
-
- /**
- * Returns true if the shader is guaranteed to produce only a single color.
- * Subclasses can override this to allow loop-hoisting optimization.
- */
- virtual bool isConstant() const { return false; }
-
- const SkMatrix& getLocalMatrix() const { return fLocalMatrix; }
-
- enum Flags {
- //!< set if all of the colors will be opaque
- kOpaqueAlpha_Flag = 1 << 0,
-
- /** set if the spans only vary in X (const in Y).
- e.g. an Nx1 bitmap that is being tiled in Y, or a linear-gradient
- that varies from left-to-right. This flag specifies this for
- shadeSpan().
- */
- kConstInY32_Flag = 1 << 1,
-
- /** hint for the blitter that 4f is the preferred shading mode.
- */
- kPrefers4f_Flag = 1 << 2,
- };
-
- /**
- * ContextRec acts as a parameter bundle for creating Contexts.
- */
- struct ContextRec {
- enum DstType {
- kPMColor_DstType, // clients prefer shading into PMColor dest
- kPM4f_DstType, // clients prefer shading into PM4f dest
- };
-
- ContextRec(const SkPaint& paint, const SkMatrix& matrix, const SkMatrix* localM,
- DstType dstType, SkColorSpace* dstColorSpace)
- : fPaint(&paint)
- , fMatrix(&matrix)
- , fLocalMatrix(localM)
- , fPreferredDstType(dstType)
- , fDstColorSpace(dstColorSpace) {}
-
- const SkPaint* fPaint; // the current paint associated with the draw
- const SkMatrix* fMatrix; // the current matrix in the canvas
- const SkMatrix* fLocalMatrix; // optional local matrix
- const DstType fPreferredDstType; // the "natural" client dest type
- SkColorSpace* fDstColorSpace; // the color space of the dest surface (if any)
- };
-
- class Context : public ::SkNoncopyable {
- public:
- Context(const SkShaderBase& shader, const ContextRec&);
-
- virtual ~Context();
-
- /**
- * Called sometimes before drawing with this shader. Return the type of
- * alpha your shader will return. The default implementation returns 0.
- * Your subclass should override if it can (even sometimes) report a
- * non-zero value, since that will enable various blitters to perform
- * faster.
- */
- virtual uint32_t getFlags() const { return 0; }
-
- /**
- * Called for each span of the object being drawn. Your subclass should
- * set the appropriate colors (with premultiplied alpha) that correspond
- * to the specified device coordinates.
- */
- virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
-
- virtual void shadeSpan4f(int x, int y, SkPM4f[], int count);
-
- struct BlitState;
- typedef void (*BlitBW)(BlitState*,
- int x, int y, const SkPixmap&, int count);
- typedef void (*BlitAA)(BlitState*,
- int x, int y, const SkPixmap&, int count, const SkAlpha[]);
-
- struct BlitState {
- // inputs
- Context* fCtx;
- SkBlendMode fMode;
-
- // outputs
- enum { N = 2 };
- void* fStorage[N];
- BlitBW fBlitBW;
- BlitAA fBlitAA;
- };
-
- // Returns true if one or more of the blitprocs are set in the BlitState
- bool chooseBlitProcs(const SkImageInfo& info, BlitState* state) {
- state->fBlitBW = nullptr;
- state->fBlitAA = nullptr;
- if (this->onChooseBlitProcs(info, state)) {
- SkASSERT(state->fBlitBW || state->fBlitAA);
- return true;
- }
- return false;
- }
-
- /**
- * The const void* ctx is only const because all the implementations are const.
- * This can be changed to non-const if a new shade proc needs to change the ctx.
- */
- typedef void (*ShadeProc)(const void* ctx, int x, int y, SkPMColor[], int count);
- virtual ShadeProc asAShadeProc(void** ctx);
-
- /**
- * Similar to shadeSpan, but only returns the alpha-channel for a span.
- * The default implementation calls shadeSpan() and then extracts the alpha
- * values from the returned colors.
- */
- virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
-
- // Notification from blitter::blitMask in case we need to see the non-alpha channels
- virtual void set3DMask(const SkMask*) {}
-
- protected:
- // Reference to shader, so we don't have to dupe information.
- const SkShaderBase& fShader;
-
- enum MatrixClass {
- kLinear_MatrixClass, // no perspective
- kFixedStepInX_MatrixClass, // fast perspective, need to call fixedStepInX() each
- // scanline
- kPerspective_MatrixClass // slow perspective, need to mappoints each pixel
- };
- static MatrixClass ComputeMatrixClass(const SkMatrix&);
-
- uint8_t getPaintAlpha() const { return fPaintAlpha; }
- const SkMatrix& getTotalInverse() const { return fTotalInverse; }
- MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
- const SkMatrix& getCTM() const { return fCTM; }
-
- virtual bool onChooseBlitProcs(const SkImageInfo&, BlitState*) { return false; }
-
- private:
- SkMatrix fCTM;
- SkMatrix fTotalInverse;
- uint8_t fPaintAlpha;
- uint8_t fTotalInverseClass;
-
- typedef SkNoncopyable INHERITED;
- };
-
- /**
- * Make a context using the memory provided by the arena.
- *
- * @return pointer to context or nullptr if can't be created
- */
- Context* makeContext(const ContextRec&, SkArenaAlloc*) const;
-
-#if SK_SUPPORT_GPU
- struct AsFPArgs {
- AsFPArgs() {}
- AsFPArgs(GrContext* context,
- const SkMatrix* viewMatrix,
- const SkMatrix* localMatrix,
- SkFilterQuality filterQuality,
- SkColorSpace* dstColorSpace)
- : fContext(context)
- , fViewMatrix(viewMatrix)
- , fLocalMatrix(localMatrix)
- , fFilterQuality(filterQuality)
- , fDstColorSpace(dstColorSpace) {}
-
- GrContext* fContext;
- const SkMatrix* fViewMatrix;
- const SkMatrix* fLocalMatrix;
- SkFilterQuality fFilterQuality;
- SkColorSpace* fDstColorSpace;
- };
-
- /**
- * Returns a GrFragmentProcessor that implements the shader for the GPU backend. NULL is
- * returned if there is no GPU implementation.
- *
- * The GPU device does not call SkShader::createContext(), instead we pass the view matrix,
- * local matrix, and filter quality directly.
- *
- * The GrContext may be used by the to create textures that are required by the returned
- * processor.
- *
- * The returned GrFragmentProcessor should expect an unpremultiplied input color and
- * produce a premultiplied output.
- */
- virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const;
-#endif
-
- /**
- * If the shader can represent its "average" luminance in a single color, return true and
- * if color is not NULL, return that color. If it cannot, return false and ignore the color
- * parameter.
- *
- * Note: if this returns true, the returned color will always be opaque, as only the RGB
- * components are used to compute luminance.
- */
- bool asLuminanceColor(SkColor*) const;
-
- /**
- * Returns a shader transformed into a new color space via the |xformer|.
- */
- sk_sp<SkShader> makeColorSpace(SkColorSpaceXformer* xformer) const {
- return this->onMakeColorSpace(xformer);
- }
-
- virtual bool isRasterPipelineOnly() const { return false; }
-
- bool appendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*,
- const SkMatrix& ctm, const SkPaint&, const SkMatrix* localM=nullptr) const;
-
- bool computeTotalInverse(const SkMatrix& ctm,
- const SkMatrix* outerLocalMatrix,
- SkMatrix* totalInverse) const;
-
-#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
- virtual bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode[2]) const {
- return false;
- }
-#endif
-
- virtual SkImage* onIsAImage(SkMatrix*, TileMode[2]) const {
- return nullptr;
- }
-
- SK_TO_STRING_VIRT()
-
- SK_DEFINE_FLATTENABLE_TYPE(SkShaderBase)
- SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
-
-protected:
- void flatten(SkWriteBuffer&) const override;
-
- /**
- * Specialize creating a SkShader context using the supplied allocator.
- * @return pointer to context owned by the arena allocator.
- */
- virtual Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const {
- return nullptr;
- }
-
- virtual bool onAsLuminanceColor(SkColor*) const {
- return false;
- }
-
- virtual sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer*) const {
- return sk_ref_sp(const_cast<SkShaderBase*>(this));
- }
-
- virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*,
- const SkMatrix&, const SkPaint&, const SkMatrix* localM) const;
-
-private:
- // This is essentially const, but not officially so it can be modified in constructors.
- SkMatrix fLocalMatrix;
-
- typedef SkShader INHERITED;
-};
-
-inline SkShaderBase* as_SB(SkShader* shader) {
- return static_cast<SkShaderBase*>(shader);
-}
-
-inline const SkShaderBase* as_SB(const SkShader* shader) {
- return static_cast<const SkShaderBase*>(shader);
-}
-
-inline const SkShaderBase* as_SB(const sk_sp<SkShader>& shader) {
- return static_cast<SkShaderBase*>(shader.get());
-}
-
-#endif // SkShaderBase_DEFINED