1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef MOZILLA_GFX_TEXTURECLIENT_RECYCLE_ALLOCATOR_H
7 #define MOZILLA_GFX_TEXTURECLIENT_RECYCLE_ALLOCATOR_H
8 
9 #include <map>
10 #include <stack>
11 #include "mozilla/gfx/Types.h"
12 #include "mozilla/layers/TextureForwarder.h"
13 #include "mozilla/RefPtr.h"
14 #include "TextureClient.h"
15 #include "mozilla/Mutex.h"
16 
17 namespace mozilla {
18 namespace layers {
19 
20 class TextureClientHolder;
21 struct PlanarYCbCrData;
22 
23 class ITextureClientRecycleAllocator
24 {
25 protected:
~ITextureClientRecycleAllocator()26   virtual ~ITextureClientRecycleAllocator() {}
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 {
38 public:
ITextureClientAllocationHelper(gfx::SurfaceFormat aFormat,gfx::IntSize aSize,BackendSelector aSelector,TextureFlags aTextureFlags,TextureAllocationFlags aAllocationFlags)39   ITextureClientAllocationHelper(gfx::SurfaceFormat aFormat,
40                                  gfx::IntSize aSize,
41                                  BackendSelector aSelector,
42                                  TextureFlags aTextureFlags,
43                                  TextureAllocationFlags aAllocationFlags)
44     : mFormat(aFormat)
45     , mSize(aSize)
46     , mSelector(aSelector)
47     , mTextureFlags(aTextureFlags | TextureFlags::RECYCLE) // Set recycle flag
48     , mAllocationFlags(aAllocationFlags)
49   {}
50 
51   virtual already_AddRefed<TextureClient> Allocate(KnowsCompositor* aAllocator) = 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 YCbCrTextureClientAllocationHelper : public ITextureClientAllocationHelper
62 {
63 public:
64   YCbCrTextureClientAllocationHelper(const PlanarYCbCrData& aData,
65                                      TextureFlags aTextureFlags);
66 
67   bool IsCompatible(TextureClient* aTextureClient) override;
68 
69   already_AddRefed<TextureClient> Allocate(KnowsCompositor* aAllocator) override;
70 
71 protected:
72   const PlanarYCbCrData& mData;
73 };
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 allocated.
81  *
82  * By default this uses TextureClient::CreateForDrawing to allocate new texture
83  * clients.
84  */
85 class TextureClientRecycleAllocator : public ITextureClientRecycleAllocator
86 {
87 protected:
88   virtual ~TextureClientRecycleAllocator();
89 
90 public:
91   explicit TextureClientRecycleAllocator(KnowsCompositor* aAllocator);
92 
93   void SetMaxPoolSize(uint32_t aMax);
94 
95   // Creates and allocates a TextureClient.
96   already_AddRefed<TextureClient>
97   CreateOrRecycle(gfx::SurfaceFormat aFormat,
98                   gfx::IntSize aSize,
99                   BackendSelector aSelector,
100                   TextureFlags aTextureFlags,
101                   TextureAllocationFlags flags = ALLOC_DEFAULT);
102 
103   already_AddRefed<TextureClient>
104   CreateOrRecycle(ITextureClientAllocationHelper& aHelper);
105 
106   void ShrinkToMinimumSize();
107 
108   void Destroy();
109 
110 protected:
111   virtual already_AddRefed<TextureClient>
112   Allocate(gfx::SurfaceFormat aFormat,
113            gfx::IntSize aSize,
114            BackendSelector aSelector,
115            TextureFlags aTextureFlags,
116            TextureAllocationFlags aAllocFlags);
117 
118   RefPtr<KnowsCompositor> mSurfaceAllocator;
119 
120   friend class DefaultTextureClientAllocationHelper;
121   void RecycleTextureClient(TextureClient* aClient) override;
122 
123   static const uint32_t kMaxPooledSized = 2;
124   uint32_t mMaxPooledSize;
125 
126   std::map<TextureClient*, RefPtr<TextureClientHolder> > mInUseClients;
127 
128   // On b2g gonk, std::queue might be a better choice.
129   // On ICS, fence wait happens implicitly before drawing.
130   // Since JB, fence wait happens explicitly when fetching a client from the pool.
131   // stack is good from Graphics cache usage point of view.
132   std::stack<RefPtr<TextureClientHolder> > mPooledClients;
133   Mutex mLock;
134   bool mIsDestroyed;
135 };
136 
137 } // namespace layers
138 } // namespace mozilla
139 
140 #endif /* MOZILLA_GFX_TEXTURECLIENT_RECYCLE_ALLOCATOR_H */
141