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