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
15class AlphaMask;
16class ShapeAlphaMask;
17
18
19class AlphaMaskCache {
20private:
21	enum {
22		kMaxCacheBytes = 8 * 1024 * 1024 // 8 MiB
23	};
24
25public:
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
38private:
39			size_t				_FindUncachedPreviousMasks(AlphaMask* mask,
40									bool reference);
41			void				_PrintAndResetStatistics();
42
43private:
44	struct ShapeMaskElement {
45		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
87private:
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