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