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