Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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 "TextureClientPool.h"
7 #include "CompositableClient.h"
8 #include "mozilla/layers/ISurfaceAllocator.h"
10 #include "gfxPrefs.h"
12 #include "nsComponentManagerUtils.h"
14 namespace mozilla {
15 namespace layers {
17 static void
18 ShrinkCallback(nsITimer *aTimer, void *aClosure)
19 {
20 static_cast<TextureClientPool*>(aClosure)->ShrinkToMinimumSize();
21 }
23 TextureClientPool::TextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
24 ISurfaceAllocator *aAllocator)
25 : mFormat(aFormat)
26 , mSize(aSize)
27 , mOutstandingClients(0)
28 , mSurfaceAllocator(aAllocator)
29 {
30 mTimer = do_CreateInstance("@mozilla.org/timer;1");
31 }
33 TextureClientPool::~TextureClientPool()
34 {
35 mTimer->Cancel();
36 }
38 TemporaryRef<TextureClient>
39 TextureClientPool::GetTextureClient()
40 {
41 mOutstandingClients++;
43 // Try to fetch a client from the pool
44 RefPtr<TextureClient> textureClient;
45 if (mTextureClients.size()) {
46 textureClient = mTextureClients.top();
47 textureClient->WaitReleaseFence();
48 mTextureClients.pop();
49 return textureClient;
50 }
52 // We're increasing the number of outstanding TextureClients without reusing a
53 // client, we may need to free a deferred-return TextureClient.
54 ShrinkToMaximumSize();
56 // No unused clients in the pool, create one
57 if (gfxPrefs::ForceShmemTiles()) {
58 // gfx::BackendType::NONE means use the content backend
59 textureClient = TextureClient::CreateBufferTextureClient(mSurfaceAllocator,
60 mFormat, TEXTURE_IMMEDIATE_UPLOAD, gfx::BackendType::NONE);
61 } else {
62 textureClient = TextureClient::CreateTextureClientForDrawing(mSurfaceAllocator,
63 mFormat, TEXTURE_IMMEDIATE_UPLOAD, gfx::BackendType::NONE, mSize);
64 }
65 textureClient->AllocateForSurface(mSize, ALLOC_DEFAULT);
67 return textureClient;
68 }
70 void
71 TextureClientPool::ReturnTextureClient(TextureClient *aClient)
72 {
73 if (!aClient) {
74 return;
75 }
76 MOZ_ASSERT(mOutstandingClients);
77 mOutstandingClients--;
79 // Add the client to the pool and shrink down if we're beyond our maximum size
80 mTextureClients.push(aClient);
81 ShrinkToMaximumSize();
83 // Kick off the pool shrinking timer if there are still more unused texture
84 // clients than our desired minimum cache size.
85 if (mTextureClients.size() > sMinCacheSize) {
86 mTimer->InitWithFuncCallback(ShrinkCallback, this, sShrinkTimeout,
87 nsITimer::TYPE_ONE_SHOT);
88 }
89 }
91 void
92 TextureClientPool::ReturnTextureClientDeferred(TextureClient *aClient)
93 {
94 mTextureClientsDeferred.push(aClient);
95 ShrinkToMaximumSize();
96 }
98 void
99 TextureClientPool::ShrinkToMaximumSize()
100 {
101 uint32_t totalClientsOutstanding = mTextureClients.size() + mOutstandingClients;
103 // We're over our desired maximum size, immediately shrink down to the
104 // maximum, or zero if we have too many outstanding texture clients.
105 // We cull from the deferred TextureClients first, as we can't reuse those
106 // until they get returned.
107 while (totalClientsOutstanding > sMaxTextureClients) {
108 if (mTextureClientsDeferred.size()) {
109 mOutstandingClients--;
110 mTextureClientsDeferred.pop();
111 } else {
112 if (!mTextureClients.size()) {
113 // Getting here means we're over our desired number of TextureClients
114 // with none in the pool. This can happen for pathological cases, or
115 // it could mean that sMaxTextureClients needs adjusting for whatever
116 // device we're running on.
117 break;
118 }
119 mTextureClients.pop();
120 }
121 totalClientsOutstanding--;
122 }
123 }
125 void
126 TextureClientPool::ShrinkToMinimumSize()
127 {
128 while (mTextureClients.size() > sMinCacheSize) {
129 mTextureClients.pop();
130 }
131 }
133 void
134 TextureClientPool::ReturnDeferredClients()
135 {
136 while (!mTextureClientsDeferred.empty()) {
137 ReturnTextureClient(mTextureClientsDeferred.top());
138 mTextureClientsDeferred.pop();
139 }
140 }
142 void
143 TextureClientPool::Clear()
144 {
145 while (!mTextureClients.empty()) {
146 mTextureClients.pop();
147 }
148 while (!mTextureClientsDeferred.empty()) {
149 mOutstandingClients--;
150 mTextureClientsDeferred.pop();
151 }
152 }
154 }
155 }