From 76d5b477c92ef076374fc7ea9d551c798656bebd Mon Sep 17 00:00:00 2001 From: piotaixr Date: Tue, 22 Jul 2014 15:02:05 -0700 Subject: [PATCH] Now able to set the localMatrix when creating a SkShader from a SkImage BUG=skia:2771 R=junov@chromium.org, reed@chromium.org, bsalomon@chromium.org, bsalomon@google.com Author: piotaixr@chromium.org Review URL: https://codereview.chromium.org/409653003 --- include/core/SkImage.h | 4 +- src/image/SkImage.cpp | 6 +- src/image/SkImage_Base.h | 4 +- src/image/SkImage_Gpu.cpp | 11 +++- src/image/SkImage_Raster.cpp | 11 +++- tests/ImageNewShaderTest.cpp | 115 ++++++++++++++++++++++++----------- 6 files changed, 107 insertions(+), 44 deletions(-) diff --git a/include/core/SkImage.h b/include/core/SkImage.h index 54ef9f44e9..04e184370f 100644 --- a/include/core/SkImage.h +++ b/include/core/SkImage.h @@ -58,7 +58,9 @@ public: */ GrTexture* getTexture(); - virtual SkShader* newShader(SkShader::TileMode, SkShader::TileMode) const; + virtual SkShader* newShader(SkShader::TileMode, + SkShader::TileMode, + const SkMatrix* localMatrix = NULL) const; void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*); diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp index 9e136f5a27..c812f58eff 100644 --- a/src/image/SkImage.cpp +++ b/src/image/SkImage.cpp @@ -78,8 +78,10 @@ GrTexture* SkImage::getTexture() { return as_IB(this)->onGetTexture(); } -SkShader* SkImage::newShader(SkShader::TileMode tileX, SkShader::TileMode tileY) const { - return as_IB(this)->onNewShader(tileX, tileY); +SkShader* SkImage::newShader(SkShader::TileMode tileX, + SkShader::TileMode tileY, + const SkMatrix* localMatrix) const { + return as_IB(this)->onNewShader(tileX, tileY, localMatrix); } SkData* SkImage::encode(SkImageEncoder::Type type, int quality) const { diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h index 1a54157b8e..752afedc09 100644 --- a/src/image/SkImage_Base.h +++ b/src/image/SkImage_Base.h @@ -31,7 +31,9 @@ public: // but only inspect them (or encode them). virtual bool getROPixels(SkBitmap*) const { return false; } - virtual SkShader* onNewShader(SkShader::TileMode, SkShader::TileMode) const { return NULL; }; + virtual SkShader* onNewShader(SkShader::TileMode, + SkShader::TileMode, + const SkMatrix* localMatrix) const { return NULL; }; private: typedef SkImage INHERITED; }; diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 7a73c7453b..81114b0fe8 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -27,7 +27,9 @@ public: GrTexture* getTexture() { return fBitmap.getTexture(); } - virtual SkShader* onNewShader(SkShader::TileMode, SkShader::TileMode) const SK_OVERRIDE; + virtual SkShader* onNewShader(SkShader::TileMode, + SkShader::TileMode, + const SkMatrix* localMatrix) const SK_OVERRIDE; private: SkBitmap fBitmap; @@ -45,8 +47,11 @@ SkImage_Gpu::SkImage_Gpu(const SkBitmap& bitmap) SkImage_Gpu::~SkImage_Gpu() { } -SkShader* SkImage_Gpu::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY) const { - return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, NULL); +SkShader* SkImage_Gpu::onNewShader(SkShader::TileMode tileX, + SkShader::TileMode tileY, + const SkMatrix* localMatrix) const +{ + return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, localMatrix); } void SkImage_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp index 464a4ba7a4..828d80276c 100644 --- a/src/image/SkImage_Raster.cpp +++ b/src/image/SkImage_Raster.cpp @@ -64,7 +64,9 @@ public: SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); } - virtual SkShader* onNewShader(SkShader::TileMode, SkShader::TileMode) const SK_OVERRIDE; + virtual SkShader* onNewShader(SkShader::TileMode, + SkShader::TileMode, + const SkMatrix* localMatrix) const SK_OVERRIDE; private: SkImage_Raster() : INHERITED(0, 0) {} @@ -113,8 +115,11 @@ SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes SkImage_Raster::~SkImage_Raster() {} -SkShader* SkImage_Raster::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY) const { - return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, NULL); +SkShader* SkImage_Raster::onNewShader(SkShader::TileMode tileX, + SkShader::TileMode tileY, + const SkMatrix* localMatrix) const +{ + return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, localMatrix); } void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) { diff --git a/tests/ImageNewShaderTest.cpp b/tests/ImageNewShaderTest.cpp index f34d066f6b..dfc5a24c33 100644 --- a/tests/ImageNewShaderTest.cpp +++ b/tests/ImageNewShaderTest.cpp @@ -17,49 +17,97 @@ #include "Test.h" void testBitmapEquality(skiatest::Reporter* reporter, SkBitmap& bm1, SkBitmap& bm2) { - bm1.lockPixels(); - bm2.lockPixels(); + SkAutoLockPixels lockBm1(bm1); + SkAutoLockPixels lockBm2(bm2); 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); +void paintSource(SkSurface* sourceSurface) { + SkCanvas* sourceCanvas = sourceSurface->getCanvas(); + sourceCanvas->clear(0xFFDEDEDE); - SkAutoTUnref rasterImage(source->newImageSnapshot()); - SkAutoTUnref rasterShader(rasterImage->newShader( + SkPaint paintColor; + paintColor.setColor(0xFFFF0000); + paintColor.setStyle(SkPaint::kFill_Style); + + SkRect rect = SkRect::MakeXYWH( + SkIntToScalar(1), + SkIntToScalar(0), + SkIntToScalar(1), + SkIntToScalar(sourceSurface->height())); + + sourceCanvas->drawRect(rect, paintColor); +} + +void runShaderTest(skiatest::Reporter* reporter, SkSurface* sourceSurface, SkSurface* destinationSurface, SkImageInfo& info) { + paintSource(sourceSurface); + + SkAutoTUnref sourceImage(sourceSurface->newImageSnapshot()); + SkAutoTUnref sourceShader(sourceImage->newShader( SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode)); SkPaint paint; - paint.setShader(rasterShader); - SkCanvas* canvasDest = destination->getCanvas(); - canvasDest->clear(SK_ColorTRANSPARENT); - canvasDest->drawPaint(paint); + paint.setShader(sourceShader); - SkIRect rect = SkIRect::MakeXYWH(0, 0, 5, 5); + SkCanvas* destinationCanvas = destinationSurface->getCanvas(); + destinationCanvas->clear(SK_ColorTRANSPARENT); + destinationCanvas->drawPaint(paint); + + SkIRect rect = SkIRect::MakeWH(info.width(), info.height()); SkBitmap bmOrig; - rasterCanvas->readPixels(rect, &bmOrig); + sourceSurface->getCanvas()->readPixels(rect, &bmOrig); + SkBitmap bm; - canvasDest->readPixels(rect, &bm); + destinationCanvas->readPixels(rect, &bm); testBitmapEquality(reporter, bmOrig, bm); + + + + // Test with a translated shader + SkMatrix matrix; + matrix.setTranslate(SkIntToScalar(-1), SkIntToScalar(0)); + + SkAutoTUnref sourceShaderTranslated(sourceImage->newShader( + SkShader::kRepeat_TileMode, + SkShader::kRepeat_TileMode, + &matrix)); + + destinationCanvas->clear(SK_ColorTRANSPARENT); + + SkPaint paintTranslated; + paintTranslated.setShader(sourceShaderTranslated); + + destinationCanvas->drawPaint(paintTranslated); + + SkBitmap bmt; + destinationCanvas->readPixels(rect, &bmt); + + // Test correctness + { + SkAutoLockPixels lockBm(bmt); + for (int y = 0; y < info.height(); y++) { + REPORTER_ASSERT(reporter, 0xFFFF0000 == bmt.getColor(0, y)); + + for (int x = 1; x < info.width(); x++) { + REPORTER_ASSERT(reporter, 0xFFDEDEDE == bmt.getColor(x, y)); + } + } + } } DEF_TEST(ImageNewShader, reporter) { SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5); - SkAutoTUnref srcSurface(SkSurface::NewRaster(info)); - SkAutoTUnref dstSurface(SkSurface::NewRaster(info)); + SkAutoTUnref sourceSurface(SkSurface::NewRaster(info)); + SkAutoTUnref destinationSurface(SkSurface::NewRaster(info)); - runShaderTest(reporter, srcSurface.get(), dstSurface.get(), info); + runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info); } #if SK_SUPPORT_GPU @@ -67,32 +115,32 @@ DEF_TEST(ImageNewShader, reporter) { void gpuToGpu(skiatest::Reporter* reporter, GrContext* context) { SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5); - SkAutoTUnref srcSurface(SkSurface::NewRenderTarget(context, info)); - SkAutoTUnref dstSurface(SkSurface::NewRenderTarget(context, info)); + SkAutoTUnref sourceSurface(SkSurface::NewRenderTarget(context, info)); + SkAutoTUnref destinationSurface(SkSurface::NewRenderTarget(context, info)); - runShaderTest(reporter, srcSurface.get(), dstSurface.get(), info); + runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info); } void gpuToRaster(skiatest::Reporter* reporter, GrContext* context) { SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5); - SkAutoTUnref srcSurface(SkSurface::NewRenderTarget(context, info)); - SkAutoTUnref dstSurface(SkSurface::NewRaster(info)); + SkAutoTUnref sourceSurface(SkSurface::NewRenderTarget(context, info)); + SkAutoTUnref destinationSurface(SkSurface::NewRaster(info)); - runShaderTest(reporter, srcSurface.get(), dstSurface.get(), info); + runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info); } void rasterToGpu(skiatest::Reporter* reporter, GrContext* context) { SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5); - SkAutoTUnref srcSurface(SkSurface::NewRaster(info)); - SkAutoTUnref dstSurface(SkSurface::NewRenderTarget(context, info)); + SkAutoTUnref sourceSurface(SkSurface::NewRaster(info)); + SkAutoTUnref destinationSurface(SkSurface::NewRenderTarget(context, info)); - runShaderTest(reporter, srcSurface.get(), dstSurface.get(), info); + runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info); } DEF_GPUTEST(ImageNewShader_GPU, reporter, factory) { - for (int i= 0; i < GrContextFactory::kGLContextTypeCnt; ++i) { + for (int i = 0; i < GrContextFactory::kGLContextTypeCnt; ++i) { GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i; if (!GrContextFactory::IsRenderingGLContext(glCtxType)) { @@ -105,14 +153,13 @@ DEF_GPUTEST(ImageNewShader_GPU, reporter, factory) { continue; } - // GPU -> GPU + // GPU -> GPU gpuToGpu(reporter, context); - // GPU -> RASTER + // GPU -> RASTER gpuToRaster(reporter, context); - - // RASTER -> GPU + // RASTER -> GPU rasterToGpu(reporter, context); } }