2015-08-14 13:30:50 +00:00
|
|
|
/*
|
|
|
|
* 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 "SkColorPriv.h"
|
|
|
|
#include "SkGradientShader.h"
|
|
|
|
#include "SkImage.h"
|
2016-06-08 00:21:10 +00:00
|
|
|
#include "SkMathPriv.h"
|
2015-08-14 13:30:50 +00:00
|
|
|
#include "SkRandom.h"
|
|
|
|
#include "SkShader.h"
|
|
|
|
#include "SkSurface.h"
|
|
|
|
|
2016-03-17 17:51:11 +00:00
|
|
|
static sk_sp<SkImage> makebm(SkCanvas* caller, int w, int h) {
|
2015-08-14 13:30:50 +00:00
|
|
|
SkImageInfo info = SkImageInfo::MakeN32Premul(w, h);
|
2016-03-24 01:59:25 +00:00
|
|
|
auto surface(caller->makeSurface(info));
|
2015-08-27 14:41:13 +00:00
|
|
|
if (nullptr == surface) {
|
2016-03-24 01:59:25 +00:00
|
|
|
surface = SkSurface::MakeRaster(info);
|
2015-08-14 13:30:50 +00:00
|
|
|
}
|
|
|
|
SkCanvas* canvas = surface->getCanvas();
|
|
|
|
|
|
|
|
const SkScalar wScalar = SkIntToScalar(w);
|
|
|
|
const SkScalar hScalar = SkIntToScalar(h);
|
|
|
|
|
|
|
|
const SkPoint pt = { wScalar / 2, hScalar / 2 };
|
|
|
|
|
|
|
|
const SkScalar radius = 4 * SkMaxScalar(wScalar, hScalar);
|
|
|
|
|
2016-09-01 18:24:54 +00:00
|
|
|
constexpr SkColor colors[] = { SK_ColorRED, SK_ColorYELLOW,
|
2015-08-14 13:30:50 +00:00
|
|
|
SK_ColorGREEN, SK_ColorMAGENTA,
|
|
|
|
SK_ColorBLUE, SK_ColorCYAN,
|
|
|
|
SK_ColorRED};
|
|
|
|
|
2016-09-01 18:24:54 +00:00
|
|
|
constexpr SkScalar pos[] = {0,
|
2015-08-14 13:30:50 +00:00
|
|
|
SK_Scalar1 / 6,
|
|
|
|
2 * SK_Scalar1 / 6,
|
|
|
|
3 * SK_Scalar1 / 6,
|
|
|
|
4 * SK_Scalar1 / 6,
|
|
|
|
5 * SK_Scalar1 / 6,
|
|
|
|
SK_Scalar1};
|
|
|
|
|
|
|
|
SkASSERT(SK_ARRAY_COUNT(colors) == SK_ARRAY_COUNT(pos));
|
|
|
|
SkPaint paint;
|
|
|
|
SkRect rect = SkRect::MakeWH(wScalar, hScalar);
|
|
|
|
SkMatrix mat = SkMatrix::I();
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
2016-03-09 17:50:50 +00:00
|
|
|
paint.setShader(SkGradientShader::MakeRadial(
|
2015-08-14 13:30:50 +00:00
|
|
|
pt, radius,
|
|
|
|
colors, pos,
|
|
|
|
SK_ARRAY_COUNT(colors),
|
|
|
|
SkShader::kRepeat_TileMode,
|
2016-03-09 17:50:50 +00:00
|
|
|
0, &mat));
|
2015-08-14 13:30:50 +00:00
|
|
|
canvas->drawRect(rect, paint);
|
|
|
|
rect.inset(wScalar / 8, hScalar / 8);
|
|
|
|
mat.postScale(SK_Scalar1 / 4, SK_Scalar1 / 4);
|
|
|
|
}
|
2016-03-17 17:51:11 +00:00
|
|
|
return surface->makeImageSnapshot();
|
2015-08-14 13:30:50 +00:00
|
|
|
}
|
|
|
|
|
2016-09-01 18:24:54 +00:00
|
|
|
constexpr int gSize = 1024;
|
|
|
|
constexpr int gSurfaceSize = 2048;
|
2015-08-14 13:30:50 +00:00
|
|
|
|
|
|
|
// This GM calls drawImageRect several times using the same texture. This is
|
|
|
|
// intended to exercise batching of these calls.
|
|
|
|
class DrawMiniBitmapRectGM : public skiagm::GM {
|
|
|
|
public:
|
|
|
|
DrawMiniBitmapRectGM(bool antiAlias) : fAA(antiAlias) {
|
|
|
|
fName.set("drawminibitmaprect");
|
|
|
|
if (fAA) {
|
|
|
|
fName.appendf("_aa");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
SkString onShortName() override { return fName; }
|
|
|
|
|
|
|
|
SkISize onISize() override { return SkISize::Make(gSize, gSize); }
|
|
|
|
|
|
|
|
void onDraw(SkCanvas* canvas) override {
|
2015-08-27 14:41:13 +00:00
|
|
|
if (nullptr == fImage) {
|
2016-03-17 17:51:11 +00:00
|
|
|
fImage = makebm(canvas, gSurfaceSize, gSurfaceSize);
|
2015-08-14 13:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const SkRect dstRect = { 0, 0, SkIntToScalar(64), SkIntToScalar(64)};
|
2016-09-01 18:24:54 +00:00
|
|
|
const int kMaxSrcRectSize = 1 << (SkNextLog2(gSurfaceSize) + 2);
|
2015-08-14 13:30:50 +00:00
|
|
|
|
2016-09-01 18:24:54 +00:00
|
|
|
constexpr int kPadX = 30;
|
|
|
|
constexpr int kPadY = 40;
|
2015-08-14 13:30:50 +00:00
|
|
|
|
|
|
|
int rowCount = 0;
|
|
|
|
canvas->translate(SkIntToScalar(kPadX), SkIntToScalar(kPadY));
|
|
|
|
canvas->save();
|
|
|
|
SkRandom random;
|
|
|
|
|
|
|
|
SkPaint paint;
|
|
|
|
paint.setAntiAlias(fAA);
|
|
|
|
for (int w = 1; w <= kMaxSrcRectSize; w *= 3) {
|
|
|
|
for (int h = 1; h <= kMaxSrcRectSize; h *= 3) {
|
|
|
|
|
|
|
|
const SkIRect srcRect =
|
|
|
|
SkIRect::MakeXYWH((gSurfaceSize - w) / 2, (gSurfaceSize - h) / 2, w, h);
|
|
|
|
canvas->save();
|
|
|
|
switch (random.nextU() % 3) {
|
|
|
|
case 0:
|
|
|
|
canvas->rotate(random.nextF() * 10.f);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
canvas->rotate(-random.nextF() * 10.f);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
// rect stays rect
|
|
|
|
break;
|
|
|
|
}
|
2016-03-17 17:51:11 +00:00
|
|
|
canvas->drawImageRect(fImage.get(), srcRect, dstRect, &paint,
|
2015-08-14 13:30:50 +00:00
|
|
|
SkCanvas::kFast_SrcRectConstraint);
|
|
|
|
canvas->restore();
|
|
|
|
|
|
|
|
canvas->translate(dstRect.width() + SK_Scalar1 * kPadX, 0);
|
|
|
|
++rowCount;
|
|
|
|
if ((dstRect.width() + 2 * kPadX) * rowCount > gSize) {
|
|
|
|
canvas->restore();
|
|
|
|
canvas->translate(0, dstRect.height() + SK_Scalar1 * kPadY);
|
|
|
|
canvas->save();
|
|
|
|
rowCount = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
canvas->restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2016-03-17 17:51:11 +00:00
|
|
|
bool fAA;
|
|
|
|
sk_sp<SkImage> fImage;
|
|
|
|
SkString fName;
|
2015-08-14 13:30:50 +00:00
|
|
|
|
|
|
|
typedef skiagm::GM INHERITED;
|
|
|
|
};
|
|
|
|
|
|
|
|
DEF_GM( return new DrawMiniBitmapRectGM(true); )
|
|
|
|
DEF_GM( return new DrawMiniBitmapRectGM(false); )
|