gfx/thebes/gfxCachedTempSurface.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 "gfxCachedTempSurface.h"
     7 #include "gfxContext.h"
     8 #include "mozilla/Attributes.h"
    10 class CachedSurfaceExpirationTracker MOZ_FINAL :
    11   public nsExpirationTracker<gfxCachedTempSurface,2> {
    13 public:
    14   // With K = 2, this means that surfaces will be released when they are not
    15   // used for 1-2 seconds.
    16   enum { TIMEOUT_MS = 1000 };
    17   CachedSurfaceExpirationTracker()
    18     : nsExpirationTracker<gfxCachedTempSurface,2>(TIMEOUT_MS) {}
    20   ~CachedSurfaceExpirationTracker() {
    21     AgeAllGenerations();
    22   }
    24   virtual void NotifyExpired(gfxCachedTempSurface* aSurface) {
    25     RemoveObject(aSurface);
    26     aSurface->Expire();
    27   }
    29   static void MarkSurfaceUsed(gfxCachedTempSurface* aSurface)
    30   {
    31     if (aSurface->GetExpirationState()->IsTracked()) {
    32       sExpirationTracker->MarkUsed(aSurface);
    33       return;
    34     }
    36     if (!sExpirationTracker) {
    37       sExpirationTracker = new CachedSurfaceExpirationTracker();
    38     }
    39     sExpirationTracker->AddObject(aSurface);
    40   }
    42   static void RemoveSurface(gfxCachedTempSurface* aSurface)
    43   {
    44     if (!sExpirationTracker)
    45       return;
    47     if (aSurface->GetExpirationState()->IsTracked()) {
    48       sExpirationTracker->RemoveObject(aSurface);
    49     }
    50     if (sExpirationTracker->IsEmpty()) {
    51       delete sExpirationTracker;
    52       sExpirationTracker = nullptr;
    53     }
    54   }
    56 private:
    57   static CachedSurfaceExpirationTracker* sExpirationTracker;
    58 };
    60 CachedSurfaceExpirationTracker*
    61 CachedSurfaceExpirationTracker::sExpirationTracker = nullptr;
    63 gfxCachedTempSurface::~gfxCachedTempSurface()
    64 {
    65   CachedSurfaceExpirationTracker::RemoveSurface(this);
    66 }
    68 already_AddRefed<gfxContext>
    69 gfxCachedTempSurface::Get(gfxContentType aContentType,
    70                           const gfxRect& aRect,
    71                           gfxASurface* aSimilarTo)
    72 {
    73   if (mSurface) {
    74     /* Verify the current buffer is valid for this purpose */
    75     if (mSize.width < aRect.width || mSize.height < aRect.height
    76         || mSurface->GetContentType() != aContentType
    77         || mType != aSimilarTo->GetType()) {
    78       mSurface = nullptr;
    79     }
    80   }
    82   bool cleared = false;
    83   if (!mSurface) {
    84     mSize = gfxIntSize(int32_t(ceil(aRect.width)), int32_t(ceil(aRect.height)));
    85     mSurface = aSimilarTo->CreateSimilarSurface(aContentType, mSize);
    86     if (!mSurface)
    87       return nullptr;
    89     cleared = true;
    90     mType = aSimilarTo->GetType();
    91   }
    92   mSurface->SetDeviceOffset(-aRect.TopLeft());
    94   nsRefPtr<gfxContext> ctx = new gfxContext(mSurface);
    95   ctx->Rectangle(aRect);
    96   ctx->Clip();
    97   if (!cleared && aContentType != gfxContentType::COLOR) {
    98     ctx->SetOperator(gfxContext::OPERATOR_CLEAR);
    99     ctx->Paint();
   100     ctx->SetOperator(gfxContext::OPERATOR_OVER);
   101   }
   103   CachedSurfaceExpirationTracker::MarkSurfaceUsed(this);
   105   return ctx.forget();
   106 }

mercurial