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