Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
michael@0 | 2 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef MOZILLA_GFX_SIMPLETEXTURECLIENTPOOL_H |
michael@0 | 7 | #define MOZILLA_GFX_SIMPLETEXTURECLIENTPOOL_H |
michael@0 | 8 | |
michael@0 | 9 | #include "mozilla/gfx/Types.h" |
michael@0 | 10 | #include "mozilla/gfx/Point.h" |
michael@0 | 11 | #include "mozilla/RefPtr.h" |
michael@0 | 12 | #include "TextureClient.h" |
michael@0 | 13 | #include "nsITimer.h" |
michael@0 | 14 | #include <stack> |
michael@0 | 15 | #include <list> |
michael@0 | 16 | |
michael@0 | 17 | namespace mozilla { |
michael@0 | 18 | namespace layers { |
michael@0 | 19 | |
michael@0 | 20 | class ISurfaceAllocator; |
michael@0 | 21 | |
michael@0 | 22 | class SimpleTextureClientPool |
michael@0 | 23 | { |
michael@0 | 24 | ~SimpleTextureClientPool() |
michael@0 | 25 | { |
michael@0 | 26 | for (auto it = mOutstandingTextureClients.begin(); it != mOutstandingTextureClients.end(); ++it) { |
michael@0 | 27 | (*it)->ClearRecycleCallback(); |
michael@0 | 28 | } |
michael@0 | 29 | } |
michael@0 | 30 | |
michael@0 | 31 | public: |
michael@0 | 32 | NS_INLINE_DECL_REFCOUNTING(SimpleTextureClientPool) |
michael@0 | 33 | |
michael@0 | 34 | SimpleTextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize, |
michael@0 | 35 | ISurfaceAllocator *aAllocator); |
michael@0 | 36 | |
michael@0 | 37 | /** |
michael@0 | 38 | * If a TextureClient is AutoRecycled, when the last reference is |
michael@0 | 39 | * released this object will be automatically return to the pool as |
michael@0 | 40 | * soon as the compositor informs us it is done with it. |
michael@0 | 41 | */ |
michael@0 | 42 | TemporaryRef<TextureClient> GetTextureClient(bool aAutoRecycle = false); |
michael@0 | 43 | TemporaryRef<TextureClient> GetTextureClientWithAutoRecycle() { return GetTextureClient(true); } |
michael@0 | 44 | |
michael@0 | 45 | void ReturnTextureClient(TextureClient *aClient); |
michael@0 | 46 | |
michael@0 | 47 | void ShrinkToMinimumSize(); |
michael@0 | 48 | |
michael@0 | 49 | void Clear(); |
michael@0 | 50 | |
michael@0 | 51 | private: |
michael@0 | 52 | // The time in milliseconds before the pool will be shrunk to the minimum |
michael@0 | 53 | // size after returning a client. |
michael@0 | 54 | static const uint32_t sShrinkTimeout = 3000; |
michael@0 | 55 | |
michael@0 | 56 | // The minimum size of the pool (the number of tiles that will be kept after |
michael@0 | 57 | // shrinking). |
michael@0 | 58 | static const uint32_t sMinCacheSize = 16; |
michael@0 | 59 | |
michael@0 | 60 | // This is the number of cached texture clients we don't want to exceed, even |
michael@0 | 61 | // temporarily (pre-shrink) |
michael@0 | 62 | static const uint32_t sMaxTextureClients = 50; |
michael@0 | 63 | |
michael@0 | 64 | static void ShrinkCallback(nsITimer *aTimer, void *aClosure); |
michael@0 | 65 | static void RecycleCallback(TextureClient* aClient, void* aClosure); |
michael@0 | 66 | static void WaitForCompositorRecycleCallback(TextureClient* aClient, void* aClosure); |
michael@0 | 67 | |
michael@0 | 68 | gfx::SurfaceFormat mFormat; |
michael@0 | 69 | gfx::IntSize mSize; |
michael@0 | 70 | |
michael@0 | 71 | // We use a std::stack and make sure to use it the following way: |
michael@0 | 72 | // new (available to be used) elements are push()'d to the front |
michael@0 | 73 | // requests are served from the front via pop() |
michael@0 | 74 | // -- the thinking is that recently-used elements are most likely |
michael@0 | 75 | // to be in any data cache, so we can get some wins there |
michael@0 | 76 | // -- the converse though is that if there is some GPU locking going on |
michael@0 | 77 | // the most recently used elements may also have the most contention; |
michael@0 | 78 | // if we see that, then we should use push_back() to add new elements |
michael@0 | 79 | // when we shrink this list, we use pop(), but should use pop_back() to |
michael@0 | 80 | // nuke the oldest. |
michael@0 | 81 | // We may need to switch to a std::deque |
michael@0 | 82 | // On b2g gonk, std::queue might be a better choice. |
michael@0 | 83 | // On ICS, fence wait happens implicitly before drawing. |
michael@0 | 84 | // Since JB, fence wait happens explicitly when fetching a client from the pool. |
michael@0 | 85 | std::stack<RefPtr<TextureClient> > mAvailableTextureClients; |
michael@0 | 86 | std::list<RefPtr<TextureClient> > mOutstandingTextureClients; |
michael@0 | 87 | |
michael@0 | 88 | nsRefPtr<nsITimer> mTimer; |
michael@0 | 89 | RefPtr<ISurfaceAllocator> mSurfaceAllocator; |
michael@0 | 90 | }; |
michael@0 | 91 | |
michael@0 | 92 | } |
michael@0 | 93 | } |
michael@0 | 94 | #endif /* MOZILLA_GFX_SIMPLETEXTURECLIENTPOOL_H */ |