1 /* 2 * Copyright 2016 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 "bench/Benchmark.h" 9 #include "include/core/SkCanvas.h" 10 #include "include/core/SkColorSpace.h" 11 #include "include/core/SkImage.h" 12 #include "include/core/SkPaint.h" 13 #include "include/core/SkSurface.h" 14 15 class GrMipMapBench: public Benchmark { 16 sk_sp<SkSurface> fSurface; 17 SkString fName; 18 const int fW, fH; 19 20 public: GrMipMapBench(int w,int h)21 GrMipMapBench(int w, int h) : fW(w), fH(h) { 22 fName.printf("gr_mipmap_build_%dx%d", w, h); 23 } 24 25 protected: isSuitableFor(Backend backend)26 bool isSuitableFor(Backend backend) override { 27 return kGPU_Backend == backend; 28 } 29 onGetName()30 const char* onGetName() override { return fName.c_str(); } 31 onDraw(int loops,SkCanvas * canvas)32 void onDraw(int loops, SkCanvas* canvas) override { 33 if (!fSurface) { 34 auto context = canvas->recordingContext(); 35 if (!context) { 36 return; 37 } 38 auto srgb = SkColorSpace::MakeSRGB(); 39 SkImageInfo info = 40 SkImageInfo::Make(fW, fH, kRGBA_8888_SkColorType, kPremul_SkAlphaType, srgb); 41 // We're benching the regeneration of the mip levels not the need to allocate them every 42 // frame. Thus we create the surface with mips to begin with. 43 fSurface = SkSurface::MakeRenderTarget(context, 44 skgpu::Budgeted::kNo, 45 info, 46 0, 47 kBottomLeft_GrSurfaceOrigin, 48 nullptr, 49 true); 50 } 51 52 // Clear surface once: 53 fSurface->getCanvas()->clear(SK_ColorBLACK); 54 55 SkSamplingOptions sampling(SkFilterMode::kLinear, 56 SkMipmapMode::kLinear); 57 SkPaint paint; 58 paint.setColor(SK_ColorWHITE); 59 for (int i = 0; i < loops; i++) { 60 // Touch surface so mips are dirtied 61 fSurface->getCanvas()->drawPoint(0, 0, paint); 62 63 // Draw reduced version of surface to original canvas, to trigger mip generation 64 canvas->save(); 65 canvas->scale(0.1f, 0.1f); 66 canvas->drawImage(fSurface->makeImageSnapshot(), 0, 0, sampling, &paint); 67 canvas->restore(); 68 } 69 } 70 onPerCanvasPostDraw(SkCanvas *)71 void onPerCanvasPostDraw(SkCanvas*) override { 72 fSurface.reset(nullptr); 73 } 74 75 private: 76 using INHERITED = Benchmark; 77 }; 78 79 // Build variants that exercise the width and heights being even or odd at each level, as the 80 // impl specializes on each of these. 81 // 82 DEF_BENCH( return new GrMipMapBench(511, 511); ) 83 DEF_BENCH( return new GrMipMapBench(512, 511); ) 84 DEF_BENCH( return new GrMipMapBench(511, 512); ) 85 DEF_BENCH( return new GrMipMapBench(512, 512); ) 86