mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
b=573409 expire unused cached double-buffering back surfaces r=vlad sr=roc
This commit is contained in:
parent
1656c232c6
commit
f7284fe424
@ -750,32 +750,10 @@ BasicLayerManager::PushGroupWithCachedSurface(gfxContext *aTarget,
|
||||
gfxRect clip = aTarget->GetClipExtents();
|
||||
clip.RoundOut();
|
||||
|
||||
if (mCachedSurface) {
|
||||
/* Verify the current buffer is valid for this purpose */
|
||||
if (mCachedSurface->GetContentType() != aContent) {
|
||||
mCachedSurface = nsnull;
|
||||
} else {
|
||||
/* bufferClip should always be {0,0,width,height} of the buffer surface */
|
||||
if (clip.size.width > mCachedSurfaceSize.width ||
|
||||
clip.size.height > mCachedSurfaceSize.height) {
|
||||
mCachedSurface = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
nsRefPtr<gfxContext> ctx;
|
||||
if (mCachedSurface) {
|
||||
ctx = new gfxContext(mCachedSurface);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||
ctx->Paint();
|
||||
ctx->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
} else {
|
||||
mCachedSurfaceSize = gfxIntSize(clip.size.width, clip.size.height);
|
||||
mCachedSurface = currentSurf->CreateSimilarSurface(aContent,
|
||||
mCachedSurfaceSize);
|
||||
if (!mCachedSurface)
|
||||
return nsnull;
|
||||
ctx = new gfxContext(mCachedSurface);
|
||||
}
|
||||
nsRefPtr<gfxContext> ctx =
|
||||
mCachedSurface.Get(aContent,
|
||||
gfxIntSize(clip.size.width, clip.size.height),
|
||||
currentSurf);
|
||||
/* Align our buffer for the original surface */
|
||||
ctx->Translate(-clip.pos);
|
||||
*aSavedOffset = clip.pos;
|
||||
@ -787,13 +765,13 @@ void
|
||||
BasicLayerManager::PopGroupWithCachedSurface(gfxContext *aTarget,
|
||||
const gfxPoint& aSavedOffset)
|
||||
{
|
||||
if (!mCachedSurface)
|
||||
if (!mTarget)
|
||||
return;
|
||||
|
||||
gfxContextMatrixAutoSaveRestore saveMatrix(aTarget);
|
||||
aTarget->IdentityMatrix();
|
||||
|
||||
aTarget->SetSource(mCachedSurface, aSavedOffset);
|
||||
aTarget->SetSource(mTarget->OriginalSurface(), aSavedOffset);
|
||||
aTarget->Paint();
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "Layers.h"
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "gfxCachedTempSurface.h"
|
||||
#include "nsAutoRef.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
@ -133,8 +134,7 @@ private:
|
||||
nsRefPtr<gfxContext> mTarget;
|
||||
|
||||
// Cached surface for double buffering
|
||||
nsRefPtr<gfxASurface> mCachedSurface;
|
||||
gfxIntSize mCachedSurfaceSize;
|
||||
gfxCachedTempSurface mCachedSurface;
|
||||
|
||||
#ifdef DEBUG
|
||||
enum TransactionPhase { PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING };
|
||||
|
@ -16,6 +16,7 @@ EXPORTS = \
|
||||
gfxASurface.h \
|
||||
gfxAlphaRecovery.h \
|
||||
gfxBlur.h \
|
||||
gfxCachedTempSurface.h \
|
||||
gfxColor.h \
|
||||
gfxContext.h \
|
||||
gfxFont.h \
|
||||
@ -162,6 +163,7 @@ CPPSRCS = \
|
||||
gfxASurface.cpp \
|
||||
gfxAlphaRecovery.cpp \
|
||||
gfxBlur.cpp \
|
||||
gfxCachedTempSurface.cpp \
|
||||
gfxContext.cpp \
|
||||
gfxImageSurface.cpp \
|
||||
gfxFont.cpp \
|
||||
|
139
gfx/thebes/gfxCachedTempSurface.cpp
Normal file
139
gfx/thebes/gfxCachedTempSurface.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Karl Tomlinson <karlt+@karlt.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "gfxCachedTempSurface.h"
|
||||
#include "gfxContext.h"
|
||||
|
||||
class CachedSurfaceExpirationTracker :
|
||||
public nsExpirationTracker<gfxCachedTempSurface,2> {
|
||||
|
||||
public:
|
||||
// With K = 2, this means that surfaces will be released when they are not
|
||||
// used for 1-2 seconds.
|
||||
enum { TIMEOUT_MS = 1000 };
|
||||
CachedSurfaceExpirationTracker()
|
||||
: nsExpirationTracker<gfxCachedTempSurface,2>(TIMEOUT_MS) {}
|
||||
|
||||
~CachedSurfaceExpirationTracker() {
|
||||
AgeAllGenerations();
|
||||
}
|
||||
|
||||
virtual void NotifyExpired(gfxCachedTempSurface* aSurface) {
|
||||
RemoveObject(aSurface);
|
||||
aSurface->Expire();
|
||||
}
|
||||
|
||||
static void MarkSurfaceUsed(gfxCachedTempSurface* aSurface)
|
||||
{
|
||||
if (aSurface->GetExpirationState()->IsTracked()) {
|
||||
sExpirationTracker->MarkUsed(aSurface);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sExpirationTracker) {
|
||||
sExpirationTracker = new CachedSurfaceExpirationTracker();
|
||||
}
|
||||
sExpirationTracker->AddObject(aSurface);
|
||||
}
|
||||
|
||||
static void RemoveSurface(gfxCachedTempSurface* aSurface)
|
||||
{
|
||||
if (!sExpirationTracker)
|
||||
return;
|
||||
|
||||
if (aSurface->GetExpirationState()->IsTracked()) {
|
||||
sExpirationTracker->RemoveObject(aSurface);
|
||||
}
|
||||
if (sExpirationTracker->IsEmpty()) {
|
||||
delete sExpirationTracker;
|
||||
sExpirationTracker = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static CachedSurfaceExpirationTracker* sExpirationTracker;
|
||||
};
|
||||
|
||||
CachedSurfaceExpirationTracker*
|
||||
CachedSurfaceExpirationTracker::sExpirationTracker = nsnull;
|
||||
|
||||
gfxCachedTempSurface::~gfxCachedTempSurface()
|
||||
{
|
||||
CachedSurfaceExpirationTracker::RemoveSurface(this);
|
||||
}
|
||||
|
||||
already_AddRefed<gfxContext>
|
||||
gfxCachedTempSurface::Get(gfxASurface::gfxContentType aContentType,
|
||||
const gfxIntSize& aSize,
|
||||
gfxASurface* aSimilarTo)
|
||||
{
|
||||
if (mSurface) {
|
||||
/* Verify the current buffer is valid for this purpose */
|
||||
if (mSize.width < aSize.width || mSize.height < aSize.height
|
||||
|| (mSurface->GetContentType() != aContentType
|
||||
&& mSurface->AreSimilarSurfacesSensitiveToContentType())) {
|
||||
mSurface = nsnull;
|
||||
} else {
|
||||
NS_ASSERTION(mType == aSimilarTo->GetType(),
|
||||
"Unexpected surface type change");
|
||||
}
|
||||
}
|
||||
|
||||
PRBool cleared = PR_FALSE;
|
||||
if (!mSurface) {
|
||||
mSize = aSize;
|
||||
mSurface = aSimilarTo->CreateSimilarSurface(aContentType, aSize);
|
||||
if (!mSurface)
|
||||
return nsnull;
|
||||
|
||||
cleared = PR_TRUE;
|
||||
#ifdef DEBUG
|
||||
mType = aSimilarTo->GetType();
|
||||
#endif
|
||||
}
|
||||
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(mSurface);
|
||||
if (!cleared && aContentType != gfxASurface::CONTENT_COLOR) {
|
||||
ctx->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||
ctx->Paint();
|
||||
ctx->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
}
|
||||
|
||||
CachedSurfaceExpirationTracker::MarkSurfaceUsed(this);
|
||||
|
||||
return ctx.forget();
|
||||
}
|
90
gfx/thebes/gfxCachedTempSurface.h
Normal file
90
gfx/thebes/gfxCachedTempSurface.h
Normal file
@ -0,0 +1,90 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Corporation code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Karl Tomlinson <karlt+@karlt.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef GFX_CACHED_TEMP_SURFACE_H
|
||||
#define GFX_CACHED_TEMP_SURFACE_H
|
||||
|
||||
#include "gfxASurface.h"
|
||||
#include "nsExpirationTracker.h"
|
||||
|
||||
class gfxContext;
|
||||
|
||||
/**
|
||||
* This class can be used to cache double-buffering back surfaces.
|
||||
*
|
||||
* Large resource allocations may have an overhead that can be avoided by
|
||||
* caching. Caching also alows the system to use history in deciding whether
|
||||
* to manage the surfaces in video or system memory.
|
||||
*
|
||||
* However, because we don't want to set aside megabytes of unused resources
|
||||
* unncessarily, these surfaces are released on a timer.
|
||||
*/
|
||||
|
||||
class THEBES_API gfxCachedTempSurface {
|
||||
public:
|
||||
/**
|
||||
* Returns a context for a surface that can be efficiently copied to
|
||||
* |aSimilarTo|.
|
||||
*
|
||||
* When |aContentType| has an alpha component, the surface will be cleared.
|
||||
* For opaque surfaces, the initial surface contents are undefined.
|
||||
* When |aContentType| differs in different invocations this is handled
|
||||
* appropriately, creating a new surface if necessary.
|
||||
*
|
||||
* |aSimilarTo| should be of the same gfxSurfaceType in each invocation.
|
||||
* Because the cached surface may have been created during a previous
|
||||
* invocation, this will not be efficient if the new |aSimilarTo| has a
|
||||
* different format.
|
||||
*/
|
||||
already_AddRefed<gfxContext> Get(gfxASurface::gfxContentType aContentType,
|
||||
const gfxIntSize& aSize,
|
||||
gfxASurface* aSimilarTo);
|
||||
|
||||
void Expire() { mSurface = nsnull; }
|
||||
nsExpirationState* GetExpirationState() { return &mExpirationState; }
|
||||
~gfxCachedTempSurface();
|
||||
|
||||
private:
|
||||
nsRefPtr<gfxASurface> mSurface;
|
||||
gfxIntSize mSize;
|
||||
nsExpirationState mExpirationState;
|
||||
#ifdef DEBUG
|
||||
gfxASurface::gfxSurfaceType mType;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* GFX_CACHED_TEMP_SURFACE_H */
|
Loading…
Reference in New Issue
Block a user