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