Home | History | Annotate | Download | only in core
      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:
     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