/* * Copyright 2021 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkVMBlitter_DEFINED #define SkVMBlitter_DEFINED #include "src/core/SkArenaAlloc.h" #include "src/core/SkBlitter.h" #include "src/core/SkLRUCache.h" #include "src/core/SkVM.h" class SkVMBlitter final : public SkBlitter { public: static SkVMBlitter* Make(const SkPixmap& dst, const SkPaint&, const SkMatrixProvider&, SkArenaAlloc*, sk_sp clipShader); static SkVMBlitter* Make(const SkPixmap& dst, const SkPaint&, const SkPixmap& sprite, int left, int top, SkArenaAlloc*, sk_sp clipShader); SkVMBlitter(const SkPixmap& device, const SkPaint& paint, const SkPixmap* sprite, SkIPoint spriteOffset, const SkMatrixProvider& matrices, sk_sp clip, bool* ok); ~SkVMBlitter() override; private: enum class Coverage { Full, UniformF, MaskA8, MaskLCD16, Mask3D }; struct Key { uint64_t shader, clip, blender, colorSpace; uint8_t colorType, alphaType, coverage; uint8_t padding8{0}; uint32_t padding{0}; // Params::{paint,quality,matrices} are only passed to {shader,clip}->program(), // not used here by the blitter itself. No need to include them in the key; // they'll be folded into the shader key if used. bool operator==(const Key& that) const; Key withCoverage(Coverage c) const; }; struct Params { sk_sp shader; sk_sp clip; sk_sp blender; // never null SkColorInfo dst; Coverage coverage; SkColor4f paint; const SkMatrixProvider& matrices; Params withCoverage(Coverage c) const; }; static Params EffectiveParams(const SkPixmap& device, const SkPixmap* sprite, SkPaint paint, const SkMatrixProvider& matrices, sk_sp clip); static skvm::Color DstColor(skvm::Builder* p, const Params& params); static void BuildProgram(skvm::Builder* p, const Params& params, skvm::Uniforms* uniforms, SkArenaAlloc* alloc); static Key CacheKey(const Params& params, skvm::Uniforms* uniforms, SkArenaAlloc* alloc, bool* ok); static SkLRUCache* TryAcquireProgramCache(); static SkString DebugName(const Key& key); static void ReleaseProgramCache(); skvm::Program buildProgram(Coverage coverage); void updateUniforms(int right, int y); const void* isSprite(int x, int y) const; void blitH(int x, int y, int w) override; void blitAntiH(int x, int y, const SkAlpha cov[], const int16_t runs[]) override; void blitMask(const SkMask& mask, const SkIRect& clip) override; SkPixmap fDevice; const SkPixmap fSprite; // See isSprite(). const SkIPoint fSpriteOffset; skvm::Uniforms fUniforms; // Most data is copied directly into fUniforms, SkArenaAlloc fAlloc{2*sizeof(void*)}; // but a few effects need to ref large content. const Params fParams; const Key fKey; skvm::Program fBlitH, fBlitAntiH, fBlitMaskA8, fBlitMask3D, fBlitMaskLCD16; friend class Viewer; }; #endif // SkVMBlitter_DEFINED