gfx/layers/client/TextureClientPool.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

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

mercurial