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