Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: src/image/SkImageShader.cpp

Issue 2195893002: Always return ImageShader, even from SkShader::MakeBitmapShader (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: update serialize-8888 ignore list: skbug.com/5595 Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698