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 "SkPixmap.h"
     13 #include "SkScalar.h"
     14 #include "SkSize.h"
     15 #include "SkShaderBase.h"
     16 
     17 class SkBitmap;
     18 class SkDiscardableMemory;
     19 
     20 typedef SkDiscardableMemory* (*SkDiscardableFactoryProc)(size_t bytes);
     21 
     22 /*
     23  * SkMipMap will generate mipmap levels when given a base mipmap level image.
     24  *
     25  * Any function which deals with mipmap levels indices will start with index 0
     26  * being the first mipmap level which was generated. Said another way, it does
     27  * not include the base level in its range.
     28  */
     29 class SkMipMap : public SkCachedData {
     30 public:
     31     static SkMipMap* Build(const SkPixmap& src, SkDestinationSurfaceColorMode,
     32                            SkDiscardableFactoryProc);
     33     static SkMipMap* Build(const SkBitmap& src, SkDestinationSurfaceColorMode,
     34                            SkDiscardableFactoryProc);
     35 
     36     static SkDestinationSurfaceColorMode DeduceColorMode(const SkShaderBase::ContextRec& rec) {
     37         return (SkShaderBase::ContextRec::kPMColor_DstType == rec.fPreferredDstType)
     38             ? SkDestinationSurfaceColorMode::kLegacy
     39             : SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware;
     40     }
     41 
     42     // Determines how many levels a SkMipMap will have without creating that mipmap.
     43     // This does not include the base mipmap level that the user provided when
     44     // creating the SkMipMap.
     45     static int ComputeLevelCount(int baseWidth, int baseHeight);
     46 
     47     // Determines the size of a given mipmap level.
     48     // |level| is an index into the generated mipmap levels. It does not include
     49     // the base level. So index 0 represents mipmap level 1.
     50     static SkISize ComputeLevelSize(int baseWidth, int baseHeight, int level);
     51 
     52     struct Level {
     53         SkPixmap    fPixmap;
     54         SkSize      fScale; // < 1.0
     55     };
     56 
     57     bool extractLevel(const SkSize& scale, Level*) const;
     58 
     59     // countLevels returns the number of mipmap levels generated (which does not
     60     // include the base mipmap level).
     61     int countLevels() const;
     62 
     63     // |index| is an index into the generated mipmap levels. It does not include
     64     // the base level. So index 0 represents mipmap level 1.
     65     bool getLevel(int index, Level*) const;
     66 
     67 protected:
     68     void onDataChange(void* oldData, void* newData) override {
     69         fLevels = (Level*)newData; // could be nullptr
     70     }
     71 
     72 private:
     73     sk_sp<SkColorSpace> fCS;
     74     Level*              fLevels;    // managed by the baseclass, may be null due to onDataChanged.
     75     int                 fCount;
     76 
     77     SkMipMap(void* malloc, size_t size) : INHERITED(malloc, size) {}
     78     SkMipMap(size_t size, SkDiscardableMemory* dm) : INHERITED(size, dm) {}
     79 
     80     static size_t AllocLevelsSize(int levelCount, size_t pixelSize);
     81 
     82     typedef SkCachedData INHERITED;
     83 };
     84 
     85 #endif
     86