xref: /aosp_15_r20/external/skia/src/core/SkMipmapDrawDownSampler.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2023 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 "include/core/SkTypes.h"
9 
10 #ifdef SK_USE_DRAWING_MIPMAP_DOWNSAMPLER
11 
12 #include "include/core/SkBitmap.h"
13 #include "include/core/SkBlendMode.h"
14 #include "include/core/SkMatrix.h"
15 #include "include/core/SkPaint.h"
16 #include "include/core/SkPixmap.h"
17 #include "include/core/SkSamplingOptions.h"
18 #include "include/core/SkScalar.h"
19 #include "src/core/SkDraw.h"
20 #include "src/core/SkMipmap.h"
21 #include "src/core/SkRasterClip.h"
22 #include <memory>
23 
24 namespace {
25 
26 struct DrawDownSampler : SkMipmapDownSampler {
27     SkPaint fPaint;
28 
DrawDownSampler__anon0035eb3a0111::DrawDownSampler29     DrawDownSampler() {
30         // For efficiency, we want to be in src mode when building levels
31         // to avoid any extra trying to "blend".
32         fPaint.setBlendMode(SkBlendMode::kSrc);
33     }
34 
35     void buildLevel(const SkPixmap& dst, const SkPixmap& src) override;
36 };
37 
choose_options(const SkPixmap & dst,const SkPixmap & src)38 static SkSamplingOptions choose_options(const SkPixmap& dst, const SkPixmap& src) {
39     // if we're a perfect 2x2 downscale, just use bilerp
40     if (dst.width() * 2 == src.width() && dst.height() * 2 == src.height()) {
41         return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);
42     }
43     // general case -- might experiment with different cubic parameter values
44     const auto cubic = SkCubicResampler::CatmullRom();
45     return SkSamplingOptions(cubic);
46 }
47 
buildLevel(const SkPixmap & dst,const SkPixmap & src)48 void DrawDownSampler::buildLevel(const SkPixmap& dst, const SkPixmap& src) {
49     const SkRasterClip rclip(dst.bounds());
50     const SkMatrix mx = SkMatrix::Scale(SkIntToScalar(dst.width())  / src.width(),
51                                         SkIntToScalar(dst.height()) / src.height());
52     const auto sampling = choose_options(dst, src);
53 
54     SkDraw draw;
55     draw.fDst = dst;
56     draw.fCTM = &mx;
57     draw.fRC = &rclip;
58 
59     SkBitmap bitmap;
60     bitmap.installPixels(src.info(), const_cast<void*>(src.addr()), src.rowBytes());
61 
62     draw.drawBitmap(bitmap, SkMatrix::I(), nullptr, sampling, fPaint);
63 }
64 
65 } // namespace
66 
MakeDownSampler(const SkPixmap & root)67 std::unique_ptr<SkMipmapDownSampler> SkMipmap::MakeDownSampler(const SkPixmap& root) {
68     return std::make_unique<DrawDownSampler>();
69 }
70 
71 #endif
72