1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2006 The Android Open Source Project 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkArenaAlloc.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkAtomics.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBitmapProcShader.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorShader.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorSpaceXformer.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkEmptyShader.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMallocPixelRef.h" 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPaint.h" 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPicture.h" 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPictureShader.h" 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPM4fPriv.h" 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRasterPipeline.h" 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkReadBuffer.h" 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkScalar.h" 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkShaderBase.h" 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTLazy.h" 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkWriteBuffer.h" 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "../jumper/SkJumper.h" 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrFragmentProcessor.h" 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//#define SK_TRACK_SHADER_LIFETIME 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_TRACK_SHADER_LIFETIME 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static int32_t gShaderCounter; 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic inline void inc_shader_counter() { 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_TRACK_SHADER_LIFETIME 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int32_t prev = sk_atomic_inc(&gShaderCounter); 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("+++ shader counter %d\n", prev + 1); 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic inline void dec_shader_counter() { 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_TRACK_SHADER_LIFETIME 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int32_t prev = sk_atomic_dec(&gShaderCounter); 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("--- shader counter %d\n", prev - 1); 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkShaderBase::SkShaderBase(const SkMatrix* localMatrix) 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : fLocalMatrix(localMatrix ? *localMatrix : SkMatrix::I()) { 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot inc_shader_counter(); 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Pre-cache so future calls to fLocalMatrix.getType() are threadsafe. 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (void)fLocalMatrix.getType(); 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkShaderBase::~SkShaderBase() { 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dec_shader_counter(); 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkShaderBase::flatten(SkWriteBuffer& buffer) const { 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->INHERITED::flatten(buffer); 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool hasLocalM = !fLocalMatrix.isIdentity(); 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot buffer.writeBool(hasLocalM); 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (hasLocalM) { 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot buffer.writeMatrix(fLocalMatrix); 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkShaderBase::computeTotalInverse(const SkMatrix& ctm, 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix* outerLocalMatrix, 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix* totalInverse) const { 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix total = SkMatrix::Concat(ctm, fLocalMatrix); 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (outerLocalMatrix) { 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot total.preConcat(*outerLocalMatrix); 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return total.invert(totalInverse); 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkShaderBase::asLuminanceColor(SkColor* colorPtr) const { 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkColor storage; 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (nullptr == colorPtr) { 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot colorPtr = &storage; 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->onAsLuminanceColor(colorPtr)) { 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *colorPtr = SkColorSetA(*colorPtr, 0xFF); // we only return opaque 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkShaderBase::Context* SkShaderBase::makeContext(const ContextRec& rec, SkArenaAlloc* alloc) const { 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return this->computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, nullptr) 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ? this->onMakeContext(rec, alloc) 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : nullptr; 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkShaderBase::Context* SkShaderBase::makeBurstPipelineContext(const ContextRec& rec, 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkArenaAlloc* alloc) const { 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(rec.fPreferredDstType == ContextRec::kPM4f_DstType); 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Always use vanilla stages for perspective. 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (rec.fMatrix->hasPerspective() || fLocalMatrix.hasPerspective()) { 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return this->computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, nullptr) 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ? this->onMakeBurstPipelineContext(rec, alloc) 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : nullptr; 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkShaderBase::Context::Context(const SkShaderBase& shader, const ContextRec& rec) 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : fShader(shader), fCTM(*rec.fMatrix) 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot{ 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We should never use a context for RP-only shaders. 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!shader.isRasterPipelineOnly(*rec.fMatrix)); 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // ... or for perspective. 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!rec.fMatrix->hasPerspective()); 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!rec.fLocalMatrix || !rec.fLocalMatrix->hasPerspective()); 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Because the context parameters must be valid at this point, we know that the matrix is 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // invertible. 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAssertResult(fShader.computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, &fTotalInverse)); 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPaintAlpha = rec.fPaint->getAlpha(); 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkShaderBase::Context::~Context() {} 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkShaderBase::Context::shadeSpan4f(int x, int y, SkPM4f dst[], int count) { 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const int N = 128; 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPMColor tmp[N]; 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (count > 0) { 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int n = SkTMin(count, N); 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->shadeSpan(x, y, tmp, n); 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < n; ++i) { 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dst[i] = SkPM4f::FromPMColor(tmp[i]); 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dst += n; 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot x += n; 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot count -= n; 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconst SkMatrix& SkShader::getLocalMatrix() const { 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return as_SB(this)->getLocalMatrix(); 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkShader::isABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, TileMode xy[2]) const { 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return as_SB(this)->onIsABitmap(outTexture, outMatrix, xy); 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkImage* SkShader::isAImage(SkMatrix* localMatrix, TileMode xy[2]) const { 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return as_SB(this)->onIsAImage(localMatrix, xy); 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return kNone_GradientType; 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstd::unique_ptr<GrFragmentProcessor> SkShaderBase::asFragmentProcessor(const GrFPArgs&) const { 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkShader> SkShader::makeAsALocalMatrixShader(SkMatrix*) const { 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkShader> SkShader::MakeEmptyShader() { return sk_make_sp<SkEmptyShader>(); } 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkShader> SkShader::MakeColorShader(SkColor color) { return sk_make_sp<SkColorShader>(color); } 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkShader> SkShader::MakeBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy, 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix* localMatrix) { 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (localMatrix && !localMatrix->invert(nullptr)) { 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkMakeBitmapShader(src, tmx, tmy, localMatrix, kIfMutable_SkCopyPixelsMode); 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkShader> SkShader::MakePictureShader(sk_sp<SkPicture> src, TileMode tmx, TileMode tmy, 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix* localMatrix, const SkRect* tile) { 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (localMatrix && !localMatrix->invert(nullptr)) { 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkPictureShader::Make(std::move(src), tmx, tmy, localMatrix, tile); 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SK_IGNORE_TO_STRING 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkShaderBase::toString(SkString* str) const { 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!fLocalMatrix.isIdentity()) { 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str->append(" "); 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fLocalMatrix.toString(str); 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkShaderBase::appendStages(const StageRec& rec) const { 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return this->onAppendStages(rec); 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkShaderBase::onAppendStages(const StageRec& rec) const { 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // SkShader::Context::shadeSpan4f() handles the paint opacity internally, 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // but SkRasterPipelineBlitter applies it as a separate stage. 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We skip the internal shadeSpan4f() step by forcing the paint opaque. 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTCopyOnFirstWrite<SkPaint> opaquePaint(rec.fPaint); 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (rec.fPaint.getAlpha() != SK_AlphaOPAQUE) { 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot opaquePaint.writable()->setAlpha(SK_AlphaOPAQUE); 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ContextRec cr(*opaquePaint, rec.fCTM, rec.fLocalM, ContextRec::kPM4f_DstType, rec.fDstCS); 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot struct CallbackCtx : SkJumper_CallbackCtx { 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<SkShader> shader; 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Context* ctx; 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto cb = rec.fAlloc->make<CallbackCtx>(); 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cb->shader = rec.fDstCS ? SkColorSpaceXformer::Make(sk_ref_sp(rec.fDstCS))->apply(this) 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : sk_ref_sp((SkShader*)this); 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cb->ctx = as_SB(cb->shader)->makeContext(cr, rec.fAlloc); 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cb->fn = [](SkJumper_CallbackCtx* self, int active_pixels) { 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto c = (CallbackCtx*)self; 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int x = (int)c->rgba[0], 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot y = (int)c->rgba[1]; 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot c->ctx->shadeSpan4f(x,y, (SkPM4f*)c->rgba, active_pixels); 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (cb->ctx) { 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rec.fPipeline->append_seed_shader(); 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rec.fPipeline->append(SkRasterPipeline::callback, cb); 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/////////////////////////////////////////////////////////////////////////////////////////////////// 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkFlattenable> SkEmptyShader::CreateProc(SkReadBuffer&) { 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkShader::MakeEmptyShader(); 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SK_IGNORE_TO_STRING 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkEmptyShader.h" 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkEmptyShader::toString(SkString* str) const { 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str->append("SkEmptyShader: ("); 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->INHERITED::toString(str); 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot str->append(")"); 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 259