Deleted SkImage::newShaderClamp: not used, not implemented.
Implemented SkImage::newShader.
BUG=skia:2701, 344804
R=junov@chromium.org, reed@chromium.org, bsalomon@chromium.org, reed@google.com
Author: piotaixr@chromium.org
Review URL: https://codereview.chromium.org/345463009
diff --git a/gyp/tests.gypi b/gyp/tests.gypi
index 66741d5..ec12461 100644
--- a/gyp/tests.gypi
+++ b/gyp/tests.gypi
@@ -102,6 +102,7 @@
'../tests/ImageCacheTest.cpp',
'../tests/ImageDecodingTest.cpp',
'../tests/ImageFilterTest.cpp',
+ '../tests/ImageNewShaderTest.cpp',
'../tests/InfRectTest.cpp',
'../tests/InterpolatorTest.cpp',
'../tests/JpegTest.cpp',
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index c9f9396..54ef9f4 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -12,17 +12,14 @@
#include "SkImageEncoder.h"
#include "SkRefCnt.h"
#include "SkScalar.h"
+#include "SkShader.h"
class SkData;
class SkCanvas;
class SkPaint;
-class SkShader;
class GrContext;
class GrTexture;
-// need for TileMode
-#include "SkShader.h"
-
/**
* SkImage is an abstraction for drawing a rectagle of pixels, though the
* particular type of image could be actually storing its data on the GPU, or
@@ -61,8 +58,7 @@
*/
GrTexture* getTexture();
- SkShader* newShaderClamp() const;
- SkShader* newShader(SkShader::TileMode, SkShader::TileMode) const;
+ virtual SkShader* newShader(SkShader::TileMode, SkShader::TileMode) const;
void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index e0a13f9..9e136f5 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -78,6 +78,10 @@
return as_IB(this)->onGetTexture();
}
+SkShader* SkImage::newShader(SkShader::TileMode tileX, SkShader::TileMode tileY) const {
+ return as_IB(this)->onNewShader(tileX, tileY);
+}
+
SkData* SkImage::encode(SkImageEncoder::Type type, int quality) const {
SkBitmap bm;
if (as_IB(this)->getROPixels(&bm)) {
diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h
index 9fdfcd2..1a54157 100644
--- a/src/image/SkImage_Base.h
+++ b/src/image/SkImage_Base.h
@@ -31,6 +31,7 @@
// but only inspect them (or encode them).
virtual bool getROPixels(SkBitmap*) const { return false; }
+ virtual SkShader* onNewShader(SkShader::TileMode, SkShader::TileMode) const { return NULL; };
private:
typedef SkImage INHERITED;
};
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index aa08f44..7a73c74 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -27,6 +27,7 @@
GrTexture* getTexture() { return fBitmap.getTexture(); }
+ virtual SkShader* onNewShader(SkShader::TileMode, SkShader::TileMode) const SK_OVERRIDE;
private:
SkBitmap fBitmap;
@@ -44,6 +45,10 @@
SkImage_Gpu::~SkImage_Gpu() {
}
+SkShader* SkImage_Gpu::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY) const {
+ return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, NULL);
+}
+
void SkImage_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y,
const SkPaint* paint) {
canvas->drawBitmap(fBitmap, x, y, paint);
diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp
index 68fc1b3..464a4ba 100644
--- a/src/image/SkImage_Raster.cpp
+++ b/src/image/SkImage_Raster.cpp
@@ -64,6 +64,8 @@
SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
+ virtual SkShader* onNewShader(SkShader::TileMode, SkShader::TileMode) const SK_OVERRIDE;
+
private:
SkImage_Raster() : INHERITED(0, 0) {}
@@ -111,6 +113,10 @@
SkImage_Raster::~SkImage_Raster() {}
+SkShader* SkImage_Raster::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY) const {
+ return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, NULL);
+}
+
void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
canvas->drawBitmap(fBitmap, x, y, paint);
}
diff --git a/tests/ImageNewShaderTest.cpp b/tests/ImageNewShaderTest.cpp
new file mode 100644
index 0000000..ac6cde0
--- /dev/null
+++ b/tests/ImageNewShaderTest.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#if SK_SUPPORT_GPU
+#include "GrContextFactory.h"
+#endif
+#include "SkCanvas.h"
+#include "SkImage.h"
+#include "SkShader.h"
+#include "SkSurface.h"
+
+#include "Test.h"
+
+void testBitmapEquality(skiatest::Reporter* reporter, SkBitmap& bm1, SkBitmap& bm2) {
+ bm1.lockPixels();
+ bm2.lockPixels();
+
+ REPORTER_ASSERT(reporter, bm1.getSize() == bm2.getSize());
+ REPORTER_ASSERT(reporter, 0 == memcmp(bm1.getPixels(), bm2.getPixels(), bm1.getSize()));
+
+ bm2.unlockPixels();
+ bm1.unlockPixels();
+}
+
+void runShaderTest(skiatest::Reporter* reporter, SkSurface* source, SkSurface* destination, SkImageInfo& info) {
+ SkCanvas* rasterCanvas = source->getCanvas();
+ rasterCanvas->drawColor(0xFFDEDEDE, SkXfermode::kSrc_Mode);
+
+ SkAutoTUnref<SkImage> rasterImage(source->newImageSnapshot());
+ SkAutoTUnref<SkShader> rasterShader(rasterImage->newShader(
+ SkShader::kRepeat_TileMode,
+ SkShader::kRepeat_TileMode));
+
+ SkPaint paint;
+ paint.setShader(rasterShader);
+ SkCanvas* canvasDest = destination->getCanvas();
+ canvasDest->clear(SK_ColorTRANSPARENT);
+ canvasDest->drawPaint(paint);
+
+ SkIRect rect = SkIRect::MakeXYWH(0, 0, 5, 5);
+
+ SkBitmap bmOrig;
+ rasterCanvas->readPixels(rect, &bmOrig);
+
+ SkBitmap bm;
+ canvasDest->readPixels(rect, &bm);
+
+ testBitmapEquality(reporter, bmOrig, bm);
+}
+
+DEF_TEST(ImageNewShader, reporter) {
+ SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
+
+ SkAutoTUnref<SkSurface> srcSurface(SkSurface::NewRaster(info));
+ SkAutoTUnref<SkSurface> dstSurface(SkSurface::NewRaster(info));
+
+ runShaderTest(reporter, srcSurface.get(), dstSurface.get(), info);
+}
+
+#if SK_SUPPORT_GPU
+
+void gpuToGpu(skiatest::Reporter* reporter, GrContext* context) {
+ SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
+
+ SkAutoTUnref<SkSurface> srcSurface(SkSurface::NewRenderTarget(context, info));
+ SkAutoTUnref<SkSurface> dstSurface(SkSurface::NewRenderTarget(context, info));
+
+ runShaderTest(reporter, srcSurface.get(), dstSurface.get(), info);
+}
+
+void gpuToRaster(skiatest::Reporter* reporter, GrContext* context) {
+ SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
+
+ SkAutoTUnref<SkSurface> srcSurface(SkSurface::NewRenderTarget(context, info));
+ SkAutoTUnref<SkSurface> dstSurface(SkSurface::NewRaster(info));
+
+ runShaderTest(reporter, srcSurface.get(), dstSurface.get(), info);
+}
+
+void rasterToGpu(skiatest::Reporter* reporter, GrContext* context) {
+ SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
+
+ SkAutoTUnref<SkSurface> srcSurface(SkSurface::NewRaster(info));
+ SkAutoTUnref<SkSurface> dstSurface(SkSurface::NewRenderTarget(context, info));
+
+ runShaderTest(reporter, srcSurface.get(), dstSurface.get(), info);
+}
+
+DEF_GPUTEST(ImageNewShader_GPU, reporter, factory) {
+ GrContext* context = factory->get(GrContextFactory::kNative_GLContextType);
+
+ // GPU -> GPU
+ gpuToGpu(reporter, context);
+
+ // GPU -> RASTER
+ gpuToRaster(reporter, context);
+
+
+ // RASTER -> GPU
+ rasterToGpu(reporter, context);
+}
+
+#endif