OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
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 "SkBitmapProcShader.h" | 8 #include "SkBitmapProcShader.h" |
9 #include "SkBitmapProvider.h" | 9 #include "SkBitmapProvider.h" |
| 10 #include "SkColorShader.h" |
| 11 #include "SkColorTable.h" |
| 12 #include "SkEmptyShader.h" |
10 #include "SkImage_Base.h" | 13 #include "SkImage_Base.h" |
11 #include "SkImageShader.h" | 14 #include "SkImageShader.h" |
12 #include "SkReadBuffer.h" | 15 #include "SkReadBuffer.h" |
13 #include "SkWriteBuffer.h" | 16 #include "SkWriteBuffer.h" |
14 | 17 |
15 SkImageShader::SkImageShader(const SkImage* img, TileMode tmx, TileMode tmy, con
st SkMatrix* matrix) | 18 SkImageShader::SkImageShader(const SkImage* img, TileMode tmx, TileMode tmy, con
st SkMatrix* matrix) |
16 : INHERITED(matrix) | 19 : INHERITED(matrix) |
17 , fImage(SkRef(img)) | 20 , fImage(SkRef(img)) |
18 , fTileModeX(tmx) | 21 , fTileModeX(tmx) |
19 , fTileModeY(tmy) | 22 , fTileModeY(tmy) |
(...skipping 16 matching lines...) Expand all Loading... |
36 buffer.writeUInt(fTileModeY); | 39 buffer.writeUInt(fTileModeY); |
37 buffer.writeMatrix(this->getLocalMatrix()); | 40 buffer.writeMatrix(this->getLocalMatrix()); |
38 buffer.writeImage(fImage); | 41 buffer.writeImage(fImage); |
39 } | 42 } |
40 | 43 |
41 bool SkImageShader::isOpaque() const { | 44 bool SkImageShader::isOpaque() const { |
42 return fImage->isOpaque(); | 45 return fImage->isOpaque(); |
43 } | 46 } |
44 | 47 |
45 size_t SkImageShader::onContextSize(const ContextRec& rec) const { | 48 size_t SkImageShader::onContextSize(const ContextRec& rec) const { |
46 return SkBitmapProcShader::ContextSize(rec, SkBitmapProvider(fImage).info())
; | 49 return SkBitmapProcLegacyShader::ContextSize(rec, SkBitmapProvider(fImage).i
nfo()); |
47 } | 50 } |
48 | 51 |
49 SkShader::Context* SkImageShader::onCreateContext(const ContextRec& rec, void* s
torage) const { | 52 SkShader::Context* SkImageShader::onCreateContext(const ContextRec& rec, void* s
torage) const { |
50 return SkBitmapProcShader::MakeContext(*this, fTileModeX, fTileModeY, | 53 return SkBitmapProcLegacyShader::MakeContext(*this, fTileModeX, fTileModeY, |
51 SkBitmapProvider(fImage), rec, storag
e); | 54 SkBitmapProvider(fImage), rec, storag
e); |
52 } | 55 } |
53 | 56 |
54 SkImage* SkImageShader::onIsAImage(SkMatrix* texM, TileMode xy[]) const { | 57 SkImage* SkImageShader::onIsAImage(SkMatrix* texM, TileMode xy[]) const { |
55 if (texM) { | 58 if (texM) { |
56 *texM = this->getLocalMatrix(); | 59 *texM = this->getLocalMatrix(); |
57 } | 60 } |
58 if (xy) { | 61 if (xy) { |
59 xy[0] = (TileMode)fTileModeX; | 62 xy[0] = (TileMode)fTileModeX; |
60 xy[1] = (TileMode)fTileModeY; | 63 xy[1] = (TileMode)fTileModeY; |
(...skipping 13 matching lines...) Expand all Loading... |
74 if (texM) { | 77 if (texM) { |
75 *texM = this->getLocalMatrix(); | 78 *texM = this->getLocalMatrix(); |
76 } | 79 } |
77 if (xy) { | 80 if (xy) { |
78 xy[0] = (TileMode)fTileModeX; | 81 xy[0] = (TileMode)fTileModeX; |
79 xy[1] = (TileMode)fTileModeY; | 82 xy[1] = (TileMode)fTileModeY; |
80 } | 83 } |
81 return true; | 84 return true; |
82 } | 85 } |
83 | 86 |
| 87 static bool bitmap_is_too_big(int w, int h) { |
| 88 // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it |
| 89 // communicates between its matrix-proc and its sampler-proc. Until we can |
| 90 // widen that, we have to reject bitmaps that are larger. |
| 91 // |
| 92 static const int kMaxSize = 65535; |
| 93 |
| 94 return w > kMaxSize || h > kMaxSize; |
| 95 } |
| 96 |
| 97 // returns true and set color if the bitmap can be drawn as a single color |
| 98 // (for efficiency) |
| 99 static bool can_use_color_shader(const SkImage* image, SkColor* color) { |
| 100 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK |
| 101 // HWUI does not support color shaders (see b/22390304) |
| 102 return false; |
| 103 #endif |
| 104 |
| 105 if (1 != image->width() || 1 != image->height()) { |
| 106 return false; |
| 107 } |
| 108 |
| 109 SkPixmap pmap; |
| 110 if (!image->peekPixels(&pmap)) { |
| 111 return false; |
| 112 } |
| 113 |
| 114 switch (pmap.colorType()) { |
| 115 case kN32_SkColorType: |
| 116 *color = SkUnPreMultiply::PMColorToColor(*pmap.addr32(0, 0)); |
| 117 return true; |
| 118 case kRGB_565_SkColorType: |
| 119 *color = SkPixel16ToColor(*pmap.addr16(0, 0)); |
| 120 return true; |
| 121 case kIndex_8_SkColorType: { |
| 122 const SkColorTable& ctable = *pmap.ctable(); |
| 123 *color = SkUnPreMultiply::PMColorToColor(ctable[*pmap.addr8(0, 0)]); |
| 124 return true; |
| 125 } |
| 126 default: // just skip the other configs for now |
| 127 break; |
| 128 } |
| 129 return false; |
| 130 } |
| 131 |
84 sk_sp<SkShader> SkImageShader::Make(const SkImage* image, TileMode tx, TileMode
ty, | 132 sk_sp<SkShader> SkImageShader::Make(const SkImage* image, TileMode tx, TileMode
ty, |
85 const SkMatrix* localMatrix) { | 133 const SkMatrix* localMatrix, |
86 if (!image) { | 134 SkTBlitterAllocator* allocator) { |
87 return nullptr; | 135 SkShader* shader; |
| 136 SkColor color; |
| 137 if (!image || bitmap_is_too_big(image->width(), image->height())) { |
| 138 if (nullptr == allocator) { |
| 139 shader = new SkEmptyShader; |
| 140 } else { |
| 141 shader = allocator->createT<SkEmptyShader>(); |
| 142 } |
| 143 } else if (can_use_color_shader(image, &color)) { |
| 144 if (nullptr == allocator) { |
| 145 shader = new SkColorShader(color); |
| 146 } else { |
| 147 shader = allocator->createT<SkColorShader>(color); |
| 148 } |
| 149 } else { |
| 150 if (nullptr == allocator) { |
| 151 shader = new SkImageShader(image, tx, ty, localMatrix); |
| 152 } else { |
| 153 shader = allocator->createT<SkImageShader>(image, tx, ty, localMatri
x); |
| 154 } |
88 } | 155 } |
89 return sk_sp<SkShader>(new SkImageShader(image, tx, ty, localMatrix)); | 156 return sk_sp<SkShader>(shader); |
90 } | 157 } |
91 | 158 |
92 #ifndef SK_IGNORE_TO_STRING | 159 #ifndef SK_IGNORE_TO_STRING |
93 void SkImageShader::toString(SkString* str) const { | 160 void SkImageShader::toString(SkString* str) const { |
94 const char* gTileModeName[SkShader::kTileModeCount] = { | 161 const char* gTileModeName[SkShader::kTileModeCount] = { |
95 "clamp", "repeat", "mirror" | 162 "clamp", "repeat", "mirror" |
96 }; | 163 }; |
97 | 164 |
98 str->appendf("ImageShader: ((%s %s) ", gTileModeName[fTileModeX], gTileModeN
ame[fTileModeY]); | 165 str->appendf("ImageShader: ((%s %s) ", gTileModeName[fTileModeX], gTileModeN
ame[fTileModeY]); |
99 fImage->toString(str); | 166 fImage->toString(str); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 inner = GrSimpleTextureEffect::Make(texture, nullptr, matrix, params); | 221 inner = GrSimpleTextureEffect::Make(texture, nullptr, matrix, params); |
155 } | 222 } |
156 | 223 |
157 if (GrPixelConfigIsAlphaOnly(texture->config())) { | 224 if (GrPixelConfigIsAlphaOnly(texture->config())) { |
158 return inner; | 225 return inner; |
159 } | 226 } |
160 return sk_sp<GrFragmentProcessor>(GrFragmentProcessor::MulOutputByInputAlpha
(std::move(inner))); | 227 return sk_sp<GrFragmentProcessor>(GrFragmentProcessor::MulOutputByInputAlpha
(std::move(inner))); |
161 } | 228 } |
162 | 229 |
163 #endif | 230 #endif |
| 231 |
| 232 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 233 #include "SkImagePriv.h" |
| 234 |
| 235 sk_sp<SkShader> SkMakeBitmapShader(const SkBitmap& src, SkShader::TileMode tmx, |
| 236 SkShader::TileMode tmy, const SkMatrix* local
Matrix, |
| 237 SkTBlitterAllocator* allocator) { |
| 238 ForceCopyMode mode = allocator ? kNever_ForceCopyMode : kNo_ForceCopyMode; |
| 239 return SkImageShader::Make(SkMakeImageFromRasterBitmap(src, mode).get(), |
| 240 tmx, tmy, localMatrix, allocator); |
| 241 } |
| 242 |
| 243 static sk_sp<SkFlattenable> SkBitmapProcShader_CreateProc(SkReadBuffer& buffer)
{ |
| 244 SkMatrix lm; |
| 245 buffer.readMatrix(&lm); |
| 246 SkBitmap bm; |
| 247 if (!buffer.readBitmap(&bm)) { |
| 248 return nullptr; |
| 249 } |
| 250 bm.setImmutable(); |
| 251 SkShader::TileMode mx = (SkShader::TileMode)buffer.readUInt(); |
| 252 SkShader::TileMode my = (SkShader::TileMode)buffer.readUInt(); |
| 253 return SkShader::MakeBitmapShader(bm, mx, my, &lm); |
| 254 } |
| 255 |
| 256 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShader) |
| 257 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkImageShader) |
| 258 SkFlattenable::Register("SkBitmapProcShader", SkBitmapProcShader_CreateProc, kSk
Shader_Type); |
| 259 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| 260 |
OLD | NEW |