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