From 715c8798779d03b0c49fdf50c89b094c4891261b Mon Sep 17 00:00:00 2001 From: Brad Lassey Date: Thu, 10 Mar 2011 23:33:43 -0500 Subject: [PATCH 01/15] bug 623820 - Text zoom reflow messes up layout on AMO and other sites r=roc,dbaron a=blocking-fennec --- content/base/src/nsDocument.cpp | 1 + docshell/base/nsDocShell.cpp | 19 ++++-- docshell/base/nsIMarkupDocumentViewer.idl | 8 +++ layout/base/nsDocumentViewer.cpp | 76 ++++++++++++++++++++++- layout/base/nsPresContext.cpp | 6 +- layout/base/nsPresContext.h | 22 ++++++- layout/printing/nsPrintEngine.cpp | 3 +- layout/style/nsRuleNode.cpp | 9 +-- 8 files changed, 126 insertions(+), 18 deletions(-) diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index ff97dbbd12f..65c0b12efba 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -889,6 +889,7 @@ TransferZoomLevels(nsIDocument* aFromDoc, return; toCtxt->SetFullZoom(fromCtxt->GetFullZoom()); + toCtxt->SetMinFontSize(fromCtxt->MinFontSize()); toCtxt->SetTextZoom(fromCtxt->TextZoom()); } diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index e5129c42277..7c57ad0e33a 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -6951,12 +6951,16 @@ nsDocShell::RestoreFromHistory() mSavingOldViewer = CanSavePresentation(mLoadType, request, doc); } - nsCOMPtr oldMUDV(do_QueryInterface(mContentViewer)); - nsCOMPtr newMUDV(do_QueryInterface(viewer)); + nsCOMPtr oldMUDV( + do_QueryInterface(mContentViewer)); + nsCOMPtr newMUDV( + do_QueryInterface(viewer)); + PRInt32 minFontSize = 0; float textZoom = 1.0f; float pageZoom = 1.0f; PRBool styleDisabled = PR_FALSE; if (oldMUDV && newMUDV) { + oldMUDV->GetMinFontSize(&minFontSize); oldMUDV->GetTextZoom(&textZoom); oldMUDV->GetFullZoom(&pageZoom); oldMUDV->GetAuthorStyleDisabled(&styleDisabled); @@ -7156,6 +7160,7 @@ nsDocShell::RestoreFromHistory() if (oldMUDV && newMUDV) { + newMUDV->SetMinFontSize(minFontSize); newMUDV->SetTextZoom(textZoom); newMUDV->SetFullZoom(pageZoom); newMUDV->SetAuthorStyleDisabled(styleDisabled); @@ -7600,14 +7605,15 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer) nsCAutoString hintCharset; PRInt32 hintCharsetSource; nsCAutoString prevDocCharset; + PRInt32 minFontSize; float textZoom; float pageZoom; PRBool styleDisabled; // |newMUDV| also serves as a flag to set the data from the above vars - nsCOMPtr newMUDV; + nsCOMPtr newMUDV; if (mContentViewer || parent) { - nsCOMPtr oldMUDV; + nsCOMPtr oldMUDV; if (mContentViewer) { // Get any interesting state from old content viewer // XXX: it would be far better to just reuse the document viewer , @@ -7648,6 +7654,9 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer) NS_ENSURE_SUCCESS(oldMUDV-> GetHintCharacterSetSource(&hintCharsetSource), NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(oldMUDV-> + GetMinFontSize(&minFontSize), + NS_ERROR_FAILURE); NS_ENSURE_SUCCESS(oldMUDV-> GetTextZoom(&textZoom), NS_ERROR_FAILURE); @@ -7728,6 +7737,8 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer) NS_ERROR_FAILURE); NS_ENSURE_SUCCESS(newMUDV->SetPrevDocCharacterSet(prevDocCharset), NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(newMUDV->SetMinFontSize(minFontSize), + NS_ERROR_FAILURE); NS_ENSURE_SUCCESS(newMUDV->SetTextZoom(textZoom), NS_ERROR_FAILURE); NS_ENSURE_SUCCESS(newMUDV->SetFullZoom(pageZoom), diff --git a/docshell/base/nsIMarkupDocumentViewer.idl b/docshell/base/nsIMarkupDocumentViewer.idl index da211f1713e..901903dd767 100644 --- a/docshell/base/nsIMarkupDocumentViewer.idl +++ b/docshell/base/nsIMarkupDocumentViewer.idl @@ -154,3 +154,11 @@ interface nsIMarkupDocumentViewer : nsISupports */ attribute PRUint32 bidiOptions; }; + +[scriptable, uuid(cadfcad1-5570-4dac-b5a2-cd1ea751fe29)] +interface nsIMarkupDocumentViewer_MOZILLA_2_0_BRANCH : nsIMarkupDocumentViewer +{ + /** The minimum font size */ + attribute long minFontSize; + +}; diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 40f38612faf..fb1e9b40fcd 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -300,7 +300,7 @@ class DocumentViewerImpl : public nsIDocumentViewer, public nsIContentViewer_MOZILLA_2_0_BRANCH, public nsIContentViewerEdit, public nsIContentViewerFile, - public nsIMarkupDocumentViewer, + public nsIMarkupDocumentViewer_MOZILLA_2_0_BRANCH, public nsIDocumentViewerPrint #ifdef NS_PRINTING @@ -345,6 +345,9 @@ public: // nsIMarkupDocumentViewer NS_DECL_NSIMARKUPDOCUMENTVIEWER + // nsIMarkupDocumentViewer_MOZILLA_2_0_BRANCH + NS_DECL_NSIMARKUPDOCUMENTVIEWER_MOZILLA_2_0_BRANCH + #ifdef NS_PRINTING // nsIWebBrowserPrint NS_DECL_NSIWEBBROWSERPRINT @@ -462,6 +465,7 @@ protected: // presshell only. float mTextZoom; // Text zoom, defaults to 1.0 float mPageZoom; + int mMinFontSize; PRInt16 mNumURLStarts; PRInt16 mDestroyRefCount; // a second "refcount" for the document viewer's "destroy" @@ -562,7 +566,7 @@ void DocumentViewerImpl::PrepareToStartLoad() // Note: operator new zeros our memory, so no need to init things to null. DocumentViewerImpl::DocumentViewerImpl() - : mTextZoom(1.0), mPageZoom(1.0), + : mTextZoom(1.0), mPageZoom(1.0), mMinFontSize(0), mIsSticky(PR_TRUE), #ifdef NS_PRINT_PREVIEW mPrintPreviewZoom(1.0), @@ -581,6 +585,7 @@ NS_INTERFACE_MAP_BEGIN(DocumentViewerImpl) NS_INTERFACE_MAP_ENTRY(nsIContentViewer) NS_INTERFACE_MAP_ENTRY(nsIDocumentViewer) NS_INTERFACE_MAP_ENTRY(nsIMarkupDocumentViewer) + NS_INTERFACE_MAP_ENTRY(nsIMarkupDocumentViewer_MOZILLA_2_0_BRANCH) NS_INTERFACE_MAP_ENTRY(nsIContentViewerFile) NS_INTERFACE_MAP_ENTRY(nsIContentViewerEdit) NS_INTERFACE_MAP_ENTRY(nsIDocumentViewerPrint) @@ -754,6 +759,7 @@ DocumentViewerImpl::InitPresentationStuff(PRBool aDoInitialReflow) mViewManager->SetWindowDimensions(width, height); mPresContext->SetTextZoom(mTextZoom); mPresContext->SetFullZoom(mPageZoom); + mPresContext->SetMinFontSize(mMinFontSize); if (aDoInitialReflow) { nsCOMPtr htmlDoc = do_QueryInterface(mDocument); @@ -2749,6 +2755,15 @@ SetChildTextZoom(nsIMarkupDocumentViewer* aChild, void* aClosure) aChild->SetTextZoom(ZoomInfo->mZoom); } +static void +SetChildMinFontSize(nsIMarkupDocumentViewer* aChild, void* aClosure) +{ + nsCOMPtr branch = + do_QueryInterface(aChild); + struct ZoomInfo* ZoomInfo = (struct ZoomInfo*) aClosure; + branch->SetMinFontSize(ZoomInfo->mZoom); +} + static void SetChildFullZoom(nsIMarkupDocumentViewer* aChild, void* aClosure) { @@ -2772,6 +2787,21 @@ SetExtResourceTextZoom(nsIDocument* aDocument, void* aClosure) return PR_TRUE; } +static PRBool +SetExtResourceMinFontSize(nsIDocument* aDocument, void* aClosure) +{ + nsIPresShell* shell = aDocument->GetShell(); + if (shell) { + nsPresContext* ctxt = shell->GetPresContext(); + if (ctxt) { + struct ZoomInfo* ZoomInfo = static_cast(aClosure); + ctxt->SetMinFontSize(ZoomInfo->mZoom); + } + } + + return PR_TRUE; +} + static PRBool SetExtResourceFullZoom(nsIDocument* aDocument, void* aClosure) { @@ -2829,6 +2859,47 @@ DocumentViewerImpl::GetTextZoom(float* aTextZoom) return NS_OK; } +NS_IMETHODIMP +DocumentViewerImpl::SetMinFontSize(PRInt32 aMinFontSize) +{ + if (GetIsPrintPreview()) { + return NS_OK; + } + + mMinFontSize = aMinFontSize; + + nsIViewManager::UpdateViewBatch batch(GetViewManager()); + + // Set the min font on all children of mContainer (even if our min font didn't + // change, our children's min font may be different, though it would be unusual). + // Do this first, in case kids are auto-sizing and post reflow commands on + // our presshell (which should be subsumed into our own style change reflow). + struct ZoomInfo ZoomInfo = { aMinFontSize }; + CallChildren(SetChildMinFontSize, &ZoomInfo); + + // Now change our own min font + nsPresContext* pc = GetPresContext(); + if (pc && aMinFontSize != mPresContext->MinFontSize()) { + pc->SetMinFontSize(aMinFontSize); + } + + // And do the external resources + mDocument->EnumerateExternalResources(SetExtResourceMinFontSize, &ZoomInfo); + + batch.EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC); + + return NS_OK; +} + +NS_IMETHODIMP +DocumentViewerImpl::GetMinFontSize(PRInt32* aMinFontSize) +{ + NS_ENSURE_ARG_POINTER(aMinFontSize); + nsPresContext* pc = GetPresContext(); + *aMinFontSize = pc ? pc->MinFontSize() : 0; + return NS_OK; +} + NS_IMETHODIMP DocumentViewerImpl::SetFullZoom(float aFullZoom) { @@ -4192,6 +4263,7 @@ DocumentViewerImpl::ReturnToGalleyPresentation() SetTextZoom(mTextZoom); SetFullZoom(mPageZoom); + SetMinFontSize(mMinFontSize); Show(); #endif // NS_PRINTING && NS_PRINT_PREVIEW diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index 875222413d5..b1a83172299 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -186,7 +186,7 @@ static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID); nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType) : mType(aType), mDocument(aDocument), mTextZoom(1.0), mFullZoom(1.0), - mPageSize(-1, -1), mPPScale(1.0f), + mPageSize(-1, -1), mPPScale(1.0f), mMinFontSize(0), mViewportStyleOverflow(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO), mImageAnimationModePref(imgIContainer::kNormalAnimMode), // Font sizes default to zero; they will be set in GetFontPreferences @@ -484,10 +484,10 @@ nsPresContext::GetFontPreferences() PRInt32 size = nsContentUtils::GetIntPref(pref.get()); if (unit == eUnit_px) { - mMinimumFontSize = CSSPixelsToAppUnits(size); + mMinimumFontSizePref = CSSPixelsToAppUnits(size); } else if (unit == eUnit_pt) { - mMinimumFontSize = CSSPointsToAppUnits(size); + mMinimumFontSizePref = CSSPointsToAppUnits(size); } // get attributes specific to each generic font diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index 9e674516aef..3a61363d1ec 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -372,7 +372,7 @@ public: // this switch statement away. switch (aPrefType) { case kPresContext_MinimumFontSize: - return mMinimumFontSize; + return mMinimumFontSizePref; case kPresContext_ScrollbarSide: return mPrefScrollbarSide; case kPresContext_BidiDirection: @@ -556,6 +556,23 @@ public: } } + PRInt32 MinFontSize() const { + return NS_MAX(mMinFontSize, mMinimumFontSizePref); + } + + void SetMinFontSize(PRInt32 aMinFontSize) { + if (aMinFontSize == mMinFontSize) + return; + + mMinFontSize = aMinFontSize; + if (HasCachedStyleData()) { + // Media queries could have changed since we changed the meaning + // of 'em' units in them. + MediaFeatureValuesChanged(PR_TRUE); + RebuildAllStyleData(NS_STYLE_HINT_REFLOW); + } + } + float GetFullZoom() { return mFullZoom; } void SetFullZoom(float aZoom); @@ -1054,6 +1071,7 @@ protected: nsWeakPtr mContainer; + PRInt32 mMinFontSize; // Min font size, defaults to 0 float mTextZoom; // Text zoom, defaults to 1.0 float mFullZoom; // Page zoom, defaults to 1.0 @@ -1079,7 +1097,7 @@ protected: nsTArray mFontFaceRules; PRInt32 mFontScaler; - nscoord mMinimumFontSize; + nscoord mMinimumFontSizePref; nsRect mVisibleArea; nsSize mPageSize; diff --git a/layout/printing/nsPrintEngine.cpp b/layout/printing/nsPrintEngine.cpp index e65d92a4a0c..9b346f249b1 100644 --- a/layout/printing/nsPrintEngine.cpp +++ b/layout/printing/nsPrintEngine.cpp @@ -503,11 +503,12 @@ nsPrintEngine::DoCommonPrint(PRBool aIsPrintPreview, if (aIsPrintPreview) { SetIsCreatingPrintPreview(PR_TRUE); SetIsPrintPreview(PR_TRUE); - nsCOMPtr viewer = + nsCOMPtr viewer = do_QueryInterface(mDocViewerPrint); if (viewer) { viewer->SetTextZoom(1.0f); viewer->SetFullZoom(1.0f); + viewer->SetMinFontSize(0); } } else { SetIsPrinting(PR_TRUE); diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index c6c84b2540e..c975633a17f 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -2175,8 +2175,7 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex { nsStyleFont* fontData = new (mPresContext) nsStyleFont(mPresContext); if (NS_LIKELY(fontData != nsnull)) { - nscoord minimumFontSize = - mPresContext->GetCachedIntPref(kPresContext_MinimumFontSize); + nscoord minimumFontSize = mPresContext->MinFontSize(); if (minimumFontSize > 0 && !mPresContext->IsChrome()) { fontData->mFont.size = NS_MAX(fontData->mSize, minimumFontSize); @@ -3275,8 +3274,7 @@ nsRuleNode::ComputeFontData(void* aStartStruct, // using the 'font' shorthand). // See if there is a minimum font-size constraint to honor - nscoord minimumFontSize = - mPresContext->GetCachedIntPref(kPresContext_MinimumFontSize); + nscoord minimumFontSize = mPresContext->MinFontSize(); if (minimumFontSize < 0) minimumFontSize = 0; @@ -3497,8 +3495,7 @@ nsRuleNode::ComputeTextData(void* aStartStruct, !textData.mLineHeight.IsRelativeLengthUnit()) { nscoord lh = nsStyleFont::ZoomText(mPresContext, text->mLineHeight.GetCoordValue()); - nscoord minimumFontSize = - mPresContext->GetCachedIntPref(kPresContext_MinimumFontSize); + nscoord minimumFontSize = mPresContext->MinFontSize(); if (minimumFontSize > 0 && !mPresContext->IsChrome()) { // If we applied a minimum font size, scale the line height by From c3286ccfb574cbfec5c4d16112196259025369bf Mon Sep 17 00:00:00 2001 From: Brian Crowder Date: Fri, 25 Feb 2011 16:31:00 -0800 Subject: [PATCH 02/15] Bug 636903 - reduces ALOG noise while debug. android only. r/a=dougt --HG-- extra : rebase_source : b2ae41c9fffaaa8f5a5222f7f0f156a21f51966c --- widget/src/android/nsWindow.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/widget/src/android/nsWindow.cpp b/widget/src/android/nsWindow.cpp index 453fcf8e726..933105eccde 100644 --- a/widget/src/android/nsWindow.cpp +++ b/widget/src/android/nsWindow.cpp @@ -523,7 +523,6 @@ NS_IMETHODIMP nsWindow::Invalidate(const nsIntRect &aRect, PRBool aIsSynchronous) { - ALOG("nsWindow::Invalidate %p [%d %d %d %d]", (void*) this, aRect.x, aRect.y, aRect.width, aRect.height); nsAppShell::gAppShell->PostEvent(new AndroidGeckoEvent(-1, -1, -1, -1)); return NS_OK; } @@ -901,8 +900,6 @@ nsWindow::DrawTo(gfxASurface *targetSurface) // If we have no covering child, then we need to render this. if (coveringChildIndex == -1) { - ALOG("nsWindow[%p]::DrawTo no covering child, drawing this", (void*) this); - nsPaintEvent event(PR_TRUE, NS_PAINT, this); event.region = boundsRect; switch (GetLayerManager(nsnull)->GetBackendType()) { @@ -950,7 +947,6 @@ nsWindow::DrawTo(gfxASurface *targetSurface) offset = targetSurface->GetDeviceOffset(); for (PRUint32 i = coveringChildIndex; i < mChildren.Length(); ++i) { - ALOG("nsWindow[%p]::DrawTo child[%d]", (void*) this, i); if (mChildren[i]->mBounds.IsEmpty() || !mChildren[i]->mBounds.Intersects(boundsRect)) { continue; @@ -970,16 +966,12 @@ nsWindow::DrawTo(gfxASurface *targetSurface) if (targetSurface) targetSurface->SetDeviceOffset(offset); - ALOG("nsWindow[%p]::DrawTo done", (void*) this); - return PR_TRUE; } void nsWindow::OnDraw(AndroidGeckoEvent *ae) { - ALOG(">> OnDraw"); - if (!IsTopLevel()) { ALOG("##### redraw for window %p, which is not a toplevel window -- sending to toplevel!", (void*) this); DumpWindows(); From bb2cc6d8a72092fa705421e09f942bd80d6b5790 Mon Sep 17 00:00:00 2001 From: Doug Turner Date: Thu, 10 Mar 2011 19:52:50 -0800 Subject: [PATCH 03/15] Bug 640068 - Browser does not restart when installing extensions. This approach uses ps instead of hitting the proc file system. r=blassey a=blocking-fennec --HG-- extra : rebase_source : c84c47ce792de31e7c6bc2f0a19b06beb4e0c183 --- embedding/android/GeckoAppShell.java | 93 +++++++++++++++++++++------- embedding/android/Restarter.java.in | 11 +++- 2 files changed, 81 insertions(+), 23 deletions(-) diff --git a/embedding/android/GeckoAppShell.java b/embedding/android/GeckoAppShell.java index 8b8a8ee86df..4364e820bc6 100644 --- a/embedding/android/GeckoAppShell.java +++ b/embedding/android/GeckoAppShell.java @@ -962,37 +962,86 @@ public class GeckoAppShell } public static void killAnyZombies() { - File proc = new File("/proc"); - File[] files = proc.listFiles(); - for (int i = 0; i < files.length; i++) { - File p = files[i]; - File pEnv = new File(p, "environ"); - if (pEnv.canRead() && !p.getName().equals("self")) { - int pid = Integer.parseInt(p.getName()); - if (pid != android.os.Process.myPid()) { - Log.i("GeckoProcs", "gonna kill pid: " + p.getName()); + GeckoProcessesVisitor visitor = new GeckoProcessesVisitor() { + public boolean callback(int pid) { + if (pid != android.os.Process.myPid()) android.os.Process.killProcess(pid); - } + return true; } - } + }; + + EnumerateGeckoProcesses(visitor); } public static boolean checkForGeckoProcs() { - File proc = new File("/proc"); - File[] files = proc.listFiles(); - for (int i = 0; i < files.length; i++) { - File p = files[i]; - File pEnv = new File(p, "environ"); - if (pEnv.canRead() && !p.getName().equals("self")) { - int pid = Integer.parseInt(p.getName()); + + class GeckoPidCallback implements GeckoProcessesVisitor { + public boolean otherPidExist = false; + public boolean callback(int pid) { if (pid != android.os.Process.myPid()) { - Log.i("GeckoProcs", "found pid: " + p.getName()); - return true; + otherPidExist = true; + return false; + } + return true; + } + } + GeckoPidCallback visitor = new GeckoPidCallback(); + EnumerateGeckoProcesses(visitor); + return visitor.otherPidExist; + } + + interface GeckoProcessesVisitor{ + boolean callback(int pid); + } + + static int sPidColumn = -1; + static int sUserColumn = -1; + private static void EnumerateGeckoProcesses(GeckoProcessesVisitor visiter) { + + try { + + // run ps and parse its output + java.lang.Process ps = Runtime.getRuntime().exec("ps"); + BufferedReader in = new BufferedReader(new InputStreamReader(ps.getInputStream()), + 2048); + + String headerOutput = in.readLine(); + + // figure out the column offsets. We only care about the pid and user fields + if (sPidColumn == -1 || sUserColumn == -1) { + StringTokenizer st = new StringTokenizer(headerOutput); + + int tokenSoFar = 0; + while(st.hasMoreTokens()) { + String next = st.nextToken(); + if (next.equalsIgnoreCase("PID")) + sPidColumn = tokenSoFar; + else if (next.equalsIgnoreCase("USER")) + sUserColumn = tokenSoFar; + tokenSoFar++; } } + + // alright, the rest are process entries. + String psOutput = null; + while ((psOutput = in.readLine()) != null) { + String[] split = psOutput.split("\\s+"); + if (split.length <= sPidColumn || split.length <= sUserColumn) + continue; + int uid = android.os.Process.getUidForName(split[sUserColumn]); + if (uid == android.os.Process.myUid() && + !split[split.length - 1].equalsIgnoreCase("ps")) { + int pid = Integer.parseInt(split[sPidColumn]); + boolean keepGoing = visiter.callback(pid); + if (keepGoing == false) + break; + } + } + in.close(); + } + catch (Exception e) { + Log.i("GeckoAppShell", "finding procs throws ", e); } - Log.i("GeckoProcs", "didn't find any other procs"); - return false; } public static void waitForAnotherGeckoProc(){ diff --git a/embedding/android/Restarter.java.in b/embedding/android/Restarter.java.in index 2c09bb2356c..b7d9b1d660e 100644 --- a/embedding/android/Restarter.java.in +++ b/embedding/android/Restarter.java.in @@ -59,8 +59,17 @@ public class Restarter extends Activity { } catch (InterruptedException ie) {} } - if (countdown <= 0) // if the countdown expired, something is hung + if (countdown <= 0) { + // if the countdown expired, something is hung GeckoAppShell.killAnyZombies(); + countdown = 10; + // wait for the kill to take effect + while (GeckoAppShell.checkForGeckoProcs() && --countdown > 0) { + try { + Thread.currentThread().sleep(100); + } catch (InterruptedException ie) {} + } + } } catch (Exception e) { Log.i("Restarter", e.toString()); } From 47b89f43e81a2b3c4d7fd491acec88ffd835f3bf Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Fri, 11 Mar 2011 01:04:44 -0500 Subject: [PATCH 04/15] Bug 640652 - When unsetting an attribute on a XUL element, don't let the script blocker to be removed when the document nested update count is 0, since that can trigger XBL bindings, which may run scripts to do things which would lead into crashes; r=sicking a=sayrer --HG-- extra : rebase_source : e79c187d59225cbc432db5b4b1629d78075477b6 --- content/xul/content/src/nsXULElement.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/content/xul/content/src/nsXULElement.cpp b/content/xul/content/src/nsXULElement.cpp index dd40b5348a5..cc32ab7d53f 100644 --- a/content/xul/content/src/nsXULElement.cpp +++ b/content/xul/content/src/nsXULElement.cpp @@ -1341,7 +1341,8 @@ nsXULElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNotify) NS_ENSURE_SUCCESS(rv, rv); } - nsAutoRemovableScriptBlocker scriptBlocker; + nsIDocument* doc = GetCurrentDoc(); + mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, aNotify); PRBool isId = PR_FALSE; if (aName == nsGkAtoms::id && aNameSpaceID == kNameSpaceID_None) { @@ -1361,9 +1362,6 @@ nsXULElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNotify) nsAutoString oldValue; GetAttr(aNameSpaceID, aName, oldValue); - nsIDocument* doc = GetCurrentDoc(); - mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, aNotify); - // When notifying, make sure to keep track of states whose value // depends solely on the value of an attribute. nsEventStates stateMask; From c1f6326631842474421e131d7e3b510954b0e978 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Fri, 11 Mar 2011 01:58:29 -0600 Subject: [PATCH 05/15] Bug 637822: Translate invalidated content by the offset at which it was made valid. r=roc a=b --- layout/base/FrameLayerBuilder.cpp | 70 +++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index e3ab866dfe8..f46588d9363 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -108,6 +108,22 @@ static void DestroyRegion(void* aPropertyValue) */ NS_DECLARE_FRAME_PROPERTY(ThebesLayerInvalidRegionProperty, DestroyRegion) +static void DestroyPoint(void* aPropertyValue) +{ + delete static_cast(aPropertyValue); +} + +/** + * The valid content in our child ThebesLayers is defined relative to + * the offset from this frame to its active scroll root, mapped back + * by the ThebesLayer's inverse transform. Since we accumulate the + * region invalidated between last-paint and next-paint, and because + * the offset of this frame to its active root may change during that + * period, we save the offset at last-paint in this property and use + * it to invalidate at next-paint. + */ +NS_DECLARE_FRAME_PROPERTY(ThebesLayerLastPaintOffsetProperty, DestroyPoint) + /** * This is a helper object used to build up the layer children for * a ContainerLayer. @@ -533,6 +549,35 @@ FrameLayerBuilder::WillEndTransaction(LayerManager* aManager) "Some frame must have a layer!"); } +static void +SetHasContainerLayer(nsIFrame* aFrame, nsPoint aOffsetToRoot) +{ + aFrame->AddStateBits(NS_FRAME_HAS_CONTAINER_LAYER); + for (nsIFrame* f = aFrame; + f && !(f->GetStateBits() & NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT); + f = nsLayoutUtils::GetCrossDocParentFrame(f)) { + f->AddStateBits(NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT); + } + + FrameProperties props = aFrame->Properties(); + nsPoint* lastPaintOffset = static_cast + (props.Get(ThebesLayerLastPaintOffsetProperty())); + if (lastPaintOffset) { + *lastPaintOffset = aOffsetToRoot; + } else { + props.Set(ThebesLayerLastPaintOffsetProperty(), new nsPoint(aOffsetToRoot)); + } +} + +static void +SetNoContainerLayer(nsIFrame* aFrame) +{ + FrameProperties props = aFrame->Properties(); + props.Delete(ThebesLayerInvalidRegionProperty()); + props.Delete(ThebesLayerLastPaintOffsetProperty()); + aFrame->RemoveStateBits(NS_FRAME_HAS_CONTAINER_LAYER); +} + /* static */ PLDHashOperator FrameLayerBuilder::UpdateDisplayItemDataForFrame(nsPtrHashKey* aEntry, void* aUserArg) @@ -555,8 +600,7 @@ FrameLayerBuilder::UpdateDisplayItemDataForFrame(nsPtrHashKey* aEntry, // is DidEndTransaction, which would recreate the user data // anyway. InternalDestroyDisplayItemData(f, prop, PR_FALSE); - props.Delete(ThebesLayerInvalidRegionProperty()); - f->RemoveStateBits(NS_FRAME_HAS_CONTAINER_LAYER); + SetNoContainerLayer(f); return PL_DHASH_REMOVE; } @@ -573,8 +617,7 @@ FrameLayerBuilder::UpdateDisplayItemDataForFrame(nsPtrHashKey* aEntry, props.Set(ThebesLayerInvalidRegionProperty(), new nsRegion()); } } else { - props.Delete(ThebesLayerInvalidRegionProperty()); - f->RemoveStateBits(NS_FRAME_HAS_CONTAINER_LAYER); + SetNoContainerLayer(f); } // We need to remove and re-add the DisplayItemDataProperty in @@ -1505,17 +1548,6 @@ ContainerState::Finish(PRUint32* aTextContentFlags) *aTextContentFlags = textContentFlags; } -static void -SetHasContainerLayer(nsIFrame* aFrame) -{ - aFrame->AddStateBits(NS_FRAME_HAS_CONTAINER_LAYER); - for (nsIFrame* f = aFrame; - f && !(f->GetStateBits() & NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT); - f = nsLayoutUtils::GetCrossDocParentFrame(f)) { - f->AddStateBits(NS_FRAME_HAS_CONTAINER_LAYER_DESCENDANT); - } -} - already_AddRefed FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder, LayerManager* aManager, @@ -1566,10 +1598,14 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder, DisplayItemData(containerLayer, containerDisplayItemKey)); } + nsPoint* offsetAtLastPaint = static_cast + (props.Get(ThebesLayerLastPaintOffsetProperty())); + nsPoint currentOffset = aBuilder->ToReferenceFrame(aContainerFrame); + nsRegion* invalidThebesContent(static_cast (props.Get(ThebesLayerInvalidRegionProperty()))); if (invalidThebesContent) { - nsPoint offset = aBuilder->ToReferenceFrame(aContainerFrame); + nsPoint offset = offsetAtLastPaint ? *offsetAtLastPaint : currentOffset; invalidThebesContent->MoveBy(offset); state.SetInvalidThebesContent(invalidThebesContent-> ToOutsidePixels(appUnitsPerDevPixel)); @@ -1583,7 +1619,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder, // invalidated. state.SetInvalidateAllThebesContent(); } - SetHasContainerLayer(aContainerFrame); + SetHasContainerLayer(aContainerFrame, currentOffset); } Clip clip; From 368d8a0909da84001a571f8bab9ecd3f6b467b6d Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Fri, 11 Mar 2011 09:15:33 -0500 Subject: [PATCH 06/15] Bug 637660 - add sandbox.Android, and skip a few crashtests so we can run green on Android. r=dbaron, a=tests --- content/media/test/crashtests/crashtests.list | 2 +- layout/generic/crashtests/crashtests.list | 2 +- layout/tools/reftest/reftest.js | 1 + layout/tools/reftest/remotereftest.py | 2 +- layout/tools/reftest/runreftest.py | 4 ++-- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/content/media/test/crashtests/crashtests.list b/content/media/test/crashtests/crashtests.list index a2077d02c5e..dfcfdc34046 100644 --- a/content/media/test/crashtests/crashtests.list +++ b/content/media/test/crashtests/crashtests.list @@ -5,6 +5,6 @@ load 468763-1.html load 474744-1.html HTTP load 481136-1.html # needs to be HTTP to recognize the ogg as an audio file? load 493915-1.html -load 495794-1.html +skip-if(Android) load 495794-1.html load 492286-1.xhtml load 576612-1.html diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list index f8a22445182..e4f161cb4e5 100644 --- a/layout/generic/crashtests/crashtests.list +++ b/layout/generic/crashtests/crashtests.list @@ -282,7 +282,7 @@ load 478170-1.html load 478185-1.html asserts(1) load 479938-1.html # Bug 575011 load 480345-1.html -load 481921.html +skip-if(Android) load 481921.html load 489462-1.html load 489480-1.xhtml load 493111-1.html diff --git a/layout/tools/reftest/reftest.js b/layout/tools/reftest/reftest.js index 2463913abd6..0e189785240 100644 --- a/layout/tools/reftest/reftest.js +++ b/layout/tools/reftest/reftest.js @@ -401,6 +401,7 @@ function BuildConditionSandbox(aURL) { sandbox.layersGPUAccelerated = false; // Shortcuts for widget toolkits. + sandbox.Android = xr.OS == "Android"; sandbox.cocoaWidget = xr.widgetToolkit == "cocoa"; sandbox.gtk2Widget = xr.widgetToolkit == "gtk2"; sandbox.qtWidget = xr.widgetToolkit == "qt"; diff --git a/layout/tools/reftest/remotereftest.py b/layout/tools/reftest/remotereftest.py index 32cdf12ba64..2e42eebf5ee 100644 --- a/layout/tools/reftest/remotereftest.py +++ b/layout/tools/reftest/remotereftest.py @@ -302,7 +302,7 @@ class RemoteReftest(RefTest): self.server.stop() def createReftestProfile(self, options, profileDir): - RefTest.createReftestProfile(self, options, profileDir) + RefTest.createReftestProfile(self, options, profileDir, server=options.remoteWebServer) if (self._devicemanager.pushDir(profileDir, options.remoteProfile) == None): raise devicemanager.FileError("Failed to copy profiledir to device") diff --git a/layout/tools/reftest/runreftest.py b/layout/tools/reftest/runreftest.py index b51761be7db..cc3266dde87 100644 --- a/layout/tools/reftest/runreftest.py +++ b/layout/tools/reftest/runreftest.py @@ -65,11 +65,11 @@ class RefTest(object): "Get the path of the manifest, and for remote testing this function is subclassed to point to remote manifest" return self.getFullPath(path) - def createReftestProfile(self, options, profileDir): + def createReftestProfile(self, options, profileDir, server='localhost'): "Sets up a profile for reftest." self.automation.setupPermissionsDatabase(profileDir, - {'allowXULXBL': [('localhost', True), ('', True)]}) + {'allowXULXBL': [(server, True), ('', True)]}) # Set preferences for communication between our command line arguments # and the reftest harness. Preferences that are required for reftest From 3028732566595fd2a247ed0e57b8014366940ca0 Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Fri, 11 Mar 2011 09:15:34 -0500 Subject: [PATCH 07/15] Bug 636641 - remote reftest needs better logic for automatically building the remote manifest. r=ctalbert, a=NPOTB --- layout/tools/reftest/remotereftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/tools/reftest/remotereftest.py b/layout/tools/reftest/remotereftest.py index 2e42eebf5ee..abb225489c3 100644 --- a/layout/tools/reftest/remotereftest.py +++ b/layout/tools/reftest/remotereftest.py @@ -375,7 +375,7 @@ def main(): reftest.startWebServer(options) # Hack in a symbolic link for jsreftest - os.system("ln -s ../jsreftest jsreftest") + os.system("ln -s ../jsreftest " + str(os.path.join(SCRIPT_DIRECTORY, "jsreftest"))) # Dynamically build the reftest URL if possible, beware that args[0] should exist 'inside' the webroot manifest = args[0] From 457e664cbe0b62af27ca8d37c8ea003802fce36f Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Fri, 11 Mar 2011 09:15:36 -0500 Subject: [PATCH 08/15] Bug 639678 - annotate manifests to see green jsreftest runs on tinderbox. r=blassey, a=tests --- js/src/tests/ecma/Date/jstests.list | 6 +++--- js/src/tests/ecma/LexicalConventions/jstests.list | 10 +++++----- js/src/tests/ecma_2/Exceptions/jstests.list | 8 ++++---- js/src/tests/ecma_2/LexicalConventions/jstests.list | 2 +- js/src/tests/ecma_3/Object/jstests.list | 2 +- js/src/tests/ecma_5/extensions/jstests.list | 2 +- js/src/tests/js1_5/Exceptions/jstests.list | 2 +- js/src/tests/js1_5/Regress/jstests.list | 8 ++++---- js/src/tests/js1_5/extensions/jstests.list | 6 +++--- js/src/tests/js1_7/block/jstests.list | 2 +- js/src/tests/js1_8_1/extensions/jstests.list | 2 +- js/src/tests/js1_8_1/strict/jstests.list | 8 ++++---- 12 files changed, 29 insertions(+), 29 deletions(-) diff --git a/js/src/tests/ecma/Date/jstests.list b/js/src/tests/ecma/Date/jstests.list index 6c87e8ec940..c2fc5fcde04 100644 --- a/js/src/tests/ecma/Date/jstests.list +++ b/js/src/tests/ecma/Date/jstests.list @@ -119,8 +119,8 @@ script 15.9.5.24-8.js script 15.9.5.25-1.js script 15.9.5.26-1.js script 15.9.5.27-1.js -script 15.9.5.28-1.js -script 15.9.5.29-1.js +fails-if(Android) script 15.9.5.28-1.js +fails-if(Android) script 15.9.5.29-1.js script 15.9.5.3-1-n.js script 15.9.5.3-2.js script 15.9.5.30-1.js @@ -128,7 +128,7 @@ script 15.9.5.31-1.js script 15.9.5.32-1.js script 15.9.5.33-1.js random-if(xulRuntime.OS=="Linux") script 15.9.5.34-1.js -script 15.9.5.35-1.js +fails-if(Android) script 15.9.5.35-1.js script 15.9.5.36-1.js script 15.9.5.36-2.js script 15.9.5.36-3.js diff --git a/js/src/tests/ecma/LexicalConventions/jstests.list b/js/src/tests/ecma/LexicalConventions/jstests.list index e0c82fb7bd4..6f39accdf4a 100644 --- a/js/src/tests/ecma/LexicalConventions/jstests.list +++ b/js/src/tests/ecma/LexicalConventions/jstests.list @@ -45,17 +45,17 @@ script 7.4.3-10-n.js script 7.4.3-11-n.js script 7.4.3-12-n.js script 7.4.3-13-n.js -script 7.4.3-14-n.js -script 7.4.3-15-n.js +fails-if(Android) script 7.4.3-14-n.js +fails-if(Android) script 7.4.3-15-n.js script 7.4.3-16-n.js script 7.4.3-2-n.js skip script 7.4.3-3-n.js # obsolete test -script 7.4.3-4-n.js +fails-if(Android) script 7.4.3-4-n.js script 7.4.3-5-n.js script 7.4.3-6-n.js -script 7.4.3-7-n.js +fails-if(Android) script 7.4.3-7-n.js script 7.4.3-8-n.js -script 7.4.3-9-n.js +fails-if(Android) script 7.4.3-9-n.js script 7.5-1.js script 7.5-10-n.js script 7.5-2-n.js diff --git a/js/src/tests/ecma_2/Exceptions/jstests.list b/js/src/tests/ecma_2/Exceptions/jstests.list index 28526df278c..9e350f7eeb6 100644 --- a/js/src/tests/ecma_2/Exceptions/jstests.list +++ b/js/src/tests/ecma_2/Exceptions/jstests.list @@ -47,17 +47,17 @@ script lexical-007.js script lexical-008.js script lexical-009.js skip script lexical-010.js # obsolete test -script lexical-011.js +fails-if(Android) script lexical-011.js script lexical-012.js script lexical-013.js -script lexical-014.js +fails-if(Android) script lexical-014.js script lexical-015.js -script lexical-016.js +fails-if(Android) script lexical-016.js script lexical-017.js script lexical-018.js script lexical-019.js script lexical-020.js -script lexical-021.js +fails-if(Android) script lexical-021.js skip script lexical-022.js # obsolete test script lexical-023.js script lexical-024.js diff --git a/js/src/tests/ecma_2/LexicalConventions/jstests.list b/js/src/tests/ecma_2/LexicalConventions/jstests.list index 5aa5e95911e..eca08c59497 100644 --- a/js/src/tests/ecma_2/LexicalConventions/jstests.list +++ b/js/src/tests/ecma_2/LexicalConventions/jstests.list @@ -1,4 +1,4 @@ url-prefix ../../jsreftest.html?test=ecma_2/LexicalConventions/ -script keywords-001.js +fails-if(Android) script keywords-001.js script regexp-literals-001.js script regexp-literals-002.js diff --git a/js/src/tests/ecma_3/Object/jstests.list b/js/src/tests/ecma_3/Object/jstests.list index 98555c0c9f1..94ec868b61e 100644 --- a/js/src/tests/ecma_3/Object/jstests.list +++ b/js/src/tests/ecma_3/Object/jstests.list @@ -1,5 +1,5 @@ url-prefix ../../jsreftest.html?test=ecma_3/Object/ -script 8.6.1-01.js +fails-if(Android) script 8.6.1-01.js script 8.6.2.6-001.js fails script 8.6.2.6-002.js script class-001.js diff --git a/js/src/tests/ecma_5/extensions/jstests.list b/js/src/tests/ecma_5/extensions/jstests.list index 962f4ee9907..71f99d7b0cd 100644 --- a/js/src/tests/ecma_5/extensions/jstests.list +++ b/js/src/tests/ecma_5/extensions/jstests.list @@ -1,5 +1,5 @@ url-prefix ../../jsreftest.html?test=ecma_5/extensions/ -script 8.12.5-01.js +fails-if(Android) script 8.12.5-01.js script 15.4.4.11.js script Boolean-toSource.js script Number-toSource.js diff --git a/js/src/tests/js1_5/Exceptions/jstests.list b/js/src/tests/js1_5/Exceptions/jstests.list index f2881be3ece..da97baee101 100644 --- a/js/src/tests/js1_5/Exceptions/jstests.list +++ b/js/src/tests/js1_5/Exceptions/jstests.list @@ -7,7 +7,7 @@ script regress-123002.js script regress-232182.js script regress-257751.js script regress-273931.js -script regress-315147.js +fails-if(Android) script regress-315147.js script regress-332472.js script regress-333728.js script regress-342359.js diff --git a/js/src/tests/js1_5/Regress/jstests.list b/js/src/tests/js1_5/Regress/jstests.list index 2c204d4f62e..f3c92f9dd85 100644 --- a/js/src/tests/js1_5/Regress/jstests.list +++ b/js/src/tests/js1_5/Regress/jstests.list @@ -114,7 +114,7 @@ script regress-295666.js script regress-299209.js script regress-299641.js skip-if(!xulRuntime.shell) script regress-303213.js # bug 524731 -script regress-306633.js +fails-if(Android) script regress-306633.js script regress-306727.js script regress-306794.js script regress-308085.js @@ -134,7 +134,7 @@ skip-if(xulRuntime.OS=="WINNT"&&isDebugBuild) slow script regress-314401.js script regress-315974.js script regress-315990.js script regress-317476.js -script regress-317533.js +fails-if(Android) script regress-317533.js script regress-317714-01.js script regress-317714-02.js script regress-319384.js @@ -145,7 +145,7 @@ script regress-321757.js script regress-321874.js script regress-321971.js script regress-322430.js -script regress-323314-1.js +fails-if(Android) script regress-323314-1.js script regress-325925.js script regress-326453.js script regress-326467.js @@ -187,7 +187,7 @@ skip script regress-350692.js # obsolete test skip-if(xulRuntime.OS=="Linux"&&!xulRuntime.shell&&!xulRuntime.XPCOMABI.match(/x86_64/)&&isDebugBuild) script regress-351116.js # bug 521549 script regress-351515.js script regress-352009.js -script regress-352197.js +fails-if(Android) script regress-352197.js script regress-352208.js script regress-352604.js skip script regress-354924.js # obsolete test diff --git a/js/src/tests/js1_5/extensions/jstests.list b/js/src/tests/js1_5/extensions/jstests.list index d9935843512..3816c033c53 100644 --- a/js/src/tests/js1_5/extensions/jstests.list +++ b/js/src/tests/js1_5/extensions/jstests.list @@ -108,7 +108,7 @@ random script regress-363258.js # bug 524788 script regress-363988.js slow script regress-365527.js script regress-365692.js -script regress-365869.js +fails-if(Android) script regress-365869.js script regress-366288.js script regress-366292.js script regress-366396.js @@ -125,7 +125,7 @@ script regress-367501-03.js script regress-367501-04.js skip-if(xulRuntime.OS=="WINNT"&&isDebugBuild) slow script regress-367589.js script regress-367630.js -script regress-367923.js +fails-if(Android) script regress-367923.js script regress-368859.js script regress-369404.js script regress-369696-01.js @@ -220,6 +220,6 @@ script regress-90596-002.js script regress-96284-001.js script regress-96284-002.js script scope-001.js -script toLocaleFormat-01.js +fails-if(Android) script toLocaleFormat-01.js fails-if(xulRuntime.OS=="WINNT") script toLocaleFormat-02.js script regress-543839.js diff --git a/js/src/tests/js1_7/block/jstests.list b/js/src/tests/js1_7/block/jstests.list index a7054deb132..5bfcf404ed6 100644 --- a/js/src/tests/js1_7/block/jstests.list +++ b/js/src/tests/js1_7/block/jstests.list @@ -7,7 +7,7 @@ script regress-344262.js script regress-344370.js script regress-344601.js script regress-345542.js -script regress-347559.js +fails-if(Android) script regress-347559.js script regress-348685.js script regress-349283.js script regress-349298.js diff --git a/js/src/tests/js1_8_1/extensions/jstests.list b/js/src/tests/js1_8_1/extensions/jstests.list index 8610b773b2f..99180a72c2c 100644 --- a/js/src/tests/js1_8_1/extensions/jstests.list +++ b/js/src/tests/js1_8_1/extensions/jstests.list @@ -12,4 +12,4 @@ script regress-477158.js script regress-477187.js script regress-520572.js script new-parenthesization.js -script strict-warning.js +fails-if(Android) script strict-warning.js diff --git a/js/src/tests/js1_8_1/strict/jstests.list b/js/src/tests/js1_8_1/strict/jstests.list index 9fed2da9ac0..1e6e5128099 100644 --- a/js/src/tests/js1_8_1/strict/jstests.list +++ b/js/src/tests/js1_8_1/strict/jstests.list @@ -1,5 +1,5 @@ url-prefix ../../jsreftest.html?test=js1_8_1/strict/ -script 8.7.2.js -script 12.2.1.js -script generator-eval-arguments.js -script let-block-eval-arguments.js +fails-if(Android) script 8.7.2.js +fails-if(Android) script 12.2.1.js +fails-if(Android) script generator-eval-arguments.js +fails-if(Android) script let-block-eval-arguments.js From 6277b5a31b4a8b9d356b07b97085ea7ba4352e24 Mon Sep 17 00:00:00 2001 From: Brad Lassey Date: Fri, 11 Mar 2011 17:03:39 -0500 Subject: [PATCH 09/15] bug 616426 - crash [@ nsThebesFontMetrics::GetMetrics ], follow up r=dougt a=blocking-fennec --- gfx/thebes/gfxAndroidPlatform.cpp | 22 +++++++++++++--------- gfx/thebes/gfxAndroidPlatform.h | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/gfx/thebes/gfxAndroidPlatform.cpp b/gfx/thebes/gfxAndroidPlatform.cpp index 60979ac664f..a3935033e39 100644 --- a/gfx/thebes/gfxAndroidPlatform.cpp +++ b/gfx/thebes/gfxAndroidPlatform.cpp @@ -418,23 +418,24 @@ gfxAndroidPlatform::AppendFacesFromFontFile(const char *aFileName, FontNameCache } void -gfxAndroidPlatform::FindFontsInDirectory(const char *aDirectory, FontNameCache* aFontCache) +gfxAndroidPlatform::FindFontsInDirectory(nsCString aFontsDir, + FontNameCache* aFontCache) { - DIR *d = opendir(aDirectory); + DIR *d = opendir(aFontsDir.get()); struct dirent *ent = NULL; while(d && (ent = readdir(d)) != NULL) { int namelen = strlen(ent->d_name); if (namelen > 4 && strcasecmp(ent->d_name + namelen - 4, ".ttf") == 0) { - nsCString s(aDirectory); - s.Append("/fonts/"); + nsCString s(aFontsDir); s.Append(nsDependentCString(ent->d_name)); AppendFacesFromFontFile(nsPromiseFlatCString(s).get(), aFontCache, &mFontList); } } + closedir(d); } void @@ -452,13 +453,16 @@ gfxAndroidPlatform::GetFontList(InfallibleTArray* retValue) return; } - // Check in both /system and $ANDROID_ROOT + // ANDROID_ROOT is the root of the android system, typically /system + // font files are in /$ANDROID_ROOT/fonts/ FontNameCache fnc; - const char *systemDirectory = "/system"; - FindFontsInDirectory(systemDirectory, &fnc); + FindFontsInDirectory(NS_LITERAL_CSTRING("/system/fonts/"), &fnc); char *androidRoot = PR_GetEnv("ANDROID_ROOT"); - if (androidRoot && strcmp(androidRoot, systemDirectory)) - FindFontsInDirectory(androidRoot, &fnc); + if (androidRoot && strcmp(androidRoot, "/system")) { + nsCString root(androidRoot); + root.Append("/fonts/"); + FindFontsInDirectory(root, &fnc); + } *retValue = mFontList; } diff --git a/gfx/thebes/gfxAndroidPlatform.h b/gfx/thebes/gfxAndroidPlatform.h index f9d5ed2ca4d..ecc344632b0 100644 --- a/gfx/thebes/gfxAndroidPlatform.h +++ b/gfx/thebes/gfxAndroidPlatform.h @@ -107,7 +107,7 @@ public: protected: void AppendFacesFromFontFile(const char *aFileName, FontNameCache* aFontCache, InfallibleTArray* retValue); - void FindFontsInDirectory(const char *aDirectory, FontNameCache* aFontCache); + void FindFontsInDirectory(nsCString aFontsDir, FontNameCache* aFontCache); typedef nsDataHashtable > FontTable; From e4ac9c5928d9e9e6148b3342e43e7e19c2a86941 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Fri, 11 Mar 2011 17:12:11 -0600 Subject: [PATCH 10/15] Bug 593243: Clip invalidations to the displayport when one is set. r=tn --- layout/base/nsPresShell.cpp | 20 +++++--------------- layout/generic/nsGfxScrollFrame.cpp | 20 ++++++++++++++++++-- view/public/nsIView.h | 11 +++++++++++ view/src/nsView.cpp | 13 +++++++++++++ view/src/nsView.h | 13 +++++++++++++ view/src/nsViewManager.cpp | 4 ++-- 6 files changed, 62 insertions(+), 19 deletions(-) diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index e2e0c3157cd..388f87e938d 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6062,21 +6062,11 @@ void PresShell::SetRenderingState(const RenderingState& aState) mXResolution = aState.mXResolution; mYResolution = aState.mYResolution; - // FIXME (Bug 593243 should fix this.) - // - // Invalidated content does not pay any attention to the displayport, so - // invalidating the subdocument's root frame could end up not repainting - // visible content. - // - // For instance, imagine the iframe is located at y=1000. Even though the - // displayport may intersect the iframe's viewport, the visual overflow - // rect of the root content could be (0, 0, 800, 500). Since the dirty region - // does not intersect the visible overflow rect, the display list for the - // iframe will not even be generated. - // - // Here, we find the very top presShell and use its root frame for - // invalidation instead. - // + nsIView* rootView; + if (NS_SUCCEEDED(mViewManager->GetRootView(rootView)) && rootView) { + rootView->SetInvalidationDimensions(&mDisplayPort); + } + nsPresContext* rootPresContext = mPresContext->GetRootPresContext(); if (rootPresContext) { nsIPresShell* rootPresShell = rootPresContext->GetPresShell(); diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 602db5fdbce..edd2efe8d47 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -195,7 +195,15 @@ nsHTMLScrollFrame::InvalidateInternal(const nsRect& aDamageRect, nsRect damage = aDamageRect + nsPoint(aX, aY); // This is the damage rect that we're going to pass up to our parent. nsRect parentDamage; - parentDamage.IntersectRect(damage, mInner.mScrollPort); + nsIPresShell* presShell = PresContext()->PresShell(); + // If we're using a displayport, we might be displaying an area + // different than our scroll port and the damage needs to be + // clipped to that instead. + if (mInner.mIsRoot && presShell->UsingDisplayPort()) { + parentDamage.IntersectRect(damage, presShell->GetDisplayPort()); + } else { + parentDamage.IntersectRect(damage, mInner.mScrollPort); + } if (IsScrollingActive()) { // This is the damage rect that we're going to pass up and @@ -1104,7 +1112,15 @@ nsXULScrollFrame::InvalidateInternal(const nsRect& aDamageRect, nsRect damage = aDamageRect + nsPoint(aX, aY); // This is the damage rect that we're going to pass up to our parent. nsRect parentDamage; - parentDamage.IntersectRect(damage, mInner.mScrollPort); + nsIPresShell* presShell = PresContext()->PresShell(); + // If we're using a displayport, we might be displaying an area + // different than our scroll port and the damage needs to be + // clipped to that instead. + if (mInner.mIsRoot && presShell->UsingDisplayPort()) { + parentDamage.IntersectRect(damage, presShell->GetDisplayPort()); + } else { + parentDamage.IntersectRect(damage, mInner.mScrollPort); + } if (IsScrollingActive()) { // This is the damage rect that we're going to pass up and diff --git a/view/public/nsIView.h b/view/public/nsIView.h index f9272b66a19..6357b8e1030 100644 --- a/view/public/nsIView.h +++ b/view/public/nsIView.h @@ -173,6 +173,17 @@ public: */ nsRect GetBounds() const { return mDimBounds; } + /** + * Set the dimensions at which invalidations are clipped, which can + * be different than |GetDimensions()|. |aRect| is relative to + * |this|. It can be null, in which case invalidations return to + * being clipped to the view dimensions. + * + * The caller is responsible for invalidating the area that may lie + * outside the view dimensions but inside |aRect| after this call. + */ + void SetInvalidationDimensions(const nsRect* aRect); + /** * Get the offset between the coordinate systems of |this| and aOther. * Adding the return value to a point in the coordinate system of |this| diff --git a/view/src/nsView.cpp b/view/src/nsView.cpp index a51a88c46fd..bbd417c3a99 100644 --- a/view/src/nsView.cpp +++ b/view/src/nsView.cpp @@ -209,6 +209,7 @@ nsView::nsView(nsViewManager* aViewManager, nsViewVisibility aVisibility) mViewManager = aViewManager; mDirtyRegion = nsnull; mDeletionObserver = nsnull; + mHaveInvalidationDimensions = PR_FALSE; mWidgetIsTopLevel = PR_FALSE; } @@ -350,6 +351,11 @@ void nsView::SetPosition(nscoord aX, nscoord aY) ResetWidgetBounds(PR_TRUE, PR_TRUE, PR_FALSE); } +void nsIView::SetInvalidationDimensions(const nsRect* aRect) +{ + return Impl()->SetInvalidationDimensions(aRect); +} + void nsView::SetPositionIgnoringChildWidgets(nscoord aX, nscoord aY) { mDimBounds.x += aX - mPosX; @@ -495,6 +501,13 @@ void nsView::SetDimensions(const nsRect& aRect, PRBool aPaint, PRBool aResizeWid } } +void nsView::SetInvalidationDimensions(const nsRect* aRect) +{ + if ((mHaveInvalidationDimensions = !!aRect)) { + mInvalidationDimensions = *aRect; + } +} + void nsView::NotifyEffectiveVisibilityChanged(PRBool aEffectivelyVisible) { if (!aEffectivelyVisible) diff --git a/view/src/nsView.h b/view/src/nsView.h index e808ee11634..51c983041d8 100644 --- a/view/src/nsView.h +++ b/view/src/nsView.h @@ -76,6 +76,7 @@ public: */ virtual void SetDimensions(const nsRect &aRect, PRBool aPaint = PR_TRUE, PRBool aResizeWidget = PR_TRUE); + void SetInvalidationDimensions(const nsRect* aRect); void GetDimensions(nsRect &aRect) const { aRect = mDimBounds; aRect.x -= mPosX; aRect.y -= mPosY; } void GetDimensions(nsSize &aSize) const { aSize.width = mDimBounds.width; aSize.height = mDimBounds.height; } @@ -148,6 +149,11 @@ public: nsRect GetDimensions() const { nsRect r = mDimBounds; r.MoveBy(-mPosX, -mPosY); return r; } // Same as GetBounds but converts to parent appunits if they are different. nsRect GetBoundsInParentUnits() const; + + nsRect GetInvalidationDimensions() const { + return mHaveInvalidationDimensions ? mInvalidationDimensions : GetDimensions(); + } + // These are defined exactly the same in nsIView, but for now they have to be redeclared // here because of stupid C++ method hiding rules @@ -202,6 +208,13 @@ protected: void DoResetWidgetBounds(PRBool aMoveOnly, PRBool aInvalidateChangedSize); nsRegion* mDirtyRegion; + // invalidations are clipped to mInvalidationDimensions, not + // GetDimensions(), when mHaveInvalidationDimensions is true. This + // is used to support persistent "displayport" rendering; see + // nsPresShell.cpp. The coordinates of mInvalidationDimensions are + // relative to |this|. + nsRect mInvalidationDimensions; + PRPackedBool mHaveInvalidationDimensions; private: void InitializeWindow(PRBool aEnableDragDrop, PRBool aResetVisibility); diff --git a/view/src/nsViewManager.cpp b/view/src/nsViewManager.cpp index 79ed1dacc51..91e018bd84f 100644 --- a/view/src/nsViewManager.cpp +++ b/view/src/nsViewManager.cpp @@ -571,7 +571,7 @@ nsViewManager::UpdateWidgetArea(nsView *aWidgetView, nsIWidget* aWidget, // If the bounds don't overlap at all, there's nothing to do nsRegion intersection; - intersection.And(aWidgetView->GetDimensions(), aDamagedRegion); + intersection.And(aWidgetView->GetInvalidationDimensions(), aDamagedRegion); if (intersection.IsEmpty()) { return; } @@ -1623,7 +1623,7 @@ nsIntRect nsViewManager::ViewToWidget(nsView *aView, const nsRect &aRect) const NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager"); // intersect aRect with bounds of aView, to prevent generating any illegal rectangles. - nsRect bounds = aView->GetDimensions(); + nsRect bounds = aView->GetInvalidationDimensions(); nsRect rect; rect.IntersectRect(aRect, bounds); From 089d97753458b923c5d1cbd1aa9756432d46e924 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Fri, 11 Mar 2011 17:12:11 -0600 Subject: [PATCH 11/15] Tests for bug 593243. a=b --- layout/reftests/bugs/593243-1-ref.html | 17 +++++++++ layout/reftests/bugs/593243-1.html | 48 ++++++++++++++++++++++++++ layout/reftests/bugs/593243-2-ref.html | 18 ++++++++++ layout/reftests/bugs/593243-2.html | 48 ++++++++++++++++++++++++++ layout/reftests/bugs/reftest.list | 2 ++ 5 files changed, 133 insertions(+) create mode 100644 layout/reftests/bugs/593243-1-ref.html create mode 100644 layout/reftests/bugs/593243-1.html create mode 100644 layout/reftests/bugs/593243-2-ref.html create mode 100644 layout/reftests/bugs/593243-2.html diff --git a/layout/reftests/bugs/593243-1-ref.html b/layout/reftests/bugs/593243-1-ref.html new file mode 100644 index 00000000000..dd2106a688c --- /dev/null +++ b/layout/reftests/bugs/593243-1-ref.html @@ -0,0 +1,17 @@ + + + +
+
+
+
+
+ + diff --git a/layout/reftests/bugs/593243-1.html b/layout/reftests/bugs/593243-1.html new file mode 100644 index 00000000000..d6db92f97c5 --- /dev/null +++ b/layout/reftests/bugs/593243-1.html @@ -0,0 +1,48 @@ + + + + + + + + +
+
+
+
+
+ + diff --git a/layout/reftests/bugs/593243-2-ref.html b/layout/reftests/bugs/593243-2-ref.html new file mode 100644 index 00000000000..36d027b281b --- /dev/null +++ b/layout/reftests/bugs/593243-2-ref.html @@ -0,0 +1,18 @@ + + + +
+
+
+ +
+
+
+ + diff --git a/layout/reftests/bugs/593243-2.html b/layout/reftests/bugs/593243-2.html new file mode 100644 index 00000000000..9b0dcdb619a --- /dev/null +++ b/layout/reftests/bugs/593243-2.html @@ -0,0 +1,48 @@ + + + + + + + + +
+
+
+ +
+
+
+ + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 316bd4ba372..0b36a9d6d0e 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1563,6 +1563,8 @@ fails-if(cocoaWidget) == 586683-1.html 586683-1-ref.html == 589615-1a.xhtml 589615-1-ref.html == 589615-1b.html 589615-1-ref.html == 589672-1.html 589672-1-ref.html +skip-if(!browserIsRemote) == 593243-1.html 593243-1-ref.html # bug 593168 +skip-if(!browserIsRemote) == 593243-2.html 593243-2-ref.html # bug 593168 == 593544-1.html 593544-1-ref.html == 594333-1.html 594333-1-ref.html == 594624-1.html 594624-1-ref.html From 61c35070cee26a4f8f8faabca954f44bb2a4d577 Mon Sep 17 00:00:00 2001 From: Doug Turner Date: Fri, 11 Mar 2011 15:41:32 -0800 Subject: [PATCH 12/15] Bug 616426 - fix paramater type. r=blassey. a=me --- gfx/thebes/gfxAndroidPlatform.cpp | 2 +- gfx/thebes/gfxAndroidPlatform.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gfx/thebes/gfxAndroidPlatform.cpp b/gfx/thebes/gfxAndroidPlatform.cpp index a3935033e39..2cf61cdc291 100644 --- a/gfx/thebes/gfxAndroidPlatform.cpp +++ b/gfx/thebes/gfxAndroidPlatform.cpp @@ -418,7 +418,7 @@ gfxAndroidPlatform::AppendFacesFromFontFile(const char *aFileName, FontNameCache } void -gfxAndroidPlatform::FindFontsInDirectory(nsCString aFontsDir, +gfxAndroidPlatform::FindFontsInDirectory(const nsCString& aFontsDir, FontNameCache* aFontCache) { DIR *d = opendir(aFontsDir.get()); diff --git a/gfx/thebes/gfxAndroidPlatform.h b/gfx/thebes/gfxAndroidPlatform.h index ecc344632b0..4d49ed4a3b5 100644 --- a/gfx/thebes/gfxAndroidPlatform.h +++ b/gfx/thebes/gfxAndroidPlatform.h @@ -107,7 +107,7 @@ public: protected: void AppendFacesFromFontFile(const char *aFileName, FontNameCache* aFontCache, InfallibleTArray* retValue); - void FindFontsInDirectory(nsCString aFontsDir, FontNameCache* aFontCache); + void FindFontsInDirectory(const nsCString& aFontsDir, FontNameCache* aFontCache); typedef nsDataHashtable > FontTable; From 472417e27496c3d21f91d56d5d1406592974e542 Mon Sep 17 00:00:00 2001 From: Steven Michaud Date: Fri, 11 Mar 2011 17:50:50 -0600 Subject: [PATCH 13/15] Bug 637367 - Add null checks to nsPluginInstanceOwner::DoCocoaEventDrawRect(). r=bsmedberg a=sayrer --- layout/generic/nsObjectFrame.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index c26ea79fc5a..22f549b3b65 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -5857,6 +5857,9 @@ void nsPluginInstanceOwner::Paint(const gfxRect& aDirtyRect, CGContextRef cgCont void nsPluginInstanceOwner::DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGContextRef cgContext) { + if (!mInstance || !mObjectFrame) + return; + // The context given here is only valid during the HandleEvent call. NPCocoaEvent updateEvent; InitializeNPCocoaEvent(&updateEvent); From 7acd6a32ad93f96a6d7910d27e0ba183cb02e079 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Fri, 11 Mar 2011 21:22:38 -0500 Subject: [PATCH 14/15] Bug 639885 - Don't use named Windows kernel objects because they will cause conflicts when running multiple Firefox processes concurrently; r=jrmuizel a=stuart --- gfx/layers/d3d10/ReadbackManagerD3D10.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gfx/layers/d3d10/ReadbackManagerD3D10.cpp b/gfx/layers/d3d10/ReadbackManagerD3D10.cpp index 19b226354ab..b66946f3e77 100644 --- a/gfx/layers/d3d10/ReadbackManagerD3D10.cpp +++ b/gfx/layers/d3d10/ReadbackManagerD3D10.cpp @@ -139,8 +139,8 @@ ReadbackManagerD3D10::ReadbackManagerD3D10() : mRefCnt(0) { ::InitializeCriticalSection(&mTaskMutex); - mShutdownEvent = ::CreateEventA(NULL, FALSE, FALSE, "ReadbackShutdownEvent"); - mTaskSemaphore = ::CreateSemaphoreA(NULL, 0, 1000000, "ReadbackTaskSemaphore"); + mShutdownEvent = ::CreateEventA(NULL, FALSE, FALSE, NULL); + mTaskSemaphore = ::CreateSemaphoreA(NULL, 0, 1000000, NULL); mTaskThread = ::CreateThread(NULL, 0, StartTaskThread, this, 0, 0); } From ae4b79a620f88e69d2ce8aa06267acee62e8f03d Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Fri, 11 Mar 2011 23:22:39 -0600 Subject: [PATCH 15/15] Bug 640444: Self-copies end up changing all buffer content, so we need to read back the entire buffer after swapping. r=Bas a=b --- gfx/layers/ThebesLayerBuffer.cpp | 2 ++ gfx/layers/ThebesLayerBuffer.h | 4 +++- gfx/layers/basic/BasicLayers.cpp | 11 ++++++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/gfx/layers/ThebesLayerBuffer.cpp b/gfx/layers/ThebesLayerBuffer.cpp index 5492d19c913..0d2480b6462 100644 --- a/gfx/layers/ThebesLayerBuffer.cpp +++ b/gfx/layers/ThebesLayerBuffer.cpp @@ -222,6 +222,7 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType, PRUint32 aFlags) { PaintState result; + result.mDidSelfCopy = PR_FALSE; float curXRes = aLayer->GetXResolution(); float curYRes = aLayer->GetYResolution(); @@ -336,6 +337,7 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType, nsIntRect srcRect(nsIntPoint(0, 0), mBufferRect.Size()); nsIntPoint dest = mBufferRect.TopLeft() - destBufferRect.TopLeft(); MovePixels(mBuffer, srcRect, dest, curXRes, curYRes); + result.mDidSelfCopy = PR_TRUE; // Don't set destBuffer; we special-case self-copies, and // just did the necessary work above. mBufferRect = destBufferRect; diff --git a/gfx/layers/ThebesLayerBuffer.h b/gfx/layers/ThebesLayerBuffer.h index 879eca6de7f..dff6bb37a41 100644 --- a/gfx/layers/ThebesLayerBuffer.h +++ b/gfx/layers/ThebesLayerBuffer.h @@ -110,12 +110,14 @@ public: * by ThebesLayerBuffer and must be redrawn on the screen. * mRegionToInvalidate is set when the buffer has changed from * opaque to transparent or vice versa, since the details of rendering can - * depend on the buffer type. + * depend on the buffer type. mDidSelfCopy is true if we kept our buffer + * but used MovePixels() to shift its content. */ struct PaintState { nsRefPtr mContext; nsIntRegion mRegionToDraw; nsIntRegion mRegionToInvalidate; + PRPackedBool mDidSelfCopy; }; enum { diff --git a/gfx/layers/basic/BasicLayers.cpp b/gfx/layers/basic/BasicLayers.cpp index b319fbf430d..6f7f31936aa 100644 --- a/gfx/layers/basic/BasicLayers.cpp +++ b/gfx/layers/basic/BasicLayers.cpp @@ -428,6 +428,7 @@ protected: const nsIntRegion& aRegionToDraw, const nsIntRegion& aExtendedRegionToDraw, const nsIntRegion& aRegionToInvalidate, + PRBool aDidSelfCopy, LayerManager::DrawThebesLayerCallback aCallback, void* aCallbackData) { @@ -608,6 +609,7 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext, SetAntialiasingFlags(this, state.mContext); PaintBuffer(state.mContext, state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate, + state.mDidSelfCopy, aCallback, aCallbackData); Mutated(); } else { @@ -1800,6 +1802,7 @@ private: const nsIntRegion& aRegionToDraw, const nsIntRegion& aExtendedRegionToDraw, const nsIntRegion& aRegionToInvalidate, + PRBool aDidSelfCopy, LayerManager::DrawThebesLayerCallback aCallback, void* aCallbackData); @@ -1860,21 +1863,27 @@ BasicShadowableThebesLayer::PaintBuffer(gfxContext* aContext, const nsIntRegion& aRegionToDraw, const nsIntRegion& aExtendedRegionToDraw, const nsIntRegion& aRegionToInvalidate, + PRBool aDidSelfCopy, LayerManager::DrawThebesLayerCallback aCallback, void* aCallbackData) { Base::PaintBuffer(aContext, aRegionToDraw, aExtendedRegionToDraw, aRegionToInvalidate, + aDidSelfCopy, aCallback, aCallbackData); if (!HasShadow()) { return; } nsIntRegion updatedRegion; - if (mIsNewBuffer) { + if (mIsNewBuffer || aDidSelfCopy) { // A buffer reallocation clears both buffers. The front buffer has all the // content by now, but the back buffer is still clear. Here, in effect, we // are saying to copy all of the pixels of the front buffer to the back. + // Also when we self-copied in the buffer, the buffer space + // changes and some changed buffer content isn't reflected in the + // draw or invalidate region (on purpose!). When this happens, we + // need to read back the entire buffer too. updatedRegion = mVisibleRegion; mIsNewBuffer = false; } else {