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> {
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() {
24 virtual void NotifyExpired(gfxCachedTempSurface
* aSurface
) {
25 RemoveObject(aSurface
);
29 static void MarkSurfaceUsed(gfxCachedTempSurface
* aSurface
)
31 if (aSurface
->GetExpirationState()->IsTracked()) {
32 sExpirationTracker
->MarkUsed(aSurface
);
36 if (!sExpirationTracker
) {
37 sExpirationTracker
= new CachedSurfaceExpirationTracker();
39 sExpirationTracker
->AddObject(aSurface
);
42 static void RemoveSurface(gfxCachedTempSurface
* aSurface
)
44 if (!sExpirationTracker
)
47 if (aSurface
->GetExpirationState()->IsTracked()) {
48 sExpirationTracker
->RemoveObject(aSurface
);
50 if (sExpirationTracker
->IsEmpty()) {
51 delete sExpirationTracker
;
52 sExpirationTracker
= nullptr;
57 static CachedSurfaceExpirationTracker
* sExpirationTracker
;
60 CachedSurfaceExpirationTracker
*
61 CachedSurfaceExpirationTracker::sExpirationTracker
= nullptr;
63 gfxCachedTempSurface::~gfxCachedTempSurface()
65 CachedSurfaceExpirationTracker::RemoveSurface(this);
68 already_AddRefed
<gfxContext
>
69 gfxCachedTempSurface::Get(gfxASurface::gfxContentType aContentType
,
71 gfxASurface
* aSimilarTo
)
74 /* Verify the current buffer is valid for this purpose */
75 if (mSize
.width
< aRect
.width
|| mSize
.height
< aRect
.height
76 || mSurface
->GetContentType() != aContentType
) {
79 NS_ASSERTION(mType
== aSimilarTo
->GetType(),
80 "Unexpected surface type change");
86 mSize
= gfxIntSize(int32_t(ceil(aRect
.width
)), int32_t(ceil(aRect
.height
)));
87 mSurface
= aSimilarTo
->CreateSimilarSurface(aContentType
, mSize
);
93 mType
= aSimilarTo
->GetType();
96 mSurface
->SetDeviceOffset(-aRect
.TopLeft());
98 nsRefPtr
<gfxContext
> ctx
= new gfxContext(mSurface
);
99 ctx
->Rectangle(aRect
);
101 if (!cleared
&& aContentType
!= gfxASurface::CONTENT_COLOR
) {
102 ctx
->SetOperator(gfxContext::OPERATOR_CLEAR
);
104 ctx
->SetOperator(gfxContext::OPERATOR_OVER
);
107 CachedSurfaceExpirationTracker::MarkSurfaceUsed(this);