summaryrefslogtreecommitdiffstats
path: root/gfx/layers/client/TextureClientPool.h
blob: 642c14bf53d95d5a847e45c08664baa45c11394e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef MOZILLA_GFX_TEXTURECLIENTPOOL_H
#define MOZILLA_GFX_TEXTURECLIENTPOOL_H

#include "mozilla/gfx/Types.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/RefPtr.h"
#include "TextureClient.h"
#include "nsITimer.h"
#include <stack>
#include <list>

namespace mozilla {
namespace layers {

class ISurfaceAllocator;
class TextureForwarder;
class TextureReadLock;

class TextureClientAllocator
{
protected:
  virtual ~TextureClientAllocator() {}
public:
  NS_INLINE_DECL_REFCOUNTING(TextureClientAllocator)

  virtual already_AddRefed<TextureClient> GetTextureClient() = 0;

  /**
   * Return a TextureClient that is not yet ready to be reused, but will be
   * imminently.
   */
  virtual void ReturnTextureClientDeferred(TextureClient *aClient) = 0;

  virtual void ReportClientLost() = 0;
};

class TextureClientPool final : public TextureClientAllocator
{
  ~TextureClientPool();

public:
  TextureClientPool(LayersBackend aBackend,
                    int32_t aMaxTextureSize,
                    gfx::SurfaceFormat aFormat,
                    gfx::IntSize aSize,
                    TextureFlags aFlags,
                    uint32_t aShrinkTimeoutMsec,
                    uint32_t aClearTimeoutMsec,
                    uint32_t aInitialPoolSize,
                    uint32_t aPoolUnusedSize,
                    TextureForwarder* aAllocator);

  /**
   * Gets an allocated TextureClient of size and format that are determined
   * by the initialisation parameters given to the pool. This will either be
   * a cached client that was returned to the pool, or a newly allocated
   * client if one isn't available.
   *
   * All clients retrieved by this method should be returned using the return
   * functions, or reported lost so that the pool can manage its size correctly.
   */
  already_AddRefed<TextureClient> GetTextureClient() override;

  /**
   * Return a TextureClient that is no longer being used and is ready for
   * immediate re-use or destruction.
   */
  void ReturnTextureClient(TextureClient *aClient);

  /**
   * Return a TextureClient that is not yet ready to be reused, but will be
   * imminently.
   */
  void ReturnTextureClientDeferred(TextureClient *aClient) override;

  /**
   * Return any clients to the pool that were previously returned in
   * ReturnTextureClientDeferred.
   */
  void ReturnDeferredClients();

  /**
   * Attempt to shrink the pool so that there are no more than
   * mInitialPoolSize outstanding.
   */
  void ShrinkToMaximumSize();

  /**
   * Report that a client retrieved via GetTextureClient() has become
   * unusable, so that it will no longer be tracked.
   */
  virtual void ReportClientLost() override;

  /**
   * Calling this will cause the pool to attempt to relinquish any unused
   * clients.
   */
  void Clear();

  LayersBackend GetBackend() const { return mBackend; }
  int32_t GetMaxTextureSize() const { return mMaxTextureSize; }
  gfx::SurfaceFormat GetFormat() { return mFormat; }
  TextureFlags GetFlags() const { return mFlags; }

  /**
   * Clear the pool and put it in a state where it won't recycle any new texture.
   */
  void Destroy();

private:
  void ReturnUnlockedClients();

  /// Allocate a single TextureClient to be returned from the pool.
  void AllocateTextureClient();

  /// Reset and/or initialise timers for shrinking/clearing the pool.
  void ResetTimers();

  /// Backend passed to the TextureClient for buffer creation.
  LayersBackend mBackend;

  // Max texture size passed to the TextureClient for buffer creation.
  int32_t mMaxTextureSize;

  /// Format is passed to the TextureClient for buffer creation.
  gfx::SurfaceFormat mFormat;

  /// The width and height of the tiles to be used.
  gfx::IntSize mSize;

  /// Flags passed to the TextureClient for buffer creation.
  const TextureFlags mFlags;

  /// How long to wait after a TextureClient is returned before trying
  /// to shrink the pool to its maximum size of mPoolUnusedSize.
  uint32_t mShrinkTimeoutMsec;

  /// How long to wait after a TextureClient is returned before trying
  /// to clear the pool.
  uint32_t mClearTimeoutMsec;

  // The initial number of unused texture clients to seed the pool with
  // on construction
  uint32_t mInitialPoolSize;

  // How many unused texture clients to try and keep around if we go over
  // the initial allocation
  uint32_t mPoolUnusedSize;

  /// This is a total number of clients in the wild and in the stack of
  /// deferred clients (see below).  So, the total number of clients in
  /// existence is always mOutstandingClients + the size of mTextureClients.
  uint32_t mOutstandingClients;

  // On b2g gonk, std::queue might be a better choice.
  // On ICS, fence wait happens implicitly before drawing.
  // Since JB, fence wait happens explicitly when fetching a client from the pool.
  std::stack<RefPtr<TextureClient> > mTextureClients;

  std::list<RefPtr<TextureClient>> mTextureClientsDeferred;
  RefPtr<nsITimer> mShrinkTimer;
  RefPtr<nsITimer> mClearTimer;
  // This mSurfaceAllocator owns us, so no need to hold a ref to it
  TextureForwarder* mSurfaceAllocator;

  // Keep track of whether this pool has been destroyed or not. If it has,
  // we won't accept returns of TextureClients anymore, and the refcounting
  // should take care of their destruction.
  bool mDestroyed;
};

} // namespace layers
} // namespace mozilla

#endif /* MOZILLA_GFX_TEXTURECLIENTPOOL_H */