From fac9ceb5de5288fa9f98a6cf77085b37da601b36 Mon Sep 17 00:00:00 2001 From: robertphillips Date: Thu, 3 Sep 2015 08:32:08 -0700 Subject: Add new GM to directly exercise perspective bitmap drawing BUG=skia:3326 Review URL: https://codereview.chromium.org/1309543012 --- gm/perspshaders.cpp | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 gm/perspshaders.cpp (limited to 'gm/perspshaders.cpp') diff --git a/gm/perspshaders.cpp b/gm/perspshaders.cpp new file mode 100644 index 0000000000..07a41e9466 --- /dev/null +++ b/gm/perspshaders.cpp @@ -0,0 +1,184 @@ +/* + * Copyright 2015 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 "SkGradientShader.h" +#include "SkImage.h" +#include "SkPath.h" +#include "SkSurface.h" + +static SkImage* make_image(SkCanvas* origCanvas, int w, int h) { + SkImageInfo info = SkImageInfo::MakeN32Premul(w, h); + SkAutoTUnref surface(origCanvas->newSurface(info)); + if (nullptr == surface) { + surface.reset(SkSurface::NewRaster(info)); + } + SkCanvas* canvas = surface->getCanvas(); + + sk_tool_utils::draw_checkerboard(canvas, SK_ColorRED, SK_ColorGREEN, w/10); + return surface->newImageSnapshot(); +} + +static SkBitmap make_bitmap(int w, int h) { + SkBitmap bitmap; + bitmap.allocN32Pixels(w, h); + SkCanvas canvas(bitmap); + + sk_tool_utils::draw_checkerboard(&canvas, SK_ColorBLUE, SK_ColorYELLOW, w/10); + return bitmap; +} + +namespace skiagm { + +class PerspShadersGM : public GM { +public: + PerspShadersGM(bool doAA) : fDoAA(doAA) { } + +protected: + SkString onShortName() override { + SkString name; + name.printf("persp_shaders_%s", + fDoAA ? "aa" : "bw"); + return name; + } + + SkISize onISize() override { + return SkISize::Make(kCellSize*kNumCols, kCellSize*kNumRows); + } + + void onOnceBeforeDraw() override { + fBitmap = make_bitmap(kCellSize, kCellSize); + + fBitmapShader.reset(SkShader::CreateBitmapShader(fBitmap, + SkShader::kClamp_TileMode, + SkShader::kClamp_TileMode)); + SkPoint pts1[] = { + { 0, 0 }, + { SkIntToScalar(kCellSize), SkIntToScalar(kCellSize) } + }; + SkPoint pts2[] = { + { 0, 0 }, + { 0, SkIntToScalar(kCellSize) } + }; + static const SkColor colors[] = { + SK_ColorRED, SK_ColorGREEN, SK_ColorRED, SK_ColorGREEN, SK_ColorRED + }; + static const SkScalar pos[] = { 0, 0.25f, 0.5f, 0.75f, SK_Scalar1 }; + + fLinearGrad1.reset(SkGradientShader::CreateLinear(pts1, colors, pos, + SK_ARRAY_COUNT(colors), + SkShader::kClamp_TileMode)); + fLinearGrad2.reset(SkGradientShader::CreateLinear(pts2, colors, pos, + SK_ARRAY_COUNT(colors), + SkShader::kClamp_TileMode)); + + fPerspMatrix.reset(); + fPerspMatrix.setPerspY(SK_Scalar1 / 50); + + fPath.moveTo(0, 0); + fPath.lineTo(0, SkIntToScalar(kCellSize)); + fPath.lineTo(kCellSize/2.0f, kCellSize/2.0f); + fPath.lineTo(SkIntToScalar(kCellSize), SkIntToScalar(kCellSize)); + fPath.lineTo(SkIntToScalar(kCellSize), 0); + fPath.close(); + } + + void drawRow(SkCanvas* canvas, SkFilterQuality filterQ) { + SkPaint filterPaint; + filterPaint.setFilterQuality(filterQ); + filterPaint.setAntiAlias(fDoAA); + + SkPaint pathPaint; + pathPaint.setShader(fBitmapShader); + pathPaint.setFilterQuality(filterQ); + pathPaint.setAntiAlias(fDoAA); + + SkPaint gradPaint1; + gradPaint1.setShader(fLinearGrad1); + gradPaint1.setAntiAlias(fDoAA); + SkPaint gradPaint2; + gradPaint2.setShader(fLinearGrad2); + gradPaint2.setAntiAlias(fDoAA); + + SkRect r = SkRect::MakeWH(SkIntToScalar(kCellSize), SkIntToScalar(kCellSize)); + + canvas->save(); + + canvas->save(); + canvas->concat(fPerspMatrix); + canvas->drawBitmapRect(fBitmap, r, &filterPaint); + canvas->restore(); + + canvas->translate(SkIntToScalar(kCellSize), 0); + canvas->save(); + canvas->concat(fPerspMatrix); + canvas->drawImage(fImage, 0, 0, &filterPaint); + canvas->restore(); + + canvas->translate(SkIntToScalar(kCellSize), 0); + canvas->save(); + canvas->concat(fPerspMatrix); + canvas->drawRect(r, pathPaint); + canvas->restore(); + + canvas->translate(SkIntToScalar(kCellSize), 0); + canvas->save(); + canvas->concat(fPerspMatrix); + canvas->drawPath(fPath, pathPaint); + canvas->restore(); + + canvas->translate(SkIntToScalar(kCellSize), 0); + canvas->save(); + canvas->concat(fPerspMatrix); + canvas->drawRect(r, gradPaint1); + canvas->restore(); + + canvas->translate(SkIntToScalar(kCellSize), 0); + canvas->save(); + canvas->concat(fPerspMatrix); + canvas->drawPath(fPath, gradPaint2); + canvas->restore(); + + canvas->restore(); + } + + void onDraw(SkCanvas* canvas) override { + if (!fImage) { + fImage.reset(make_image(canvas, kCellSize, kCellSize)); + } + + this->drawRow(canvas, kNone_SkFilterQuality); + canvas->translate(0, SkIntToScalar(kCellSize)); + this->drawRow(canvas, kLow_SkFilterQuality); + canvas->translate(0, SkIntToScalar(kCellSize)); + this->drawRow(canvas, kMedium_SkFilterQuality); + canvas->translate(0, SkIntToScalar(kCellSize)); + this->drawRow(canvas, kHigh_SkFilterQuality); + canvas->translate(0, SkIntToScalar(kCellSize)); + } +private: + static const int kCellSize = 50; + static const int kNumRows = 4; + static const int kNumCols = 6; + + bool fDoAA; + SkPath fPath; + SkAutoTUnref fBitmapShader; + SkAutoTUnref fLinearGrad1; + SkAutoTUnref fLinearGrad2; + SkMatrix fPerspMatrix; + SkAutoTUnref fImage; + SkBitmap fBitmap; + + typedef GM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +DEF_GM(return new PerspShadersGM(true);) +DEF_GM(return new PerspShadersGM(false);) +} -- cgit v1.2.3