Coverage Report

Created: 2024-09-14 07:19

/src/skia/src/core/SkMipmap.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2013 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
#ifndef SkMipmap_DEFINED
9
#define SkMipmap_DEFINED
10
11
#include "include/core/SkPixmap.h"
12
#include "include/core/SkScalar.h"
13
#include "include/core/SkSize.h"
14
#include "src/core/SkCachedData.h"
15
#include "src/core/SkImageInfoPriv.h"
16
#include "src/shaders/SkShaderBase.h"
17
#include <memory>
18
19
class SkBitmap;
20
class SkData;
21
class SkDiscardableMemory;
22
class SkMipmapBuilder;
23
24
typedef SkDiscardableMemory* (*SkDiscardableFactoryProc)(size_t bytes);
25
26
struct SkMipmapDownSampler {
27
237
    virtual ~SkMipmapDownSampler() {}
28
29
    virtual void buildLevel(const SkPixmap& dst, const SkPixmap& src) = 0;
30
};
31
32
/*
33
 * SkMipmap will generate mipmap levels when given a base mipmap level image.
34
 *
35
 * Any function which deals with mipmap levels indices will start with index 0
36
 * being the first mipmap level which was generated. Said another way, it does
37
 * not include the base level in its range.
38
 */
39
class SkMipmap : public SkCachedData {
40
public:
41
    ~SkMipmap() override;
42
    // Allocate and fill-in a mipmap. If computeContents is false, we just allocated
43
    // and compute the sizes/rowbytes, but leave the pixel-data uninitialized.
44
    static SkMipmap* Build(const SkPixmap& src, SkDiscardableFactoryProc,
45
                           bool computeContents = true);
46
47
    static SkMipmap* Build(const SkBitmap& src, SkDiscardableFactoryProc);
48
49
    // Determines how many levels a SkMipmap will have without creating that mipmap.
50
    // This does not include the base mipmap level that the user provided when
51
    // creating the SkMipmap.
52
    static int ComputeLevelCount(int baseWidth, int baseHeight);
53
0
    static int ComputeLevelCount(SkISize s) { return ComputeLevelCount(s.width(), s.height()); }
54
55
    // Determines the size of a given mipmap level.
56
    // |level| is an index into the generated mipmap levels. It does not include
57
    // the base level. So index 0 represents mipmap level 1.
58
    static SkISize ComputeLevelSize(int baseWidth, int baseHeight, int level);
59
0
    static SkISize ComputeLevelSize(SkISize s, int level) {
60
0
        return ComputeLevelSize(s.width(), s.height(), level);
61
0
    }
62
63
    // Computes the fractional level based on the scaling in X and Y.
64
    static float ComputeLevel(SkSize scaleSize);
65
66
    // We use a block of (possibly discardable) memory to hold an array of Level structs, followed
67
    // by the pixel data for each level. On 32-bit platforms, Level would naturally be 4 byte
68
    // aligned, so the pixel data could end up with 4 byte alignment. If the pixel data is F16,
69
    // it must be 8 byte aligned. To ensure this, keep the Level struct 8 byte aligned as well.
70
    struct alignas(8) Level {
71
        SkPixmap    fPixmap;
72
        SkSize      fScale; // < 1.0
73
    };
74
75
    bool extractLevel(SkSize scale, Level*) const;
76
77
    // countLevels returns the number of mipmap levels generated (which does not
78
    // include the base mipmap level).
79
    int countLevels() const;
80
81
    // |index| is an index into the generated mipmap levels. It does not include
82
    // the base level. So index 0 represents mipmap level 1.
83
    bool getLevel(int index, Level*) const;
84
85
    bool validForRootLevel(const SkImageInfo&) const;
86
87
    static std::unique_ptr<SkMipmapDownSampler> MakeDownSampler(const SkPixmap&);
88
89
protected:
90
6.17k
    void onDataChange(void* oldData, void* newData) override {
91
6.17k
        fLevels = (Level*)newData; // could be nullptr
92
6.17k
    }
93
94
private:
95
    sk_sp<SkColorSpace> fCS;
96
    Level*              fLevels;    // managed by the baseclass, may be null due to onDataChanged.
97
    int                 fCount;
98
99
    SkMipmap(void* malloc, size_t size);
100
    SkMipmap(size_t size, SkDiscardableMemory* dm);
101
102
    static size_t AllocLevelsSize(int levelCount, size_t pixelSize);
103
};
104
105
#endif