xref: /haiku/src/servers/app/drawing/AlphaMaskCache.h (revision c302a243e15e640fae0f689e32cdf0c18749afee)
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 {
ShapeMaskElementShapeMaskElement45*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