Bug 1632310 [wpt PR 23186] - Add test for computed versus resolved style., a=testonly
[gecko.git] / gfx / layers / mlgpu / BufferCache.h
blob0f67597e3a9a83d963f37e7aa5d25791023dab29
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_gfx_layers_mlgpu_BufferCache_h
8 #define mozilla_gfx_layers_mlgpu_BufferCache_h
10 #include "mozilla/EnumeratedArray.h"
11 #include "mozilla/RefPtr.h"
12 #include <deque>
13 #include <vector>
15 namespace mozilla {
16 namespace layers {
18 class MLGBuffer;
19 class MLGDevice;
21 // Cache MLGBuffers based on how long ago they were last used.
22 class BufferCache final {
23 public:
24 explicit BufferCache(MLGDevice* aDevice);
25 ~BufferCache();
27 // Get a buffer that has at least |aBytes|, or create a new one
28 // if none can be re-used.
29 RefPtr<MLGBuffer> GetOrCreateBuffer(size_t aBytes);
31 // Age out old buffers after a frame has been completed.
32 void EndFrame();
34 private:
35 // Not RefPtr since this would create a cycle.
36 MLGDevice* mDevice;
38 // The first size class is Log2(N), where 16 is the minimum size of a
39 // constant buffer (currently 16 bytes).
40 size_t mFirstSizeClass;
42 // Each size class is a power of 2. Each pool of buffers is represented as a
43 // deque, with the least-recently-used (i.e., oldest) buffers at the front,
44 // and most-recently-used (i.e., newest) buffers at the back. To re-use a
45 // buffer it is popped off the front and re-added to the back.
47 // This is not always efficient use of storage: if a single frame allocates
48 // 300 buffers of the same size, we may keep recycling through all those
49 // buffers for a long time, as long as at least one gets used per frame.
50 // But since buffers use tiny amounts of memory, and they are only mapped
51 // while drawing, it shouldn't be a big deal.
52 struct CacheEntry {
53 CacheEntry() : mLastUsedFrame(0) {}
54 // XXX The copy constructor can be deleted once RefPtr's move constructor is
55 // declared noexcept, see Bug 1612680.
56 CacheEntry(const CacheEntry& aEntry) = default;
57 CacheEntry(CacheEntry&& aEntry) = default;
58 CacheEntry(size_t aLastUsedFrame, MLGBuffer* aBuffer)
59 : mLastUsedFrame(aLastUsedFrame), mBuffer(aBuffer) {}
61 uint64_t mLastUsedFrame;
62 RefPtr<MLGBuffer> mBuffer;
64 typedef std::deque<CacheEntry> CachePool;
66 // We track how many frames have occurred to determine the age of cache
67 // entries.
68 uint64_t mFrameNumber;
70 // To avoid doing too much work in one frame, we only shrink one size class
71 // per frame.
72 uint64_t mNextSizeClassToShrink;
74 // There is one pool of buffers for each power of 2 allocation size. The
75 // maximum buffer size is at most 64KB on Direct3D 11.
76 std::vector<CachePool> mCaches;
79 } // namespace layers
80 } // namespace mozilla
82 #endif // mozilla_gfx_layers_mlgpu_BufferCache_h