aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorreed <reed@google.com>2014-09-10 10:20:24 -0700
committerDerek Sollenberger <djsollen@google.com>2014-09-10 16:00:31 -0400
commit9f23a27ed9961fd4575864e590eda328452895e7 (patch)
treeb4528a7759b306e5510dc0d8f32a6810aedbab1c
parentea0c3d4919fbf2af04a01a80f6b4510b460e1701 (diff)
downloadskia-9f23a27ed9961fd4575864e590eda328452895e7.tar.gz
make set3DMask virtual, so we can safely notify the shadercontextlollipop-dev
also boost preallocated storage to account for this combo of bitmapshader + emboss + colorfilter BUG=skia: R=djsollen@google.com Author: reed@google.com Review URL: https://codereview.chromium.org/563563002 bug:16307475 Change-Id: I404fa776511a27b7be1b3b41dcb06b8b828a4716
-rw-r--r--gm/emboss.cpp61
-rw-r--r--gyp/gmslides.gypi1
-rw-r--r--include/core/SkShader.h3
-rw-r--r--src/core/SkBitmapProcShader.h2
-rw-r--r--src/core/SkBlitter.cpp20
-rw-r--r--src/core/SkFilterShader.h5
6 files changed, 81 insertions, 11 deletions
diff --git a/gm/emboss.cpp b/gm/emboss.cpp
new file mode 100644
index 0000000000..c2ee49723f
--- /dev/null
+++ b/gm/emboss.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#include "SkBlurMaskFilter.h"
+#include "SkCanvas.h"
+#include "SkColorFilter.h"
+
+#include "SkColorFilter.h"
+static SkBitmap make_bm() {
+ SkBitmap bm;
+ bm.allocN32Pixels(100, 100);
+
+ SkCanvas canvas(bm);
+ canvas.clear(0);
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ canvas.drawCircle(50, 50, 50, paint);
+ return bm;
+}
+
+class EmbossGM : public skiagm::GM {
+public:
+ EmbossGM() {
+ }
+
+protected:
+ virtual SkString onShortName() SK_OVERRIDE {
+ return SkString("emboss");
+ }
+
+ virtual SkISize onISize() SK_OVERRIDE {
+ return SkISize::Make(600, 120);
+ }
+
+ virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+ SkPaint paint;
+ SkBitmap bm = make_bm();
+ canvas->drawBitmap(bm, 10, 10, &paint);
+
+ const SkScalar dir[] = { 1, 1, 1 };
+ paint.setMaskFilter(SkBlurMaskFilter::CreateEmboss(3, dir, 0.3f, 0.1f))->unref();
+ canvas->translate(bm.width() + SkIntToScalar(10), 0);
+ canvas->drawBitmap(bm, 10, 10, &paint);
+
+ // this combination of emboss+colorfilter used to crash -- so we exercise it to
+ // confirm that we have a fix.
+ paint.setColorFilter(SkColorFilter::CreateModeFilter(0xFFFF0000, SkXfermode::kSrcATop_Mode))->unref();
+ canvas->translate(bm.width() + SkIntToScalar(10), 0);
+ canvas->drawBitmap(bm, 10, 10, &paint);
+ }
+
+private:
+ typedef skiagm::GM INHERITED;
+};
+
+DEF_GM( return SkNEW(EmbossGM); )
diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi
index 18e589b3f4..ae3279f4b8 100644
--- a/gyp/gmslides.gypi
+++ b/gyp/gmslides.gypi
@@ -70,6 +70,7 @@
'../gm/drrect.cpp',
'../gm/etc1bitmap.cpp',
'../gm/extractbitmap.cpp',
+ '../gm/emboss.cpp',
'../gm/emptypath.cpp',
'../gm/fatpathfill.cpp',
'../gm/factory.cpp',
diff --git a/include/core/SkShader.h b/include/core/SkShader.h
index 5ec23ca94f..0b7a702cb1 100644
--- a/include/core/SkShader.h
+++ b/include/core/SkShader.h
@@ -192,6 +192,9 @@ public:
return SkShader::CanCallShadeSpan16(this->getFlags());
}
+ // Notification from blitter::blitMask in case we need to see the non-alpha channels
+ virtual void set3DMask(const SkMask*) {}
+
protected:
// Reference to shader, so we don't have to dupe information.
const SkShader& fShader;
diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h
index 08e8397a73..c12b548a5f 100644
--- a/src/core/SkBitmapProcShader.h
+++ b/src/core/SkBitmapProcShader.h
@@ -71,7 +71,7 @@ private:
// an Sk3DBlitter in SkDraw.cpp
// Note that some contexts may contain other contexts (e.g. for compose shaders), but we've not
// yet found a situation where the size below isn't big enough.
-typedef SkSmallAllocator<3, 768> SkTBlitterAllocator;
+typedef SkSmallAllocator<3, 1024> SkTBlitterAllocator;
// If alloc is non-NULL, it will be used to allocate the returned SkShader, and MUST outlive
// the SkShader.
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index cb84ec7d9d..2560ee968c 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -620,7 +620,7 @@ public:
}
}
- void setMask(const SkMask* mask) { fMask = mask; }
+ virtual void set3DMask(const SkMask* mask) SK_OVERRIDE { fMask = mask; }
virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE {
if (fProxyContext) {
@@ -737,9 +737,9 @@ private:
class Sk3DBlitter : public SkBlitter {
public:
- Sk3DBlitter(SkBlitter* proxy, Sk3DShader::Sk3DShaderContext* shaderContext)
+ Sk3DBlitter(SkBlitter* proxy, SkShader::Context* shaderContext)
: fProxy(proxy)
- , f3DShaderContext(shaderContext)
+ , fShaderContext(shaderContext)
{}
virtual void blitH(int x, int y, int width) {
@@ -761,13 +761,13 @@ public:
virtual void blitMask(const SkMask& mask, const SkIRect& clip) {
if (mask.fFormat == SkMask::k3D_Format) {
- f3DShaderContext->setMask(&mask);
+ fShaderContext->set3DMask(&mask);
((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
fProxy->blitMask(mask, clip);
((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
- f3DShaderContext->setMask(NULL);
+ fShaderContext->set3DMask(NULL);
} else {
fProxy->blitMask(mask, clip);
}
@@ -775,8 +775,8 @@ public:
private:
// Both pointers are unowned. They will be deleted by SkSmallAllocator.
- SkBlitter* fProxy;
- Sk3DShader::Sk3DShaderContext* f3DShaderContext;
+ SkBlitter* fProxy;
+ SkShader::Context* fShaderContext;
};
///////////////////////////////////////////////////////////////////////////////
@@ -984,9 +984,9 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
if (shader3D) {
SkBlitter* innerBlitter = blitter;
// innerBlitter was allocated by allocator, which will delete it.
- // We know shaderContext is of type Sk3DShaderContext because it belongs to shader3D.
- blitter = allocator->createT<Sk3DBlitter>(innerBlitter,
- static_cast<Sk3DShader::Sk3DShaderContext*>(shaderContext));
+ // We know shaderContext or its proxies is of type Sk3DShaderContext, so we need to
+ // wrapper the blitter to notify it when we see an emboss mask.
+ blitter = allocator->createT<Sk3DBlitter>(innerBlitter, shaderContext);
}
return blitter;
}
diff --git a/src/core/SkFilterShader.h b/src/core/SkFilterShader.h
index 1a4b71fe46..9c74a8c3af 100644
--- a/src/core/SkFilterShader.h
+++ b/src/core/SkFilterShader.h
@@ -30,6 +30,11 @@ public:
virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE;
virtual void shadeSpan16(int x, int y, uint16_t[], int count) SK_OVERRIDE;
+ virtual void set3DMask(const SkMask* mask) SK_OVERRIDE {
+ // forward to our proxy
+ fShaderContext->set3DMask(mask);
+ }
+
private:
SkShader::Context* fShaderContext;