| 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 |  |