| 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 |