Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/mlgpu/BufferCache.h
Line
Count
Source (jump to first uncovered line)
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/. */
6
7
#ifndef mozilla_gfx_layers_mlgpu_BufferCache_h
8
#define mozilla_gfx_layers_mlgpu_BufferCache_h
9
10
#include "mozilla/EnumeratedArray.h"
11
#include "mozilla/RefPtr.h"
12
#include <deque>
13
#include <vector>
14
15
namespace mozilla {
16
namespace layers {
17
18
class MLGBuffer;
19
class MLGDevice;
20
21
// Cache MLGBuffers based on how long ago they were last used.
22
class BufferCache
23
{
24
public:
25
  explicit BufferCache(MLGDevice* aDevice);
26
  ~BufferCache();
27
28
  // Get a buffer that has at least |aBytes|, or create a new one
29
  // if none can be re-used.
30
  RefPtr<MLGBuffer> GetOrCreateBuffer(size_t aBytes);
31
32
  // Age out old buffers after a frame has been completed.
33
  void EndFrame();
34
35
private:
36
  // Not RefPtr since this would create a cycle.
37
  MLGDevice* mDevice;
38
39
  // The first size class is Log2(N), where 16 is the minimum size of a
40
  // constant buffer (currently 16 bytes).
41
  size_t mFirstSizeClass;
42
43
  // Each size class is a power of 2. Each pool of buffers is represented as a
44
  // deque, with the least-recently-used (i.e., oldest) buffers at the front,
45
  // and most-recently-used (i.e., newest) buffers at the back. To re-use a
46
  // buffer it is popped off the front and re-added to the back.
47
  //
48
  // This is not always efficient use of storage: if a single frame allocates
49
  // 300 buffers of the same size, we may keep recycling through all those
50
  // buffers for a long time, as long as at least one gets used per frame.
51
  // But since buffers use tiny amounts of memory, and they are only mapped
52
  // while drawing, it shouldn't be a big deal.
53
  struct CacheEntry {
54
    CacheEntry() : mLastUsedFrame(0)
55
0
    {}
56
    CacheEntry(const CacheEntry& aEntry)
57
     : mLastUsedFrame(aEntry.mLastUsedFrame),
58
       mBuffer(aEntry.mBuffer)
59
0
    {}
60
    CacheEntry(CacheEntry&& aEntry)
61
     : mLastUsedFrame(aEntry.mLastUsedFrame),
62
       mBuffer(std::move(aEntry.mBuffer))
63
0
    {}
64
    CacheEntry(size_t aLastUsedFrame, MLGBuffer* aBuffer)
65
     : mLastUsedFrame(aLastUsedFrame),
66
       mBuffer(aBuffer)
67
0
    {}
68
69
    uint64_t mLastUsedFrame;
70
    RefPtr<MLGBuffer> mBuffer;
71
  };
72
  typedef std::deque<CacheEntry> CachePool;
73
74
  // We track how many frames have occurred to determine the age of cache entries.
75
  uint64_t mFrameNumber;
76
77
  // To avoid doing too much work in one frame, we only shrink one size class
78
  // per frame.
79
  uint64_t mNextSizeClassToShrink;
80
81
  // There is one pool of buffers for each power of 2 allocation size. The
82
  // maximum buffer size is at most 64KB on Direct3D 11.
83
  std::vector<CachePool> mCaches;
84
};
85
86
} // namespace layers
87
} // namespace mozilla
88
89
#endif // mozilla_gfx_layers_mlgpu_BufferCache_h