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