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