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

     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 }

mercurial