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
This commit is contained in:
piotaixr 2014-07-22 15:02:05 -07:00 committed by Commit bot
parent 85d36525c6
commit 76d5b477c9
6 changed files with 107 additions and 44 deletions

View File

@ -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*);

View File

@ -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 {

View File

@ -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;
};

View File

@ -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,

View File

@ -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) {

View File

@ -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<SkImage> rasterImage(source->newImageSnapshot());
SkAutoTUnref<SkShader> 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<SkImage> sourceImage(sourceSurface->newImageSnapshot());
SkAutoTUnref<SkShader> 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<SkShader> 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<SkSurface> srcSurface(SkSurface::NewRaster(info));
SkAutoTUnref<SkSurface> dstSurface(SkSurface::NewRaster(info));
SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRaster(info));
SkAutoTUnref<SkSurface> 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<SkSurface> srcSurface(SkSurface::NewRenderTarget(context, info));
SkAutoTUnref<SkSurface> dstSurface(SkSurface::NewRenderTarget(context, info));
SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRenderTarget(context, info));
SkAutoTUnref<SkSurface> 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<SkSurface> srcSurface(SkSurface::NewRenderTarget(context, info));
SkAutoTUnref<SkSurface> dstSurface(SkSurface::NewRaster(info));
SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRenderTarget(context, info));
SkAutoTUnref<SkSurface> 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<SkSurface> srcSurface(SkSurface::NewRaster(info));
SkAutoTUnref<SkSurface> dstSurface(SkSurface::NewRenderTarget(context, info));
SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRaster(info));
SkAutoTUnref<SkSurface> 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);
}
}