OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkSmallAllocator.h" | 8 #include "SkSmallAllocator.h" |
9 #include "SkSpriteBlitter.h" | 9 #include "SkSpriteBlitter.h" |
10 | 10 |
(...skipping 20 matching lines...) Expand all Loading... |
31 SkDEBUGFAIL("how did we get here?"); | 31 SkDEBUGFAIL("how did we get here?"); |
32 } | 32 } |
33 | 33 |
34 void SkSpriteBlitter::blitMask(const SkMask&, const SkIRect& clip) { | 34 void SkSpriteBlitter::blitMask(const SkMask&, const SkIRect& clip) { |
35 SkDEBUGFAIL("how did we get here?"); | 35 SkDEBUGFAIL("how did we get here?"); |
36 } | 36 } |
37 #endif | 37 #endif |
38 | 38 |
39 /////////////////////////////////////////////////////////////////////////////// | 39 /////////////////////////////////////////////////////////////////////////////// |
40 | 40 |
| 41 // Only valid if... |
| 42 // 1. src == dst format |
| 43 // 2. paint has no modifiers (i.e. alpha, colorfilter, etc.) |
| 44 // 3. xfermode needs no blending: e.g. kSrc_Mode or kSrcOver_Mode + opaque
src |
| 45 // |
| 46 class SkSpriteBlitter_memcpy : public SkSpriteBlitter { |
| 47 public: |
| 48 static bool Supports(const SkPixmap& dst, const SkPixmap& src, const SkPaint
& paint) { |
| 49 if (dst.colorType() != src.colorType()) { |
| 50 return false; |
| 51 } |
| 52 if (dst.info().profileType() != src.info().profileType()) { |
| 53 return false; |
| 54 } |
| 55 if (paint.getMaskFilter() || paint.getColorFilter() || paint.getImageFil
ter()) { |
| 56 return false; |
| 57 } |
| 58 if (0xFF != paint.getAlpha()) { |
| 59 return false; |
| 60 } |
| 61 SkXfermode::Mode mode; |
| 62 if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) { |
| 63 return false; |
| 64 } |
| 65 if (SkXfermode::kSrc_Mode == mode) { |
| 66 return true; |
| 67 } |
| 68 if (SkXfermode::kSrcOver_Mode == mode && src.isOpaque()) { |
| 69 return true; |
| 70 } |
| 71 return false; |
| 72 } |
| 73 |
| 74 SkSpriteBlitter_memcpy(const SkPixmap& src) : INHERITED(src) {} |
| 75 |
| 76 void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) ove
rride { |
| 77 SkASSERT(Supports(dst, fSource, paint)); |
| 78 this->INHERITED::setup(dst, left, top, paint); |
| 79 } |
| 80 |
| 81 void blitRect(int x, int y, int width, int height) override { |
| 82 SkASSERT(fDst.colorType() == fSource.colorType()); |
| 83 SkASSERT(fDst.info().profileType() == fSource.info().profileType()); |
| 84 SkASSERT(width > 0 && height > 0); |
| 85 |
| 86 char* dst = (char*)fDst.writable_addr(x, y); |
| 87 const char* src = (const char*)fSource.addr(x - fLeft, y - fTop); |
| 88 const size_t dstRB = fDst.rowBytes(); |
| 89 const size_t srcRB = fSource.rowBytes(); |
| 90 const size_t bytesToCopy = width << fSource.shiftPerPixel(); |
| 91 |
| 92 while (--height >= 0) { |
| 93 memcpy(dst, src, bytesToCopy); |
| 94 dst += dstRB; |
| 95 src += srcRB; |
| 96 } |
| 97 } |
| 98 |
| 99 typedef SkSpriteBlitter INHERITED; |
| 100 }; |
| 101 |
| 102 |
41 // returning null means the caller will call SkBlitter::Choose() and | 103 // returning null means the caller will call SkBlitter::Choose() and |
42 // have wrapped the source bitmap inside a shader | 104 // have wrapped the source bitmap inside a shader |
43 SkBlitter* SkBlitter::ChooseSprite(const SkPixmap& dst, const SkPaint& paint, | 105 SkBlitter* SkBlitter::ChooseSprite(const SkPixmap& dst, const SkPaint& paint, |
44 const SkPixmap& source, int left, int top, SkTBlitterAllocator* allocato
r) { | 106 const SkPixmap& source, int left, int top, SkTBlitterAllocator* allocato
r) { |
45 /* We currently ignore antialiasing and filtertype, meaning we will take ou
r | 107 /* We currently ignore antialiasing and filtertype, meaning we will take ou
r |
46 special blitters regardless of these settings. Ignoring filtertype seems
fine | 108 special blitters regardless of these settings. Ignoring filtertype seems
fine |
47 since by definition there is no scale in the matrix. Ignoring antialiasi
ng is | 109 since by definition there is no scale in the matrix. Ignoring antialiasi
ng is |
48 a bit of a hack, since we "could" pass in the fractional left/top for th
e bitmap, | 110 a bit of a hack, since we "could" pass in the fractional left/top for th
e bitmap, |
49 and respect that by blending the edges of the bitmap against the device.
To support | 111 and respect that by blending the edges of the bitmap against the device.
To support |
50 this we could either add more special blitters here, or detect antialias
ing in the | 112 this we could either add more special blitters here, or detect antialias
ing in the |
51 paint and return null if it is set, forcing the client to take the slow
shader case | 113 paint and return null if it is set, forcing the client to take the slow
shader case |
52 (which does respect soft edges). | 114 (which does respect soft edges). |
53 */ | 115 */ |
54 SkASSERT(allocator != nullptr); | 116 SkASSERT(allocator != nullptr); |
55 | 117 |
56 SkSpriteBlitter* blitter; | 118 SkSpriteBlitter* blitter; |
57 | 119 |
58 switch (dst.colorType()) { | 120 if (SkSpriteBlitter_memcpy::Supports(dst, source, paint)) { |
59 case kRGB_565_SkColorType: | 121 blitter = allocator->createT<SkSpriteBlitter_memcpy>(source); |
60 blitter = SkSpriteBlitter::ChooseD16(source, paint, allocator); | 122 } else { |
61 break; | 123 switch (dst.colorType()) { |
62 case kN32_SkColorType: | 124 case kRGB_565_SkColorType: |
63 if (dst.info().isSRGB()) { | 125 blitter = SkSpriteBlitter::ChooseD16(source, paint, allocator); |
64 blitter = SkSpriteBlitter::ChooseS32(source, paint, allocator); | 126 break; |
65 } else { | 127 case kN32_SkColorType: |
66 blitter = SkSpriteBlitter::ChooseL32(source, paint, allocator); | 128 if (dst.info().isSRGB()) { |
67 } | 129 blitter = SkSpriteBlitter::ChooseS32(source, paint, allocato
r); |
68 break; | 130 } else { |
69 case kRGBA_F16_SkColorType: | 131 blitter = SkSpriteBlitter::ChooseL32(source, paint, allocato
r); |
70 blitter = SkSpriteBlitter::ChooseF16(source, paint, allocator); | 132 } |
71 break; | 133 break; |
72 default: | 134 case kRGBA_F16_SkColorType: |
73 blitter = nullptr; | 135 blitter = SkSpriteBlitter::ChooseF16(source, paint, allocator); |
74 break; | 136 break; |
| 137 default: |
| 138 blitter = nullptr; |
| 139 break; |
| 140 } |
75 } | 141 } |
76 | 142 |
77 if (blitter) { | 143 if (blitter) { |
78 blitter->setup(dst, left, top, paint); | 144 blitter->setup(dst, left, top, paint); |
79 } | 145 } |
80 return blitter; | 146 return blitter; |
81 } | 147 } |
OLD | NEW |