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

Unified 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, 5 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 side-by-side diff with in-line comments
Download patch
Index: src/image/SkImageShader.cpp
diff --git a/src/image/SkImageShader.cpp b/src/image/SkImageShader.cpp
index 12caa7a3d2862024907e710a6bfae6a6a081ea65..a486f71dfde21365f54db34b6619be9b2508ebaf 100644
--- a/src/image/SkImageShader.cpp
+++ b/src/image/SkImageShader.cpp
@@ -7,6 +7,9 @@
#include "SkBitmapProcShader.h"
#include "SkBitmapProvider.h"
+#include "SkColorShader.h"
+#include "SkColorTable.h"
+#include "SkEmptyShader.h"
#include "SkImage_Base.h"
#include "SkImageShader.h"
#include "SkReadBuffer.h"
@@ -43,11 +46,11 @@ bool SkImageShader::isOpaque() const {
}
size_t SkImageShader::onContextSize(const ContextRec& rec) const {
- return SkBitmapProcShader::ContextSize(rec, SkBitmapProvider(fImage).info());
+ return SkBitmapProcLegacyShader::ContextSize(rec, SkBitmapProvider(fImage).info());
}
SkShader::Context* SkImageShader::onCreateContext(const ContextRec& rec, void* storage) const {
- return SkBitmapProcShader::MakeContext(*this, fTileModeX, fTileModeY,
+ return SkBitmapProcLegacyShader::MakeContext(*this, fTileModeX, fTileModeY,
SkBitmapProvider(fImage), rec, storage);
}
@@ -81,12 +84,76 @@ bool SkImageShader::onIsABitmap(SkBitmap* texture, SkMatrix* texM, TileMode xy[]
return true;
}
+static bool bitmap_is_too_big(int w, int h) {
+ // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it
+ // communicates between its matrix-proc and its sampler-proc. Until we can
+ // widen that, we have to reject bitmaps that are larger.
+ //
+ static const int kMaxSize = 65535;
+
+ return w > kMaxSize || h > kMaxSize;
+}
+
+// returns true and set color if the bitmap can be drawn as a single color
+// (for efficiency)
+static bool can_use_color_shader(const SkImage* image, SkColor* color) {
+#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
+ // HWUI does not support color shaders (see b/22390304)
+ return false;
+#endif
+
+ if (1 != image->width() || 1 != image->height()) {
+ return false;
+ }
+
+ SkPixmap pmap;
+ if (!image->peekPixels(&pmap)) {
+ return false;
+ }
+
+ switch (pmap.colorType()) {
+ case kN32_SkColorType:
+ *color = SkUnPreMultiply::PMColorToColor(*pmap.addr32(0, 0));
+ return true;
+ case kRGB_565_SkColorType:
+ *color = SkPixel16ToColor(*pmap.addr16(0, 0));
+ return true;
+ case kIndex_8_SkColorType: {
+ const SkColorTable& ctable = *pmap.ctable();
+ *color = SkUnPreMultiply::PMColorToColor(ctable[*pmap.addr8(0, 0)]);
+ return true;
+ }
+ default: // just skip the other configs for now
+ break;
+ }
+ return false;
+}
+
sk_sp<SkShader> SkImageShader::Make(const SkImage* image, TileMode tx, TileMode ty,
- const SkMatrix* localMatrix) {
- if (!image) {
- return nullptr;
+ const SkMatrix* localMatrix,
+ SkTBlitterAllocator* allocator) {
+ SkShader* shader;
+ SkColor color;
+ if (!image || bitmap_is_too_big(image->width(), image->height())) {
+ if (nullptr == allocator) {
+ shader = new SkEmptyShader;
+ } else {
+ shader = allocator->createT<SkEmptyShader>();
+ }
+ } else if (can_use_color_shader(image, &color)) {
+ if (nullptr == allocator) {
+ shader = new SkColorShader(color);
+ } else {
+ shader = allocator->createT<SkColorShader>(color);
+ }
+ } else {
+ if (nullptr == allocator) {
+ shader = new SkImageShader(image, tx, ty, localMatrix);
+ } else {
+ shader = allocator->createT<SkImageShader>(image, tx, ty, localMatrix);
+ }
}
- return sk_sp<SkShader>(new SkImageShader(image, tx, ty, localMatrix));
+ return sk_sp<SkShader>(shader);
}
#ifndef SK_IGNORE_TO_STRING
@@ -161,3 +228,33 @@ sk_sp<GrFragmentProcessor> SkImageShader::asFragmentProcessor(const AsFPArgs& ar
}
#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+#include "SkImagePriv.h"
+
+sk_sp<SkShader> SkMakeBitmapShader(const SkBitmap& src, SkShader::TileMode tmx,
+ SkShader::TileMode tmy, const SkMatrix* localMatrix,
+ SkTBlitterAllocator* allocator) {
+ ForceCopyMode mode = allocator ? kNever_ForceCopyMode : kNo_ForceCopyMode;
+ return SkImageShader::Make(SkMakeImageFromRasterBitmap(src, mode).get(),
+ tmx, tmy, localMatrix, allocator);
+}
+
+static sk_sp<SkFlattenable> SkBitmapProcShader_CreateProc(SkReadBuffer& buffer) {
+ SkMatrix lm;
+ buffer.readMatrix(&lm);
+ SkBitmap bm;
+ if (!buffer.readBitmap(&bm)) {
+ return nullptr;
+ }
+ bm.setImmutable();
+ SkShader::TileMode mx = (SkShader::TileMode)buffer.readUInt();
+ SkShader::TileMode my = (SkShader::TileMode)buffer.readUInt();
+ return SkShader::MakeBitmapShader(bm, mx, my, &lm);
+}
+
+SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShader)
+SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkImageShader)
+SkFlattenable::Register("SkBitmapProcShader", SkBitmapProcShader_CreateProc, kSkShader_Type);
+SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
+

Powered by Google App Engine
This is Rietveld 408576698