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_TEXTURECLIENT_RECYCLE_ALLOCATOR_H
8 #define MOZILLA_GFX_TEXTURECLIENT_RECYCLE_ALLOCATOR_H
9 
10 #include <map>
11 #include <stack>
12 #include "mozilla/gfx/Types.h"
13 #include "mozilla/layers/TextureForwarder.h"
14 #include "mozilla/RefPtr.h"
15 #include "TextureClient.h"
16 #include "mozilla/Mutex.h"
17 
18 namespace mozilla {
19 namespace layers {
20 
21 class TextureClientHolder;
22 struct PlanarYCbCrData;
23 
24 class ITextureClientRecycleAllocator {
25  protected:
26   virtual ~ITextureClientRecycleAllocator() = default;
27 
28  public:
29   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ITextureClientRecycleAllocator)
30 
31  protected:
32   friend class TextureClient;
33   virtual void RecycleTextureClient(TextureClient* aClient) = 0;
34 };
35 
36 class ITextureClientAllocationHelper {
37  public:
ITextureClientAllocationHelper(gfx::SurfaceFormat aFormat,gfx::IntSize aSize,BackendSelector aSelector,TextureFlags aTextureFlags,TextureAllocationFlags aAllocationFlags)38   ITextureClientAllocationHelper(gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
39                                  BackendSelector aSelector,
40                                  TextureFlags aTextureFlags,
41                                  TextureAllocationFlags aAllocationFlags)
42       : mFormat(aFormat),
43         mSize(aSize),
44         mSelector(aSelector),
45         mTextureFlags(aTextureFlags |
46                       TextureFlags::RECYCLE)  // Set recycle flag
47         ,
48         mAllocationFlags(aAllocationFlags) {}
49 
50   virtual already_AddRefed<TextureClient> Allocate(
51       KnowsCompositor* aKnowsCompositor) = 0;
52   virtual bool IsCompatible(TextureClient* aTextureClient) = 0;
53 
54   const gfx::SurfaceFormat mFormat;
55   const gfx::IntSize mSize;
56   const BackendSelector mSelector;
57   const TextureFlags mTextureFlags;
58   const TextureAllocationFlags mAllocationFlags;
59 };
60 
61 class MOZ_RAII YCbCrTextureClientAllocationHelper
62     : public ITextureClientAllocationHelper {
63  public:
64   YCbCrTextureClientAllocationHelper(const PlanarYCbCrData& aData,
65                                      TextureFlags aTextureFlags);
66 
67   bool IsCompatible(TextureClient* aTextureClient) override;
68 
69   already_AddRefed<TextureClient> Allocate(
70       KnowsCompositor* aKnowsCompositor) override;
71 
72  protected:
73   const PlanarYCbCrData& mData;
74 };
75 
76 /**
77  * TextureClientRecycleAllocator provides TextureClients allocation and
78  * recycling capabilities. It expects allocations of same sizes and
79  * attributres. If a recycled TextureClient is different from
80  * requested one, the recycled one is dropped and new TextureClient is
81  * allocated.
82  *
83  * By default this uses TextureClient::CreateForDrawing to allocate new texture
84  * clients.
85  */
86 class TextureClientRecycleAllocator : public ITextureClientRecycleAllocator {
87  protected:
88   virtual ~TextureClientRecycleAllocator();
89 
90  public:
91   explicit TextureClientRecycleAllocator(KnowsCompositor* aKnowsCompositor);
92 
93   void SetMaxPoolSize(uint32_t aMax);
94 
95   // Creates and allocates a TextureClient.
96   already_AddRefed<TextureClient> CreateOrRecycle(
97       gfx::SurfaceFormat aFormat, gfx::IntSize aSize, BackendSelector aSelector,
98       TextureFlags aTextureFlags, TextureAllocationFlags flags = ALLOC_DEFAULT);
99 
100   already_AddRefed<TextureClient> CreateOrRecycle(
101       ITextureClientAllocationHelper& aHelper);
102 
103   void ShrinkToMinimumSize();
104 
105   void Destroy();
106 
GetKnowsCompositor()107   KnowsCompositor* GetKnowsCompositor() { return mKnowsCompositor; }
108 
109  protected:
110   virtual already_AddRefed<TextureClient> Allocate(
111       gfx::SurfaceFormat aFormat, gfx::IntSize aSize, BackendSelector aSelector,
112       TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags);
113 
114   const RefPtr<KnowsCompositor> mKnowsCompositor;
115 
116   friend class DefaultTextureClientAllocationHelper;
117   void RecycleTextureClient(TextureClient* aClient) override;
118 
119   static const uint32_t kMaxPooledSized = 2;
120   uint32_t mMaxPooledSize;
121 
122   std::map<TextureClient*, RefPtr<TextureClientHolder> > mInUseClients;
123 
124   // stack is good from Graphics cache usage point of view.
125   std::stack<RefPtr<TextureClientHolder> > mPooledClients;
126   Mutex mLock;
127   bool mIsDestroyed;
128 };
129 
130 }  // namespace layers
131 }  // namespace mozilla
132 
133 #endif /* MOZILLA_GFX_TEXTURECLIENT_RECYCLE_ALLOCATOR_H */
134