Bug 1036011 - Remove WaitForBufferOwnership() from TextureClientPool::GetTextureClien...
[gecko.git] / gfx / layers / client / SimpleTextureClientPool.cpp
blob2b82c1675a4754001bcd3985ab73d3627e2ff3cd
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 mAvailableTextureClients.pop();
68 RECYCLE_LOG("%s Skip allocate (%i left), returning %p\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), mAvailableTextureClients.size(), textureClient.get());
70 } else {
71 // No unused clients in the pool, create one
72 if (gfxPrefs::ForceShmemTiles()) {
73 textureClient = TextureClient::CreateBufferTextureClient(mSurfaceAllocator,
74 mFormat, TextureFlags::IMMEDIATE_UPLOAD | TextureFlags::RECYCLE, gfx::BackendType::NONE);
75 } else {
76 textureClient = TextureClient::CreateTextureClientForDrawing(mSurfaceAllocator,
77 mFormat, TextureFlags::DEFAULT | TextureFlags::RECYCLE, gfx::BackendType::NONE, mSize);
79 if (!textureClient->AllocateForSurface(mSize, ALLOC_DEFAULT)) {
80 NS_WARNING("TextureClient::AllocateForSurface failed!");
82 RECYCLE_LOG("%s Must allocate (0 left), returning %p\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), textureClient.get());
85 if (aAutoRecycle) {
86 mOutstandingTextureClients.push_back(textureClient);
87 textureClient->SetRecycleCallback(SimpleTextureClientPool::WaitForCompositorRecycleCallback, this);
90 return textureClient;
93 void
94 SimpleTextureClientPool::ReturnTextureClient(TextureClient *aClient)
96 if (!aClient) {
97 return;
100 // If we haven't hit our max cached client limit, add this one
101 if (mAvailableTextureClients.size() < sMaxTextureClients) {
102 mAvailableTextureClients.push(aClient);
103 RECYCLE_LOG("%s recycled %p (have %d)\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), aClient, mAvailableTextureClients.size());
104 } else {
105 RECYCLE_LOG("%s did not recycle %p (have %d)\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), aClient, mAvailableTextureClients.size());
108 // Kick off the pool shrinking timer if there are still more unused texture
109 // clients than our desired minimum cache size.
110 if (mAvailableTextureClients.size() > sMinCacheSize) {
111 mTimer->InitWithFuncCallback(SimpleTextureClientPool::ShrinkCallback, this, sShrinkTimeout,
112 nsITimer::TYPE_ONE_SHOT);
115 mOutstandingTextureClients.remove(aClient);
118 void
119 SimpleTextureClientPool::ShrinkToMinimumSize()
121 RECYCLE_LOG("%s ShrinkToMinimumSize, removing %d clients", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), mAvailableTextureClients.size() > sMinCacheSize ? mAvailableTextureClients.size() - sMinCacheSize : 0);
123 mTimer->Cancel();
125 while (mAvailableTextureClients.size() > sMinCacheSize) {
126 mAvailableTextureClients.pop();
130 void
131 SimpleTextureClientPool::Clear()
133 while (!mAvailableTextureClients.empty()) {
134 mAvailableTextureClients.pop();