1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkVMBlitter_DEFINED 9 #define SkVMBlitter_DEFINED 10 11 #include "include/core/SkPixmap.h" 12 #include "src/base/SkArenaAlloc.h" 13 #include "src/base/SkTLazy.h" 14 #include "src/core/SkBlitter.h" 15 #include "src/core/SkLRUCache.h" 16 #include "src/core/SkVM.h" 17 18 class SkVMBlitter final : public SkBlitter { 19 public: 20 static SkVMBlitter* Make(const SkPixmap& dst, 21 const SkPaint&, 22 const SkMatrix& ctm, 23 SkArenaAlloc*, 24 sk_sp<SkShader> clipShader); 25 26 static SkVMBlitter* Make(const SkPixmap& dst, 27 const SkPaint&, 28 const SkPixmap& sprite, 29 int left, int top, 30 SkArenaAlloc*, 31 sk_sp<SkShader> clipShader); 32 33 SkVMBlitter(const SkPixmap& device, 34 const SkPaint& paint, 35 const SkPixmap* sprite, 36 SkIPoint spriteOffset, 37 const SkMatrix& ctm, 38 sk_sp<SkShader> clip, 39 bool* ok); 40 41 ~SkVMBlitter() override; 42 43 private: 44 enum Coverage { Full, UniformF, MaskA8, MaskLCD16, Mask3D, kCount }; 45 struct Key { 46 uint64_t shader, 47 clip, 48 blender, 49 colorSpace; 50 uint8_t colorType, 51 alphaType, 52 coverage; 53 uint8_t padding8{0}; 54 uint32_t padding{0}; 55 // Params::{paint,quality,matrices} are only passed to {shader,clip}->program(), 56 // not used here by the blitter itself. No need to include them in the key; 57 // they'll be folded into the shader key if used. 58 59 bool operator==(const Key& that) const; 60 Key withCoverage(Coverage c) const; 61 }; 62 63 struct Params { 64 sk_sp<SkShader> shader; 65 sk_sp<SkShader> clip; 66 sk_sp<SkBlender> blender; // never null 67 SkColorInfo dst; 68 Coverage coverage; 69 SkColor4f paint; 70 SkMatrix ctm; 71 72 Params withCoverage(Coverage c) const; 73 }; 74 75 static Params EffectiveParams(const SkPixmap& device, 76 const SkPixmap* sprite, 77 SkPaint paint, 78 const SkMatrix& ctm, 79 sk_sp<SkShader> clip); 80 static skvm::Color DstColor(skvm::Builder* p, const Params& params); 81 static void BuildProgram(skvm::Builder* p, const Params& params, 82 skvm::Uniforms* uniforms, SkArenaAlloc* alloc); 83 static Key CacheKey(const Params& params, 84 skvm::Uniforms* uniforms, SkArenaAlloc* alloc, bool* ok); 85 static SkLRUCache<Key, skvm::Program>* TryAcquireProgramCache(); 86 static SkString DebugName(const Key& key); 87 static void ReleaseProgramCache(); 88 89 skvm::Program* buildProgram(Coverage coverage); 90 void updateUniforms(int right, int y); 91 const void* isSprite(int x, int y) const; 92 93 void blitH(int x, int y, int w) override; 94 void blitAntiH(int x, int y, const SkAlpha cov[], const int16_t runs[]) override; 95 96 private: 97 void blitMask(const SkMask& mask, const SkIRect& clip) override; 98 99 SkPixmap fDevice; 100 const SkPixmap fSprite; // See isSprite(). 101 const SkIPoint fSpriteOffset; 102 skvm::Uniforms fUniforms; // Most data is copied directly into fUniforms, 103 SkArenaAlloc fAlloc{2*sizeof(void*)}; // but a few effects need to ref large content. 104 const Params fParams; 105 const Key fKey; 106 bool fStoreToCache = false; 107 108 skvm::Program* fProgramPtrs[Coverage::kCount] = {nullptr}; 109 SkTLazy<skvm::Program> fPrograms[Coverage::kCount]; 110 111 friend class Viewer; 112 }; 113 #endif // SkVMBlitter_DEFINED 114