1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2011 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "src/shaders/SkBitmapProcShader.h"
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPixmap.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkArenaAlloc.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkBitmapProcState.h"
16*c8dee2aaSAndroid Build Coastguard Worker
17*c8dee2aaSAndroid Build Coastguard Worker #include <algorithm>
18*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
19*c8dee2aaSAndroid Build Coastguard Worker
20*c8dee2aaSAndroid Build Coastguard Worker enum class SkTileMode;
21*c8dee2aaSAndroid Build Coastguard Worker
22*c8dee2aaSAndroid Build Coastguard Worker class BitmapProcShaderContext : public SkShaderBase::Context {
23*c8dee2aaSAndroid Build Coastguard Worker public:
BitmapProcShaderContext(const SkShaderBase & shader,const SkShaderBase::ContextRec & rec,SkBitmapProcState * state)24*c8dee2aaSAndroid Build Coastguard Worker BitmapProcShaderContext(const SkShaderBase& shader, const SkShaderBase::ContextRec& rec,
25*c8dee2aaSAndroid Build Coastguard Worker SkBitmapProcState* state)
26*c8dee2aaSAndroid Build Coastguard Worker : INHERITED(shader, rec)
27*c8dee2aaSAndroid Build Coastguard Worker , fState(state)
28*c8dee2aaSAndroid Build Coastguard Worker , fFlags(0)
29*c8dee2aaSAndroid Build Coastguard Worker {
30*c8dee2aaSAndroid Build Coastguard Worker if (fState->fPixmap.isOpaque() && (255 == this->getPaintAlpha())) {
31*c8dee2aaSAndroid Build Coastguard Worker fFlags |= SkShaderBase::kOpaqueAlpha_Flag;
32*c8dee2aaSAndroid Build Coastguard Worker }
33*c8dee2aaSAndroid Build Coastguard Worker }
34*c8dee2aaSAndroid Build Coastguard Worker
getFlags() const35*c8dee2aaSAndroid Build Coastguard Worker uint32_t getFlags() const override { return fFlags; }
36*c8dee2aaSAndroid Build Coastguard Worker
shadeSpan(int x,int y,SkPMColor dstC[],int count)37*c8dee2aaSAndroid Build Coastguard Worker void shadeSpan(int x, int y, SkPMColor dstC[], int count) override {
38*c8dee2aaSAndroid Build Coastguard Worker const SkBitmapProcState& state = *fState;
39*c8dee2aaSAndroid Build Coastguard Worker if (state.getShaderProc32()) {
40*c8dee2aaSAndroid Build Coastguard Worker state.getShaderProc32()(&state, x, y, dstC, count);
41*c8dee2aaSAndroid Build Coastguard Worker return;
42*c8dee2aaSAndroid Build Coastguard Worker }
43*c8dee2aaSAndroid Build Coastguard Worker
44*c8dee2aaSAndroid Build Coastguard Worker const int BUF_MAX = 128;
45*c8dee2aaSAndroid Build Coastguard Worker uint32_t buffer[BUF_MAX];
46*c8dee2aaSAndroid Build Coastguard Worker SkBitmapProcState::MatrixProc mproc = state.getMatrixProc();
47*c8dee2aaSAndroid Build Coastguard Worker SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32();
48*c8dee2aaSAndroid Build Coastguard Worker const int max = state.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX);
49*c8dee2aaSAndroid Build Coastguard Worker
50*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(state.fPixmap.addr());
51*c8dee2aaSAndroid Build Coastguard Worker
52*c8dee2aaSAndroid Build Coastguard Worker for (;;) {
53*c8dee2aaSAndroid Build Coastguard Worker int n = std::min(count, max);
54*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(n > 0 && n < BUF_MAX*2);
55*c8dee2aaSAndroid Build Coastguard Worker mproc(state, buffer, n, x, y);
56*c8dee2aaSAndroid Build Coastguard Worker sproc(state, buffer, n, dstC);
57*c8dee2aaSAndroid Build Coastguard Worker
58*c8dee2aaSAndroid Build Coastguard Worker if ((count -= n) == 0) {
59*c8dee2aaSAndroid Build Coastguard Worker break;
60*c8dee2aaSAndroid Build Coastguard Worker }
61*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(count > 0);
62*c8dee2aaSAndroid Build Coastguard Worker x += n;
63*c8dee2aaSAndroid Build Coastguard Worker dstC += n;
64*c8dee2aaSAndroid Build Coastguard Worker }
65*c8dee2aaSAndroid Build Coastguard Worker }
66*c8dee2aaSAndroid Build Coastguard Worker
67*c8dee2aaSAndroid Build Coastguard Worker private:
68*c8dee2aaSAndroid Build Coastguard Worker SkBitmapProcState* fState;
69*c8dee2aaSAndroid Build Coastguard Worker uint32_t fFlags;
70*c8dee2aaSAndroid Build Coastguard Worker
71*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = SkShaderBase::Context;
72*c8dee2aaSAndroid Build Coastguard Worker };
73*c8dee2aaSAndroid Build Coastguard Worker
74*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////////////////////////
75*c8dee2aaSAndroid Build Coastguard Worker
MakeContext(const SkShaderBase & shader,SkTileMode tmx,SkTileMode tmy,const SkSamplingOptions & sampling,const SkImage_Base * image,const ContextRec & rec,SkArenaAlloc * alloc)76*c8dee2aaSAndroid Build Coastguard Worker SkShaderBase::Context* SkBitmapProcLegacyShader::MakeContext(
77*c8dee2aaSAndroid Build Coastguard Worker const SkShaderBase& shader, SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions& sampling,
78*c8dee2aaSAndroid Build Coastguard Worker const SkImage_Base* image, const ContextRec& rec, SkArenaAlloc* alloc)
79*c8dee2aaSAndroid Build Coastguard Worker {
80*c8dee2aaSAndroid Build Coastguard Worker SkMatrix totalInverse;
81*c8dee2aaSAndroid Build Coastguard Worker // Do this first, so we know the matrix can be inverted.
82*c8dee2aaSAndroid Build Coastguard Worker if (!rec.fMatrixRec.totalInverse(&totalInverse)) {
83*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
84*c8dee2aaSAndroid Build Coastguard Worker }
85*c8dee2aaSAndroid Build Coastguard Worker
86*c8dee2aaSAndroid Build Coastguard Worker SkBitmapProcState* state = alloc->make<SkBitmapProcState>(image, tmx, tmy);
87*c8dee2aaSAndroid Build Coastguard Worker if (!state->setup(totalInverse, rec.fPaintAlpha, sampling)) {
88*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
89*c8dee2aaSAndroid Build Coastguard Worker }
90*c8dee2aaSAndroid Build Coastguard Worker return alloc->make<BitmapProcShaderContext>(shader, rec, state);
91*c8dee2aaSAndroid Build Coastguard Worker }
92