1*b54b3ae5SJulian Harnath /* 2*b54b3ae5SJulian Harnath * Copyright 2015 Julian Harnath <julian.harnath@rwth-aachen.de> 3*b54b3ae5SJulian Harnath * All rights reserved. Distributed under the terms of the MIT license. 4*b54b3ae5SJulian Harnath */ 5*b54b3ae5SJulian Harnath #ifndef ALPHA_MASK_CACHE_H 6*b54b3ae5SJulian Harnath #define ALPHA_MASK_CACHE_H 7*b54b3ae5SJulian Harnath 8*b54b3ae5SJulian Harnath #include <set> 9*b54b3ae5SJulian Harnath 10*b54b3ae5SJulian Harnath #include "ShapePrivate.h" 11*b54b3ae5SJulian Harnath #include <Locker.h> 12*b54b3ae5SJulian Harnath #include <kernel/OS.h> 13*b54b3ae5SJulian Harnath 14*b54b3ae5SJulian Harnath 15*b54b3ae5SJulian Harnath class AlphaMask; 16*b54b3ae5SJulian Harnath class ShapeAlphaMask; 17*b54b3ae5SJulian Harnath 18*b54b3ae5SJulian Harnath 19*b54b3ae5SJulian Harnath class AlphaMaskCache { 20*b54b3ae5SJulian Harnath private: 21*b54b3ae5SJulian Harnath enum { 22*b54b3ae5SJulian Harnath kMaxCacheBytes = 8 * 1024 * 1024 // 8 MiB 23*b54b3ae5SJulian Harnath }; 24*b54b3ae5SJulian Harnath 25*b54b3ae5SJulian Harnath public: 26*b54b3ae5SJulian Harnath AlphaMaskCache(); 27*b54b3ae5SJulian Harnath ~AlphaMaskCache(); 28*b54b3ae5SJulian Harnath 29*b54b3ae5SJulian Harnath static AlphaMaskCache* Default(); 30*b54b3ae5SJulian Harnath 31*b54b3ae5SJulian Harnath status_t Put(ShapeAlphaMask* mask); 32*b54b3ae5SJulian Harnath ShapeAlphaMask* Get(const shape_data& shape, 33*b54b3ae5SJulian Harnath AlphaMask* previousMask, 34*b54b3ae5SJulian Harnath bool inverse); 35*b54b3ae5SJulian Harnath 36*b54b3ae5SJulian Harnath void Clear(); 37*b54b3ae5SJulian Harnath 38*b54b3ae5SJulian Harnath private: 39*b54b3ae5SJulian Harnath size_t _FindUncachedPreviousMasks(AlphaMask* mask, 40*b54b3ae5SJulian Harnath bool reference); 41*b54b3ae5SJulian Harnath void _PrintAndResetStatistics(); 42*b54b3ae5SJulian Harnath 43*b54b3ae5SJulian Harnath private: 44*b54b3ae5SJulian Harnath struct ShapeMaskElement { 45*b54b3ae5SJulian Harnath ShapeMaskElement(const shape_data* shape, 46*b54b3ae5SJulian Harnath ShapeAlphaMask* mask, AlphaMask* previousMask, 47*b54b3ae5SJulian Harnath bool inverse) 48*b54b3ae5SJulian Harnath : 49*b54b3ae5SJulian Harnath fShape(shape), 50*b54b3ae5SJulian Harnath fInverse(inverse), 51*b54b3ae5SJulian Harnath fMask(mask), 52*b54b3ae5SJulian Harnath fPreviousMask(previousMask) 53*b54b3ae5SJulian Harnath { 54*b54b3ae5SJulian Harnath } 55*b54b3ae5SJulian Harnath 56*b54b3ae5SJulian Harnath bool operator<(const ShapeMaskElement& other) const 57*b54b3ae5SJulian Harnath { 58*b54b3ae5SJulian Harnath if (fInverse != other.fInverse) 59*b54b3ae5SJulian Harnath return fInverse < other.fInverse; 60*b54b3ae5SJulian Harnath if (fPreviousMask != other.fPreviousMask) 61*b54b3ae5SJulian Harnath return fPreviousMask < other.fPreviousMask; 62*b54b3ae5SJulian Harnath 63*b54b3ae5SJulian Harnath // compare shapes 64*b54b3ae5SJulian Harnath if (fShape->ptCount != other.fShape->ptCount) 65*b54b3ae5SJulian Harnath return fShape->ptCount < other.fShape->ptCount; 66*b54b3ae5SJulian Harnath if (fShape->opCount != other.fShape->opCount) 67*b54b3ae5SJulian Harnath return fShape->opCount < other.fShape->opCount; 68*b54b3ae5SJulian Harnath int diff = memcmp(fShape->ptList, other.fShape->ptList, 69*b54b3ae5SJulian Harnath fShape->ptSize); 70*b54b3ae5SJulian Harnath if (diff != 0) 71*b54b3ae5SJulian Harnath return diff < 0; 72*b54b3ae5SJulian Harnath diff = memcmp(fShape->opList, other.fShape->opList, 73*b54b3ae5SJulian Harnath fShape->opSize); 74*b54b3ae5SJulian Harnath if (diff != 0) 75*b54b3ae5SJulian Harnath return diff < 0; 76*b54b3ae5SJulian Harnath 77*b54b3ae5SJulian Harnath // equal 78*b54b3ae5SJulian Harnath return false; 79*b54b3ae5SJulian Harnath } 80*b54b3ae5SJulian Harnath 81*b54b3ae5SJulian Harnath const shape_data* fShape; 82*b54b3ae5SJulian Harnath bool fInverse; 83*b54b3ae5SJulian Harnath ShapeAlphaMask* fMask; 84*b54b3ae5SJulian Harnath AlphaMask* fPreviousMask; 85*b54b3ae5SJulian Harnath }; 86*b54b3ae5SJulian Harnath 87*b54b3ae5SJulian Harnath private: 88*b54b3ae5SJulian Harnath typedef std::set<ShapeMaskElement> ShapeMaskSet; 89*b54b3ae5SJulian Harnath 90*b54b3ae5SJulian Harnath static AlphaMaskCache sDefaultInstance; 91*b54b3ae5SJulian Harnath 92*b54b3ae5SJulian Harnath BLocker fLock; 93*b54b3ae5SJulian Harnath 94*b54b3ae5SJulian Harnath size_t fCurrentCacheBytes; 95*b54b3ae5SJulian Harnath ShapeMaskSet fShapeMasks; 96*b54b3ae5SJulian Harnath 97*b54b3ae5SJulian Harnath // Statistics counters 98*b54b3ae5SJulian Harnath uint32 fTooLargeMaskCount; 99*b54b3ae5SJulian Harnath uint32 fMasksReplacedCount; 100*b54b3ae5SJulian Harnath uint32 fHitCount; 101*b54b3ae5SJulian Harnath uint32 fMissCount; 102*b54b3ae5SJulian Harnath uint32 fLowerMaskReferencedCount; 103*b54b3ae5SJulian Harnath }; 104*b54b3ae5SJulian Harnath 105*b54b3ae5SJulian Harnath 106*b54b3ae5SJulian Harnath #endif // ALPHA_MASK_CACHE_H 107