Bug 977880 - Handle ReleaseFence on tiled thebes layer r=cwiiis,nical,BenWa
[gecko.git] / gfx / layers / client / SimpleTextureClientPool.cpp
blob2f650f0611863d7f00ff54be90b9604df8ba2b7b
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/. */
6 #include "SimpleTextureClientPool.h"
7 #include "CompositableClient.h"
8 #include "mozilla/layers/ISurfaceAllocator.h"
10 #include "gfxPrefs.h"
12 #include "nsComponentManagerUtils.h"
14 #if 0
15 #define RECYCLE_LOG(...) printf_stderr(__VA_ARGS__)
16 #else
17 #define RECYCLE_LOG(...) do { } while (0)
18 #endif
20 namespace mozilla {
21 namespace layers {
23 using gfx::SurfaceFormat;
25 /* static */ void
26 SimpleTextureClientPool::ShrinkCallback(nsITimer *aTimer, void *aClosure)
28 static_cast<SimpleTextureClientPool*>(aClosure)->ShrinkToMinimumSize();
31 /* static */ void
32 SimpleTextureClientPool::RecycleCallback(TextureClient* aClient, void* aClosure)
34 SimpleTextureClientPool* pool =
35 static_cast<SimpleTextureClientPool*>(aClosure);
37 aClient->ClearRecycleCallback();
38 pool->ReturnTextureClient(aClient);
41 /* static */ void
42 SimpleTextureClientPool::WaitForCompositorRecycleCallback(TextureClient* aClient, void* aClosure)
44 // This will grab a reference that will be released once the compositor
45 // acknowledges the remote recycle. Once it is received the object
46 // will be fully recycled.
47 aClient->WaitForCompositorRecycle();
48 aClient->SetRecycleCallback(SimpleTextureClientPool::RecycleCallback, aClosure);
51 SimpleTextureClientPool::SimpleTextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
52 ISurfaceAllocator *aAllocator)
53 : mFormat(aFormat)
54 , mSize(aSize)
55 , mSurfaceAllocator(aAllocator)
57 mTimer = do_CreateInstance("@mozilla.org/timer;1");
60 TemporaryRef<TextureClient>
61 SimpleTextureClientPool::GetTextureClient(bool aAutoRecycle)
63 // Try to fetch a client from the pool
64 RefPtr<TextureClient> textureClient;
65 if (mAvailableTextureClients.size()) {
66 textureClient = mAvailableTextureClients.top();
67 textureClient->WaitReleaseFence();
68 mAvailableTextureClients.pop();
69 RECYCLE_LOG("%s Skip allocate (%i left), returning %p\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), mAvailableTextureClients.size(), textureClient.get());
71 } else {
72 // No unused clients in the pool, create one
73 if (gfxPrefs::ForceShmemTiles()) {
74 textureClient = TextureClient::CreateBufferTextureClient(mSurfaceAllocator,
75 mFormat, TEXTURE_IMMEDIATE_UPLOAD | TEXTURE_RECYCLE, gfx::BackendType::NONE);
76 } else {
77 textureClient = TextureClient::CreateTextureClientForDrawing(mSurfaceAllocator,
78 mFormat, TEXTURE_FLAGS_DEFAULT | TEXTURE_RECYCLE, gfx::BackendType::NONE, mSize);
80 if (!textureClient->AsTextureClientDrawTarget()->AllocateForSurface(mSize, ALLOC_DEFAULT)) {
81 NS_WARNING("TextureClient::AllocateForSurface failed!");
83 RECYCLE_LOG("%s Must allocate (0 left), returning %p\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), textureClient.get());
86 if (aAutoRecycle) {
87 mOutstandingTextureClients.push_back(textureClient);
88 textureClient->SetRecycleCallback(SimpleTextureClientPool::WaitForCompositorRecycleCallback, this);
91 return textureClient;
94 void
95 SimpleTextureClientPool::ReturnTextureClient(TextureClient *aClient)
97 if (!aClient) {
98 return;
101 // If we haven't hit our max cached client limit, add this one
102 if (mAvailableTextureClients.size() < sMaxTextureClients) {
103 mAvailableTextureClients.push(aClient);
104 RECYCLE_LOG("%s recycled %p (have %d)\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), aClient, mAvailableTextureClients.size());
105 } else {
106 RECYCLE_LOG("%s did not recycle %p (have %d)\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), aClient, mAvailableTextureClients.size());
109 // Kick off the pool shrinking timer if there are still more unused texture
110 // clients than our desired minimum cache size.
111 if (mAvailableTextureClients.size() > sMinCacheSize) {
112 mTimer->InitWithFuncCallback(SimpleTextureClientPool::ShrinkCallback, this, sShrinkTimeout,
113 nsITimer::TYPE_ONE_SHOT);
116 mOutstandingTextureClients.remove(aClient);
119 void
120 SimpleTextureClientPool::ShrinkToMinimumSize()
122 RECYCLE_LOG("%s ShrinkToMinimumSize, removing %d clients", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), mAvailableTextureClients.size() > sMinCacheSize ? mAvailableTextureClients.size() - sMinCacheSize : 0);
124 mTimer->Cancel();
126 while (mAvailableTextureClients.size() > sMinCacheSize) {
127 mAvailableTextureClients.pop();
131 void
132 SimpleTextureClientPool::Clear()
134 while (!mAvailableTextureClients.empty()) {
135 mAvailableTextureClients.pop();