gfx/thebes/gfxCachedTempSurface.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/thebes/gfxCachedTempSurface.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,106 @@
     1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "gfxCachedTempSurface.h"
    1.10 +#include "gfxContext.h"
    1.11 +#include "mozilla/Attributes.h"
    1.12 +
    1.13 +class CachedSurfaceExpirationTracker MOZ_FINAL :
    1.14 +  public nsExpirationTracker<gfxCachedTempSurface,2> {
    1.15 +
    1.16 +public:
    1.17 +  // With K = 2, this means that surfaces will be released when they are not
    1.18 +  // used for 1-2 seconds.
    1.19 +  enum { TIMEOUT_MS = 1000 };
    1.20 +  CachedSurfaceExpirationTracker()
    1.21 +    : nsExpirationTracker<gfxCachedTempSurface,2>(TIMEOUT_MS) {}
    1.22 +
    1.23 +  ~CachedSurfaceExpirationTracker() {
    1.24 +    AgeAllGenerations();
    1.25 +  }
    1.26 +
    1.27 +  virtual void NotifyExpired(gfxCachedTempSurface* aSurface) {
    1.28 +    RemoveObject(aSurface);
    1.29 +    aSurface->Expire();
    1.30 +  }
    1.31 +
    1.32 +  static void MarkSurfaceUsed(gfxCachedTempSurface* aSurface)
    1.33 +  {
    1.34 +    if (aSurface->GetExpirationState()->IsTracked()) {
    1.35 +      sExpirationTracker->MarkUsed(aSurface);
    1.36 +      return;
    1.37 +    }
    1.38 +
    1.39 +    if (!sExpirationTracker) {
    1.40 +      sExpirationTracker = new CachedSurfaceExpirationTracker();
    1.41 +    }
    1.42 +    sExpirationTracker->AddObject(aSurface);
    1.43 +  }
    1.44 +
    1.45 +  static void RemoveSurface(gfxCachedTempSurface* aSurface)
    1.46 +  {
    1.47 +    if (!sExpirationTracker)
    1.48 +      return;
    1.49 +
    1.50 +    if (aSurface->GetExpirationState()->IsTracked()) {
    1.51 +      sExpirationTracker->RemoveObject(aSurface);
    1.52 +    }
    1.53 +    if (sExpirationTracker->IsEmpty()) {
    1.54 +      delete sExpirationTracker;
    1.55 +      sExpirationTracker = nullptr;
    1.56 +    }
    1.57 +  }
    1.58 +
    1.59 +private:
    1.60 +  static CachedSurfaceExpirationTracker* sExpirationTracker;
    1.61 +};
    1.62 +
    1.63 +CachedSurfaceExpirationTracker*
    1.64 +CachedSurfaceExpirationTracker::sExpirationTracker = nullptr;
    1.65 +
    1.66 +gfxCachedTempSurface::~gfxCachedTempSurface()
    1.67 +{
    1.68 +  CachedSurfaceExpirationTracker::RemoveSurface(this);
    1.69 +}
    1.70 +
    1.71 +already_AddRefed<gfxContext>
    1.72 +gfxCachedTempSurface::Get(gfxContentType aContentType,
    1.73 +                          const gfxRect& aRect,
    1.74 +                          gfxASurface* aSimilarTo)
    1.75 +{
    1.76 +  if (mSurface) {
    1.77 +    /* Verify the current buffer is valid for this purpose */
    1.78 +    if (mSize.width < aRect.width || mSize.height < aRect.height
    1.79 +        || mSurface->GetContentType() != aContentType
    1.80 +        || mType != aSimilarTo->GetType()) {
    1.81 +      mSurface = nullptr;
    1.82 +    }
    1.83 +  }
    1.84 +
    1.85 +  bool cleared = false;
    1.86 +  if (!mSurface) {
    1.87 +    mSize = gfxIntSize(int32_t(ceil(aRect.width)), int32_t(ceil(aRect.height)));
    1.88 +    mSurface = aSimilarTo->CreateSimilarSurface(aContentType, mSize);
    1.89 +    if (!mSurface)
    1.90 +      return nullptr;
    1.91 +
    1.92 +    cleared = true;
    1.93 +    mType = aSimilarTo->GetType();
    1.94 +  }
    1.95 +  mSurface->SetDeviceOffset(-aRect.TopLeft());
    1.96 +
    1.97 +  nsRefPtr<gfxContext> ctx = new gfxContext(mSurface);
    1.98 +  ctx->Rectangle(aRect);
    1.99 +  ctx->Clip();
   1.100 +  if (!cleared && aContentType != gfxContentType::COLOR) {
   1.101 +    ctx->SetOperator(gfxContext::OPERATOR_CLEAR);
   1.102 +    ctx->Paint();
   1.103 +    ctx->SetOperator(gfxContext::OPERATOR_OVER);
   1.104 +  }
   1.105 +
   1.106 +  CachedSurfaceExpirationTracker::MarkSurfaceUsed(this);
   1.107 +
   1.108 +  return ctx.forget();
   1.109 +}

mercurial