1 /* 2 * Copyright 2006 The Android Open Source Project 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 SkBlitter_DEFINED 9 #define SkBlitter_DEFINED 10 11 #include "SkAutoMalloc.h" 12 #include "SkBitmapProcShader.h" 13 #include "SkColor.h" 14 #include "SkCoverageDelta.h" 15 #include "SkRect.h" 16 #include "SkRegion.h" 17 #include "SkShaderBase.h" 18 19 class SkArenaAlloc; 20 class SkMatrix; 21 class SkPaint; 22 class SkPixmap; 23 struct SkMask; 24 25 /** SkBlitter and its subclasses are responsible for actually writing pixels 26 into memory. Besides efficiency, they handle clipping and antialiasing. 27 A SkBlitter subclass contains all the context needed to generate pixels 28 for the destination and how src/generated pixels map to the destination. 29 The coordinates passed to the blitX calls are in destination pixel space. 30 */ 31 class SkBlitter { 32 public: 33 virtual ~SkBlitter(); 34 35 // The actual blitter may speedup the process by rewriting this in a more efficient way. 36 // For example, one may avoid some virtual blitAntiH calls by directly calling 37 // SkBlitRow::Color32. 38 virtual void blitCoverageDeltas(SkCoverageDeltaList* deltas, const SkIRect& clip, 39 bool isEvenOdd, bool isInverse, bool isConvex, 40 SkArenaAlloc* alloc); 41 42 /// Blit a horizontal run of one or more pixels. 43 virtual void blitH(int x, int y, int width) = 0; 44 45 /// Blit a horizontal run of antialiased pixels; runs[] is a *sparse* 46 /// zero-terminated run-length encoding of spans of constant alpha values. 47 /// The runs[] and antialias[] work together to represent long runs of pixels with the same 48 /// alphas. The runs[] contains the number of pixels with the same alpha, and antialias[] 49 /// contain the coverage value for that number of pixels. The runs[] (and antialias[]) are 50 /// encoded in a clever way. The runs array is zero terminated, and has enough entries for 51 /// each pixel plus one, in most cases some of the entries will not contain valid data. An entry 52 /// in the runs array contains the number of pixels (np) that have the same alpha value. The 53 /// next np value is found np entries away. For example, if runs[0] = 7, then the next valid 54 /// entry will by at runs[7]. The runs array and antialias[] are coupled by index. So, if the 55 /// np entry is at runs[45] = 12 then the alpha value can be found at antialias[45] = 0x88. 56 /// This would mean to use an alpha value of 0x88 for the next 12 pixels starting at pixel 45. 57 virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) = 0; 58 59 /// Blit a vertical run of pixels with a constant alpha value. 60 virtual void blitV(int x, int y, int height, SkAlpha alpha); 61 62 /// Blit a solid rectangle one or more pixels wide. 63 virtual void blitRect(int x, int y, int width, int height); 64 65 /** Blit a rectangle with one alpha-blended column on the left, 66 width (zero or more) opaque pixels, and one alpha-blended column 67 on the right. 68 The result will always be at least two pixels wide. 69 */ 70 virtual void blitAntiRect(int x, int y, int width, int height, 71 SkAlpha leftAlpha, SkAlpha rightAlpha); 72 73 // Blit a rect in AA with size at least 3 x 3 (small rect has too many edge cases...) 74 void blitFatAntiRect(const SkRect& rect); 75 76 /// Blit a pattern of pixels defined by a rectangle-clipped mask; 77 /// typically used for text. 78 virtual void blitMask(const SkMask&, const SkIRect& clip); 79 80 /** If the blitter just sets a single value for each pixel, return the 81 bitmap it draws into, and assign value. If not, return nullptr and ignore 82 the value parameter. 83 */ 84 virtual const SkPixmap* justAnOpaqueColor(uint32_t* value); 85 86 // (x, y), (x + 1, y) 87 virtual void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) { 88 int16_t runs[3]; 89 uint8_t aa[2]; 90 91 runs[0] = 1; 92 runs[1] = 1; 93 runs[2] = 0; 94 aa[0] = SkToU8(a0); 95 aa[1] = SkToU8(a1); 96 this->blitAntiH(x, y, aa, runs); 97 } 98 99 // (x, y), (x, y + 1) 100 virtual void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) { 101 int16_t runs[2]; 102 uint8_t aa[1]; 103 104 runs[0] = 1; 105 runs[1] = 0; 106 aa[0] = SkToU8(a0); 107 this->blitAntiH(x, y, aa, runs); 108 // reset in case the clipping blitter modified runs 109 runs[0] = 1; 110 runs[1] = 0; 111 aa[0] = SkToU8(a1); 112 this->blitAntiH(x, y + 1, aa, runs); 113 } 114 115 /** 116 * Special method just to identify the null blitter, which is returned 117 * from Choose() if the request cannot be fulfilled. Default impl 118 * returns false. 119 */ 120 virtual bool isNullBlitter() const; 121 122 /** 123 * Special methods for blitters that can blit more than one row at a time. 124 * This function returns the number of rows that this blitter could optimally 125 * process at a time. It is still required to support blitting one scanline 126 * at a time. 127 */ 128 virtual int requestRowsPreserved() const { return 1; } 129 130 /** 131 * This function allocates memory for the blitter that the blitter then owns. 132 * The memory can be used by the calling function at will, but it will be 133 * released when the blitter's destructor is called. This function returns 134 * nullptr if no persistent memory is needed by the blitter. 135 */ 136 virtual void* allocBlitMemory(size_t sz) { 137 return fBlitMemory.reset(sz, SkAutoMalloc::kReuse_OnShrink); 138 } 139 140 ///@name non-virtual helpers 141 void blitMaskRegion(const SkMask& mask, const SkRegion& clip); 142 void blitRectRegion(const SkIRect& rect, const SkRegion& clip); 143 void blitRegion(const SkRegion& clip); 144 ///@} 145 146 /** @name Factories 147 Return the correct blitter to use given the specified context. 148 */ 149 static SkBlitter* Choose(const SkPixmap& dst, 150 const SkMatrix& matrix, 151 const SkPaint& paint, 152 SkArenaAlloc*, 153 bool drawCoverage = false); 154 155 static SkBlitter* ChooseSprite(const SkPixmap& dst, 156 const SkPaint&, 157 const SkPixmap& src, 158 int left, int top, 159 SkArenaAlloc*); 160 ///@} 161 162 static SkShaderBase::ContextRec::DstType PreferredShaderDest(const SkImageInfo&); 163 164 static bool UseRasterPipelineBlitter(const SkPixmap&, const SkPaint&, const SkMatrix&); 165 166 protected: 167 SkAutoMalloc fBlitMemory; 168 }; 169 170 /** This blitter silently never draws anything. 171 */ 172 class SkNullBlitter : public SkBlitter { 173 public: 174 void blitH(int x, int y, int width) override; 175 void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override; 176 void blitV(int x, int y, int height, SkAlpha alpha) override; 177 void blitRect(int x, int y, int width, int height) override; 178 void blitMask(const SkMask&, const SkIRect& clip) override; 179 const SkPixmap* justAnOpaqueColor(uint32_t* value) override; 180 bool isNullBlitter() const override; 181 }; 182 183 /** Wraps another (real) blitter, and ensures that the real blitter is only 184 called with coordinates that have been clipped by the specified clipRect. 185 This means the caller need not perform the clipping ahead of time. 186 */ 187 class SkRectClipBlitter : public SkBlitter { 188 public: 189 void init(SkBlitter* blitter, const SkIRect& clipRect) { 190 SkASSERT(!clipRect.isEmpty()); 191 fBlitter = blitter; 192 fClipRect = clipRect; 193 } 194 195 void blitH(int x, int y, int width) override; 196 void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override; 197 void blitV(int x, int y, int height, SkAlpha alpha) override; 198 void blitRect(int x, int y, int width, int height) override; 199 virtual void blitAntiRect(int x, int y, int width, int height, 200 SkAlpha leftAlpha, SkAlpha rightAlpha) override; 201 void blitMask(const SkMask&, const SkIRect& clip) override; 202 const SkPixmap* justAnOpaqueColor(uint32_t* value) override; 203 204 int requestRowsPreserved() const override { 205 return fBlitter->requestRowsPreserved(); 206 } 207 208 void* allocBlitMemory(size_t sz) override { 209 return fBlitter->allocBlitMemory(sz); 210 } 211 212 private: 213 SkBlitter* fBlitter; 214 SkIRect fClipRect; 215 }; 216 217 /** Wraps another (real) blitter, and ensures that the real blitter is only 218 called with coordinates that have been clipped by the specified clipRgn. 219 This means the caller need not perform the clipping ahead of time. 220 */ 221 class SkRgnClipBlitter : public SkBlitter { 222 public: 223 void init(SkBlitter* blitter, const SkRegion* clipRgn) { 224 SkASSERT(clipRgn && !clipRgn->isEmpty()); 225 fBlitter = blitter; 226 fRgn = clipRgn; 227 } 228 229 void blitH(int x, int y, int width) override; 230 void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override; 231 void blitV(int x, int y, int height, SkAlpha alpha) override; 232 void blitRect(int x, int y, int width, int height) override; 233 void blitAntiRect(int x, int y, int width, int height, 234 SkAlpha leftAlpha, SkAlpha rightAlpha) override; 235 void blitMask(const SkMask&, const SkIRect& clip) override; 236 const SkPixmap* justAnOpaqueColor(uint32_t* value) override; 237 238 int requestRowsPreserved() const override { 239 return fBlitter->requestRowsPreserved(); 240 } 241 242 void* allocBlitMemory(size_t sz) override { 243 return fBlitter->allocBlitMemory(sz); 244 } 245 246 private: 247 SkBlitter* fBlitter; 248 const SkRegion* fRgn; 249 }; 250 251 #ifdef SK_DEBUG 252 class SkRectClipCheckBlitter : public SkBlitter { 253 public: 254 void init(SkBlitter* blitter, const SkIRect& clipRect) { 255 SkASSERT(blitter); 256 SkASSERT(!clipRect.isEmpty()); 257 fBlitter = blitter; 258 fClipRect = clipRect; 259 } 260 261 void blitH(int x, int y, int width) override; 262 void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override; 263 void blitV(int x, int y, int height, SkAlpha alpha) override; 264 void blitRect(int x, int y, int width, int height) override; 265 void blitAntiRect(int x, int y, int width, int height, 266 SkAlpha leftAlpha, SkAlpha rightAlpha) override; 267 void blitMask(const SkMask&, const SkIRect& clip) override; 268 const SkPixmap* justAnOpaqueColor(uint32_t* value) override; 269 void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) override; 270 void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) override; 271 272 int requestRowsPreserved() const override { 273 return fBlitter->requestRowsPreserved(); 274 } 275 276 void* allocBlitMemory(size_t sz) override { 277 return fBlitter->allocBlitMemory(sz); 278 } 279 280 private: 281 SkBlitter* fBlitter; 282 SkIRect fClipRect; 283 }; 284 #endif 285 286 /** Factory to set up the appropriate most-efficient wrapper blitter 287 to apply a clip. Returns a pointer to a member, so lifetime must 288 be managed carefully. 289 */ 290 class SkBlitterClipper { 291 public: 292 SkBlitter* apply(SkBlitter* blitter, const SkRegion* clip, 293 const SkIRect* bounds = nullptr); 294 295 private: 296 SkNullBlitter fNullBlitter; 297 SkRectClipBlitter fRectBlitter; 298 SkRgnClipBlitter fRgnBlitter; 299 }; 300 301 #endif 302