Merge m-c to b2g-inbound

This commit is contained in:
Carsten "Tomcat" Book 2013-11-25 15:37:21 +01:00
commit e4de02ad27
47 changed files with 659 additions and 193 deletions

View File

@ -256,14 +256,13 @@ pref("ui.dragThresholdY", 25);
// Layers Acceleration. We can only have nice things on gonk, because
// they're not maintained anywhere else.
pref("layers.offmainthreadcomposition.enabled", true);
#ifndef MOZ_WIDGET_GONK
pref("dom.ipc.tabs.disabled", true);
pref("layers.offmainthreadcomposition.enabled", false);
pref("layers.offmainthreadcomposition.async-animations", false);
pref("layers.async-video.enabled", false);
#else
pref("dom.ipc.tabs.disabled", false);
pref("layers.offmainthreadcomposition.enabled", true);
pref("layers.acceleration.disabled", false);
pref("layers.offmainthreadcomposition.async-animations", true);
pref("layers.async-video.enabled", true);

View File

@ -186,6 +186,7 @@
if (!this._statusPanel) {
this._statusPanel = document.createElementNS(this.namespaceURI, "statuspanel");
this._statusPanel.setAttribute("inactive", "true");
this._statusPanel.setAttribute("layer", "true");
this._appendStatusPanel();
}
return this._statusPanel;

View File

@ -2036,7 +2036,7 @@ let SessionStoreInternal = {
}
for (let tab of win.gBrowser.tabs) {
if (!TabStateCache.has(tab)) {
if (!tab.closing && !TabStateCache.has(tab)) {
countdown++;
TabState.collect(tab).then(done, fail);
}

View File

@ -5,8 +5,7 @@
let tmp = {};
Cu.import("resource://gre/modules/Promise.jsm", tmp);
Cu.import("resource://gre/modules/ForgetAboutSite.jsm", tmp);
let {Promise, ForgetAboutSite} = tmp;
let {Promise} = tmp;
const INITIAL_VALUE = "initial-value-" + Date.now();
@ -75,8 +74,10 @@ add_task(function purge_domain() {
let tab = yield createTabWithStorageData(["http://example.com", "http://mochi.test:8888"]);
let browser = tab.linkedBrowser;
ForgetAboutSite.removeDataFromDomain("mochi.test");
yield waitForUpdateMessage(browser);
yield notifyObservers(browser, "browser:purge-domain-data", "mochi.test");
// Flush to make sure chrome received all data.
SyncHandlers.get(browser).flush();
let {storage} = JSON.parse(ss.getTabState(tab));
ok(!storage["http://mochi.test:8888"],
@ -97,6 +98,9 @@ add_task(function purge_shistory() {
yield notifyObservers(browser, "browser:purge-session-history");
// Flush to make sure chrome received all data.
SyncHandlers.get(browser).flush();
let {storage} = JSON.parse(ss.getTabState(tab));
ok(!storage["http://example.com"],
"sessionStorage data for example.com has been purged");
@ -188,7 +192,8 @@ function modifySessionStorage(browser, data) {
return waitForStorageEvent(browser);
}
function notifyObservers(browser, topic) {
browser.messageManager.sendAsyncMessage("ss-test:notifyObservers", topic);
function notifyObservers(browser, topic, data) {
let msg = {topic: topic, data: data};
browser.messageManager.sendAsyncMessage("ss-test:notifyObservers", msg);
return waitForUpdateMessage(browser);
}

View File

@ -17,8 +17,8 @@ addMessageListener("ss-test:modifySessionStorage", function (msg) {
}
});
addMessageListener("ss-test:notifyObservers", function (msg) {
Services.obs.notifyObservers(null, msg.data, "");
addMessageListener("ss-test:notifyObservers", function ({data: {topic, data}}) {
Services.obs.notifyObservers(null, topic, data || "");
});
addMessageListener("ss-test:getStyleSheets", function (msg) {

View File

@ -2208,11 +2208,13 @@ CanvasRenderingContext2D::SetFont(const nsAString& font,
fontStyle->mFont.AddFontFeaturesToStyle(&style);
nsPresContext *c = presShell->GetPresContext();
CurrentState().fontGroup =
gfxPlatform::GetPlatform()->CreateFontGroup(fontStyle->mFont.name,
&style,
presShell->GetPresContext()->GetUserFontSet());
c->GetUserFontSet());
NS_ASSERTION(CurrentState().fontGroup, "Could not get font group");
CurrentState().fontGroup->SetTextPerfMetrics(c->GetTextPerfMetrics());
// The font getter is required to be reserialized based on what we
// parsed (including having line-height removed). (Older drafts of
@ -2806,6 +2808,12 @@ gfxFontGroup *CanvasRenderingContext2D::GetCurrentFontStyle()
nullptr);
if (CurrentState().fontGroup) {
CurrentState().font = kDefaultFontStyle;
nsIPresShell* presShell = GetPresShell();
if (presShell) {
CurrentState().fontGroup->SetTextPerfMetrics(
presShell->GetPresContext()->GetTextPerfMetrics());
}
} else {
NS_ERROR("Default canvas font is invalid");
}

View File

@ -1139,7 +1139,7 @@ void WriteSnapshotLinkToDumpFile(T* aObj, FILE* aFile)
nsCString string(aObj->Name());
string.Append("-");
string.AppendInt((uint64_t)aObj);
fprintf(aFile, "href=\"javascript:ViewImage('%s')\"", string.BeginReading());
fprintf_stderr(aFile, "href=\"javascript:ViewImage('%s')\"", string.BeginReading());
}
template <typename T>
@ -1148,11 +1148,13 @@ void WriteSnapshotToDumpFile_internal(T* aObj, gfxASurface* aSurf)
nsCString string(aObj->Name());
string.Append("-");
string.AppendInt((uint64_t)aObj);
if (gfxUtils::sDumpPaintFile)
fprintf(gfxUtils::sDumpPaintFile, "array[\"%s\"]=\"", string.BeginReading());
if (gfxUtils::sDumpPaintFile) {
fprintf_stderr(gfxUtils::sDumpPaintFile, "array[\"%s\"]=\"", string.BeginReading());
}
aSurf->DumpAsDataURL(gfxUtils::sDumpPaintFile);
if (gfxUtils::sDumpPaintFile)
fprintf(gfxUtils::sDumpPaintFile, "\";");
if (gfxUtils::sDumpPaintFile) {
fprintf_stderr(gfxUtils::sDumpPaintFile, "\";");
}
}
void WriteSnapshotToDumpFile(Layer* aLayer, gfxASurface* aSurf)
@ -1176,13 +1178,13 @@ void
Layer::Dump(FILE* aFile, const char* aPrefix, bool aDumpHtml)
{
if (aDumpHtml) {
fprintf(aFile, "<li><a id=\"%p\" ", this);
fprintf_stderr(aFile, "<li><a id=\"%p\" ", this);
#ifdef MOZ_DUMP_PAINTING
if (GetType() == TYPE_CONTAINER || GetType() == TYPE_THEBES) {
WriteSnapshotLinkToDumpFile(this, aFile);
}
#endif
fprintf(aFile, ">");
fprintf_stderr(aFile, ">");
}
DumpSelf(aFile, aPrefix);
@ -1193,7 +1195,7 @@ Layer::Dump(FILE* aFile, const char* aPrefix, bool aDumpHtml)
#endif
if (aDumpHtml) {
fprintf(aFile, "</a>");
fprintf_stderr(aFile, "</a>");
}
if (Layer* mask = GetMaskLayer()) {
@ -1206,16 +1208,16 @@ Layer::Dump(FILE* aFile, const char* aPrefix, bool aDumpHtml)
nsAutoCString pfx(aPrefix);
pfx += " ";
if (aDumpHtml) {
fprintf(aFile, "<ul>");
fprintf_stderr(aFile, "<ul>");
}
kid->Dump(aFile, pfx.get(), aDumpHtml);
if (aDumpHtml) {
fprintf(aFile, "</ul>");
fprintf_stderr(aFile, "</ul>");
}
}
if (aDumpHtml) {
fprintf(aFile, "</li>");
fprintf_stderr(aFile, "</li>");
}
if (Layer* next = GetNextSibling())
next->Dump(aFile, aPrefix, aDumpHtml);
@ -1226,11 +1228,7 @@ Layer::DumpSelf(FILE* aFile, const char* aPrefix)
{
nsAutoCString str;
PrintInfo(str, aPrefix);
if (!aFile || aFile == stderr) {
printf_stderr("%s\n", str.get());
} else {
fprintf(aFile, "%s\n", str.get());
}
fprintf_stderr(aFile, "%s\n", str.get());
}
void
@ -1407,34 +1405,34 @@ LayerManager::Dump(FILE* aFile, const char* aPrefix, bool aDumpHtml)
#ifdef MOZ_DUMP_PAINTING
if (aDumpHtml) {
fprintf(file, "<ul><li><a ");
fprintf_stderr(file, "<ul><li><a ");
WriteSnapshotLinkToDumpFile(this, file);
fprintf(file, ">");
fprintf_stderr(file, ">");
}
#endif
DumpSelf(file, aPrefix);
#ifdef MOZ_DUMP_PAINTING
if (aDumpHtml) {
fprintf(file, "</a>");
fprintf_stderr(file, "</a>");
}
#endif
nsAutoCString pfx(aPrefix);
pfx += " ";
if (!GetRoot()) {
fprintf(file, "%s(null)", pfx.get());
fprintf_stderr(file, "%s(null)", pfx.get());
if (aDumpHtml) {
fprintf(file, "</li></ul>");
fprintf_stderr(file, "</li></ul>");
}
return;
}
if (aDumpHtml) {
fprintf(file, "<ul>");
fprintf_stderr(file, "<ul>");
}
GetRoot()->Dump(file, pfx.get(), aDumpHtml);
if (aDumpHtml) {
fprintf(file, "</ul></li></ul>");
fprintf_stderr(file, "</ul></li></ul>");
}
fputc('\n', file);
}
@ -1444,7 +1442,7 @@ LayerManager::DumpSelf(FILE* aFile, const char* aPrefix)
{
nsAutoCString str;
PrintInfo(str, aPrefix);
fprintf(FILEOrDefault(aFile), "%s\n", str.get());
fprintf_stderr(FILEOrDefault(aFile), "%s\n", str.get());
}
void

View File

@ -260,20 +260,20 @@ ContentHostBase::Dump(FILE* aFile,
if (!aFile) {
aFile = stderr;
}
fprintf(aFile, "<ul>");
fprintf_stderr(aFile, "<ul>");
if (mDeprecatedTextureHost) {
fprintf(aFile, "%s", aPrefix);
fprintf(aFile, "<li> <a href=");
fprintf_stderr(aFile, "%s", aPrefix);
fprintf_stderr(aFile, "<li> <a href=");
DumpDeprecatedTextureHost(aFile, mDeprecatedTextureHost);
fprintf(aFile, "> Front buffer </a></li> ");
fprintf_stderr(aFile, "> Front buffer </a></li> ");
}
if (mDeprecatedTextureHostOnWhite) {
fprintf(aFile, "%s", aPrefix);
fprintf(aFile, "<li> <a href=");
fprintf_stderr(aFile, "%s", aPrefix);
fprintf_stderr(aFile, "<li> <a href=");
DumpDeprecatedTextureHost(aFile, mDeprecatedTextureHostOnWhite);
fprintf(aFile, "> Front buffer on white </a> </li> ");
fprintf_stderr(aFile, "> Front buffer on white </a> </li> ");
}
fprintf(aFile, "</ul>");
fprintf_stderr(aFile, "</ul>");
}
#endif
@ -816,20 +816,20 @@ ContentHostDoubleBuffered::Dump(FILE* aFile,
if (!aFile) {
aFile = stderr;
}
fprintf(aFile, "<ul>");
fprintf_stderr(aFile, "<ul>");
if (mBackHost) {
fprintf(aFile, "%s", aPrefix);
fprintf(aFile, "<li> <a href=");
fprintf_stderr(aFile, "%s", aPrefix);
fprintf_stderr(aFile, "<li> <a href=");
DumpDeprecatedTextureHost(aFile, mBackHost);
fprintf(aFile, " >Back buffer</a></li>");
fprintf_stderr(aFile, " >Back buffer</a></li>");
}
if (mBackHostOnWhite) {
fprintf(aFile, "%s", aPrefix);
fprintf(aFile, "<li> <a href=");
fprintf_stderr(aFile, "%s", aPrefix);
fprintf_stderr(aFile, "<li> <a href=");
DumpDeprecatedTextureHost(aFile, mBackHostOnWhite);
fprintf(aFile, " >Back buffer on white</a> </li>");
fprintf_stderr(aFile, " >Back buffer on white</a> </li>");
}
fprintf(aFile, "</ul>");
fprintf_stderr(aFile, "</ul>");
}
#endif

View File

@ -181,11 +181,11 @@ ImageHost::Dump(FILE* aFile,
aFile = stderr;
}
if (mFrontBuffer) {
fprintf(aFile, "%s", aPrefix);
fprintf(aFile, aDumpHtml ? "<ul><li>TextureHost: "
fprintf_stderr(aFile, "%s", aPrefix);
fprintf_stderr(aFile, aDumpHtml ? "<ul><li>TextureHost: "
: "TextureHost: ");
DumpTextureHost(aFile, mFrontBuffer);
fprintf(aFile, aDumpHtml ? " </li></ul> " : " ");
fprintf_stderr(aFile, aDumpHtml ? " </li></ul> " : " ");
}
}
#endif
@ -391,11 +391,11 @@ DeprecatedImageHostSingle::Dump(FILE* aFile,
aFile = stderr;
}
if (mDeprecatedTextureHost) {
fprintf(aFile, "%s", aPrefix);
fprintf(aFile, aDumpHtml ? "<ul><li>DeprecatedTextureHost: "
fprintf_stderr(aFile, "%s", aPrefix);
fprintf_stderr(aFile, aDumpHtml ? "<ul><li>DeprecatedTextureHost: "
: "DeprecatedTextureHost: ");
DumpDeprecatedTextureHost(aFile, mDeprecatedTextureHost);
fprintf(aFile, aDumpHtml ? " </li></ul> " : " ");
fprintf_stderr(aFile, aDumpHtml ? " </li></ul> " : " ");
}
}

View File

@ -331,16 +331,16 @@ TiledContentHost::Dump(FILE* aFile,
TiledLayerBufferComposite::Iterator it = mVideoMemoryTiledBuffer.TilesBegin();
TiledLayerBufferComposite::Iterator stop = mVideoMemoryTiledBuffer.TilesEnd();
if (aDumpHtml) {
fprintf(aFile, "<ul>");
fprintf_stderr(aFile, "<ul>");
}
for (;it != stop; ++it) {
fprintf(aFile, "%s", aPrefix);
fprintf(aFile, aDumpHtml ? "<li> <a href=" : "Tile ");
fprintf_stderr(aFile, "%s", aPrefix);
fprintf_stderr(aFile, aDumpHtml ? "<li> <a href=" : "Tile ");
DumpDeprecatedTextureHost(aFile, it->mDeprecatedTextureHost);
fprintf(aFile, aDumpHtml ? " >Tile</a></li>" : " ");
fprintf_stderr(aFile, aDumpHtml ? " >Tile</a></li>" : " ");
}
if (aDumpHtml) {
fprintf(aFile, "</ul>");
fprintf_stderr(aFile, "</ul>");
}
}
#endif

View File

@ -554,8 +554,8 @@ CompositorParent::CompositeInTransaction()
#ifdef MOZ_DUMP_PAINTING
static bool gDumpCompositorTree = false;
if (gDumpCompositorTree) {
fprintf(stdout, "Painting --- compositing layer tree:\n");
mLayerManager->Dump(stdout, "", false);
printf_stderr("Painting --- compositing layer tree:\n");
mLayerManager->Dump();
}
#endif
mLayerManager->EndEmptyTransaction();

View File

@ -66,6 +66,7 @@ public:
nsresult GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
gfxUserFontSet* aUserFontSet,
gfxTextPerfMetrics* aTextPerf,
nsFontMetrics*& aMetrics);
void FontMetricsDeleted(const nsFontMetrics* aFontMetrics);
@ -123,6 +124,7 @@ nsFontCache::Observe(nsISupports*, const char* aTopic, const PRUnichar*)
nsresult
nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
gfxUserFontSet* aUserFontSet,
gfxTextPerfMetrics* aTextPerf,
nsFontMetrics*& aMetrics)
{
if (!aLanguage)
@ -152,7 +154,7 @@ nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
fm = new nsFontMetrics();
NS_ADDREF(fm);
nsresult rv = fm->Init(aFont, aLanguage, mContext, aUserFontSet);
nsresult rv = fm->Init(aFont, aLanguage, mContext, aUserFontSet, aTextPerf);
if (NS_SUCCEEDED(rv)) {
// the mFontMetrics list has the "head" at the end, because append
// is cheaper than insert
@ -171,7 +173,7 @@ nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
Compact();
fm = new nsFontMetrics();
NS_ADDREF(fm);
rv = fm->Init(aFont, aLanguage, mContext, aUserFontSet);
rv = fm->Init(aFont, aLanguage, mContext, aUserFontSet, aTextPerf);
if (NS_SUCCEEDED(rv)) {
mFontMetrics.AppendElement(fm);
aMetrics = fm;
@ -260,6 +262,7 @@ nsresult
nsDeviceContext::GetMetricsFor(const nsFont& aFont,
nsIAtom* aLanguage,
gfxUserFontSet* aUserFontSet,
gfxTextPerfMetrics* aTextPerf,
nsFontMetrics*& aMetrics)
{
if (!mFontCache) {
@ -268,7 +271,8 @@ nsDeviceContext::GetMetricsFor(const nsFont& aFont,
mFontCache->Init(this);
}
return mFontCache->GetMetricsFor(aFont, aLanguage, aUserFontSet, aMetrics);
return mFontCache->GetMetricsFor(aFont, aLanguage, aUserFontSet,
aTextPerf, aMetrics);
}
nsresult

View File

@ -20,6 +20,7 @@
#include "mozilla/AppUnits.h" // for AppUnits
class gfxASurface;
class gfxTextPerfMetrics;
class gfxUserFontSet;
class nsFont;
class nsFontCache;
@ -119,6 +120,7 @@ public:
*/
nsresult GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
gfxUserFontSet* aUserFontSet,
gfxTextPerfMetrics* aTextPerf,
nsFontMetrics*& aMetrics);
/**

View File

@ -96,7 +96,8 @@ nsFontMetrics::~nsFontMetrics()
nsresult
nsFontMetrics::Init(const nsFont& aFont, nsIAtom* aLanguage,
nsDeviceContext *aContext,
gfxUserFontSet *aUserFontSet)
gfxUserFontSet *aUserFontSet,
gfxTextPerfMetrics *aTextPerf)
{
NS_ABORT_IF_FALSE(mP2A == 0, "already initialized");
@ -119,6 +120,7 @@ nsFontMetrics::Init(const nsFont& aFont, nsIAtom* aLanguage,
mFontGroup = gfxPlatform::GetPlatform()->
CreateFontGroup(aFont.name, &style, aUserFontSet);
mFontGroup->SetTextPerfMetrics(aTextPerf);
if (mFontGroup->FontListLength() < 1)
return NS_ERROR_UNEXPECTED;

View File

@ -19,6 +19,7 @@
#include "nscore.h" // for PRUnichar
class gfxUserFontSet;
class gfxTextPerfMetrics;
class nsDeviceContext;
class nsIAtom;
class nsRenderingContext;
@ -58,7 +59,8 @@ public:
*/
nsresult Init(const nsFont& aFont, nsIAtom* aLanguage,
nsDeviceContext *aContext,
gfxUserFontSet *aUserFontSet = nullptr);
gfxUserFontSet *aUserFontSet,
gfxTextPerfMetrics *aTextPerf);
/**
* Destroy this font metrics. This breaks the association between

View File

@ -6,10 +6,6 @@
#ifndef GFX_ASURFACE_H
#define GFX_ASURFACE_H
#ifdef MOZ_DUMP_PAINTING
#define MOZ_DUMP_IMAGES
#endif
#include "mozilla/MemoryReporting.h"
#include "gfxTypes.h"
#include "mozilla/Scoped.h"

View File

@ -3083,6 +3083,12 @@ HashMix(uint32_t aHash, PRUnichar aCh)
return (aHash >> 28) ^ (aHash << 4) ^ aCh;
}
#ifdef __GNUC__
#define GFX_MAYBE_UNUSED __attribute__((unused))
#else
#define GFX_MAYBE_UNUSED
#endif
template<typename T>
gfxShapedWord*
gfxFont::GetShapedWord(gfxContext *aContext,
@ -3091,7 +3097,8 @@ gfxFont::GetShapedWord(gfxContext *aContext,
uint32_t aHash,
int32_t aRunScript,
int32_t aAppUnitsPerDevUnit,
uint32_t aFlags)
uint32_t aFlags,
gfxTextPerfMetrics *aTextPerf GFX_MAYBE_UNUSED)
{
// if the cache is getting too big, flush it and start over
uint32_t wordCacheMaxEntries =
@ -3121,12 +3128,23 @@ gfxFont::GetShapedWord(gfxContext *aContext,
Telemetry::Accumulate((isContent ? Telemetry::WORD_CACHE_HITS_CONTENT :
Telemetry::WORD_CACHE_HITS_CHROME),
aLength);
#ifndef RELEASE_BUILD
if (aTextPerf) {
aTextPerf->current.wordCacheHit++;
}
#endif
return sw;
}
Telemetry::Accumulate((isContent ? Telemetry::WORD_CACHE_MISSES_CONTENT :
Telemetry::WORD_CACHE_MISSES_CHROME),
aLength);
#ifndef RELEASE_BUILD
if (aTextPerf) {
aTextPerf->current.wordCacheMiss++;
}
#endif
sw = entry->mShapedWord = gfxShapedWord::Create(aText, aLength,
aRunScript,
aAppUnitsPerDevUnit,
@ -3371,6 +3389,12 @@ gfxFont::ShapeTextWithoutWordCache(gfxContext *aContext,
return ok;
}
#ifndef RELEASE_BUILD
#define TEXT_PERF_INCR(tp, m) (tp ? (tp)->current.m++ : 0)
#else
#define TEXT_PERF_INCR(tp, m)
#endif
inline static bool IsChar8Bit(uint8_t /*aCh*/) { return true; }
inline static bool IsChar8Bit(PRUnichar aCh) { return aCh < 0x100; }
@ -3387,7 +3411,25 @@ gfxFont::SplitAndInitTextRun(gfxContext *aContext,
return true;
}
gfxTextPerfMetrics *tp = nullptr;
#ifndef RELEASE_BUILD
tp = aTextRun->GetFontGroup()->GetTextPerfMetrics();
if (tp) {
if (mStyle.systemFont) {
tp->current.numChromeTextRuns++;
} else {
tp->current.numContentTextRuns++;
}
tp->current.numChars += aRunLength;
if (aRunLength > tp->current.maxTextRunLen) {
tp->current.maxTextRunLen = aRunLength;
}
}
#endif
if (BypassShapedWordCache(aRunScript)) {
TEXT_PERF_INCR(tp, wordCacheSpaceRules);
return ShapeTextWithoutWordCache(aContext, aString + aRunStart,
aRunStart, aRunLength, aRunScript,
aTextRun);
@ -3436,6 +3478,7 @@ gfxFont::SplitAndInitTextRun(gfxContext *aContext,
// For words longer than the limit, we don't use the
// font's word cache but just shape directly into the textrun.
if (length > wordCacheCharLimit) {
TEXT_PERF_INCR(tp, wordCacheLong);
bool ok = ShapeFragmentWithoutWordCache(aContext,
text + wordStart,
aRunStart + wordStart,
@ -3459,7 +3502,7 @@ gfxFont::SplitAndInitTextRun(gfxContext *aContext,
text + wordStart, length,
hash, aRunScript,
appUnitsPerDevUnit,
wordFlags);
wordFlags, tp);
if (sw) {
aTextRun->CopyGlyphDataFrom(sw, aRunStart + wordStart);
} else {
@ -3478,7 +3521,7 @@ gfxFont::SplitAndInitTextRun(gfxContext *aContext,
&space, 1,
HashMix(0, ' '), aRunScript,
appUnitsPerDevUnit,
flags | gfxTextRunFactory::TEXT_IS_8BIT);
flags | gfxTextRunFactory::TEXT_IS_8BIT, tp);
if (sw) {
aTextRun->CopyGlyphDataFrom(sw, aRunStart + i);
} else {
@ -4017,6 +4060,7 @@ gfxFontGroup::gfxFontGroup(const nsAString& aFamilies,
, mStyle(*aStyle)
, mUnderlineOffset(UNDERLINE_OFFSET_NOT_SET)
, mHyphenWidth(-1)
, mTextPerf(nullptr)
{
mUserFontSet = nullptr;
SetUserFontSet(aUserFontSet);
@ -4177,7 +4221,9 @@ gfxFontGroup::~gfxFontGroup()
gfxFontGroup *
gfxFontGroup::Copy(const gfxFontStyle *aStyle)
{
return new gfxFontGroup(mFamilies, aStyle, mUserFontSet);
gfxFontGroup *fg = new gfxFontGroup(mFamilies, aStyle, mUserFontSet);
fg->SetTextPerfMetrics(mTextPerf);
return fg;
}
bool
@ -5013,6 +5059,16 @@ void gfxFontGroup::ComputeRanges(nsTArray<gfxTextRange>& aRanges,
nsRefPtr<gfxFont> font =
FindFontForChar(ch, prevCh, aRunScript, prevFont, &matchType);
#ifndef RELEASE_BUILD
if (MOZ_UNLIKELY(mTextPerf)) {
if (matchType == gfxTextRange::kPrefsFallback) {
mTextPerf->current.fallbackPrefs++;
} else if (matchType == gfxTextRange::kSystemFallback) {
mTextPerf->current.fallbackSystem++;
}
}
#endif
prevCh = ch;
if (lastRangeIndex == -1) {
@ -5569,6 +5625,13 @@ gfxTextRun::gfxTextRun(const gfxTextRunFactory::Parameters *aParams,
MOZ_COUNT_CTOR(gfxTextRun);
NS_ADDREF(mFontGroup);
#ifndef RELEASE_BUILD
gfxTextPerfMetrics *tp = aFontGroup->GetTextPerfMetrics();
if (tp) {
tp->current.textrunConst++;
}
#endif
mCharacterGlyphs = reinterpret_cast<CompressedGlyph*>(this + 1);
if (aParams->mSkipChars) {
@ -5596,6 +5659,12 @@ gfxTextRun::~gfxTextRun()
// been told to release its reference to the group, so we mustn't do that
// again here.
if (!mReleasedFontGroup) {
#ifndef RELEASE_BUILD
gfxTextPerfMetrics *tp = mFontGroup->GetTextPerfMetrics();
if (tp) {
tp->current.textrunDestr++;
}
#endif
NS_RELEASE(mFontGroup);
}
@ -6648,7 +6717,8 @@ gfxTextRun::SetSpaceGlyph(gfxFont *aFont, gfxContext *aContext,
mAppUnitsPerDevUnit,
gfxTextRunFactory::TEXT_IS_8BIT |
gfxTextRunFactory::TEXT_IS_ASCII |
gfxTextRunFactory::TEXT_IS_PERSISTENT);
gfxTextRunFactory::TEXT_IS_PERSISTENT,
nullptr);
if (sw) {
AddGlyphRun(aFont, gfxTextRange::kFontGroup, aCharIndex, false);
CopyGlyphDataFrom(sw, aCharIndex);

View File

@ -1014,6 +1014,59 @@ protected:
nsCOMPtr<nsITimer> mWordCacheExpirationTimer;
};
class gfxTextPerfMetrics {
public:
struct TextCounts {
uint32_t numContentTextRuns;
uint32_t numChromeTextRuns;
uint32_t numChars;
uint32_t maxTextRunLen;
uint32_t wordCacheSpaceRules;
uint32_t wordCacheLong;
uint32_t wordCacheHit;
uint32_t wordCacheMiss;
uint32_t fallbackPrefs;
uint32_t fallbackSystem;
uint32_t textrunConst;
uint32_t textrunDestr;
};
uint32_t reflowCount;
// counts per reflow operation
TextCounts current;
// totals for the lifetime of a document
TextCounts cumulative;
gfxTextPerfMetrics() {
memset(this, 0, sizeof(gfxTextPerfMetrics));
}
// add current totals to cumulative ones
void Accumulate() {
if (current.numChars == 0) {
return;
}
cumulative.numContentTextRuns += current.numContentTextRuns;
cumulative.numChromeTextRuns += current.numChromeTextRuns;
cumulative.numChars += current.numChars;
if (current.maxTextRunLen > cumulative.maxTextRunLen) {
cumulative.maxTextRunLen = current.maxTextRunLen;
}
cumulative.wordCacheSpaceRules += current.wordCacheSpaceRules;
cumulative.wordCacheLong += current.wordCacheLong;
cumulative.wordCacheHit += current.wordCacheHit;
cumulative.wordCacheMiss += current.wordCacheMiss;
cumulative.fallbackPrefs += current.fallbackPrefs;
cumulative.fallbackSystem += current.fallbackSystem;
cumulative.textrunConst += current.textrunConst;
cumulative.textrunDestr += current.textrunDestr;
memset(&current, 0, sizeof(current));
}
};
class gfxTextRunFactory {
NS_INLINE_DECL_REFCOUNTING(gfxTextRunFactory)
@ -1645,7 +1698,8 @@ public:
uint32_t aHash,
int32_t aRunScript,
int32_t aAppUnitsPerDevUnit,
uint32_t aFlags);
uint32_t aFlags,
gfxTextPerfMetrics *aTextPerf);
// Ensure the ShapedWord cache is initialized. This MUST be called before
// any attempt to use GetShapedWord().
@ -3456,6 +3510,10 @@ public:
// with no @font-face rule, this always returns 0.
uint64_t GetGeneration();
// used when logging text performance
gfxTextPerfMetrics *GetTextPerfMetrics() { return mTextPerf; }
void SetTextPerfMetrics(gfxTextPerfMetrics *aTextPerf) { mTextPerf = aTextPerf; }
// If there is a user font set, check to see whether the font list or any
// caches need updating.
virtual void UpdateFontList();
@ -3486,6 +3544,8 @@ protected:
gfxUserFontSet* mUserFontSet;
uint64_t mCurrGeneration; // track the current user font set generation, rebuild font list if needed
gfxTextPerfMetrics *mTextPerf;
// Cache a textrun representing an ellipsis (useful for CSS text-overflow)
// at a specific appUnitsPerDevPixel size
nsAutoPtr<gfxTextRun> mCachedEllipsisTextRun;

View File

@ -120,6 +120,7 @@ static PRLogModuleInfo *sFontInitLog = nullptr;
static PRLogModuleInfo *sTextrunLog = nullptr;
static PRLogModuleInfo *sTextrunuiLog = nullptr;
static PRLogModuleInfo *sCmapDataLog = nullptr;
static PRLogModuleInfo *sTextPerfLog = nullptr;
#endif
/* Class to listen for pref changes so that chrome code can dynamically
@ -364,11 +365,12 @@ gfxPlatform::Init()
gEverInitialized = true;
#ifdef PR_LOGGING
sFontlistLog = PR_NewLogModule("fontlist");;
sFontInitLog = PR_NewLogModule("fontinit");;
sTextrunLog = PR_NewLogModule("textrun");;
sTextrunuiLog = PR_NewLogModule("textrunui");;
sCmapDataLog = PR_NewLogModule("cmapdata");;
sFontlistLog = PR_NewLogModule("fontlist");
sFontInitLog = PR_NewLogModule("fontinit");
sTextrunLog = PR_NewLogModule("textrun");
sTextrunuiLog = PR_NewLogModule("textrunui");
sCmapDataLog = PR_NewLogModule("cmapdata");
sTextPerfLog = PR_NewLogModule("textperf");
#endif
gGfxPlatformPrefsLock = new Mutex("gfxPlatform::gGfxPlatformPrefsLock");
@ -1945,6 +1947,9 @@ gfxPlatform::GetLog(eGfxLog aWhichLog)
case eGfxLog_cmapdata:
return sCmapDataLog;
break;
case eGfxLog_textperf:
return sTextPerfLog;
break;
default:
break;
}

View File

@ -117,7 +117,9 @@ enum eGfxLog {
// dump text runs, font matching, system fallback for chrome
eGfxLog_textrunui = 3,
// dump cmap coverage data as they are loaded
eGfxLog_cmapdata = 4
eGfxLog_cmapdata = 4,
// text perf data
eGfxLog_textperf = 5
};
// when searching through pref langs, max number of pref langs

View File

@ -180,7 +180,7 @@ public:
#ifdef DEBUG_DISPLAY_ITEM_DATA
void Dump(const char *aPrefix = "") {
printf("%sLayerManagerData %p\n", aPrefix, this);
printf_stderr("%sLayerManagerData %p\n", aPrefix, this);
nsAutoCString prefix;
prefix += aPrefix;
prefix += " ";
@ -899,7 +899,7 @@ InvalidatePostTransformRegion(ThebesLayer* aLayer, const nsIntRegion& aRegion,
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
nsAutoCString str;
AppendToString(str, rgn);
printf("Invalidating layer %p: %s\n", aLayer, str.get());
printf_stderr("Invalidating layer %p: %s\n", aLayer, str.get());
}
#endif
}
@ -967,7 +967,7 @@ FrameLayerBuilder::RemoveFrameFromLayerManager(nsIFrame* aFrame,
while (rootData->mParent) {
rootData = rootData->mParent;
}
printf("Removing frame %p - dumping display data\n", aFrame);
printf_stderr("Removing frame %p - dumping display data\n", aFrame);
rootData->Dump();
}
#endif
@ -1057,7 +1057,7 @@ FrameLayerBuilder::ProcessRemovedDisplayItems(nsRefPtrHashKey<DisplayItemData>*
if (t) {
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf("Invalidating unused display item (%i) belonging to frame %p from layer %p\n", data->mDisplayItemKey, data->mFrameList[0], t);
printf_stderr("Invalidating unused display item (%i) belonging to frame %p from layer %p\n", data->mDisplayItemKey, data->mFrameList[0], t);
}
#endif
InvalidatePostTransformRegion(t,
@ -1116,11 +1116,11 @@ FrameLayerBuilder::DumpDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>*
}
str += "\n";
printf("%s", str.get());
printf_stderr("%s", str.get());
if (data->mInactiveManager) {
prefix += " ";
printf("%sDumping inactive layer info:\n", prefix.get());
printf_stderr("%sDumping inactive layer info:\n", prefix.get());
LayerManagerData* lmd = static_cast<LayerManagerData*>
(data->mInactiveManager->GetUserData(&gLayerManagerUserData));
lmd->Dump(prefix.get());
@ -1352,7 +1352,7 @@ InvalidateEntireThebesLayer(ThebesLayer* aLayer, const nsIFrame* aAnimatedGeomet
{
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf("Invalidating entire layer %p\n", aLayer);
printf_stderr("Invalidating entire layer %p\n", aLayer);
}
#endif
nsIntRect invalidate = aLayer->GetValidRegion().GetBounds();
@ -1402,7 +1402,7 @@ ContainerState::CreateOrRecycleThebesLayer(const nsIFrame* aAnimatedGeometryRoot
if (!data->mRegionToInvalidate.IsEmpty()) {
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf("Invalidating deleted frame content from layer %p\n", layer.get());
printf_stderr("Invalidating deleted frame content from layer %p\n", layer.get());
}
#endif
layer->InvalidateRegion(data->mRegionToInvalidate);
@ -1410,7 +1410,7 @@ ContainerState::CreateOrRecycleThebesLayer(const nsIFrame* aAnimatedGeometryRoot
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
nsAutoCString str;
AppendToString(str, data->mRegionToInvalidate);
printf("Invalidating layer %p: %s\n", layer.get(), str.get());
printf_stderr("Invalidating layer %p: %s\n", layer.get(), str.get());
}
#endif
data->mRegionToInvalidate.SetEmpty();
@ -2053,9 +2053,9 @@ DumpPaintedImage(nsDisplayItem* aItem, gfxASurface* aSurf)
nsCString string(aItem->Name());
string.Append("-");
string.AppendInt((uint64_t)aItem);
fprintf(gfxUtils::sDumpPaintFile, "array[\"%s\"]=\"", string.BeginReading());
fprintf_stderr(gfxUtils::sDumpPaintFile, "array[\"%s\"]=\"", string.BeginReading());
aSurf->DumpAsDataURL(gfxUtils::sDumpPaintFile);
fprintf(gfxUtils::sDumpPaintFile, "\";");
fprintf_stderr(gfxUtils::sDumpPaintFile, "\";");
}
#endif
@ -2396,7 +2396,7 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem,
// or a new scale here
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf("Display item type %s(%p) changed layers %p to %p!\n", aItem->Name(), aItem->Frame(), t, aNewLayer);
printf_stderr("Display item type %s(%p) changed layers %p to %p!\n", aItem->Name(), aItem->Frame(), t, aNewLayer);
}
#endif
InvalidatePostTransformRegion(t,
@ -2439,7 +2439,7 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem,
combined = aClip.ApplyNonRoundedIntersection(aGeometry->ComputeInvalidationRegion());
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf("Display item type %s(%p) added to layer %p!\n", aItem->Name(), aItem->Frame(), aNewLayer);
printf_stderr("Display item type %s(%p) added to layer %p!\n", aItem->Name(), aItem->Frame(), aNewLayer);
}
#endif
} else if (isInvalid || (aItem->IsInvalid(invalid) && invalid.IsEmpty())) {
@ -2449,7 +2449,7 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem,
combined.Or(combined, aClip.ApplyNonRoundedIntersection(aGeometry->ComputeInvalidationRegion()));
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf("Display item type %s(%p) (in layer %p) belongs to an invalidated frame!\n", aItem->Name(), aItem->Frame(), aNewLayer);
printf_stderr("Display item type %s(%p) (in layer %p) belongs to an invalidated frame!\n", aItem->Name(), aItem->Frame(), aNewLayer);
}
#endif
} else {
@ -2476,7 +2476,7 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem,
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
if (!combined.IsEmpty()) {
printf("Display item type %s(%p) (in layer %p) changed geometry!\n", aItem->Name(), aItem->Frame(), aNewLayer);
printf_stderr("Display item type %s(%p) (in layer %p) changed geometry!\n", aItem->Name(), aItem->Frame(), aNewLayer);
}
}
#endif
@ -2583,7 +2583,7 @@ FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
if (!invalid.IsEmpty()) {
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf("Inactive LayerManager(%p) for display item %s(%p) has an invalid region - invalidating layer %p\n", tempManager.get(), aItem->Name(), aItem->Frame(), aLayer);
printf_stderr("Inactive LayerManager(%p) for display item %s(%p) has an invalid region - invalidating layer %p\n", tempManager.get(), aItem->Name(), aItem->Frame(), aLayer);
}
#endif
if (hasClip) {

View File

@ -2234,7 +2234,7 @@ nsDisplayThemedBackground::~nsDisplayThemedBackground()
void
nsDisplayThemedBackground::WriteDebugInfo(FILE *aOutput)
{
fprintf(aOutput, "(themed, appearance:%d) ", mAppearance);
fprintf_stderr(aOutput, "(themed, appearance:%d) ", mAppearance);
}
#endif
@ -4713,32 +4713,32 @@ nsDisplaySVGEffects::PrintEffects(FILE* aOutput)
bool isOK = true;
nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK);
bool first = true;
fprintf(aOutput, " effects=(");
fprintf_stderr(aOutput, " effects=(");
if (mFrame->StyleDisplay()->mOpacity != 1.0f) {
first = false;
fprintf(aOutput, "opacity(%f)", mFrame->StyleDisplay()->mOpacity);
fprintf_stderr(aOutput, "opacity(%f)", mFrame->StyleDisplay()->mOpacity);
}
if (clipPathFrame) {
if (!first) {
fprintf(aOutput, ", ");
fprintf_stderr(aOutput, ", ");
}
fprintf(aOutput, "clip(%s)", clipPathFrame->IsTrivial() ? "trivial" : "non-trivial");
fprintf_stderr(aOutput, "clip(%s)", clipPathFrame->IsTrivial() ? "trivial" : "non-trivial");
first = false;
}
if (effectProperties.GetFilterFrame(&isOK)) {
if (!first) {
fprintf(aOutput, ", ");
fprintf_stderr(aOutput, ", ");
}
fprintf(aOutput, "filter");
fprintf_stderr(aOutput, "filter");
first = false;
}
if (effectProperties.GetMaskFrame(&isOK)) {
if (!first) {
fprintf(aOutput, ", ");
fprintf_stderr(aOutput, ", ");
}
fprintf(aOutput, "mask");
fprintf_stderr(aOutput, "mask");
}
fprintf(aOutput, ")");
fprintf_stderr(aOutput, ")");
}
#endif

View File

@ -1934,17 +1934,32 @@ public:
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
{
return new nsDisplayItemBoundsGeometry(this, aBuilder);
return new nsDisplaySolidColorGeometry(this, aBuilder, mColor);
}
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion* aInvalidRegion) MOZ_OVERRIDE
{
const nsDisplayItemBoundsGeometry* geometry = static_cast<const nsDisplayItemBoundsGeometry*>(aGeometry);
const nsDisplaySolidColorGeometry* geometry =
static_cast<const nsDisplaySolidColorGeometry*>(aGeometry);
if (mColor != geometry->mColor) {
bool dummy;
aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &dummy));
return;
}
ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
}
#ifdef MOZ_DUMP_PAINTING
virtual void WriteDebugInfo(FILE *aOutput) MOZ_OVERRIDE
{
fprintf(aOutput, "(rgba %d,%d,%d,%d)",
NS_GET_R(mColor), NS_GET_G(mColor),
NS_GET_B(mColor), NS_GET_A(mColor));
}
#endif
NS_DISPLAY_DECL_NAME("SolidColor", TYPE_SOLID_COLOR)
private:
@ -2155,7 +2170,7 @@ public:
NS_DISPLAY_DECL_NAME("BackgroundColor", TYPE_BACKGROUND_COLOR)
#ifdef MOZ_DUMP_PAINTING
virtual void WriteDebugInfo(FILE *aOutput) MOZ_OVERRIDE {
fprintf(aOutput, "(rgba %d,%d,%d,%d)",
fprintf_stderr(aOutput, "(rgba %d,%d,%d,%d)",
NS_GET_R(mColor), NS_GET_G(mColor),
NS_GET_B(mColor), NS_GET_A(mColor));
@ -2489,7 +2504,7 @@ public:
NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
#ifdef MOZ_DUMP_PAINTING
virtual void WriteDebugInfo(FILE *aOutput) MOZ_OVERRIDE {
fprintf(aOutput, "(opacity %f)", mFrame->StyleDisplay()->mOpacity);
fprintf_stderr(aOutput, "(opacity %f)", mFrame->StyleDisplay()->mOpacity);
}
#endif

View File

@ -116,4 +116,17 @@ public:
nsRect mPaddingRect;
};
class nsDisplaySolidColorGeometry : public nsDisplayItemBoundsGeometry
{
public:
nsDisplaySolidColorGeometry(nsDisplayItem* aItem,
nsDisplayListBuilder* aBuilder,
nscolor aColor)
: nsDisplayItemBoundsGeometry(aItem, aBuilder)
, mColor(aColor)
{ }
nscolor mColor;
};
#endif /*NSDISPLAYLISTINVALIDATION_H_*/

View File

@ -1025,6 +1025,7 @@ nsDocumentViewer::LoadComplete(nsresult aStatus)
// mPresShell could have been removed now, see bug 378682/421432
if (mPresShell) {
mPresShell->ScrollToAnchor();
mPresShell->LoadComplete();
}
}

View File

@ -417,6 +417,11 @@ public:
*/
virtual bool IsLayoutFlushObserver() = 0;
/**
* Called when document load completes.
*/
virtual NS_HIDDEN_(void) LoadComplete() = 0;
/**
* This calls through to the frame manager to get the root frame.
*/

View File

@ -127,16 +127,16 @@ PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
FILE* aOutput, bool aDumpHtml)
{
if (aDumpHtml) {
fprintf(aOutput, "<ul>");
fprintf_stderr(aOutput, "<ul>");
}
for (nsDisplayItem* i = aList.GetBottom(); i != nullptr; i = i->GetAbove()) {
if (aDumpHtml) {
fprintf(aOutput, "<li>");
fprintf_stderr(aOutput, "<li>");
} else {
sPrintDisplayListIndent ++;
for (int indent = 0; indent < sPrintDisplayListIndent; indent++) {
fprintf(aOutput, " ");
fprintf_stderr(aOutput, " ");
}
}
nsIFrame* f = i->Frame();
@ -161,9 +161,9 @@ PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
nsCString string(i->Name());
string.Append("-");
string.AppendInt((uint64_t)i);
fprintf(aOutput, "<a href=\"javascript:ViewImage('%s')\">", string.BeginReading());
fprintf_stderr(aOutput, "<a href=\"javascript:ViewImage('%s')\">", string.BeginReading());
}
fprintf(aOutput, "%s %p(%s) bounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) %s",
fprintf_stderr(aOutput, "%s %p(%s) bounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) %s",
i->Name(), (void*)f, NS_ConvertUTF16toUTF8(fName).get(),
rect.x, rect.y, rect.width, rect.height,
vis.x, vis.y, vis.width, vis.height,
@ -172,19 +172,19 @@ PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
i->IsUniform(aBuilder, &color) ? " uniform" : "");
nsRegionRectIterator iter(opaque);
for (const nsRect* r = iter.Next(); r; r = iter.Next()) {
fprintf(aOutput, " (opaque %d,%d,%d,%d)", r->x, r->y, r->width, r->height);
fprintf_stderr(aOutput, " (opaque %d,%d,%d,%d)", r->x, r->y, r->width, r->height);
}
i->WriteDebugInfo(aOutput);
if (aDumpHtml && i->Painted()) {
fprintf(aOutput, "</a>");
fprintf_stderr(aOutput, "</a>");
}
uint32_t key = i->GetPerFrameKey();
Layer* layer = mozilla::FrameLayerBuilder::GetDebugOldLayerFor(f, key);
if (layer) {
if (aDumpHtml) {
fprintf(aOutput, " <a href=\"#%p\">layer=%p</a>", layer, layer);
fprintf_stderr(aOutput, " <a href=\"#%p\">layer=%p</a>", layer, layer);
} else {
fprintf(aOutput, " layer=%p", layer);
fprintf_stderr(aOutput, " layer=%p", layer);
}
}
if (i->GetType() == nsDisplayItem::TYPE_SVG_EFFECTS) {
@ -195,14 +195,14 @@ PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
PrintDisplayListTo(aBuilder, *list, aOutput, aDumpHtml);
}
if (aDumpHtml) {
fprintf(aOutput, "</li>");
fprintf_stderr(aOutput, "</li>");
} else {
sPrintDisplayListIndent --;
}
}
if (aDumpHtml) {
fprintf(aOutput, "</ul>");
fprintf_stderr(aOutput, "</ul>");
}
}

View File

@ -2086,7 +2086,7 @@ nsLayoutUtils::GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect,
#ifdef MOZ_DUMP_PAINTING
if (gDumpEventList) {
fprintf(stdout, "Event handling --- (%d,%d):\n", aRect.x, aRect.y);
fprintf_stderr(stderr, "Event handling --- (%d,%d):\n", aRect.x, aRect.y);
nsFrame::PrintDisplayList(&builder, list);
}
#endif
@ -2277,16 +2277,16 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
string.Append(".html");
gfxUtils::sDumpPaintFile = fopen(string.BeginReading(), "w");
} else {
gfxUtils::sDumpPaintFile = stdout;
gfxUtils::sDumpPaintFile = stderr;
}
if (gfxUtils::sDumpPaintingToFile) {
fprintf(gfxUtils::sDumpPaintFile, "<html><head><script>var array = {}; function ViewImage(index) { window.location = array[index]; }</script></head><body>");
fprintf_stderr(gfxUtils::sDumpPaintFile, "<html><head><script>var array = {}; function ViewImage(index) { window.location = array[index]; }</script></head><body>");
}
fprintf(gfxUtils::sDumpPaintFile, "Painting --- before optimization (dirty %d,%d,%d,%d):\n",
fprintf_stderr(gfxUtils::sDumpPaintFile, "Painting --- before optimization (dirty %d,%d,%d,%d):\n",
dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height);
nsFrame::PrintDisplayList(&builder, list, gfxUtils::sDumpPaintFile, gfxUtils::sDumpPaintingToFile);
if (gfxUtils::sDumpPaintingToFile) {
fprintf(gfxUtils::sDumpPaintFile, "<script>");
fprintf_stderr(gfxUtils::sDumpPaintFile, "<script>");
}
}
#endif
@ -2327,12 +2327,12 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
#ifdef MOZ_DUMP_PAINTING
if (gfxUtils::sDumpPaintList || gfxUtils::sDumpPainting) {
if (gfxUtils::sDumpPaintingToFile) {
fprintf(gfxUtils::sDumpPaintFile, "</script>");
fprintf_stderr(gfxUtils::sDumpPaintFile, "</script>");
}
fprintf(gfxUtils::sDumpPaintFile, "Painting --- after optimization:\n");
fprintf_stderr(gfxUtils::sDumpPaintFile, "Painting --- after optimization:\n");
nsFrame::PrintDisplayList(&builder, list, gfxUtils::sDumpPaintFile, gfxUtils::sDumpPaintingToFile);
fprintf(gfxUtils::sDumpPaintFile, "Painting --- retained layer tree:\n");
fprintf_stderr(gfxUtils::sDumpPaintFile, "Painting --- retained layer tree:\n");
nsIWidget* widget = aFrame->GetNearestWidget();
if (widget) {
nsRefPtr<LayerManager> layerManager = widget->GetLayerManager();
@ -2599,7 +2599,9 @@ nsLayoutUtils::GetFontMetricsForStyleContext(nsStyleContext* aStyleContext,
float aInflation)
{
// pass the user font set object into the device context to pass along to CreateFontGroup
gfxUserFontSet* fs = aStyleContext->PresContext()->GetUserFontSet();
nsPresContext* pc = aStyleContext->PresContext();
gfxUserFontSet* fs = pc->GetUserFontSet();
gfxTextPerfMetrics* tp = pc->GetTextPerfMetrics();
nsFont font = aStyleContext->StyleFont()->mFont;
// We need to not run font.size through floats when it's large since
@ -2608,9 +2610,9 @@ nsLayoutUtils::GetFontMetricsForStyleContext(nsStyleContext* aStyleContext,
if (aInflation != 1.0f) {
font.size = NSToCoordRound(font.size * aInflation);
}
return aStyleContext->PresContext()->DeviceContext()->GetMetricsFor(
return pc->DeviceContext()->GetMetricsFor(
font, aStyleContext->StyleFont()->mLanguage,
fs, *aFontMetrics);
fs, tp, *aFontMetrics);
}
nsIFrame*
@ -2947,9 +2949,9 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
NS_PRECONDITION(aType == MIN_WIDTH || aType == PREF_WIDTH, "bad type");
#ifdef DEBUG_INTRINSIC_WIDTH
nsFrame::IndentBy(stdout, gNoiseIndent);
static_cast<nsFrame*>(aFrame)->ListTag(stdout);
printf(" %s intrinsic width for container:\n",
nsFrame::IndentBy(stderr, gNoiseIndent);
static_cast<nsFrame*>(aFrame)->ListTag(stderr);
printf_stderr(" %s intrinsic width for container:\n",
aType == MIN_WIDTH ? "min" : "pref");
#endif
@ -3007,9 +3009,9 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
result = aFrame->GetPrefWidth(aRenderingContext);
#ifdef DEBUG_INTRINSIC_WIDTH
--gNoiseIndent;
nsFrame::IndentBy(stdout, gNoiseIndent);
static_cast<nsFrame*>(aFrame)->ListTag(stdout);
printf(" %s intrinsic width from frame is %d.\n",
nsFrame::IndentBy(stderr, gNoiseIndent);
static_cast<nsFrame*>(aFrame)->ListTag(stderr);
printf_stderr(" %s intrinsic width from frame is %d.\n",
aType == MIN_WIDTH ? "min" : "pref", result);
#endif
@ -3196,9 +3198,9 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
}
#ifdef DEBUG_INTRINSIC_WIDTH
nsFrame::IndentBy(stdout, gNoiseIndent);
static_cast<nsFrame*>(aFrame)->ListTag(stdout);
printf(" %s intrinsic width for container is %d twips.\n",
nsFrame::IndentBy(stderr, gNoiseIndent);
static_cast<nsFrame*>(aFrame)->ListTag(stderr);
printf_stderr(" %s intrinsic width for container is %d twips.\n",
aType == MIN_WIDTH ? "min" : "pref", result);
#endif

View File

@ -235,6 +235,12 @@ nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType)
mUserFontSet = nullptr;
mUserFontSetDirty = true;
// if text perf logging enabled, init stats struct
PRLogModuleInfo *log = gfxPlatform::GetLog(eGfxLog_textperf);
if (log && PR_LOG_TEST(log, PR_LOG_WARNING)) {
mTextPerf = new gfxTextPerfMetrics();
}
PR_INIT_CLIST(&mDOMMediaQueryLists);
}

View File

@ -56,6 +56,7 @@ struct nsStyleBackground;
struct nsStyleBorder;
class nsIRunnable;
class gfxUserFontSet;
class gfxTextPerfMetrics;
class nsUserFontSet;
struct nsFontFaceRuleContainer;
class nsObjectFrame;
@ -788,6 +789,8 @@ public:
*/
const nscoord* GetBorderWidthTable() { return mBorderWidthTable; }
gfxTextPerfMetrics *GetTextPerfMetrics() { return mTextPerf; }
bool IsDynamic() { return (mType == eContext_PageLayout || mType == eContext_Galley); }
bool IsScreen() { return (mMedium == nsGkAtoms::screen ||
mType == eContext_PageLayout ||
@ -1194,6 +1197,9 @@ protected:
// container for per-context fonts (downloadable, SVG, etc.)
nsUserFontSet* mUserFontSet;
// text performance metrics
nsAutoPtr<gfxTextPerfMetrics> mTextPerf;
nsRect mVisibleArea;
nsSize mPageSize;
float mPageScale;

View File

@ -878,12 +878,106 @@ PresShell::Init(nsIDocument* aDocument,
SetupFontInflation();
}
#ifdef PR_LOGGING
enum TextPerfLogType {
eLog_reflow,
eLog_loaddone,
eLog_totals
};
static void
LogTextPerfStats(gfxTextPerfMetrics* aTextPerf,
PresShell* aPresShell,
const gfxTextPerfMetrics::TextCounts& aCounts,
float aTime, TextPerfLogType aLogType, const char* aURL)
{
char prefix[256];
switch (aLogType) {
case eLog_reflow:
sprintf(prefix, "(textperf-reflow) %p time-ms: %7.0f", aPresShell, aTime);
break;
case eLog_loaddone:
sprintf(prefix, "(textperf-loaddone) %p time-ms: %7.0f", aPresShell, aTime);
break;
default:
MOZ_ASSERT(aLogType == eLog_totals, "unknown textperf log type");
sprintf(prefix, "(textperf-totals) %p", aPresShell);
}
PRLogModuleInfo* tpLog = gfxPlatform::GetLog(eGfxLog_textperf);
// ignore XUL contexts unless at debug level
PRLogModuleLevel logLevel = PR_LOG_WARNING;
if (aCounts.numContentTextRuns == 0) {
logLevel = PR_LOG_DEBUG;
}
double hitRatio = 0.0;
uint32_t lookups = aCounts.wordCacheHit + aCounts.wordCacheMiss;
if (lookups) {
hitRatio = double(aCounts.wordCacheHit) / double(lookups);
}
if (aLogType == eLog_loaddone) {
PR_LOG(tpLog, logLevel,
("%s reflow: %d chars: %d "
"[%s] "
"content-textruns: %d chrome-textruns: %d "
"max-textrun-len: %d "
"word-cache-lookups: %d word-cache-hit-ratio: %4.3f "
"word-cache-space: %d word-cache-long: %d "
"pref-fallbacks: %d system-fallbacks: %d "
"textruns-const: %d textruns-destr: %d "
"cumulative-textruns-destr: %d\n",
prefix, aTextPerf->reflowCount, aCounts.numChars,
(aURL ? aURL : ""),
aCounts.numContentTextRuns, aCounts.numChromeTextRuns,
aCounts.maxTextRunLen,
lookups, hitRatio,
aCounts.wordCacheSpaceRules, aCounts.wordCacheLong,
aCounts.fallbackPrefs, aCounts.fallbackSystem,
aCounts.textrunConst, aCounts.textrunDestr,
aTextPerf->cumulative.textrunDestr));
} else {
PR_LOG(tpLog, logLevel,
("%s reflow: %d chars: %d "
"content-textruns: %d chrome-textruns: %d "
"max-textrun-len: %d "
"word-cache-lookups: %d word-cache-hit-ratio: %4.3f "
"word-cache-space: %d word-cache-long: %d "
"pref-fallbacks: %d system-fallbacks: %d "
"textruns-const: %d textruns-destr: %d "
"cumulative-textruns-destr: %d\n",
prefix, aTextPerf->reflowCount, aCounts.numChars,
aCounts.numContentTextRuns, aCounts.numChromeTextRuns,
aCounts.maxTextRunLen,
lookups, hitRatio,
aCounts.wordCacheSpaceRules, aCounts.wordCacheLong,
aCounts.fallbackPrefs, aCounts.fallbackSystem,
aCounts.textrunConst, aCounts.textrunDestr,
aTextPerf->cumulative.textrunDestr));
}
}
#endif
void
PresShell::Destroy()
{
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
"destroy called on presshell while scripts not blocked");
// dump out cumulative text perf metrics
#ifdef PR_LOGGING
gfxTextPerfMetrics* tp;
if (mPresContext && (tp = mPresContext->GetTextPerfMetrics())) {
tp->Accumulate();
if (tp->cumulative.numChars > 0) {
LogTextPerfStats(tp, this, tp->cumulative, 0.0, eLog_totals, nullptr);
}
}
#endif
#ifdef MOZ_REFLOW_PERF
DumpReflows();
if (mReflowCountMgr) {
@ -2399,15 +2493,24 @@ PresShell::BeginLoad(nsIDocument *aDocument)
mDocumentLoading = true;
#ifdef PR_LOGGING
if (gLog && PR_LOG_TEST(gLog, PR_LOG_DEBUG)) {
gfxTextPerfMetrics *tp = nullptr;
if (mPresContext) {
tp = mPresContext->GetTextPerfMetrics();
}
bool shouldLog = gLog && PR_LOG_TEST(gLog, PR_LOG_DEBUG);
if (shouldLog || tp) {
mLoadBegin = TimeStamp::Now();
}
if (shouldLog) {
nsIURI* uri = mDocument->GetDocumentURI();
nsAutoCString spec;
if (uri) {
uri->GetSpec(spec);
}
PR_LOG(gLog, PR_LOG_DEBUG,
("(presshell) %p begin load [%s]\n",
("(presshell) %p load begin [%s]\n",
this, spec.get()));
}
#endif
@ -2421,19 +2524,38 @@ PresShell::EndLoad(nsIDocument *aDocument)
RestoreRootScrollPosition();
mDocumentLoading = false;
}
void
PresShell::LoadComplete()
{
#ifdef PR_LOGGING
gfxTextPerfMetrics *tp = nullptr;
if (mPresContext) {
tp = mPresContext->GetTextPerfMetrics();
}
// log load
if (gLog && PR_LOG_TEST(gLog, PR_LOG_DEBUG)) {
bool shouldLog = gLog && PR_LOG_TEST(gLog, PR_LOG_DEBUG);
if (shouldLog || tp) {
TimeDuration loadTime = TimeStamp::Now() - mLoadBegin;
nsIURI* uri = mDocument->GetDocumentURI();
nsAutoCString spec;
if (uri) {
uri->GetSpec(spec);
}
PR_LOG(gLog, PR_LOG_DEBUG,
("(presshell) %p end load time-ms: %9.2f [%s]\n",
this, loadTime.ToMilliseconds(), spec.get()));
if (shouldLog) {
PR_LOG(gLog, PR_LOG_DEBUG,
("(presshell) %p load done time-ms: %9.2f [%s]\n",
this, loadTime.ToMilliseconds(), spec.get()));
}
if (tp) {
tp->Accumulate();
if (tp->cumulative.numChars > 0) {
LogTextPerfStats(tp, this, tp->cumulative, loadTime.ToMilliseconds(),
eLog_loaddone, spec.get());
}
}
}
#endif
}
@ -7877,6 +7999,14 @@ PresShell::DoReflow(nsIFrame* target, bool aInterruptible)
return true;
}
gfxTextPerfMetrics* tp = mPresContext->GetTextPerfMetrics();
TimeStamp timeStart;
if (tp) {
tp->Accumulate();
tp->reflowCount++;
timeStart = TimeStamp::Now();
}
target->SchedulePaint();
nsIFrame *parent = nsLayoutUtils::GetCrossDocParentFrame(target);
while (parent) {
@ -8032,6 +8162,18 @@ PresShell::DoReflow(nsIFrame* target, bool aInterruptible)
MaybeScheduleReflow();
}
#ifdef PR_LOGGING
// dump text perf metrics for reflows with significant text processing
if (tp) {
if (tp->current.numChars > 100) {
TimeDuration reflowTime = TimeStamp::Now() - timeStart;
LogTextPerfStats(tp, this, tp->current,
reflowTime.ToMilliseconds(), eLog_reflow, nullptr);
}
tp->Accumulate();
}
#endif
return !interrupted;
}
@ -9141,7 +9283,9 @@ void ReflowCountMgr::PaintCount(const char* aName,
// We have one frame, therefore we must have a root...
aPresContext->GetPresShell()->GetRootFrame()->
StyleFont()->mLanguage,
aPresContext->GetUserFontSet(), *getter_AddRefs(fm));
aPresContext->GetUserFontSet(),
aPresContext->GetTextPerfMetrics(),
*getter_AddRefs(fm));
aRenderingContext->SetFont(fm);
char buf[16];

View File

@ -318,6 +318,8 @@ public:
IsLayoutFlushObserver(this);
}
virtual void LoadComplete() MOZ_OVERRIDE;
void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
nsArenaMemoryStats *aArenaObjectsSize,
size_t *aPresShellSize,

View File

@ -1199,7 +1199,7 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
if (mViewManagerFlushIsPending) {
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf("Starting ProcessPendingUpdates\n");
printf_stderr("Starting ProcessPendingUpdates\n");
}
#endif
#ifndef MOZ_WIDGET_GONK
@ -1215,7 +1215,7 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
vm->ProcessPendingUpdates();
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf("Ending ProcessPendingUpdates\n");
printf_stderr("Ending ProcessPendingUpdates\n");
}
#endif
}

View File

@ -2017,6 +2017,8 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
new (aBuilder) nsDisplayBlendContainer(aBuilder, this, &resultList));
}
CreateOwnLayerIfNeeded(aBuilder, &resultList);
aList->AppendToTop(&resultList);
}
@ -8054,7 +8056,9 @@ void
nsIFrame::CreateOwnLayerIfNeeded(nsDisplayListBuilder* aBuilder,
nsDisplayList* aList)
{
if (GetContent()->HasAttr(kNameSpaceID_None, nsGkAtoms::layer)) {
if (GetContent() &&
GetContent()->IsXUL() &&
GetContent()->HasAttr(kNameSpaceID_None, nsGkAtoms::layer)) {
aList->AppendNewToTop(new (aBuilder)
nsDisplayOwnLayer(aBuilder, this, aList));
}

View File

@ -575,6 +575,7 @@ nsPageFrame::PaintHeaderFooter(nsRenderingContext& aRenderingContext,
nsRefPtr<nsFontMetrics> fontMet;
pc->DeviceContext()->GetMetricsFor(mPD->mHeadFootFont, nullptr,
pc->GetUserFontSet(),
pc->GetTextPerfMetrics(),
*getter_AddRefs(fontMet));
aRenderingContext.SetFont(fontMet);

View File

@ -924,6 +924,7 @@ SetFontFamily(nsStyleContext* aStyleContext,
aRenderingContext.DeviceContext()->GetMetricsFor(font,
aStyleContext->StyleFont()->mLanguage,
aStyleContext->PresContext()->GetUserFontSet(),
aStyleContext->PresContext()->GetTextPerfMetrics(),
*getter_AddRefs(fm));
// Set the font if it is an unicode table
// or if the same family name has been found
@ -1312,7 +1313,8 @@ nsMathMLChar::StretchInternal(nsPresContext* aPresContext,
nsRefPtr<nsFontMetrics> fm;
aRenderingContext.DeviceContext()->GetMetricsFor(font,
mStyleContext->StyleFont()->mLanguage,
aPresContext->GetUserFontSet(), *getter_AddRefs(fm));
aPresContext->GetUserFontSet(),
aPresContext->GetTextPerfMetrics(), *getter_AddRefs(fm));
aRenderingContext.SetFont(fm);
aDesiredStretchSize =
aRenderingContext.GetBoundingMetrics(mData.get(), uint32_t(mData.Length()));
@ -1868,7 +1870,7 @@ nsMathMLChar::PaintForeground(nsPresContext* aPresContext,
nsRefPtr<nsFontMetrics> fm;
aRenderingContext.DeviceContext()->GetMetricsFor(theFont,
styleContext->StyleFont()->mLanguage,
aPresContext->GetUserFontSet(),
aPresContext->GetUserFontSet(), aPresContext->GetTextPerfMetrics(),
*getter_AddRefs(fm));
aRenderingContext.SetFont(fm);

View File

@ -221,10 +221,11 @@ GetMetricsFor(nsPresContext* aPresContext,
if (aUseUserFontSet) {
fs = aPresContext->GetUserFontSet();
}
gfxTextPerfMetrics *tp = aPresContext->GetTextPerfMetrics();
nsRefPtr<nsFontMetrics> fm;
aPresContext->DeviceContext()->GetMetricsFor(font,
aStyleFont->mLanguage,
fs, *getter_AddRefs(fm));
fs, tp, *getter_AddRefs(fm));
return fm.forget();
}

View File

@ -5,12 +5,13 @@
MOCHITEST_FILES = \
tree_shared.js \
test_audiocontrols_dimensions.html \
test_mousecapture_area.html \
test_videocontrols.html \
test_videocontrols_audio.html \
test_videocontrols_video_direction.html \
test_videocontrols_audio_direction.html \
test_audiocontrols_dimensions.html \
test_videocontrols_standalone.html \
test_videocontrols_video_direction.html \
videocontrols_direction-1-ref.html \
videocontrols_direction-1a.html \
videocontrols_direction-1b.html \

View File

@ -0,0 +1,75 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Video controls test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<pre id="test">
<script class="testbody" type="text/javascript">
const videoWidth = 320;
const videoHeight = 240;
function getMediaElement(aWindow) {
return aWindow.document.getElementsByTagName("video")[0];
}
var popup = window.open("seek_with_sound.ogg");
popup.addEventListener("load", function onLoad() {
popup.removeEventListener("load", onLoad);
var video = getMediaElement(popup);
if (video.readyState >= video.HAVE_METADATA)
runTestVideo(video);
else {
video.addEventListener("loadedmetadata", function onLoadedMetaData() {
video.removeEventListener("loadedmetadata", onLoadedMetaData);
runTestVideo(video);
});
}
});
function runTestVideo(aVideo) {
var boundingRect = aVideo.getBoundingClientRect();
is(boundingRect.width, videoWidth, "Width of the video should match expectation");
is(boundingRect.height, videoHeight, "Height of video should match expectation");
popup.close();
runTestAudioPre();
}
function runTestAudioPre() {
popup = window.open("audio.ogg");
popup.addEventListener("load", function onLoad() {
popup.removeEventListener("load", onLoad);
var audio = getMediaElement(popup);
if (audio.readyState >= audio.HAVE_METADATA)
runTestAudio(audio);
else {
audio.addEventListener("loadedmetadata", function onLoadedMetaData() {
audio.removeEventListener("loadedmetadata", onLoadedMetaData);
runTestAudio(audio);
})
}
})
}
function runTestAudio(aAudio) {
var boundingRect = aAudio.getBoundingClientRect();
var isAndroid = (navigator.userAgent.indexOf("Android") !== -1);
var expectedHeight = isAndroid ? 123 : 28;
is(boundingRect.height, expectedHeight,
"Height of audio element should be " + expectedHeight + ", which is equal to the controls bar.");
popup.close();
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View File

@ -344,8 +344,13 @@
this._isAudioOnly = val;
if (!this.isTopLevelSyntheticDocument)
return;
this.video.style.height = this._controlBarHeight + "px";
this.video.style.width = "66%";
if (this._isAudioOnly) {
this.video.style.height = this._controlBarHeight + "px";
this.video.style.width = "66%";
} else {
this.video.style.removeProperty("height");
this.video.style.removeProperty("width");
}
},
suppressError : false,

View File

@ -481,6 +481,9 @@ function BrowserTabActor(aConnection, aBrowser, aTabBrowser)
this._extraActors = {};
this._onWindowCreated = this.onWindowCreated.bind(this);
// Number of event loops nested.
this._nestedEventLoopDepth = 0;
}
// XXX (bug 710213): BrowserTabActor attach/detach/exit/disconnect is a
@ -634,6 +637,9 @@ BrowserTabActor.prototype = {
type: "tabDetached" });
}
// Pop all nested event loops if we haven't already.
while (this._nestedEventLoopDepth > 0)
this.postNest();
this._browser = null;
this._tabbrowser = null;
},
@ -782,6 +788,7 @@ BrowserTabActor.prototype = {
.getInterface(Ci.nsIDOMWindowUtils);
windowUtils.suppressEventHandling(true);
windowUtils.suspendTimeouts();
this._nestedEventLoopDepth++;
},
/**
@ -790,6 +797,8 @@ BrowserTabActor.prototype = {
postNest: function BTA_postNest(aNestData) {
if (!this.window) {
// The tab is already closed.
dbg_assert(this._nestedEventLoopDepth === 0,
"window shouldn't be closed before all nested event loops have been popped");
return;
}
let windowUtils = this.window
@ -801,6 +810,7 @@ BrowserTabActor.prototype = {
this._pendingNavigation.resume();
this._pendingNavigation = null;
}
this._nestedEventLoopDepth--;
},
/**

View File

@ -309,7 +309,7 @@ void nsViewManager::Refresh(nsView *aView, const nsIntRegion& aRegion)
#ifdef DEBUG_roc
nsRect viewRect = aView->GetDimensions();
nsRect damageRect = damageRegion.GetBounds();
printf("XXX Damage rectangle (%d,%d,%d,%d) does not intersect the widget's view (%d,%d,%d,%d)!\n",
printf_stderr("XXX Damage rectangle (%d,%d,%d,%d) does not intersect the widget's view (%d,%d,%d,%d)!\n",
damageRect.x, damageRect.y, damageRect.width, damageRect.height,
viewRect.x, viewRect.y, viewRect.width, viewRect.height);
#endif
@ -337,7 +337,7 @@ void nsViewManager::Refresh(nsView *aView, const nsIntRegion& aRegion)
if (mPresShell) {
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf("--COMPOSITE-- %p\n", mPresShell);
printf_stderr("--COMPOSITE-- %p\n", mPresShell);
}
#endif
uint32_t paintFlags = nsIPresShell::PAINT_COMPOSITE;
@ -350,7 +350,7 @@ void nsViewManager::Refresh(nsView *aView, const nsIntRegion& aRegion)
}
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf("--ENDCOMPOSITE--\n");
printf_stderr("--ENDCOMPOSITE--\n");
}
#endif
mozilla::StartupTimeline::RecordOnce(mozilla::StartupTimeline::FIRST_PAINT);
@ -411,7 +411,7 @@ void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n", mPresShell, aView, widget);
printf_stderr("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n", mPresShell, aView, widget);
}
#endif
nsAutoScriptBlocker scriptBlocker;
@ -421,7 +421,7 @@ void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
nsIPresShell::PAINT_LAYERS);
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf("---- PAINT END ----\n");
printf_stderr("---- PAINT END ----\n");
}
#endif

View File

@ -3337,16 +3337,7 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager,
// Fall back to software if we couldn't use any hardware backends.
if (!mLayerManager) {
// Try to use an async compositor first, if possible
if (ShouldUseOffMainThreadCompositing()) {
// e10s uses the parameter to pass in the shadow manager from the TabChild
// so we don't expect to see it there since this doesn't support e10s.
NS_ASSERTION(aShadowManager == nullptr, "Async Compositor not supported with e10s");
CreateCompositor();
}
if (!mLayerManager)
mLayerManager = CreateBasicLayerManager();
mLayerManager = CreateBasicLayerManager();
}
}

View File

@ -268,16 +268,19 @@ void NS_MakeRandomString(char *aBuf, int32_t aBufLen)
#endif
#if defined(XP_WIN)
#define va_copy(dest, src) (dest = src)
void
printf_stderr(const char *fmt, ...)
vprintf_stderr(const char *fmt, va_list args)
{
if (IsDebuggerPresent()) {
char buf[2048];
va_list args;
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_list argsCpy;
va_copy(argsCpy, args);
vsnprintf(buf, sizeof(buf), fmt, argsCpy);
buf[sizeof(buf) - 1] = '\0';
va_end(args);
va_end(argsCpy);
OutputDebugStringA(buf);
}
@ -285,29 +288,47 @@ printf_stderr(const char *fmt, ...)
if (!fp)
return;
va_list args;
va_start(args, fmt);
vfprintf(fp, fmt, args);
va_end(args);
fclose(fp);
}
#undef va_copy
#elif defined(ANDROID)
void
printf_stderr(const char *fmt, ...)
vprintf_stderr(const char *fmt, va_list args)
{
va_list args;
va_start(args, fmt);
__android_log_vprint(ANDROID_LOG_INFO, "Gecko", fmt, args);
va_end(args);
}
#else
void
vprintf_stderr(const char *fmt, va_list args)
{
vfprintf(stderr, fmt, args);
}
#endif
void
printf_stderr(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
vprintf_stderr(fmt, args);
va_end(args);
}
#endif
void
fprintf_stderr(FILE* aFile, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
if (aFile == stderr) {
vprintf_stderr(fmt, args);
} else {
vfprintf(aFile, fmt, args);
}
va_end(args);
}

View File

@ -398,6 +398,13 @@ extern "C" {
NS_COM_GLUE void
printf_stderr(const char *fmt, ...);
NS_COM_GLUE void
vprintf_stderr(const char *fmt, va_list args);
// fprintf with special handling for stderr to print to the console
NS_COM_GLUE void
fprintf_stderr(FILE* aFile, const char *fmt, ...);
#ifdef __cplusplus
}
#endif