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 "SkCachedData.h" 12 #include "SkImageInfoPriv.h" 13 #include "SkPixmap.h" 14 #include "SkScalar.h" 15 #include "SkSize.h" 16 #include "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 extractLevel(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: onDataChange(void * oldData,void * newData)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 SkMipMap(void * malloc,size_t size)74 SkMipMap(void* malloc, size_t size) : INHERITED(malloc, size) {} SkMipMap(size_t size,SkDiscardableMemory * dm)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