Add new GM to directly exercise perspective bitmap drawing
BUG=skia:3326 Review URL: https://codereview.chromium.org/1309543012
This commit is contained in:
parent
75db90c4d7
commit
fac9ceb5de
184
gm/perspshaders.cpp
Normal file
184
gm/perspshaders.cpp
Normal file
@ -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<SkSurface> 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<SkShader> fBitmapShader;
|
||||
SkAutoTUnref<SkShader> fLinearGrad1;
|
||||
SkAutoTUnref<SkShader> fLinearGrad2;
|
||||
SkMatrix fPerspMatrix;
|
||||
SkAutoTUnref<SkImage> fImage;
|
||||
SkBitmap fBitmap;
|
||||
|
||||
typedef GM INHERITED;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DEF_GM(return new PerspShadersGM(true);)
|
||||
DEF_GM(return new PerspShadersGM(false);)
|
||||
}
|
@ -273,11 +273,11 @@ void GrDrawContext::drawRect(GrRenderTarget* rt,
|
||||
|
||||
// The fill path can handle rotation but not skew
|
||||
// The stroke path needs the rect to remain axis aligned (no rotation or skew)
|
||||
// None of our draw rect calls can handle perspective yet
|
||||
SkASSERT(!viewMatrix.hasPerspective());
|
||||
// None of our AA draw rect calls can handle perspective yet
|
||||
bool canApplyAA = width >=0 ? viewMatrix.rectStaysRect() : viewMatrix.preservesRightAngles();
|
||||
|
||||
if (needAA && canApplyAA) {
|
||||
SkASSERT(!viewMatrix.hasPerspective());
|
||||
SkRect devBoundRect;
|
||||
viewMatrix.mapRect(&devBoundRect, rect);
|
||||
SkAutoTUnref<GrDrawBatch> batch;
|
||||
|
Loading…
Reference in New Issue
Block a user