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 "include/private/SkImageInfoPriv.h" |
15 | #include "src/core/SkCachedData.h" |
16 | #include "src/shaders/SkShaderBase.h" |
17 | |
18 | class SkBitmap; |
19 | class SkDiscardableMemory; |
20 | |
21 | typedef SkDiscardableMemory* (*SkDiscardableFactoryProc)(size_t bytes); |
22 | |
23 | /* |
24 | * SkMipMap will generate mipmap levels when given a base mipmap level image. |
25 | * |
26 | * Any function which deals with mipmap levels indices will start with index 0 |
27 | * being the first mipmap level which was generated. Said another way, it does |
28 | * not include the base level in its range. |
29 | */ |
30 | class SkMipMap : public SkCachedData { |
31 | public: |
32 | static SkMipMap* Build(const SkPixmap& src, SkDiscardableFactoryProc); |
33 | static SkMipMap* Build(const SkBitmap& src, SkDiscardableFactoryProc); |
34 | |
35 | // Determines how many levels a SkMipMap will have without creating that mipmap. |
36 | // This does not include the base mipmap level that the user provided when |
37 | // creating the SkMipMap. |
38 | static int ComputeLevelCount(int baseWidth, int baseHeight); |
39 | |
40 | // Determines the size of a given mipmap level. |
41 | // |level| is an index into the generated mipmap levels. It does not include |
42 | // the base level. So index 0 represents mipmap level 1. |
43 | static SkISize ComputeLevelSize(int baseWidth, int baseHeight, int level); |
44 | |
45 | // We use a block of (possibly discardable) memory to hold an array of Level structs, followed |
46 | // by the pixel data for each level. On 32-bit platforms, Level would naturally be 4 byte |
47 | // aligned, so the pixel data could end up with 4 byte alignment. If the pixel data is F16, |
48 | // it must be 8 byte aligned. To ensure this, keep the Level struct 8 byte aligned as well. |
49 | struct alignas(8) Level { |
50 | SkPixmap fPixmap; |
51 | SkSize fScale; // < 1.0 |
52 | }; |
53 | |
54 | bool (const SkSize& scale, Level*) const; |
55 | |
56 | // countLevels returns the number of mipmap levels generated (which does not |
57 | // include the base mipmap level). |
58 | int countLevels() const; |
59 | |
60 | // |index| is an index into the generated mipmap levels. It does not include |
61 | // the base level. So index 0 represents mipmap level 1. |
62 | bool getLevel(int index, Level*) const; |
63 | |
64 | protected: |
65 | void onDataChange(void* oldData, void* newData) override { |
66 | fLevels = (Level*)newData; // could be nullptr |
67 | } |
68 | |
69 | private: |
70 | sk_sp<SkColorSpace> fCS; |
71 | Level* fLevels; // managed by the baseclass, may be null due to onDataChanged. |
72 | int fCount; |
73 | |
74 | SkMipMap(void* malloc, size_t size) : INHERITED(malloc, size) {} |
75 | SkMipMap(size_t size, SkDiscardableMemory* dm) : INHERITED(size, dm) {} |
76 | |
77 | static size_t AllocLevelsSize(int levelCount, size_t pixelSize); |
78 | |
79 | typedef SkCachedData INHERITED; |
80 | }; |
81 | |
82 | #endif |
83 | |