drawminibitmaprect.cpp revision 4dbbd04314cc0606f8d3bafe515c97e52c180f73
1/* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "gm.h" 9#include "SkColorPriv.h" 10#include "SkGradientShader.h" 11#include "SkImage.h" 12#include "SkMathPriv.h" 13#include "SkRandom.h" 14#include "SkShader.h" 15#include "SkSurface.h" 16 17static sk_sp<SkImage> makebm(SkCanvas* caller, int w, int h) { 18 SkImageInfo info = SkImageInfo::MakeN32Premul(w, h); 19 auto surface(caller->makeSurface(info)); 20 if (nullptr == surface) { 21 surface = SkSurface::MakeRaster(info); 22 } 23 SkCanvas* canvas = surface->getCanvas(); 24 25 const SkScalar wScalar = SkIntToScalar(w); 26 const SkScalar hScalar = SkIntToScalar(h); 27 28 const SkPoint pt = { wScalar / 2, hScalar / 2 }; 29 30 const SkScalar radius = 4 * SkMaxScalar(wScalar, hScalar); 31 32 static const SkColor colors[] = { SK_ColorRED, SK_ColorYELLOW, 33 SK_ColorGREEN, SK_ColorMAGENTA, 34 SK_ColorBLUE, SK_ColorCYAN, 35 SK_ColorRED}; 36 37 static const SkScalar pos[] = {0, 38 SK_Scalar1 / 6, 39 2 * SK_Scalar1 / 6, 40 3 * SK_Scalar1 / 6, 41 4 * SK_Scalar1 / 6, 42 5 * SK_Scalar1 / 6, 43 SK_Scalar1}; 44 45 SkASSERT(SK_ARRAY_COUNT(colors) == SK_ARRAY_COUNT(pos)); 46 SkPaint paint; 47 SkRect rect = SkRect::MakeWH(wScalar, hScalar); 48 SkMatrix mat = SkMatrix::I(); 49 for (int i = 0; i < 4; ++i) { 50 paint.setShader(SkGradientShader::MakeRadial( 51 pt, radius, 52 colors, pos, 53 SK_ARRAY_COUNT(colors), 54 SkShader::kRepeat_TileMode, 55 0, &mat)); 56 canvas->drawRect(rect, paint); 57 rect.inset(wScalar / 8, hScalar / 8); 58 mat.postScale(SK_Scalar1 / 4, SK_Scalar1 / 4); 59 } 60 return surface->makeImageSnapshot(); 61} 62 63static const int gSize = 1024; 64static const int gSurfaceSize = 2048; 65 66// This GM calls drawImageRect several times using the same texture. This is 67// intended to exercise batching of these calls. 68class DrawMiniBitmapRectGM : public skiagm::GM { 69public: 70 DrawMiniBitmapRectGM(bool antiAlias) : fAA(antiAlias) { 71 fName.set("drawminibitmaprect"); 72 if (fAA) { 73 fName.appendf("_aa"); 74 } 75 } 76 77protected: 78 SkString onShortName() override { return fName; } 79 80 SkISize onISize() override { return SkISize::Make(gSize, gSize); } 81 82 void onDraw(SkCanvas* canvas) override { 83 if (nullptr == fImage) { 84 fImage = makebm(canvas, gSurfaceSize, gSurfaceSize); 85 } 86 87 const SkRect dstRect = { 0, 0, SkIntToScalar(64), SkIntToScalar(64)}; 88 static const int kMaxSrcRectSize = 1 << (SkNextLog2(gSurfaceSize) + 2); 89 90 static const int kPadX = 30; 91 static const int kPadY = 40; 92 93 int rowCount = 0; 94 canvas->translate(SkIntToScalar(kPadX), SkIntToScalar(kPadY)); 95 canvas->save(); 96 SkRandom random; 97 98 SkPaint paint; 99 paint.setAntiAlias(fAA); 100 for (int w = 1; w <= kMaxSrcRectSize; w *= 3) { 101 for (int h = 1; h <= kMaxSrcRectSize; h *= 3) { 102 103 const SkIRect srcRect = 104 SkIRect::MakeXYWH((gSurfaceSize - w) / 2, (gSurfaceSize - h) / 2, w, h); 105 canvas->save(); 106 switch (random.nextU() % 3) { 107 case 0: 108 canvas->rotate(random.nextF() * 10.f); 109 break; 110 case 1: 111 canvas->rotate(-random.nextF() * 10.f); 112 break; 113 case 2: 114 // rect stays rect 115 break; 116 } 117 canvas->drawImageRect(fImage.get(), srcRect, dstRect, &paint, 118 SkCanvas::kFast_SrcRectConstraint); 119 canvas->restore(); 120 121 canvas->translate(dstRect.width() + SK_Scalar1 * kPadX, 0); 122 ++rowCount; 123 if ((dstRect.width() + 2 * kPadX) * rowCount > gSize) { 124 canvas->restore(); 125 canvas->translate(0, dstRect.height() + SK_Scalar1 * kPadY); 126 canvas->save(); 127 rowCount = 0; 128 } 129 } 130 } 131 canvas->restore(); 132 } 133 134private: 135 bool fAA; 136 sk_sp<SkImage> fImage; 137 SkString fName; 138 139 typedef skiagm::GM INHERITED; 140}; 141 142DEF_GM( return new DrawMiniBitmapRectGM(true); ) 143DEF_GM( return new DrawMiniBitmapRectGM(false); ) 144