Bug 651017, part 3: Make nsThebesDeviceContext not an nsIObserver. Also remove some more obsolete junk from nsThebesDeviceContext itself.

--HG--
extra : rebase_source : 38fdc667532509e272726bf8098c6f728e94e8ad
This commit is contained in:
Zack Weinberg 2011-04-16 18:22:41 -07:00
Родитель cf9f8f9844
Коммит 67295a5d8d
2 изменённых файлов: 67 добавлений и 105 удалений

Просмотреть файл

@ -44,6 +44,8 @@
#include "nsIServiceManager.h"
#include "nsIPrefService.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "nsCRT.h"
#include "mozilla/Services.h"
@ -92,56 +94,70 @@ static nsSystemFontsAndroid *gSystemFonts = nsnull;
#error Need to declare gSystemFonts!
#endif
#ifdef PR_LOGGING
PRLogModuleInfo* gThebesGFXLog = nsnull;
#endif
using mozilla::services::GetObserverService;
class nsFontCache
class nsFontCache : public nsIObserver
{
public:
nsFontCache();
~nsFontCache();
nsFontCache() { MOZ_COUNT_CTOR(nsFontCache); }
~nsFontCache() { MOZ_COUNT_DTOR(nsFontCache); }
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
void Init(nsIDeviceContext* aContext);
void Destroy();
nsresult Init(nsIDeviceContext* aContext);
nsresult GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
gfxUserFontSet* aUserFontSet,
nsFontMetrics*& aMetrics);
nsresult FontMetricsDeleted(const nsFontMetrics* aFontMetrics);
nsresult Compact();
nsresult Flush();
void FontMetricsDeleted(const nsFontMetrics* aFontMetrics);
void Compact();
void Flush();
protected:
nsIDeviceContext* mContext; // owner
nsTArray<nsFontMetrics*> mFontMetrics;
nsIDeviceContext *mContext; // we do not addref this since
// ownership is implied. MMP.
};
nsFontCache::nsFontCache()
NS_IMPL_ISUPPORTS1(nsFontCache, nsIObserver)
// The Init and Destroy methods are necessary because it's not
// safe to call AddObserver from a constructor or RemoveObserver
// from a destructor. That should be fixed.
void
nsFontCache::Init(nsIDeviceContext* aContext)
{
MOZ_COUNT_CTOR(nsFontCache);
mContext = nsnull;
mContext = aContext;
// register as a memory-pressure observer to free font resources
// in low-memory situations.
nsCOMPtr<nsIObserverService> obs = GetObserverService();
if (obs)
obs->AddObserver(this, "memory-pressure", PR_FALSE);
}
nsFontCache::~nsFontCache()
void
nsFontCache::Destroy()
{
MOZ_COUNT_DTOR(nsFontCache);
nsCOMPtr<nsIObserverService> obs = GetObserverService();
if (obs)
obs->RemoveObserver(this, "memory-pressure");
Flush();
}
nsresult
nsFontCache::Init(nsIDeviceContext* aContext)
NS_IMETHODIMP
nsFontCache::Observe(nsISupports*, const char* aTopic, const PRUnichar*)
{
NS_PRECONDITION(nsnull != aContext, "null ptr");
// Note: we don't hold a reference to the device context, because it
// holds a reference to us and we don't want circular references
mContext = aContext;
if (!nsCRT::strcmp(aTopic, "memory-pressure"))
Compact();
return NS_OK;
}
nsresult
nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
gfxUserFontSet* aUserFontSet, nsFontMetrics*& aMetrics)
gfxUserFontSet* aUserFontSet,
nsFontMetrics*& aMetrics)
{
// First check our cache
// start from the end, which is where we put the most-recent-used element
@ -205,17 +221,19 @@ nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
return NS_OK;
}
NS_POSTCONDITION(NS_SUCCEEDED(rv), "font metrics should not be null - bug 136248");
NS_POSTCONDITION(NS_SUCCEEDED(rv),
"font metrics should not be null - bug 136248");
return rv;
}
nsresult nsFontCache::FontMetricsDeleted(const nsFontMetrics* aFontMetrics)
void
nsFontCache::FontMetricsDeleted(const nsFontMetrics* aFontMetrics)
{
mFontMetrics.RemoveElement(aFontMetrics);
return NS_OK;
}
nsresult nsFontCache::Compact()
void
nsFontCache::Compact()
{
// Need to loop backward because the running element can be removed on
// the way
@ -227,15 +245,15 @@ nsresult nsFontCache::Compact()
NS_RELEASE(fm); // this will reset fm to nsnull
// if the font is really gone, it would have called back in
// FontMetricsDeleted() and would have removed itself
if (mFontMetrics.IndexOf(oldfm) != mFontMetrics.NoIndex) {
if (mFontMetrics.IndexOf(oldfm) != mFontMetrics.NoIndex) {
// nope, the font is still there, so let's hold onto it too
NS_ADDREF(oldfm);
}
}
return NS_OK;
}
nsresult nsFontCache::Flush()
void
nsFontCache::Flush()
{
for (PRInt32 i = mFontMetrics.Length()-1; i >= 0; --i) {
nsFontMetrics* fm = mFontMetrics[i];
@ -245,23 +263,13 @@ nsresult nsFontCache::Flush()
fm->Destroy();
NS_RELEASE(fm);
}
mFontMetrics.Clear();
return NS_OK;
}
NS_IMPL_ISUPPORTS3(nsThebesDeviceContext, nsIDeviceContext, nsIObserver, nsISupportsWeakReference)
NS_IMPL_ISUPPORTS1(nsThebesDeviceContext, nsIDeviceContext)
nsThebesDeviceContext::nsThebesDeviceContext()
{
#ifdef PR_LOGGING
if (!gThebesGFXLog)
gThebesGFXLog = PR_NewLogModule("thebesGfx");
#endif
PR_LOG(gThebesGFXLog, PR_LOG_DEBUG, ("#### Creating DeviceContext %p\n", this));
mAppUnitsPerDevPixel = nscoord(-1);
mAppUnitsPerPhysicalInch = nscoord(-1);
mAppUnitsPerDevNotScaledPixel = nscoord(-1);
@ -274,41 +282,26 @@ nsThebesDeviceContext::nsThebesDeviceContext()
mWidth = 0;
mHeight = 0;
mPrintingScale = 1.0f;
#if defined(XP_WIN) && !defined(WINCE)
SCRIPT_DIGITSUBSTITUTE sds;
ScriptRecordDigitSubstitution(LOCALE_USER_DEFAULT, &sds);
#endif
}
// Note: we use a bare pointer for mFontCache so that nsFontCache
// can be an incomplete type in nsThebesDeviceContext.h.
// Therefore we have to do all the refcounting by hand.
nsThebesDeviceContext::~nsThebesDeviceContext()
{
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs)
obs->RemoveObserver(this, "memory-pressure");
if (nsnull != mFontCache) {
delete mFontCache;
mFontCache = nsnull;
if (mFontCache) {
mFontCache->Destroy();
NS_RELEASE(mFontCache);
}
}
NS_IMETHODIMP
nsThebesDeviceContext::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aSomeData)
{
if (mFontCache && !nsCRT::strcmp(aTopic, "memory-pressure")) {
mFontCache->Compact();
}
return NS_OK;
}
NS_IMETHODIMP nsThebesDeviceContext::CreateFontCache()
{
mFontCache = new nsFontCache();
if (!mFontCache) {
return NS_ERROR_OUT_OF_MEMORY;
}
return mFontCache->Init(this);
NS_ADDREF(mFontCache);
mFontCache->Init(this);
GetLocaleLanguage();
return NS_OK;
}
NS_IMETHODIMP nsThebesDeviceContext::FontMetricsDeleted(const nsFontMetrics* aFontMetrics)
@ -337,15 +330,8 @@ nsThebesDeviceContext::GetLocaleLanguage(void)
NS_IMETHODIMP nsThebesDeviceContext::GetMetricsFor(const nsFont& aFont,
nsIAtom* aLanguage, gfxUserFontSet* aUserFontSet, nsFontMetrics*& aMetrics)
{
if (nsnull == mFontCache) {
nsresult rv = CreateFontCache();
if (NS_FAILED(rv)) {
aMetrics = nsnull;
return rv;
}
// XXX temporary fix for performance problem -- erik
GetLocaleLanguage();
}
if (!mFontCache)
CreateFontCache();
// XXX figure out why aLanguage is NULL sometimes
// -> see nsPageFrame.cpp:511
@ -360,15 +346,9 @@ NS_IMETHODIMP nsThebesDeviceContext::GetMetricsFor(const nsFont& aFont,
gfxUserFontSet* aUserFontSet,
nsFontMetrics*& aMetrics)
{
if (nsnull == mFontCache) {
nsresult rv = CreateFontCache();
if (NS_FAILED(rv)) {
aMetrics = nsnull;
return rv;
}
// XXX temporary fix for performance problem -- erik
GetLocaleLanguage();
}
if (!mFontCache)
CreateFontCache();
return mFontCache->GetMetricsFor(aFont, mLocaleLanguage, aUserFontSet,
aMetrics);
}
@ -409,7 +389,7 @@ nsThebesDeviceContext::GetLocalFontName(const nsString& aFaceName,
NS_IMETHODIMP nsThebesDeviceContext::FlushFontCache(void)
{
if (nsnull != mFontCache)
if (mFontCache)
mFontCache->Flush();
return NS_OK;
}
@ -536,12 +516,6 @@ nsThebesDeviceContext::Init(nsIWidget *aWidget)
if (mScreenManager)
return NS_OK;
// register as a memory-pressure observer to free font resources
// in low-memory situations.
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs)
obs->AddObserver(this, "memory-pressure", PR_TRUE);
mScreenManager = do_GetService("@mozilla.org/gfx/screenmanager;1");
return NS_OK;

Просмотреть файл

@ -45,17 +45,8 @@
#include "nsIDeviceContextSpec.h"
#include "nsCOMPtr.h"
#include "nsIAtom.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "nsWeakReference.h"
#include "gfxContext.h"
#include "prlog.h"
#ifdef PR_LOGGING
extern PRLogModuleInfo* gThebesGFXLog;
#endif
#ifdef XP_WIN
#include "gfxWindowsSurface.h"
#elif defined(XP_OS2)
@ -64,9 +55,7 @@ extern PRLogModuleInfo* gThebesGFXLog;
class nsFontCache;
class nsThebesDeviceContext : public nsIDeviceContext,
public nsIObserver,
public nsSupportsWeakReference
class nsThebesDeviceContext : public nsIDeviceContext
{
public:
nsThebesDeviceContext();
@ -75,7 +64,6 @@ public:
static void Shutdown();
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
NS_IMETHOD Init(nsIWidget *aWidget);
NS_IMETHOD InitForPrinting(nsIDeviceContextSpec *aDevSpec);