1a40be09c443d15fcb080adde0ab9625e8a5af73dreed/*
2a40be09c443d15fcb080adde0ab9625e8a5af73dreed * Copyright 2016 Google Inc.
3a40be09c443d15fcb080adde0ab9625e8a5af73dreed *
4a40be09c443d15fcb080adde0ab9625e8a5af73dreed * Use of this source code is governed by a BSD-style license that can be
5a40be09c443d15fcb080adde0ab9625e8a5af73dreed * found in the LICENSE file.
6a40be09c443d15fcb080adde0ab9625e8a5af73dreed */
7a40be09c443d15fcb080adde0ab9625e8a5af73dreed
8a40be09c443d15fcb080adde0ab9625e8a5af73dreed#include "gm.h"
933d2055e594177b27360f84e0631b26d74a55a9bMike Klein#include "sk_tool_utils.h"
10a40be09c443d15fcb080adde0ab9625e8a5af73dreed
11a40be09c443d15fcb080adde0ab9625e8a5af73dreed#include "Resources.h"
12a40be09c443d15fcb080adde0ab9625e8a5af73dreed#include "SkBitmapScaler.h"
13a40be09c443d15fcb080adde0ab9625e8a5af73dreed#include "SkGradientShader.h"
14a40be09c443d15fcb080adde0ab9625e8a5af73dreed#include "SkTypeface.h"
15a40be09c443d15fcb080adde0ab9625e8a5af73dreed#include "SkStream.h"
16a40be09c443d15fcb080adde0ab9625e8a5af73dreed#include "SkPaint.h"
17a40be09c443d15fcb080adde0ab9625e8a5af73dreed#include "SkMipMap.h"
18a40be09c443d15fcb080adde0ab9625e8a5af73dreed#include "Resources.h"
19a40be09c443d15fcb080adde0ab9625e8a5af73dreed
2032e0b4a34a2d461927056677e0ef99241e29df0dreed#define SHOW_MIP_COLOR  0xFF000000
2132e0b4a34a2d461927056677e0ef99241e29df0dreed
2201dc44ae669b53b45f9b33ab826ba22956bddf62reedstatic SkBitmap make_bitmap(int w, int h) {
23a40be09c443d15fcb080adde0ab9625e8a5af73dreed    SkBitmap bm;
2401dc44ae669b53b45f9b33ab826ba22956bddf62reed    bm.allocN32Pixels(w, h);
25a40be09c443d15fcb080adde0ab9625e8a5af73dreed    SkCanvas canvas(bm);
26a40be09c443d15fcb080adde0ab9625e8a5af73dreed    canvas.clear(0xFFFFFFFF);
27a40be09c443d15fcb080adde0ab9625e8a5af73dreed    SkPaint paint;
28a40be09c443d15fcb080adde0ab9625e8a5af73dreed    paint.setStyle(SkPaint::kStroke_Style);
2901dc44ae669b53b45f9b33ab826ba22956bddf62reed    paint.setStrokeWidth(w / 16.0f);
3032e0b4a34a2d461927056677e0ef99241e29df0dreed    paint.setColor(SHOW_MIP_COLOR);
3101dc44ae669b53b45f9b33ab826ba22956bddf62reed    canvas.drawCircle(w/2.0f, h/2.0f, w/3.0f, paint);
32a40be09c443d15fcb080adde0ab9625e8a5af73dreed    return bm;
33a40be09c443d15fcb080adde0ab9625e8a5af73dreed}
34a40be09c443d15fcb080adde0ab9625e8a5af73dreed
3501dc44ae669b53b45f9b33ab826ba22956bddf62reedstatic SkBitmap make_bitmap2(int w, int h) {
36a40be09c443d15fcb080adde0ab9625e8a5af73dreed    SkBitmap bm;
3701dc44ae669b53b45f9b33ab826ba22956bddf62reed    bm.allocN32Pixels(w, h);
38a40be09c443d15fcb080adde0ab9625e8a5af73dreed    SkCanvas canvas(bm);
39a40be09c443d15fcb080adde0ab9625e8a5af73dreed    canvas.clear(0xFFFFFFFF);
40a40be09c443d15fcb080adde0ab9625e8a5af73dreed    SkPaint paint;
4132e0b4a34a2d461927056677e0ef99241e29df0dreed    paint.setColor(SHOW_MIP_COLOR);
42a40be09c443d15fcb080adde0ab9625e8a5af73dreed    paint.setStyle(SkPaint::kStroke_Style);
43a40be09c443d15fcb080adde0ab9625e8a5af73dreed
44a40be09c443d15fcb080adde0ab9625e8a5af73dreed    SkScalar inset = 2;
4501dc44ae669b53b45f9b33ab826ba22956bddf62reed    SkRect r = SkRect::MakeIWH(w, h).makeInset(0.5f, 0.5f);
46a40be09c443d15fcb080adde0ab9625e8a5af73dreed    while (r.width() > 4) {
47a40be09c443d15fcb080adde0ab9625e8a5af73dreed        canvas.drawRect(r, paint);
48a40be09c443d15fcb080adde0ab9625e8a5af73dreed        r.inset(inset, inset);
49a40be09c443d15fcb080adde0ab9625e8a5af73dreed        inset += 1;
50a40be09c443d15fcb080adde0ab9625e8a5af73dreed    }
51a40be09c443d15fcb080adde0ab9625e8a5af73dreed    return bm;
52a40be09c443d15fcb080adde0ab9625e8a5af73dreed}
53a40be09c443d15fcb080adde0ab9625e8a5af73dreed
54a40be09c443d15fcb080adde0ab9625e8a5af73dreed#include "SkNx.h"
5501dc44ae669b53b45f9b33ab826ba22956bddf62reedstatic SkBitmap make_bitmap3(int w, int h) {
56a40be09c443d15fcb080adde0ab9625e8a5af73dreed    SkBitmap bm;
5701dc44ae669b53b45f9b33ab826ba22956bddf62reed    bm.allocN32Pixels(w, h);
58a40be09c443d15fcb080adde0ab9625e8a5af73dreed    SkCanvas canvas(bm);
59a40be09c443d15fcb080adde0ab9625e8a5af73dreed    canvas.clear(0xFFFFFFFF);
60a40be09c443d15fcb080adde0ab9625e8a5af73dreed    SkPaint paint;
61a40be09c443d15fcb080adde0ab9625e8a5af73dreed    paint.setStyle(SkPaint::kStroke_Style);
62a40be09c443d15fcb080adde0ab9625e8a5af73dreed    paint.setStrokeWidth(2.1f);
6332e0b4a34a2d461927056677e0ef99241e29df0dreed    paint.setColor(SHOW_MIP_COLOR);
64a40be09c443d15fcb080adde0ab9625e8a5af73dreed
6501dc44ae669b53b45f9b33ab826ba22956bddf62reed    SkScalar s = SkIntToScalar(w);
66a40be09c443d15fcb080adde0ab9625e8a5af73dreed    Sk4f p(s, -s, -s, s);
67a40be09c443d15fcb080adde0ab9625e8a5af73dreed    Sk4f d(5);
687c249e531900929c2fe2cdde76619fa6d2538c49mtklein    while (p[1] < s) {
697c249e531900929c2fe2cdde76619fa6d2538c49mtklein        canvas.drawLine(p[0],p[1], p[2], p[3], paint);
70a40be09c443d15fcb080adde0ab9625e8a5af73dreed        p = p + d;
71a40be09c443d15fcb080adde0ab9625e8a5af73dreed    }
72a40be09c443d15fcb080adde0ab9625e8a5af73dreed    return bm;
73a40be09c443d15fcb080adde0ab9625e8a5af73dreed}
74a40be09c443d15fcb080adde0ab9625e8a5af73dreed
75a40be09c443d15fcb080adde0ab9625e8a5af73dreedclass ShowMipLevels : public skiagm::GM {
76a40be09c443d15fcb080adde0ab9625e8a5af73dreed    const int fN;
77a40be09c443d15fcb080adde0ab9625e8a5af73dreed    SkBitmap  fBM[4];
78a40be09c443d15fcb080adde0ab9625e8a5af73dreed
79a40be09c443d15fcb080adde0ab9625e8a5af73dreedpublic:
80a40be09c443d15fcb080adde0ab9625e8a5af73dreed    static unsigned gamma(unsigned n) {
81a40be09c443d15fcb080adde0ab9625e8a5af73dreed        float x = n / 255.0f;
82a40be09c443d15fcb080adde0ab9625e8a5af73dreed#if 0
83a40be09c443d15fcb080adde0ab9625e8a5af73dreed        x = sqrtf(x);
84a40be09c443d15fcb080adde0ab9625e8a5af73dreed#else
85a40be09c443d15fcb080adde0ab9625e8a5af73dreed        if (x > 0.0031308f) {
86a40be09c443d15fcb080adde0ab9625e8a5af73dreed            x = 1.055f * (powf(x, (1.0f / 2.4f))) - 0.055f;
87a40be09c443d15fcb080adde0ab9625e8a5af73dreed        } else {
88a40be09c443d15fcb080adde0ab9625e8a5af73dreed            x = 12.92f * x;
89a40be09c443d15fcb080adde0ab9625e8a5af73dreed        }
90a40be09c443d15fcb080adde0ab9625e8a5af73dreed#endif
91a40be09c443d15fcb080adde0ab9625e8a5af73dreed        return (int)(x * 255);
92a40be09c443d15fcb080adde0ab9625e8a5af73dreed    }
93a40be09c443d15fcb080adde0ab9625e8a5af73dreed
94a40be09c443d15fcb080adde0ab9625e8a5af73dreed    static void apply_gamma(const SkBitmap& bm) {
95a40be09c443d15fcb080adde0ab9625e8a5af73dreed        return; // below is our experiment for sRGB correction
96a40be09c443d15fcb080adde0ab9625e8a5af73dreed        bm.lockPixels();
97a40be09c443d15fcb080adde0ab9625e8a5af73dreed        for (int y = 0; y < bm.height(); ++y) {
98a40be09c443d15fcb080adde0ab9625e8a5af73dreed            for (int x = 0; x < bm.width(); ++x) {
99a40be09c443d15fcb080adde0ab9625e8a5af73dreed                SkPMColor c = *bm.getAddr32(x, y);
100a40be09c443d15fcb080adde0ab9625e8a5af73dreed                unsigned r = gamma(SkGetPackedR32(c));
101a40be09c443d15fcb080adde0ab9625e8a5af73dreed                unsigned g = gamma(SkGetPackedG32(c));
102a40be09c443d15fcb080adde0ab9625e8a5af73dreed                unsigned b = gamma(SkGetPackedB32(c));
103a40be09c443d15fcb080adde0ab9625e8a5af73dreed                *bm.getAddr32(x, y) = SkPackARGB32(0xFF, r, g, b);
104a40be09c443d15fcb080adde0ab9625e8a5af73dreed            }
105a40be09c443d15fcb080adde0ab9625e8a5af73dreed        }
106a40be09c443d15fcb080adde0ab9625e8a5af73dreed    }
107a40be09c443d15fcb080adde0ab9625e8a5af73dreed
10855713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips    ShowMipLevels(int N) : fN(N) { }
109a40be09c443d15fcb080adde0ab9625e8a5af73dreed
110a40be09c443d15fcb080adde0ab9625e8a5af73dreedprotected:
111a40be09c443d15fcb080adde0ab9625e8a5af73dreed
112a40be09c443d15fcb080adde0ab9625e8a5af73dreed    SkString onShortName() override {
113a40be09c443d15fcb080adde0ab9625e8a5af73dreed        SkString str;
114a40be09c443d15fcb080adde0ab9625e8a5af73dreed        str.printf("showmiplevels_%d", fN);
115a40be09c443d15fcb080adde0ab9625e8a5af73dreed        return str;
116a40be09c443d15fcb080adde0ab9625e8a5af73dreed    }
117a40be09c443d15fcb080adde0ab9625e8a5af73dreed
118a40be09c443d15fcb080adde0ab9625e8a5af73dreed    SkISize onISize() override {
119a40be09c443d15fcb080adde0ab9625e8a5af73dreed        return { 824, 862 };
120a40be09c443d15fcb080adde0ab9625e8a5af73dreed    }
121a40be09c443d15fcb080adde0ab9625e8a5af73dreed
122a40be09c443d15fcb080adde0ab9625e8a5af73dreed    static void DrawAndFrame(SkCanvas* canvas, const SkBitmap& orig, SkScalar x, SkScalar y) {
123a40be09c443d15fcb080adde0ab9625e8a5af73dreed        SkBitmap bm;
124a40be09c443d15fcb080adde0ab9625e8a5af73dreed        orig.copyTo(&bm);
125a40be09c443d15fcb080adde0ab9625e8a5af73dreed        apply_gamma(bm);
126a40be09c443d15fcb080adde0ab9625e8a5af73dreed
127a40be09c443d15fcb080adde0ab9625e8a5af73dreed        canvas->drawBitmap(bm, x, y, nullptr);
128a40be09c443d15fcb080adde0ab9625e8a5af73dreed        SkPaint paint;
129a40be09c443d15fcb080adde0ab9625e8a5af73dreed        paint.setStyle(SkPaint::kStroke_Style);
130a40be09c443d15fcb080adde0ab9625e8a5af73dreed        paint.setColor(0xFFFFCCCC);
131a40be09c443d15fcb080adde0ab9625e8a5af73dreed        canvas->drawRect(SkRect::MakeIWH(bm.width(), bm.height()).makeOffset(x, y).makeOutset(0.5f, 0.5f), paint);
132a40be09c443d15fcb080adde0ab9625e8a5af73dreed    }
133a40be09c443d15fcb080adde0ab9625e8a5af73dreed
134a40be09c443d15fcb080adde0ab9625e8a5af73dreed    template <typename F> void drawLevels(SkCanvas* canvas, const SkBitmap& baseBM, F func) {
135a40be09c443d15fcb080adde0ab9625e8a5af73dreed        SkScalar x = 4;
136a40be09c443d15fcb080adde0ab9625e8a5af73dreed        SkScalar y = 4;
137a40be09c443d15fcb080adde0ab9625e8a5af73dreed
138a40be09c443d15fcb080adde0ab9625e8a5af73dreed        SkPixmap prevPM;
139a40be09c443d15fcb080adde0ab9625e8a5af73dreed        baseBM.lockPixels();
140a40be09c443d15fcb080adde0ab9625e8a5af73dreed        baseBM.peekPixels(&prevPM);
141a40be09c443d15fcb080adde0ab9625e8a5af73dreed
1427b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman        SkDestinationSurfaceColorMode colorMode = SkDestinationSurfaceColorMode::kLegacy;
1437b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman        sk_sp<SkMipMap> mm(SkMipMap::Build(baseBM, colorMode, nullptr));
144a40be09c443d15fcb080adde0ab9625e8a5af73dreed
145a40be09c443d15fcb080adde0ab9625e8a5af73dreed        int index = 0;
146a40be09c443d15fcb080adde0ab9625e8a5af73dreed        SkMipMap::Level level;
147a40be09c443d15fcb080adde0ab9625e8a5af73dreed        SkScalar scale = 0.5f;
14833ed3ad9f62b3c84d439b92ab45732d4fa6d05adfmalita        while (mm->extractLevel(SkSize::Make(scale, scale), &level)) {
14967b09bf6b7422c7a3209781cbb7827224e3ffc17reed            SkBitmap bm = func(prevPM, level.fPixmap);
150a40be09c443d15fcb080adde0ab9625e8a5af73dreed            DrawAndFrame(canvas, bm, x, y);
151a40be09c443d15fcb080adde0ab9625e8a5af73dreed
15267b09bf6b7422c7a3209781cbb7827224e3ffc17reed            if (level.fPixmap.width() <= 2 || level.fPixmap.height() <= 2) {
153a40be09c443d15fcb080adde0ab9625e8a5af73dreed                break;
154a40be09c443d15fcb080adde0ab9625e8a5af73dreed            }
155a40be09c443d15fcb080adde0ab9625e8a5af73dreed            if (index & 1) {
15667b09bf6b7422c7a3209781cbb7827224e3ffc17reed                x += level.fPixmap.width() + 4;
157a40be09c443d15fcb080adde0ab9625e8a5af73dreed            } else {
15867b09bf6b7422c7a3209781cbb7827224e3ffc17reed                y += level.fPixmap.height() + 4;
159a40be09c443d15fcb080adde0ab9625e8a5af73dreed            }
160a40be09c443d15fcb080adde0ab9625e8a5af73dreed            scale /= 2;
16167b09bf6b7422c7a3209781cbb7827224e3ffc17reed            prevPM = level.fPixmap;
162a40be09c443d15fcb080adde0ab9625e8a5af73dreed            index += 1;
163a40be09c443d15fcb080adde0ab9625e8a5af73dreed        }
164a40be09c443d15fcb080adde0ab9625e8a5af73dreed    }
165a40be09c443d15fcb080adde0ab9625e8a5af73dreed
166a40be09c443d15fcb080adde0ab9625e8a5af73dreed    void drawSet(SkCanvas* canvas, const SkBitmap& orig) {
167a40be09c443d15fcb080adde0ab9625e8a5af73dreed        SkAutoCanvasRestore acr(canvas, true);
168a40be09c443d15fcb080adde0ab9625e8a5af73dreed
169a40be09c443d15fcb080adde0ab9625e8a5af73dreed        drawLevels(canvas, orig, [](const SkPixmap& prev, const SkPixmap& curr) {
170a40be09c443d15fcb080adde0ab9625e8a5af73dreed            SkBitmap bm;
171a40be09c443d15fcb080adde0ab9625e8a5af73dreed            bm.installPixels(curr);
172a40be09c443d15fcb080adde0ab9625e8a5af73dreed            return bm;
173a40be09c443d15fcb080adde0ab9625e8a5af73dreed        });
174a40be09c443d15fcb080adde0ab9625e8a5af73dreed
175a40be09c443d15fcb080adde0ab9625e8a5af73dreed        const SkBitmapScaler::ResizeMethod methods[] = {
176a40be09c443d15fcb080adde0ab9625e8a5af73dreed            SkBitmapScaler::RESIZE_BOX,
177a40be09c443d15fcb080adde0ab9625e8a5af73dreed            SkBitmapScaler::RESIZE_TRIANGLE,
178a40be09c443d15fcb080adde0ab9625e8a5af73dreed            SkBitmapScaler::RESIZE_LANCZOS3,
179a40be09c443d15fcb080adde0ab9625e8a5af73dreed            SkBitmapScaler::RESIZE_HAMMING,
180a40be09c443d15fcb080adde0ab9625e8a5af73dreed            SkBitmapScaler::RESIZE_MITCHELL,
181a40be09c443d15fcb080adde0ab9625e8a5af73dreed        };
182a40be09c443d15fcb080adde0ab9625e8a5af73dreed
183a40be09c443d15fcb080adde0ab9625e8a5af73dreed        SkPixmap basePM;
184a40be09c443d15fcb080adde0ab9625e8a5af73dreed        orig.lockPixels();
185a40be09c443d15fcb080adde0ab9625e8a5af73dreed        orig.peekPixels(&basePM);
186a40be09c443d15fcb080adde0ab9625e8a5af73dreed        for (auto method : methods) {
187a40be09c443d15fcb080adde0ab9625e8a5af73dreed            canvas->translate(orig.width()/2 + 8.0f, 0);
18865a17539d2ab1866b2c8252155b0a7fbe127d861Brian Salomon            drawLevels(canvas, orig, [method](const SkPixmap& prev, const SkPixmap& curr) {
189a40be09c443d15fcb080adde0ab9625e8a5af73dreed                SkBitmap bm;
190a40be09c443d15fcb080adde0ab9625e8a5af73dreed                SkBitmapScaler::Resize(&bm, prev, method, curr.width(), curr.height());
191a40be09c443d15fcb080adde0ab9625e8a5af73dreed                return bm;
192a40be09c443d15fcb080adde0ab9625e8a5af73dreed            });
193a40be09c443d15fcb080adde0ab9625e8a5af73dreed        }
194a40be09c443d15fcb080adde0ab9625e8a5af73dreed    }
195a40be09c443d15fcb080adde0ab9625e8a5af73dreed
19655713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips    void onOnceBeforeDraw() override {
19755713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips        fBM[0] = sk_tool_utils::create_checkerboard_bitmap(fN, fN, SK_ColorBLACK, SK_ColorWHITE, 2);
19855713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips        fBM[1] = make_bitmap(fN, fN);
19955713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips        fBM[2] = make_bitmap2(fN, fN);
20055713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips        fBM[3] = make_bitmap3(fN, fN);
20155713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips    }
20255713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips
203a40be09c443d15fcb080adde0ab9625e8a5af73dreed    void onDraw(SkCanvas* canvas) override {
204a40be09c443d15fcb080adde0ab9625e8a5af73dreed        canvas->translate(4, 4);
205a40be09c443d15fcb080adde0ab9625e8a5af73dreed        for (const auto& bm : fBM) {
206a40be09c443d15fcb080adde0ab9625e8a5af73dreed            this->drawSet(canvas, bm);
207a40be09c443d15fcb080adde0ab9625e8a5af73dreed            canvas->translate(0, bm.height() * 0.85f);
208a40be09c443d15fcb080adde0ab9625e8a5af73dreed        }
209a40be09c443d15fcb080adde0ab9625e8a5af73dreed    }
2109d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
211a40be09c443d15fcb080adde0ab9625e8a5af73dreedprivate:
212a40be09c443d15fcb080adde0ab9625e8a5af73dreed    typedef skiagm::GM INHERITED;
213a40be09c443d15fcb080adde0ab9625e8a5af73dreed};
214a40be09c443d15fcb080adde0ab9625e8a5af73dreedDEF_GM( return new ShowMipLevels(255); )
215a40be09c443d15fcb080adde0ab9625e8a5af73dreedDEF_GM( return new ShowMipLevels(256); )
216a40be09c443d15fcb080adde0ab9625e8a5af73dreed
21701dc44ae669b53b45f9b33ab826ba22956bddf62reed///////////////////////////////////////////////////////////////////////////////////////////////////
21801dc44ae669b53b45f9b33ab826ba22956bddf62reed
219cb6266b5aa5bbfd880532f08eec83b0c585e873fMatt Sarettvoid copy_to(SkBitmap* dst, SkColorType dstColorType, const SkBitmap& src) {
220cb6266b5aa5bbfd880532f08eec83b0c585e873fMatt Sarett    if (kGray_8_SkColorType == dstColorType) {
2214897fb898f62a983829e56fc72b5ce6fd1ad62e4Matt Sarett        return sk_tool_utils::copy_to_g8(dst, src);
222cb6266b5aa5bbfd880532f08eec83b0c585e873fMatt Sarett    }
223cb6266b5aa5bbfd880532f08eec83b0c585e873fMatt Sarett
224cb6266b5aa5bbfd880532f08eec83b0c585e873fMatt Sarett    src.copyTo(dst, dstColorType);
225cb6266b5aa5bbfd880532f08eec83b0c585e873fMatt Sarett}
226cb6266b5aa5bbfd880532f08eec83b0c585e873fMatt Sarett
22701dc44ae669b53b45f9b33ab826ba22956bddf62reed/**
22801dc44ae669b53b45f9b33ab826ba22956bddf62reed *  Show mip levels that were built, for all supported colortypes
22901dc44ae669b53b45f9b33ab826ba22956bddf62reed */
23001dc44ae669b53b45f9b33ab826ba22956bddf62reedclass ShowMipLevels2 : public skiagm::GM {
23101dc44ae669b53b45f9b33ab826ba22956bddf62reed    const int fW, fH;
23201dc44ae669b53b45f9b33ab826ba22956bddf62reed    SkBitmap  fBM[4];
23301dc44ae669b53b45f9b33ab826ba22956bddf62reed
23401dc44ae669b53b45f9b33ab826ba22956bddf62reedpublic:
23555713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips    ShowMipLevels2(int w, int h) : fW(w), fH(h) { }
23601dc44ae669b53b45f9b33ab826ba22956bddf62reed
23701dc44ae669b53b45f9b33ab826ba22956bddf62reedprotected:
23801dc44ae669b53b45f9b33ab826ba22956bddf62reed
23901dc44ae669b53b45f9b33ab826ba22956bddf62reed    SkString onShortName() override {
24001dc44ae669b53b45f9b33ab826ba22956bddf62reed        SkString str;
24101dc44ae669b53b45f9b33ab826ba22956bddf62reed        str.printf("showmiplevels2_%dx%d", fW, fH);
24201dc44ae669b53b45f9b33ab826ba22956bddf62reed        return str;
24301dc44ae669b53b45f9b33ab826ba22956bddf62reed    }
24401dc44ae669b53b45f9b33ab826ba22956bddf62reed
24501dc44ae669b53b45f9b33ab826ba22956bddf62reed    SkISize onISize() override {
24601dc44ae669b53b45f9b33ab826ba22956bddf62reed        return { 824, 862 };
24701dc44ae669b53b45f9b33ab826ba22956bddf62reed    }
24801dc44ae669b53b45f9b33ab826ba22956bddf62reed
24901dc44ae669b53b45f9b33ab826ba22956bddf62reed    static void DrawAndFrame(SkCanvas* canvas, const SkBitmap& bm, SkScalar x, SkScalar y) {
25001dc44ae669b53b45f9b33ab826ba22956bddf62reed        canvas->drawBitmap(bm, x, y, nullptr);
25101dc44ae669b53b45f9b33ab826ba22956bddf62reed        SkPaint paint;
25201dc44ae669b53b45f9b33ab826ba22956bddf62reed        paint.setStyle(SkPaint::kStroke_Style);
25301dc44ae669b53b45f9b33ab826ba22956bddf62reed        paint.setColor(0xFFFFCCCC);
25401dc44ae669b53b45f9b33ab826ba22956bddf62reed        canvas->drawRect(SkRect::MakeIWH(bm.width(), bm.height()).makeOffset(x, y).makeOutset(0.5f, 0.5f), paint);
25501dc44ae669b53b45f9b33ab826ba22956bddf62reed    }
25601dc44ae669b53b45f9b33ab826ba22956bddf62reed
25701dc44ae669b53b45f9b33ab826ba22956bddf62reed    void drawLevels(SkCanvas* canvas, const SkBitmap& baseBM) {
25801dc44ae669b53b45f9b33ab826ba22956bddf62reed        SkScalar x = 4;
25901dc44ae669b53b45f9b33ab826ba22956bddf62reed        SkScalar y = 4;
26001dc44ae669b53b45f9b33ab826ba22956bddf62reed
2617b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman        SkDestinationSurfaceColorMode colorMode = SkDestinationSurfaceColorMode::kLegacy;
2627b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman        sk_sp<SkMipMap> mm(SkMipMap::Build(baseBM, colorMode, nullptr));
26301dc44ae669b53b45f9b33ab826ba22956bddf62reed
26401dc44ae669b53b45f9b33ab826ba22956bddf62reed        int index = 0;
26501dc44ae669b53b45f9b33ab826ba22956bddf62reed        SkMipMap::Level level;
26601dc44ae669b53b45f9b33ab826ba22956bddf62reed        SkScalar scale = 0.5f;
26733ed3ad9f62b3c84d439b92ab45732d4fa6d05adfmalita        while (mm->extractLevel(SkSize::Make(scale, scale), &level)) {
26801dc44ae669b53b45f9b33ab826ba22956bddf62reed            SkBitmap bm;
26967b09bf6b7422c7a3209781cbb7827224e3ffc17reed            bm.installPixels(level.fPixmap);
27001dc44ae669b53b45f9b33ab826ba22956bddf62reed            DrawAndFrame(canvas, bm, x, y);
27101dc44ae669b53b45f9b33ab826ba22956bddf62reed
27267b09bf6b7422c7a3209781cbb7827224e3ffc17reed            if (level.fPixmap.width() <= 2 || level.fPixmap.height() <= 2) {
27301dc44ae669b53b45f9b33ab826ba22956bddf62reed                break;
27401dc44ae669b53b45f9b33ab826ba22956bddf62reed            }
27501dc44ae669b53b45f9b33ab826ba22956bddf62reed            if (index & 1) {
27667b09bf6b7422c7a3209781cbb7827224e3ffc17reed                x += level.fPixmap.width() + 4;
27701dc44ae669b53b45f9b33ab826ba22956bddf62reed            } else {
27867b09bf6b7422c7a3209781cbb7827224e3ffc17reed                y += level.fPixmap.height() + 4;
27901dc44ae669b53b45f9b33ab826ba22956bddf62reed            }
28001dc44ae669b53b45f9b33ab826ba22956bddf62reed            scale /= 2;
28101dc44ae669b53b45f9b33ab826ba22956bddf62reed            index += 1;
28201dc44ae669b53b45f9b33ab826ba22956bddf62reed        }
28301dc44ae669b53b45f9b33ab826ba22956bddf62reed    }
28401dc44ae669b53b45f9b33ab826ba22956bddf62reed
28501dc44ae669b53b45f9b33ab826ba22956bddf62reed    void drawSet(SkCanvas* canvas, const SkBitmap& orig) {
28601dc44ae669b53b45f9b33ab826ba22956bddf62reed        const SkColorType ctypes[] = {
28701dc44ae669b53b45f9b33ab826ba22956bddf62reed            kN32_SkColorType, kRGB_565_SkColorType, kARGB_4444_SkColorType, kGray_8_SkColorType
28801dc44ae669b53b45f9b33ab826ba22956bddf62reed        };
28901dc44ae669b53b45f9b33ab826ba22956bddf62reed
29001dc44ae669b53b45f9b33ab826ba22956bddf62reed        SkAutoCanvasRestore acr(canvas, true);
29101dc44ae669b53b45f9b33ab826ba22956bddf62reed
29201dc44ae669b53b45f9b33ab826ba22956bddf62reed        for (auto ctype : ctypes) {
29301dc44ae669b53b45f9b33ab826ba22956bddf62reed            SkBitmap bm;
294cb6266b5aa5bbfd880532f08eec83b0c585e873fMatt Sarett            copy_to(&bm, ctype, orig);
29501dc44ae669b53b45f9b33ab826ba22956bddf62reed            drawLevels(canvas, bm);
29601dc44ae669b53b45f9b33ab826ba22956bddf62reed            canvas->translate(orig.width()/2 + 8.0f, 0);
29701dc44ae669b53b45f9b33ab826ba22956bddf62reed        }
29801dc44ae669b53b45f9b33ab826ba22956bddf62reed    }
29901dc44ae669b53b45f9b33ab826ba22956bddf62reed
30055713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips    void onOnceBeforeDraw() override {
30155713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips        fBM[0] = sk_tool_utils::create_checkerboard_bitmap(fW, fH,
30255713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips                                                           SHOW_MIP_COLOR, SK_ColorWHITE, 2);
30355713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips        fBM[1] = make_bitmap(fW, fH);
30455713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips        fBM[2] = make_bitmap2(fW, fH);
30555713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips        fBM[3] = make_bitmap3(fW, fH);
30655713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips    }
30755713afb7a531bbb6a345a42b5a25ad709d8fd19robertphillips
30801dc44ae669b53b45f9b33ab826ba22956bddf62reed    void onDraw(SkCanvas* canvas) override {
30901dc44ae669b53b45f9b33ab826ba22956bddf62reed        canvas->translate(4, 4);
31001dc44ae669b53b45f9b33ab826ba22956bddf62reed        for (const auto& bm : fBM) {
31101dc44ae669b53b45f9b33ab826ba22956bddf62reed            this->drawSet(canvas, bm);
31201dc44ae669b53b45f9b33ab826ba22956bddf62reed            // round so we always produce an integral translate, so the GOLD tool won't show
31301dc44ae669b53b45f9b33ab826ba22956bddf62reed            // unimportant diffs if this is drawn on a GPU with different rounding rules
31401dc44ae669b53b45f9b33ab826ba22956bddf62reed            // since we draw the bitmaps using nearest-neighbor
31501dc44ae669b53b45f9b33ab826ba22956bddf62reed            canvas->translate(0, SkScalarRoundToScalar(bm.height() * 0.85f));
31601dc44ae669b53b45f9b33ab826ba22956bddf62reed        }
31701dc44ae669b53b45f9b33ab826ba22956bddf62reed    }
3189d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
31901dc44ae669b53b45f9b33ab826ba22956bddf62reedprivate:
32001dc44ae669b53b45f9b33ab826ba22956bddf62reed    typedef skiagm::GM INHERITED;
32101dc44ae669b53b45f9b33ab826ba22956bddf62reed};
32201dc44ae669b53b45f9b33ab826ba22956bddf62reedDEF_GM( return new ShowMipLevels2(255, 255); )
32301dc44ae669b53b45f9b33ab826ba22956bddf62reedDEF_GM( return new ShowMipLevels2(256, 255); )
32401dc44ae669b53b45f9b33ab826ba22956bddf62reedDEF_GM( return new ShowMipLevels2(255, 256); )
32501dc44ae669b53b45f9b33ab826ba22956bddf62reedDEF_GM( return new ShowMipLevels2(256, 256); )
326