diff --git a/accessible/base/TextAttrs.cpp b/accessible/base/TextAttrs.cpp index 26c32f839e21..d9daab9568d4 100644 --- a/accessible/base/TextAttrs.cpp +++ b/accessible/base/TextAttrs.cpp @@ -460,7 +460,7 @@ TextAttrsMgr::FontFamilyTextAttr:: nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm)); gfxFontGroup* fontGroup = fm->GetThebesFontGroup(); - gfxFont* font = fontGroup->GetFontAt(0); + gfxFont* font = fontGroup->GetFirstValidFont(); gfxFontEntry* fontEntry = font->GetFontEntry(); aFamily = fontEntry->FamilyName(); return true; @@ -618,7 +618,7 @@ TextAttrsMgr::FontWeightTextAttr:: nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm)); gfxFontGroup *fontGroup = fm->GetThebesFontGroup(); - gfxFont *font = fontGroup->GetFontAt(0); + gfxFont *font = fontGroup->GetFirstValidFont(); // When there doesn't exist a bold font in the family and so the rendering of // a non-bold font face is changed so that the user sees what looks like a diff --git a/accessible/base/nsAccessibilityService.cpp b/accessible/base/nsAccessibilityService.cpp index 95675ef9b816..7e32d0078b8d 100644 --- a/accessible/base/nsAccessibilityService.cpp +++ b/accessible/base/nsAccessibilityService.cpp @@ -57,7 +57,7 @@ #include "nsImageFrame.h" #include "nsIObserverService.h" #include "nsLayoutUtils.h" -#include "nsObjectFrame.h" +#include "nsPluginFrame.h" #include "nsSVGPathGeometryFrame.h" #include "nsTreeBodyFrame.h" #include "nsTreeColumns.h" @@ -263,11 +263,11 @@ NS_IMPL_ISUPPORTS(PluginTimerCallBack, nsITimerCallback) #endif already_AddRefed -nsAccessibilityService::CreatePluginAccessible(nsObjectFrame* aFrame, +nsAccessibilityService::CreatePluginAccessible(nsPluginFrame* aFrame, nsIContent* aContent, Accessible* aContext) { - // nsObjectFrame means a plugin, so we need to use the accessibility support + // nsPluginFrame means a plugin, so we need to use the accessibility support // of the plugin. if (aFrame->GetRect().IsEmpty()) return nullptr; @@ -1619,8 +1619,8 @@ nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame, newAcc = new OuterDocAccessible(aContent, document); break; case ePluginType: { - nsObjectFrame* objectFrame = do_QueryFrame(aFrame); - newAcc = CreatePluginAccessible(objectFrame, aContent, aContext); + nsPluginFrame* pluginFrame = do_QueryFrame(aFrame); + newAcc = CreatePluginAccessible(pluginFrame, aContent, aContext); break; } case eTextLeafType: diff --git a/accessible/base/nsAccessibilityService.h b/accessible/base/nsAccessibilityService.h index 1ea1ab85bcb7..d466e6f457b0 100644 --- a/accessible/base/nsAccessibilityService.h +++ b/accessible/base/nsAccessibilityService.h @@ -15,7 +15,7 @@ #include "nsIObserver.h" class nsImageFrame; -class nsObjectFrame; +class nsPluginFrame; class nsITreeView; namespace mozilla { @@ -63,7 +63,7 @@ public: virtual Accessible* GetRootDocumentAccessible(nsIPresShell* aPresShell, bool aCanCreate); already_AddRefed - CreatePluginAccessible(nsObjectFrame* aFrame, nsIContent* aContent, + CreatePluginAccessible(nsPluginFrame* aFrame, nsIContent* aContent, Accessible* aContext); /** diff --git a/accessible/interfaces/nsIAccessibilityService.h b/accessible/interfaces/nsIAccessibilityService.h index fe7c33acc591..4b894ae52a53 100644 --- a/accessible/interfaces/nsIAccessibilityService.h +++ b/accessible/interfaces/nsIAccessibilityService.h @@ -24,7 +24,7 @@ class nsINode; class nsIContent; class nsIFrame; class nsIPresShell; -class nsObjectFrame; +class nsPluginFrame; // 10ff6dca-b219-4b64-9a4c-67a62b86edce #define NS_IACCESSIBILITYSERVICE_IID \ diff --git a/accessible/windows/sdn/sdnTextAccessible.cpp b/accessible/windows/sdn/sdnTextAccessible.cpp index ae5a82985181..37b5ee8d6590 100644 --- a/accessible/windows/sdn/sdnTextAccessible.cpp +++ b/accessible/windows/sdn/sdnTextAccessible.cpp @@ -182,7 +182,8 @@ sdnTextAccessible::get_fontFamily(BSTR __RPC_FAR* aFontFamily) nsRefPtr fm; nsLayoutUtils::GetFontMetricsForFrame(frame, getter_AddRefs(fm)); - const nsString& name = fm->GetThebesFontGroup()->GetFontAt(0)->GetName(); + const nsString& name = + fm->GetThebesFontGroup()->GetFirstValidFont()->GetName(); if (name.IsEmpty()) return S_FALSE; diff --git a/addon-sdk/mach_commands.py b/addon-sdk/mach_commands.py index 4cc208729d8e..c920efa7eccc 100644 --- a/addon-sdk/mach_commands.py +++ b/addon-sdk/mach_commands.py @@ -48,14 +48,14 @@ class MachCommands(MachCommandBase): dirs_to_files = {} for path, dirs, files in os.walk(js_src_dir): - js_files = [f for f in files if f.endswith(('.js', '.jsm'))] + js_files = [f for f in files if f.endswith(('.js', '.jsm', '.html'))] if not js_files: continue relative = mozpath.relpath(path, js_src_dir) dirs_to_files[relative] = js_files - moz_build = """# AUTOMATICALLY GENERATED FROM moz.build.in AND mach. DO NOT EDIT. + moz_build = """# AUTOMATICALLY GENERATED FROM mozbuild.template AND mach. DO NOT EDIT. # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/addon-sdk/moz.build b/addon-sdk/moz.build index 32e5091dd96e..5bd2ffa4563b 100644 --- a/addon-sdk/moz.build +++ b/addon-sdk/moz.build @@ -399,6 +399,7 @@ EXTRA_JS_MODULES.commonjs.sdk.ui.button.view += [ EXTRA_JS_MODULES.commonjs.sdk.ui.frame += [ 'source/lib/sdk/ui/frame/model.js', + 'source/lib/sdk/ui/frame/view.html', 'source/lib/sdk/ui/frame/view.js', ] diff --git a/addon-sdk/mozbuild.template b/addon-sdk/mozbuild.template index be0b58ee5fd4..174593e33d76 100644 --- a/addon-sdk/mozbuild.template +++ b/addon-sdk/mozbuild.template @@ -8,8 +8,11 @@ BROWSER_CHROME_MANIFESTS += ['test/browser.ini'] JETPACK_PACKAGE_MANIFESTS += ['source/test/jetpack-package.ini'] JETPACK_ADDON_MANIFESTS += ['source/test/addons/jetpack-addon.ini'] -DIRS += ["source/modules/system"] - EXTRA_JS_MODULES.sdk += [ 'source/app-extension/bootstrap.js', ] + +EXTRA_JS_MODULES.sdk.system += [ + 'source/modules/system/Startup.js', + 'source/modules/system/XulApp.js', +] diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index 665dcf23a880..4c7ffcfef89a 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -744,14 +744,14 @@ pref("hal.processPriorityManager.gonk.LowCPUNice", 18); // priority can be enabled by setting this pref to a value between 1 and 99. // Note that audio processing currently runs at RT priority 2 or 3 at most. // -// If RT priority is disabled, then the compositor nice value is used. The -// code will default to ANDROID_PRIORITY_URGENT_DISPLAY which is -8. Per gfx -// request we are keeping the compositor at nice level 0 until we can complete -// the investigation in bug 982972. +// If RT priority is disabled, then the compositor nice value is used. We prefer +// to use a nice value of -4, which matches Android's preferences. Setting a preference +// of RT priority 1 would mean it is higher than audio, which is -16. The compositor +// priority must be below the audio thread. // // Do not change these values without gfx team review. pref("hal.gonk.COMPOSITOR.rt_priority", 0); -pref("hal.gonk.COMPOSITOR.nice", 0); +pref("hal.gonk.COMPOSITOR.nice", -4); // Fire a memory pressure event when the system has less than Xmb of memory // remaining. You should probably set this just above Y.KillUnderKB for diff --git a/content/base/src/nsInProcessTabChildGlobal.cpp b/content/base/src/nsInProcessTabChildGlobal.cpp index 7dc02315233d..a80a5b2506c6 100644 --- a/content/base/src/nsInProcessTabChildGlobal.cpp +++ b/content/base/src/nsInProcessTabChildGlobal.cpp @@ -305,6 +305,8 @@ nsInProcessTabChildGlobal::PreHandleEvent(EventChainPreVisitor& aVisitor) nsresult nsInProcessTabChildGlobal::InitTabChildGlobal() { + // If you change this, please change GetCompartmentName() in XPCJSRuntime.cpp + // accordingly. nsAutoCString id; id.AssignLiteral("inProcessTabChildGlobal"); nsIURI* uri = mOwner->OwnerDoc()->GetDocumentURI(); diff --git a/content/base/src/nsObjectLoadingContent.cpp b/content/base/src/nsObjectLoadingContent.cpp index 3efe85db3d7b..5ca840c3a98d 100644 --- a/content/base/src/nsObjectLoadingContent.cpp +++ b/content/base/src/nsObjectLoadingContent.cpp @@ -68,7 +68,7 @@ #include "nsIChannelPolicy.h" #include "nsChannelPolicy.h" #include "GeckoProfiler.h" -#include "nsObjectFrame.h" +#include "nsPluginFrame.h" #include "nsDOMClassInfo.h" #include "nsWrapperCacheInlines.h" #include "nsDOMJSUtils.h" @@ -860,7 +860,7 @@ nsObjectLoadingContent::InstantiatePluginInstance(bool aIsLoading) // dangling. (Bug 854082) nsIFrame* frame = thisContent->GetPrimaryFrame(); if (frame && mInstanceOwner) { - mInstanceOwner->SetFrame(static_cast(frame)); + mInstanceOwner->SetFrame(static_cast(frame)); // Bug 870216 - Adobe Reader renders with incorrect dimensions until it gets // a second SetWindow call. This is otherwise redundant. @@ -1296,7 +1296,7 @@ nsObjectLoadingContent::HasNewFrame(nsIObjectFrame* aFrame) // Otherwise, we're just changing frames // Set up relationship between instance owner and frame. - nsObjectFrame *objFrame = static_cast(aFrame); + nsPluginFrame *objFrame = static_cast(aFrame); mInstanceOwner->SetFrame(objFrame); return NS_OK; @@ -2718,13 +2718,13 @@ nsObjectLoadingContent::GetTypeOfContent(const nsCString& aMIMEType) return eType_Null; } -nsObjectFrame* +nsPluginFrame* nsObjectLoadingContent::GetExistingFrame() { nsCOMPtr thisContent = do_QueryInterface(static_cast(this)); nsIFrame* frame = thisContent->GetPrimaryFrame(); nsIObjectFrame* objFrame = do_QueryFrame(frame); - return static_cast(objFrame); + return static_cast(objFrame); } void @@ -3576,7 +3576,7 @@ nsObjectLoadingContent::GetPluginJSObject(JSContext *cx, JS::MutableHandle plugin_proto) { // NB: We need an AutoEnterCompartment because we can be called from - // nsObjectFrame when the plugin loads after the JS object for our content + // nsPluginFrame when the plugin loads after the JS object for our content // node has been created. JSAutoCompartment ac(cx, obj); diff --git a/content/base/src/nsObjectLoadingContent.h b/content/base/src/nsObjectLoadingContent.h index a4bc7b1d3091..b6a56c7dfa1d 100644 --- a/content/base/src/nsObjectLoadingContent.h +++ b/content/base/src/nsObjectLoadingContent.h @@ -26,7 +26,7 @@ class nsAsyncInstantiateEvent; class nsStopPluginRunnable; class AutoSetInstantiatingToFalse; -class nsObjectFrame; +class nsPluginFrame; class nsFrameLoader; class nsXULElement; class nsPluginInstanceOwner; @@ -502,7 +502,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent * Gets the frame that's associated with this content node. * Does not flush. */ - nsObjectFrame* GetExistingFrame(); + nsPluginFrame* GetExistingFrame(); // Helper class for SetupProtoChain class SetupProtoChainRunner MOZ_FINAL : public nsIRunnable diff --git a/content/media/fmp4/moz.build b/content/media/fmp4/moz.build index ad5bc311331f..0326858af6cb 100644 --- a/content/media/fmp4/moz.build +++ b/content/media/fmp4/moz.build @@ -12,11 +12,11 @@ EXPORTS += [ UNIFIED_SOURCES += [ 'BlankDecoderModule.cpp', + 'MP4Decoder.cpp', 'PlatformDecoderModule.cpp', ] SOURCES += [ - 'MP4Decoder.cpp', 'MP4Reader.cpp', ] diff --git a/content/media/omx/AudioOffloadPlayer.cpp b/content/media/omx/AudioOffloadPlayer.cpp index 4379fb69160d..44d912815162 100644 --- a/content/media/omx/AudioOffloadPlayer.cpp +++ b/content/media/omx/AudioOffloadPlayer.cpp @@ -22,6 +22,8 @@ #include "nsITimer.h" #include "mozilla/dom/HTMLMediaElement.h" #include "VideoUtils.h" +#include "mozilla/dom/power/PowerManagerService.h" +#include "mozilla/dom/WakeLock.h" #include #include @@ -215,6 +217,7 @@ status_t AudioOffloadPlayer::ChangeState(MediaDecoder::PlayState aState) static void ResetCallback(nsITimer* aTimer, void* aClosure) { + AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("%s", __FUNCTION__)); AudioOffloadPlayer* player = static_cast(aClosure); if (player) { player->Reset(); @@ -227,6 +230,8 @@ void AudioOffloadPlayer::Pause(bool aPlayPendingSamples) if (mStarted) { CHECK(mAudioSink.get()); + WakeLockCreate(); + if (aPlayPendingSamples) { mAudioSink->Stop(); } else { @@ -252,6 +257,7 @@ status_t AudioOffloadPlayer::Play() if (mResetTimer) { mResetTimer->Cancel(); mResetTimer = nullptr; + WakeLockRelease(); } status_t err = OK; @@ -281,6 +287,7 @@ status_t AudioOffloadPlayer::Play() void AudioOffloadPlayer::Reset() { + MOZ_ASSERT(NS_IsMainThread()); if (!mStarted) { return; } @@ -323,6 +330,8 @@ void AudioOffloadPlayer::Reset() mStarted = false; mPlaying = false; mStartPosUs = 0; + + WakeLockRelease(); } status_t AudioOffloadPlayer::SeekTo(int64_t aTimeUs, bool aDispatchSeekEvents) @@ -711,4 +720,30 @@ void AudioOffloadPlayer::SetVolume(double aVolume) mAudioSink->SetVolume((float) aVolume); } +void AudioOffloadPlayer::WakeLockCreate() +{ + MOZ_ASSERT(NS_IsMainThread()); + AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("%s", __FUNCTION__)); + if (!mWakeLock) { + nsRefPtr pmService = + dom::power::PowerManagerService::GetInstance(); + NS_ENSURE_TRUE_VOID(pmService); + + ErrorResult rv; + mWakeLock = pmService->NewWakeLock(NS_LITERAL_STRING("cpu"), nullptr, rv); + } +} + +void AudioOffloadPlayer::WakeLockRelease() +{ + MOZ_ASSERT(NS_IsMainThread()); + AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("%s", __FUNCTION__)); + if (mWakeLock) { + ErrorResult rv; + mWakeLock->Unlock(rv); + NS_WARN_IF_FALSE(!rv.Failed(), "Failed to unlock the wakelock."); + mWakeLock = nullptr; + } +} + } // namespace mozilla diff --git a/content/media/omx/AudioOffloadPlayer.h b/content/media/omx/AudioOffloadPlayer.h index 0d28bded1185..aef8961c2eaf 100644 --- a/content/media/omx/AudioOffloadPlayer.h +++ b/content/media/omx/AudioOffloadPlayer.h @@ -33,6 +33,10 @@ namespace mozilla { +namespace dom { +class WakeLock; +} + /** * AudioOffloadPlayer adds support for audio tunneling to a digital signal * processor (DSP) in the device chipset. With tunneling, audio decoding is @@ -193,6 +197,10 @@ private: // OFFLOAD_PAUSE_MAX_USECS. Used only from main thread so no lock is needed. nsCOMPtr mResetTimer; + // To avoid device suspend when mResetTimer is going to be triggered. + // Used only from main thread so no lock is needed. + nsRefPtr mWakeLock; + int64_t GetMediaTimeUs(); // Provide the playback position in microseconds from total number of @@ -240,6 +248,9 @@ private: nsresult StartTimeUpdate(); nsresult StopTimeUpdate(); + void WakeLockCreate(); + void WakeLockRelease(); + // Notify end of stream by sending PlaybackEnded event to observer // (i.e.MediaDecoder) void NotifyAudioEOS(); diff --git a/dom/animation/Animation.cpp b/dom/animation/Animation.cpp index 6253b67b75cd..91fe3bf91a01 100644 --- a/dom/animation/Animation.cpp +++ b/dom/animation/Animation.cpp @@ -114,12 +114,8 @@ Animation::GetComputedTimingAt(const Nullable& aLocalTime, bool isEndOfFinalIteration = false; // Get the normalized time within the active interval. - TimeDuration activeTime; - // FIXME: The following check that the active duration is not equal to Forever - // is a temporary workaround to avoid overflow and should be removed once - // bug 1039924 is fixed. - if (result.mActiveDuration != TimeDuration::Forever() && - localTime >= aTiming.mDelay + result.mActiveDuration) { + StickyTimeDuration activeTime; + if (localTime >= aTiming.mDelay + result.mActiveDuration) { result.mPhase = ComputedTiming::AnimationPhase_After; if (!aTiming.FillsForwards()) { // The animation isn't active or filling at this time. @@ -148,10 +144,10 @@ Animation::GetComputedTimingAt(const Nullable& aLocalTime, } // Get the position within the current iteration. - TimeDuration iterationTime; + StickyTimeDuration iterationTime; if (aTiming.mIterationDuration != zeroDuration) { iterationTime = isEndOfFinalIteration - ? aTiming.mIterationDuration + ? StickyTimeDuration(aTiming.mIterationDuration) : activeTime % aTiming.mIterationDuration; } /* else, iterationTime is zero */ @@ -215,19 +211,20 @@ Animation::GetComputedTimingAt(const Nullable& aLocalTime, return result; } -TimeDuration +StickyTimeDuration Animation::ActiveDuration(const AnimationTiming& aTiming) { if (aTiming.mIterationCount == mozilla::PositiveInfinity()) { // An animation that repeats forever has an infinite active duration // unless its iteration duration is zero, in which case it has a zero // active duration. - const TimeDuration zeroDuration; + const StickyTimeDuration zeroDuration; return aTiming.mIterationDuration == zeroDuration ? zeroDuration - : TimeDuration::Forever(); + : StickyTimeDuration::Forever(); } - return aTiming.mIterationDuration.MultDouble(aTiming.mIterationCount); + return StickyTimeDuration( + aTiming.mIterationDuration.MultDouble(aTiming.mIterationCount)); } bool diff --git a/dom/animation/Animation.h b/dom/animation/Animation.h index b72858b7b268..afdb81bc97f2 100644 --- a/dom/animation/Animation.h +++ b/dom/animation/Animation.h @@ -11,6 +11,7 @@ #include "nsIDocument.h" #include "nsWrapperCache.h" #include "mozilla/Attributes.h" +#include "mozilla/StickyTimeDuration.h" #include "mozilla/StyleAnimationValue.h" #include "mozilla/TimeStamp.h" #include "mozilla/dom/Nullable.h" @@ -61,8 +62,9 @@ struct ComputedTiming static const double kNullTimeFraction; // The total duration of the animation including all iterations. - // Will equal TimeDuration::Forever() if the animation repeats indefinitely. - TimeDuration mActiveDuration; + // Will equal StickyTimeDuration::Forever() if the animation repeats + // indefinitely. + StickyTimeDuration mActiveDuration; // Will be kNullTimeFraction if the animation is neither animating nor // filling at the sampled time. @@ -205,7 +207,8 @@ public: } // Return the duration of the active interval for the given timing parameters. - static TimeDuration ActiveDuration(const AnimationTiming& aTiming); + static StickyTimeDuration + ActiveDuration(const AnimationTiming& aTiming); // After transitions finish they need to be retained for one throttle-able // cycle (for reasons see explanation in diff --git a/dom/base/nsPerformance.cpp b/dom/base/nsPerformance.cpp index 286967ab667a..1a300eb9dcf8 100644 --- a/dom/base/nsPerformance.cpp +++ b/dom/base/nsPerformance.cpp @@ -41,6 +41,11 @@ nsPerformanceTiming::nsPerformanceTiming(nsPerformance* aPerformance, { MOZ_ASSERT(aPerformance, "Parent performance object should be provided"); SetIsDOMBinding(); + + if (!nsContentUtils::IsPerformanceTimingEnabled()) { + mZeroTime = 0; + } + // The aHttpChannel argument is null if this nsPerformanceTiming object // is being used for the navigation timing (document) and has a non-null // value for the resource timing (any resources within the page). diff --git a/dom/camera/DOMCameraManager.cpp b/dom/camera/DOMCameraManager.cpp index 0284385f31c0..063c4486e881 100644 --- a/dom/camera/DOMCameraManager.cpp +++ b/dom/camera/DOMCameraManager.cpp @@ -51,7 +51,7 @@ GetCameraLog() return sLog; } -WindowTable* nsDOMCameraManager::sActiveWindows = nullptr; +::WindowTable* nsDOMCameraManager::sActiveWindows = nullptr; nsDOMCameraManager::nsDOMCameraManager(nsPIDOMWindow* aWindow) : mWindowId(aWindow->WindowID()) @@ -109,7 +109,7 @@ nsDOMCameraManager::CreateInstance(nsPIDOMWindow* aWindow) { // Initialize the shared active window tracker if (!sActiveWindows) { - sActiveWindows = new WindowTable(); + sActiveWindows = new ::WindowTable(); } nsRefPtr cameraManager = diff --git a/dom/camera/moz.build b/dom/camera/moz.build index e7ff01620714..394bad2a8d1b 100644 --- a/dom/camera/moz.build +++ b/dom/camera/moz.build @@ -13,7 +13,7 @@ EXPORTS += [ 'DOMCameraManager.h', ] -SOURCES += [ +UNIFIED_SOURCES += [ 'CameraControlImpl.cpp', 'CameraPreferences.cpp', 'CameraPreviewMediaStream.cpp', @@ -38,7 +38,7 @@ if CONFIG['MOZ_B2G_CAMERA']: 'TestGonkCameraHardware.cpp', ] else: - SOURCES += [ + UNIFIED_SOURCES += [ 'FallbackCameraControl.cpp', 'FallbackCameraManager.cpp', ] diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 243e79bd6c7d..755540a14936 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -3103,7 +3103,7 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess virtual void SetText(const char16_t* text, int32_t length, nsBidiDirection direction) { - mFontgrp->UpdateFontList(); // ensure user font generation is current + mFontgrp->UpdateUserFonts(); // ensure user font generation is current mTextRun = mFontgrp->MakeTextRun(text, length, mThebes, @@ -3455,9 +3455,9 @@ CanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText, processor.mPt.x -= anchorX * totalWidth; // offset pt.y based on text baseline - processor.mFontgrp->UpdateFontList(); // ensure user font generation is current - NS_ASSERTION(processor.mFontgrp->FontListLength()>0, "font group contains no fonts"); - const gfxFont::Metrics& fontMetrics = processor.mFontgrp->GetFontAt(0)->GetMetrics(); + processor.mFontgrp->UpdateUserFonts(); // ensure user font generation is current + const gfxFont::Metrics& fontMetrics = + processor.mFontgrp->GetFirstValidFont()->GetMetrics(); gfxFloat anchorY; diff --git a/dom/canvas/test/webgl-mochitest.ini b/dom/canvas/test/webgl-mochitest.ini index 3ca441d71641..77c4a7f27fcd 100644 --- a/dom/canvas/test/webgl-mochitest.ini +++ b/dom/canvas/test/webgl-mochitest.ini @@ -3,6 +3,8 @@ support-files = webgl-mochitest/driver-info.js webgl-mochitest/webgl-util.js +[webgl-mochitest/test-backbuffer-channels.html] +[webgl-mochitest/test-hidden-alpha.html] [webgl-mochitest/test_depth_readpixels.html] [webgl-mochitest/test_draw.html] [webgl-mochitest/test_fb_param.html] diff --git a/dom/canvas/test/webgl-mochitest/mochi-to-testcase.py b/dom/canvas/test/webgl-mochitest/mochi-to-testcase.py index 56ac24e37b67..77461162675a 100644 --- a/dom/canvas/test/webgl-mochitest/mochi-to-testcase.py +++ b/dom/canvas/test/webgl-mochitest/mochi-to-testcase.py @@ -9,7 +9,7 @@ extDotPos = mochiPath.find('.html') assert extDotPos != -1, 'mochitest target must be an html doc.' testPath = mochiPath[:extDotPos] + '.solo.html' - + def ReadLocalFile(include): incPath = os.path.dirname(mochiPath) filePath = os.path.join(incPath, include) @@ -31,22 +31,29 @@ def ReadLocalFile(include): kSimpleTestReplacement = '''\n
\n''' -fin = open(mochiPath, 'r') -fout = open(testPath, 'w') +fin = open(mochiPath, 'rb') +fout = open(testPath, 'wb') includePattern = re.compile('\\s*') cssPattern = re.compile(']*)[\'"]>') for line in fin: @@ -54,7 +61,7 @@ for line in fin: for css in cssPattern.findall(line): skipLine = True print('Ignoring stylesheet: ' + css) - + for inc in includePattern.findall(line): skipLine = True if inc == '/MochiKit/MochiKit': @@ -64,7 +71,7 @@ for line in fin: print('Injecting SimpleTest replacement') fout.write(kSimpleTestReplacement); continue - + incData = ReadLocalFile(inc + '.js') if not incData: print('Warning: Unknown JS file ignored: ' + inc + '.js') @@ -78,7 +85,7 @@ for line in fin: if skipLine: continue - + fout.write(line) continue diff --git a/dom/canvas/test/webgl-mochitest/test-backbuffer-channels.html b/dom/canvas/test/webgl-mochitest/test-backbuffer-channels.html new file mode 100644 index 000000000000..28434e6dc0b9 --- /dev/null +++ b/dom/canvas/test/webgl-mochitest/test-backbuffer-channels.html @@ -0,0 +1,111 @@ + +WebGL test: bug 958723 + + + + + + + diff --git a/dom/canvas/test/webgl-mochitest/test-hidden-alpha.html b/dom/canvas/test/webgl-mochitest/test-hidden-alpha.html new file mode 100644 index 000000000000..3b15993d483f --- /dev/null +++ b/dom/canvas/test/webgl-mochitest/test-hidden-alpha.html @@ -0,0 +1,153 @@ + +WebGL test: Hidden alpha on no-alpha contexts + + + + + + + + + + + diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index e6b974192959..a2acea5884ec 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -23,7 +23,7 @@ using mozilla::DefaultXDisplay; #include "nsDisplayList.h" #include "ImageLayers.h" #include "GLImages.h" -#include "nsObjectFrame.h" +#include "nsPluginFrame.h" #include "nsIPluginDocument.h" #include "nsIStringStream.h" #include "nsNetUtil.h" @@ -222,7 +222,7 @@ nsPluginInstanceOwner::GetImageContainer() // NotifySize() causes Flash to do a bunch of stuff like ask for surfaces to render // into, set y-flip flags, etc, so we do this at the beginning. - gfxSize resolution = mObjectFrame->PresContext()->PresShell()->GetCumulativeResolution(); + gfxSize resolution = mPluginFrame->PresContext()->PresShell()->GetCumulativeResolution(); ScreenSize screenSize = (r * LayoutDeviceToScreenScale(resolution.width, resolution.height)).Size(); mInstance->NotifySize(nsIntSize(screenSize.width, screenSize.height)); @@ -322,7 +322,7 @@ nsPluginInstanceOwner::nsPluginInstanceOwner() else mPluginWindow = nullptr; - mObjectFrame = nullptr; + mPluginFrame = nullptr; mContent = nullptr; mWidgetCreationComplete = false; #ifdef XP_MACOSX @@ -365,7 +365,7 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner() NS_DispatchToMainThread(event); } - mObjectFrame = nullptr; + mPluginFrame = nullptr; PLUG_DeletePluginNativeWindow(mPluginWindow); mPluginWindow = nullptr; @@ -543,10 +543,10 @@ NS_IMETHODIMP nsPluginInstanceOwner::ShowStatus(const char16_t *aStatusMsg) { nsresult rv = NS_ERROR_FAILURE; - if (!mObjectFrame) { + if (!mPluginFrame) { return rv; } - nsCOMPtr docShellItem = mObjectFrame->PresContext()->GetDocShell(); + nsCOMPtr docShellItem = mPluginFrame->PresContext()->GetDocShell(); if (NS_FAILED(rv) || !docShellItem) { return rv; } @@ -582,7 +582,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect) { // If our object frame has gone away, we won't be able to determine // up-to-date-ness, so just fire off the event. - if (mWaitingForPaint && (!mObjectFrame || IsUpToDate())) { + if (mWaitingForPaint && (!mPluginFrame || IsUpToDate())) { // We don't care when the event is dispatched as long as it's "soon", // since whoever needs it will be waiting for it. nsCOMPtr event = new AsyncPaintWaitEvent(mContent, true); @@ -590,7 +590,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect) mWaitingForPaint = false; } - if (!mObjectFrame || !invalidRect || !mWidgetVisible) + if (!mPluginFrame || !invalidRect || !mWidgetVisible) return NS_ERROR_FAILURE; #if defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID) @@ -621,7 +621,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect) double scaleFactor = 1.0; GetContentsScaleFactor(&scaleFactor); rect.ScaleRoundOut(scaleFactor); - mObjectFrame->InvalidateLayer(nsDisplayItem::TYPE_PLUGIN, &rect); + mPluginFrame->InvalidateLayer(nsDisplayItem::TYPE_PLUGIN, &rect); return NS_OK; } @@ -633,22 +633,22 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRegion(NPRegion invalidRegion) NS_IMETHODIMP nsPluginInstanceOwner::RedrawPlugin() { - if (mObjectFrame) { - mObjectFrame->InvalidateLayer(nsDisplayItem::TYPE_PLUGIN); + if (mPluginFrame) { + mPluginFrame->InvalidateLayer(nsDisplayItem::TYPE_PLUGIN); } return NS_OK; } NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value) { - if (!mObjectFrame) { + if (!mPluginFrame) { NS_WARNING("plugin owner has no owner in getting doc's window handle"); return NS_ERROR_FAILURE; } #if defined(XP_WIN) void** pvalue = (void**)value; - nsViewManager* vm = mObjectFrame->PresContext()->GetPresShell()->GetViewManager(); + nsViewManager* vm = mPluginFrame->PresContext()->GetPresShell()->GetViewManager(); if (!vm) return NS_ERROR_FAILURE; #if defined(XP_WIN) @@ -680,7 +680,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value) // fixing both the caret and ability to interact issues for a windowless control in a non document aligned windw // does not seem to be possible without a change to the flash plugin - nsIWidget* win = mObjectFrame->GetNearestWidget(); + nsIWidget* win = mPluginFrame->GetNearestWidget(); if (win) { nsView *view = nsView::GetViewFor(win); NS_ASSERTION(view, "No view for widget"); @@ -708,7 +708,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value) return NS_OK; #elif (defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)) && defined(MOZ_X11) // X11 window managers want the toplevel window for WM_TRANSIENT_FOR. - nsIWidget* win = mObjectFrame->GetNearestWidget(); + nsIWidget* win = mPluginFrame->GetNearestWidget(); if (!win) return NS_ERROR_FAILURE; *static_cast(value) = (long unsigned int)win->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW); @@ -1127,8 +1127,8 @@ GetOffsetRootContent(nsIFrame* aFrame) LayoutDeviceRect nsPluginInstanceOwner::GetPluginRect() { // Get the offset of the content relative to the page - nsRect bounds = mObjectFrame->GetContentRectRelativeToSelf() + GetOffsetRootContent(mObjectFrame); - LayoutDeviceIntRect rect = LayoutDeviceIntRect::FromAppUnitsToNearest(bounds, mObjectFrame->PresContext()->AppUnitsPerDevPixel()); + nsRect bounds = mPluginFrame->GetContentRectRelativeToSelf() + GetOffsetRootContent(mPluginFrame); + LayoutDeviceIntRect rect = LayoutDeviceIntRect::FromAppUnitsToNearest(bounds, mPluginFrame->PresContext()->AppUnitsPerDevPixel()); return LayoutDeviceRect(rect); } @@ -1350,7 +1350,7 @@ nsPluginInstanceOwner::ProcessMouseDown(nsIDOMEvent* aMouseEvent) // if the plugin is windowless, we need to set focus ourselves // otherwise, we might not get key events - if (mObjectFrame && mPluginWindow && + if (mPluginFrame && mPluginWindow && mPluginWindow->type == NPWindowTypeDrawable) { nsIFocusManager* fm = nsFocusManager::GetFocusManager(); @@ -1482,7 +1482,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent) { nsEventStatus rv = nsEventStatus_eIgnore; - if (!mInstance || !mObjectFrame) // if mInstance is null, we shouldn't be here + if (!mInstance || !mPluginFrame) // if mInstance is null, we shouldn't be here return nsEventStatus_eIgnore; #ifdef XP_MACOSX @@ -1503,9 +1503,9 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent) NPCocoaEvent synthCocoaEvent; const NPCocoaEvent* event = static_cast(anEvent.mPluginEvent); nsPoint pt = - nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame) - - mObjectFrame->GetContentRectRelativeToSelf().TopLeft(); - nsPresContext* presContext = mObjectFrame->PresContext(); + nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) - + mPluginFrame->GetContentRectRelativeToSelf().TopLeft(); + nsPresContext* presContext = mPluginFrame->PresContext(); // Plugin event coordinates need to be translated from device pixels // into "display pixels" in HiDPI modes. double scaleFactor = 1.0; @@ -1521,9 +1521,9 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent) { // Ignore mouse-moved events that happen as part of a dragging // operation that started over another frame. See bug 525078. - nsRefPtr frameselection = mObjectFrame->GetFrameSelection(); + nsRefPtr frameselection = mPluginFrame->GetFrameSelection(); if (!frameselection->GetDragState() || - (nsIPresShell::GetCapturingContent() == mObjectFrame->GetContent())) { + (nsIPresShell::GetCapturingContent() == mPluginFrame->GetContent())) { synthCocoaEvent.type = NPCocoaEventMouseMoved; synthCocoaEvent.data.mouse.pluginX = static_cast(ptPx.x); synthCocoaEvent.data.mouse.pluginY = static_cast(ptPx.y); @@ -1542,7 +1542,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent) // convert it into a mouse-entered event (in the Cocoa Event Model). // See bug 525078. if (anEvent.AsMouseEvent()->button == WidgetMouseEvent::eLeftButton && - (nsIPresShell::GetCapturingContent() != mObjectFrame->GetContent())) { + (nsIPresShell::GetCapturingContent() != mPluginFrame->GetContent())) { synthCocoaEvent.type = NPCocoaEventMouseEntered; synthCocoaEvent.data.mouse.pluginX = static_cast(ptPx.x); synthCocoaEvent.data.mouse.pluginY = static_cast(ptPx.y); @@ -1652,12 +1652,12 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent) anEvent.message == NS_MOUSE_MOVE, "Incorrect event type for coordinate translation"); nsPoint pt = - nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame) - - mObjectFrame->GetContentRectRelativeToSelf().TopLeft(); - nsPresContext* presContext = mObjectFrame->PresContext(); + nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) - + mPluginFrame->GetContentRectRelativeToSelf().TopLeft(); + nsPresContext* presContext = mPluginFrame->PresContext(); nsIntPoint ptPx(presContext->AppUnitsToDevPixels(pt.x), presContext->AppUnitsToDevPixels(pt.y)); - nsIntPoint widgetPtPx = ptPx + mObjectFrame->GetWindowOriginInPixels(true); + nsIntPoint widgetPtPx = ptPx + mPluginFrame->GetWindowOriginInPixels(true); const_cast(pPluginEvent)->lParam = MAKELPARAM(widgetPtPx.x, widgetPtPx.y); } } @@ -1680,7 +1680,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent) if (pPluginEvent && !pPluginEvent->event) { // Don't send null events to plugins. - NS_WARNING("nsObjectFrame ProcessEvent: trying to send null event to plugin."); + NS_WARNING("nsPluginFrame ProcessEvent: trying to send null event to plugin."); return rv; } @@ -1712,10 +1712,10 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent) } // Get reference point relative to plugin origin. - const nsPresContext* presContext = mObjectFrame->PresContext(); + const nsPresContext* presContext = mPluginFrame->PresContext(); nsPoint appPoint = - nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame) - - mObjectFrame->GetContentRectRelativeToSelf().TopLeft(); + nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) - + mPluginFrame->GetContentRectRelativeToSelf().TopLeft(); nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x), presContext->AppUnitsToDevPixels(appPoint.y)); const WidgetMouseEvent& mouseEvent = *anEvent.AsMouseEvent(); @@ -1913,10 +1913,10 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent) } // Get reference point relative to plugin origin. - const nsPresContext* presContext = mObjectFrame->PresContext(); + const nsPresContext* presContext = mPluginFrame->PresContext(); nsPoint appPoint = - nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame) - - mObjectFrame->GetContentRectRelativeToSelf().TopLeft(); + nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) - + mPluginFrame->GetContentRectRelativeToSelf().TopLeft(); nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x), presContext->AppUnitsToDevPixels(appPoint.y)); @@ -2045,7 +2045,7 @@ nsPluginInstanceOwner::Destroy() #ifdef XP_MACOSX void nsPluginInstanceOwner::Paint(const gfxRect& aDirtyRect, CGContextRef cgContext) { - if (!mInstance || !mObjectFrame) + if (!mInstance || !mPluginFrame) return; gfxRect dirtyRectCopy = aDirtyRect; @@ -2067,7 +2067,7 @@ void nsPluginInstanceOwner::Paint(const gfxRect& aDirtyRect, CGContextRef cgCont void nsPluginInstanceOwner::DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGContextRef cgContext) { - if (!mInstance || !mObjectFrame) + if (!mInstance || !mPluginFrame) return; // The context given here is only valid during the HandleEvent call. @@ -2087,7 +2087,7 @@ void nsPluginInstanceOwner::DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGCon #ifdef XP_WIN void nsPluginInstanceOwner::Paint(const RECT& aDirty, HDC aDC) { - if (!mInstance || !mObjectFrame) + if (!mInstance || !mPluginFrame) return; NPEvent pluginEvent; @@ -2104,7 +2104,7 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext, const gfxRect& aFrameRect, const gfxRect& aDirtyRect) { - if (!mInstance || !mObjectFrame || !mPluginDocumentActiveState || mFullScreen) + if (!mInstance || !mPluginFrame || !mPluginDocumentActiveState || mFullScreen) return; int32_t model = mInstance->GetANPDrawingModel(); @@ -2169,7 +2169,7 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext, const gfxRect& aFrameRect, const gfxRect& aDirtyRect) { - if (!mInstance || !mObjectFrame) + if (!mInstance || !mPluginFrame) return; // to provide crisper and faster drawing. @@ -2372,7 +2372,7 @@ nsresult nsPluginInstanceOwner::Init(nsIContent* aContent) // done at a higher level than this (content). nsIFrame* frame = aContent->GetPrimaryFrame(); nsIObjectFrame* iObjFrame = do_QueryFrame(frame); - nsObjectFrame* objFrame = static_cast(iObjFrame); + nsPluginFrame* objFrame = static_cast(iObjFrame); if (objFrame) { SetFrame(objFrame); // Some plugins require a specific sequence of shutdown and startup when @@ -2524,9 +2524,9 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void) #endif } - if (mObjectFrame) { + if (mPluginFrame) { // nullptr widget is fine, will result in windowless setup. - mObjectFrame->PrepForDrawing(mWidget); + mPluginFrame->PrepForDrawing(mWidget); } if (windowless) { @@ -2573,21 +2573,21 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void) void* nsPluginInstanceOwner::FixUpPluginWindow(int32_t inPaintState) { - if (!mWidget || !mPluginWindow || !mInstance || !mObjectFrame) + if (!mWidget || !mPluginWindow || !mInstance || !mPluginFrame) return nullptr; nsCOMPtr pluginWidget = do_QueryInterface(mWidget); if (!pluginWidget) return nullptr; - // If we've already set up a CGContext in nsObjectFrame::PaintPlugin(), we + // If we've already set up a CGContext in nsPluginFrame::PaintPlugin(), we // don't want calls to SetPluginPortAndDetectChange() to step on our work. if (mInCGPaintLevel < 1) { SetPluginPortAndDetectChange(); } // We'll need the top-level Cocoa window for the Cocoa event model. - nsIWidget* widget = mObjectFrame->GetNearestWidget(); + nsIWidget* widget = mPluginFrame->GetNearestWidget(); if (!widget) return nullptr; void *cocoaTopLevelWindow = widget->GetNativeData(NS_NATIVE_WINDOW); @@ -2722,7 +2722,7 @@ void nsPluginInstanceOwner::UpdateWindowPositionAndClipRect(bool aSetWindow) const NPWindow oldWindow = *mPluginWindow; bool windowless = (mPluginWindow->type == NPWindowTypeDrawable); - nsIntPoint origin = mObjectFrame->GetWindowOriginInPixels(windowless); + nsIntPoint origin = mPluginFrame->GetWindowOriginInPixels(windowless); mPluginWindow->x = origin.x; mPluginWindow->y = origin.y; @@ -2786,8 +2786,8 @@ nsPluginInstanceOwner::UpdateDocumentActiveState(bool aIsActive) NS_IMETHODIMP nsPluginInstanceOwner::CallSetWindow() { - if (mObjectFrame) { - mObjectFrame->CallSetWindow(false); + if (mPluginFrame) { + mPluginFrame->CallSetWindow(false); } else if (mInstance) { if (UseAsyncRendering()) { mInstance->AsyncSetWindow(mPluginWindow); @@ -2818,32 +2818,32 @@ nsPluginInstanceOwner::GetContentsScaleFactor(double *result) return NS_OK; } -void nsPluginInstanceOwner::SetFrame(nsObjectFrame *aFrame) +void nsPluginInstanceOwner::SetFrame(nsPluginFrame *aFrame) { // Don't do anything if the frame situation hasn't changed. - if (mObjectFrame == aFrame) { + if (mPluginFrame == aFrame) { return; } // If we already have a frame that is changing or going away... - if (mObjectFrame) { + if (mPluginFrame) { // Make sure the old frame isn't holding a reference to us. - mObjectFrame->SetInstanceOwner(nullptr); + mPluginFrame->SetInstanceOwner(nullptr); } // Swap in the new frame (or no frame) - mObjectFrame = aFrame; + mPluginFrame = aFrame; // Set up a new frame - if (mObjectFrame) { - mObjectFrame->SetInstanceOwner(this); + if (mPluginFrame) { + mPluginFrame->SetInstanceOwner(this); // Can only call PrepForDrawing on an object frame once. Don't do it here unless // widget creation is complete. Doesn't matter if we actually have a widget. if (mWidgetCreationComplete) { - mObjectFrame->PrepForDrawing(mWidget); + mPluginFrame->PrepForDrawing(mWidget); } - mObjectFrame->FixupWindow(mObjectFrame->GetContentRectRelativeToSelf().Size()); - mObjectFrame->InvalidateFrame(); + mPluginFrame->FixupWindow(mPluginFrame->GetContentRectRelativeToSelf().Size()); + mPluginFrame->InvalidateFrame(); nsFocusManager* fm = nsFocusManager::GetFocusManager(); const nsIContent* content = aFrame->GetContent(); @@ -2853,9 +2853,9 @@ void nsPluginInstanceOwner::SetFrame(nsObjectFrame *aFrame) } } -nsObjectFrame* nsPluginInstanceOwner::GetFrame() +nsPluginFrame* nsPluginInstanceOwner::GetFrame() { - return mObjectFrame; + return mPluginFrame; } NS_IMETHODIMP nsPluginInstanceOwner::PrivateModeChanged(bool aEnabled) diff --git a/dom/plugins/base/nsPluginInstanceOwner.h b/dom/plugins/base/nsPluginInstanceOwner.h index d86525691331..634311a3edbd 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.h +++ b/dom/plugins/base/nsPluginInstanceOwner.h @@ -26,7 +26,7 @@ class nsIInputStream; struct nsIntRect; class nsPluginDOMContextMenuListener; -class nsObjectFrame; +class nsPluginFrame; class nsDisplayListBuilder; namespace mozilla { @@ -143,9 +143,9 @@ public: // changed, and SetWindow() needs to be called again. void* SetPluginPortAndDetectChange(); // Flag when we've set up a Thebes (and CoreGraphics) context in - // nsObjectFrame::PaintPlugin(). We need to know this in + // nsPluginFrame::PaintPlugin(). We need to know this in // FixUpPluginWindow() (i.e. we need to know when FixUpPluginWindow() has - // been called from nsObjectFrame::PaintPlugin() when we're using the + // been called from nsPluginFrame::PaintPlugin() when we're using the // CoreGraphics drawing model). void BeginCGPaint(); void EndCGPaint(); @@ -155,8 +155,8 @@ public: void UpdateDocumentActiveState(bool aIsActive); #endif // XP_MACOSX - void SetFrame(nsObjectFrame *aFrame); - nsObjectFrame* GetFrame(); + void SetFrame(nsPluginFrame *aFrame); + nsPluginFrame* GetFrame(); uint32_t GetLastEventloopNestingLevel() const { return mLastEventloopNestingLevel; @@ -276,7 +276,7 @@ private: nsPluginNativeWindow *mPluginWindow; nsRefPtr mInstance; - nsObjectFrame *mObjectFrame; + nsPluginFrame *mPluginFrame; nsIContent *mContent; // WEAK, content owns us nsCString mDocumentBase; bool mWidgetCreationComplete; diff --git a/dom/plugins/base/nsPluginNativeWindowGtk.cpp b/dom/plugins/base/nsPluginNativeWindowGtk.cpp index 2c3ae4a89157..e664da52e761 100644 --- a/dom/plugins/base/nsPluginNativeWindowGtk.cpp +++ b/dom/plugins/base/nsPluginNativeWindowGtk.cpp @@ -145,7 +145,7 @@ nsresult nsPluginNativeWindowGtk::CallSetWindow(nsRefPtr // Make sure to resize and re-place the window if required. SetAllocation(); - // Need to reset "window" each time as nsObjectFrame::DidReflow sets it + // Need to reset "window" each time as nsPluginFrame::DidReflow sets it // to the ancestor window. #if (MOZ_WIDGET_GTK == 2) if (GTK_IS_XTBIN(mSocketWidget)) { @@ -225,7 +225,7 @@ nsresult nsPluginNativeWindowGtk::CreateXEmbedWindow(bool aEnableXtFocus) { SetWindow(gtk_socket_get_id(GTK_SOCKET(mSocketWidget))); // Fill out the ws_info structure. - // (The windowless case is done in nsObjectFrame.cpp.) + // (The windowless case is done in nsPluginFrame.cpp.) GdkWindow *gdkWindow = gdk_x11_window_lookup_for_display(display, GetWindow()); if(!gdkWindow) return NS_ERROR_FAILURE; diff --git a/dom/plugins/ipc/PluginInstanceChild.cpp b/dom/plugins/ipc/PluginInstanceChild.cpp index 50791ba61833..ce18ec310595 100644 --- a/dom/plugins/ipc/PluginInstanceChild.cpp +++ b/dom/plugins/ipc/PluginInstanceChild.cpp @@ -1948,7 +1948,7 @@ PluginInstanceChild::SharedSurfacePaint(NPEvent& evcopy) break; case RENDER_BACK_ONE: // Handle a double pass render used in alpha extraction for transparent - // plugins. (See nsObjectFrame and gfxWindowsNativeDrawing for details.) + // plugins. (See nsPluginFrame and gfxWindowsNativeDrawing for details.) // We render twice, once to the shared dib, and once to a cache which // we copy back on a second paint. These paints can't be spread across // multiple rpc messages as delays cause animation frame changes. diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index fa23e89280b9..c0c2ab318cd4 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -367,7 +367,7 @@ PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginDrawingModel( if (drawingModel == NPDrawingModelCoreAnimation || drawingModel == NPDrawingModelInvalidatingCoreAnimation) { // We need to request CoreGraphics otherwise - // the nsObjectFrame will try to draw a CALayer + // the nsPluginFrame will try to draw a CALayer // that can not be shared across process. mDrawingModel = drawingModel; *result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel, @@ -1231,7 +1231,7 @@ PluginInstanceParent::NPP_HandleEvent(void* event) case WM_WINDOWPOSCHANGED: { - // We send this in nsObjectFrame just before painting + // We send this in nsPluginFrame just before painting return SendWindowPosChanged(npremoteevent); } break; diff --git a/dom/plugins/test/testplugin/nptest_macosx.mm b/dom/plugins/test/testplugin/nptest_macosx.mm index ece4e248539e..3e8fa9c63cfb 100644 --- a/dom/plugins/test/testplugin/nptest_macosx.mm +++ b/dom/plugins/test/testplugin/nptest_macosx.mm @@ -100,7 +100,7 @@ pluginDoSetWindow(InstanceData* instanceData, NPWindow* newWindow) { // Ugh. Due to a terrible Gecko bug, we have to ignore position changes // when the clip rect doesn't change; the position can be wrong - // when set by a path other than nsObjectFrame::FixUpPluginWindow. + // when set by a path other than nsPluginFrame::FixUpPluginWindow. int32_t oldX = instanceData->window.x; int32_t oldY = instanceData->window.y; bool clipChanged = diff --git a/dom/tests/mochitest/general/mochitest.ini b/dom/tests/mochitest/general/mochitest.ini index dde7a7b348fc..ce316172e524 100644 --- a/dom/tests/mochitest/general/mochitest.ini +++ b/dom/tests/mochitest/general/mochitest.ini @@ -32,6 +32,7 @@ support-files = res7.resource^headers^ res8.resource res8.resource^headers^ + resource_timing.js [test_497898.html] skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || toolkit == 'android' #Bug 931116, b2g desktop specific, initial triage diff --git a/dom/tests/mochitest/general/resource_timing.js b/dom/tests/mochitest/general/resource_timing.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/dom/tests/mochitest/general/resource_timing_cross_origin.html b/dom/tests/mochitest/general/resource_timing_cross_origin.html index e4a8bdde10cd..c5b906280744 100644 --- a/dom/tests/mochitest/general/resource_timing_cross_origin.html +++ b/dom/tests/mochitest/general/resource_timing_cross_origin.html @@ -86,6 +86,10 @@ function firstCheck() { ok(!!entries[0], "redirected res8.resource is missing from entries"); checkRedirectCrossOriginResourceSameOrigin(entries[0]); + entries = window.performance.getEntriesByName("http://mochi.test:8888/tests/dom/tests/mochitest/general/resource_timing.js"); + ok(!!entries[0], "same origin resource_timing.js is missing from entries"); + checkSameOrigin(entries[0]); + is(bufferFullCounter, expectedBufferFullEvents, "Buffer full was called"); finishTests(); } @@ -176,6 +180,7 @@ function finishTests() { + diff --git a/dom/tests/mochitest/notification/mochitest.ini b/dom/tests/mochitest/notification/mochitest.ini index 9972c9c1d05d..0e47d3b7355d 100644 --- a/dom/tests/mochitest/notification/mochitest.ini +++ b/dom/tests/mochitest/notification/mochitest.ini @@ -6,7 +6,7 @@ support-files = [test_notification_basics.html] [test_notification_storage.html] -skip-if = (toolkit == 'gonk' && debug) #debug-only timeout +skip-if = (toolkit == 'gonk') [test_bug931307.html] skip-if = (toolkit == 'gonk' && debug) #debug-only timeout [test_notification_resend.html] diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index b790c118a832..76f1883b768a 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -95,6 +95,7 @@ static const char *sExtensionNames[] = { "GL_ARB_texture_float", "GL_ARB_texture_non_power_of_two", "GL_ARB_texture_rectangle", + "GL_ARB_texture_storage", "GL_ARB_transform_feedback2", "GL_ARB_uniform_buffer_object", "GL_ARB_vertex_array_object", @@ -930,6 +931,22 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl) } } + if (IsSupported(GLFeature::texture_storage)) { + SymLoadStruct coreSymbols[] = { + { (PRFuncPtr*) &mSymbols.fTexStorage2D, { "TexStorage2D", nullptr } }, + { (PRFuncPtr*) &mSymbols.fTexStorage3D, { "TexStorage3D", nullptr } }, + END_SYMBOLS + }; + + if (!LoadSymbols(coreSymbols, trygl, prefix)) { + NS_ERROR("GL supports texture storage without supplying its functions."); + + MarkUnsupported(GLFeature::texture_storage); + MarkExtensionUnsupported(ARB_texture_storage); + ClearSymbols(coreSymbols); + } + } + // ARB_transform_feedback2/NV_transform_feedback2 is a // superset of EXT_transform_feedback/NV_transform_feedback // and adds glPauseTransformFeedback & diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index cb9ffdb71dbc..f99d4e07ddfc 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -118,6 +118,7 @@ MOZ_BEGIN_ENUM_CLASS(GLFeature) texture_half_float, texture_half_float_linear, texture_non_power_of_two, + texture_storage, transform_feedback2, uniform_buffer_object, uniform_matrix_nonsquare, @@ -374,6 +375,7 @@ public: ARB_texture_float, ARB_texture_non_power_of_two, ARB_texture_rectangle, + ARB_texture_storage, ARB_transform_feedback2, ARB_uniform_buffer_object, ARB_vertex_array_object, @@ -3066,6 +3068,23 @@ public: AFTER_GL_CALL; } +// ----------------------------------------------------------------------------- +// Core GL 4.2, GL ES 3.0 & Extension ARB_texture_storage/EXT_texture_storage + void fTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) + { + BEFORE_GL_CALL; + ASSERT_SYMBOL_PRESENT(fTexStorage2D); + mSymbols.fTexStorage2D(target, levels, internalformat, width, height); + AFTER_GL_CALL; + } + + void fTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) + { + BEFORE_GL_CALL; + ASSERT_SYMBOL_PRESENT(fTexStorage3D); + mSymbols.fTexStorage3D(target, levels, internalformat, width, height, depth); + AFTER_GL_CALL; + } // ----------------------------------------------------------------------------- // 3D Textures diff --git a/gfx/gl/GLContextFeatures.cpp b/gfx/gl/GLContextFeatures.cpp index 2ea198a50ae7..771085bde13f 100644 --- a/gfx/gl/GLContextFeatures.cpp +++ b/gfx/gl/GLContextFeatures.cpp @@ -508,6 +508,20 @@ static const FeatureInfo sFeatureInfoArr[] = { GLContext::Extensions_End } }, + { + "texture_storage", + 420, // OpenGL version + 300, // OpenGL ES version + GLContext::ARB_texture_storage, + { + /* + * Not including GL_EXT_texture_storage here because it + * doesn't guarantee glTexStorage3D, which is required for + * WebGL 2. + */ + GLContext::Extensions_End + } + }, { "transform_feedback2", 400, // OpenGL version diff --git a/gfx/gl/GLContextSymbols.h b/gfx/gl/GLContextSymbols.h index 591abf1afc79..cf838f263c10 100644 --- a/gfx/gl/GLContextSymbols.h +++ b/gfx/gl/GLContextSymbols.h @@ -580,6 +580,12 @@ struct GLContextSymbols typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); PFNGLGETSAMPLERPARAMETERFVPROC fGetSamplerParameterfv; + // texture_storage + typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); + PFNGLTEXSTORAGE2DPROC fTexStorage2D; + typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + PFNGLTEXSTORAGE3DPROC fTexStorage3D; + // uniform_buffer_object typedef void (GLAPIENTRY * PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices); diff --git a/gfx/gl/SharedSurfaceANGLE.cpp b/gfx/gl/SharedSurfaceANGLE.cpp index 20ff9f872f6e..355a338427d2 100644 --- a/gfx/gl/SharedSurfaceANGLE.cpp +++ b/gfx/gl/SharedSurfaceANGLE.cpp @@ -11,6 +11,73 @@ namespace mozilla { namespace gl { +// Returns `EGL_NO_SURFACE` (`0`) on error. +static EGLSurface +CreatePBufferSurface(GLLibraryEGL* egl, + EGLDisplay display, + EGLConfig config, + const gfx::IntSize& size) +{ + auto width = size.width; + auto height = size.height; + + EGLint attribs[] = { + LOCAL_EGL_WIDTH, width, + LOCAL_EGL_HEIGHT, height, + LOCAL_EGL_NONE + }; + + DebugOnly preCallErr = egl->fGetError(); + MOZ_ASSERT(preCallErr == LOCAL_EGL_SUCCESS); + EGLSurface surface = egl->fCreatePbufferSurface(display, config, attribs); + EGLint err = egl->fGetError(); + if (err != LOCAL_EGL_SUCCESS) + return 0; + + return surface; +} + +/*static*/ UniquePtr +SharedSurface_ANGLEShareHandle::Create(GLContext* gl, + EGLContext context, EGLConfig config, + const gfx::IntSize& size, bool hasAlpha) +{ + GLLibraryEGL* egl = &sEGLLibrary; + MOZ_ASSERT(egl); + MOZ_ASSERT(egl->IsExtensionSupported( + GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle)); + + if (!context || !config) + return nullptr; + + EGLDisplay display = egl->Display(); + EGLSurface pbuffer = CreatePBufferSurface(egl, display, config, size); + if (!pbuffer) + return nullptr; + + // Declare everything before 'goto's. + HANDLE shareHandle = nullptr; + bool ok = egl->fQuerySurfacePointerANGLE(display, + pbuffer, + LOCAL_EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, + &shareHandle); + if (!ok) { + egl->fDestroySurface(egl->Display(), pbuffer); + return nullptr; + } + + GLuint fence = 0; + if (gl->IsExtensionSupported(GLContext::NV_fence)) { + gl->MakeCurrent(); + gl->fGenFences(1, &fence); + } + + typedef SharedSurface_ANGLEShareHandle ptrT; + UniquePtr ret( new ptrT(gl, egl, size, hasAlpha, context, + pbuffer, shareHandle, fence) ); + return Move(ret); +} + EGLDisplay SharedSurface_ANGLEShareHandle::Display() { @@ -114,6 +181,9 @@ SharedSurface_ANGLEShareHandle::PollSync_ContentThread_Impl() return PollSync(); } +//////////////////////////////////////////////////////////////////////////////// +// Factory + static void FillPBufferAttribs_ByBits(nsTArray& aAttrs, int redBits, int greenBits, @@ -169,15 +239,25 @@ FillPBufferAttribs_BySizes(nsTArray& attribs, alpha = 8; } - FillPBufferAttribs_ByBits(attribs, - red, green, blue, alpha, - depthBits, stencilBits); + FillPBufferAttribs_ByBits(attribs, red, green, blue, alpha, depthBits, + stencilBits); +} + +static bool +DoesAttribBitsMatchCapBool(GLLibraryEGL* egl, EGLConfig config, EGLint attrib, + bool capBool) +{ + EGLint bits = 0; + egl->fGetConfigAttrib(egl->Display(), config, attrib, &bits); + MOZ_ASSERT(egl->fGetError() == LOCAL_EGL_SUCCESS); + + bool hasBits = !!bits; + + return hasBits == capBool; } static EGLConfig -ChooseConfig(GLContext* gl, - GLLibraryEGL* egl, - const SurfaceCaps& caps) +ChooseConfig(GLContext* gl, GLLibraryEGL* egl, const SurfaceCaps& caps) { MOZ_ASSERT(egl); MOZ_ASSERT(caps.color); @@ -188,28 +268,43 @@ ChooseConfig(GLContext* gl, // Ok, now we have everything. nsTArray attribs(32); - FillPBufferAttribs_BySizes(attribs, - caps.bpp16, caps.alpha, - depthBits, stencilBits); + FillPBufferAttribs_BySizes(attribs, caps.bpp16, caps.alpha, depthBits, + stencilBits); // Time to try to get this config: EGLConfig configs[64]; int numConfigs = sizeof(configs)/sizeof(EGLConfig); int foundConfigs = 0; - if (!egl->fChooseConfig(egl->Display(), - attribs.Elements(), - configs, numConfigs, - &foundConfigs) || + if (!egl->fChooseConfig(egl->Display(), attribs.Elements(), configs, + numConfigs, &foundConfigs) || !foundConfigs) { NS_WARNING("No configs found for the requested formats."); return EGL_NO_CONFIG; } - // TODO: Pick a config progamatically instead of hoping that - // the first config will be minimally matching our request. - EGLConfig config = configs[0]; + // The requests passed to ChooseConfig are treated as minimums. If you ask + // for 0 bits of alpha, we might still get 8 bits. + EGLConfig config = EGL_NO_CONFIG; + for (int i = 0; i < foundConfigs; i++) { + EGLConfig cur = configs[0]; + if (DoesAttribBitsMatchCapBool(egl, cur, LOCAL_EGL_ALPHA_SIZE, + caps.alpha) && + DoesAttribBitsMatchCapBool(egl, cur, LOCAL_EGL_DEPTH_SIZE, + caps.depth) && + DoesAttribBitsMatchCapBool(egl, cur, LOCAL_EGL_STENCIL_SIZE, + caps.stencil)) + { + config = cur; + break; + } + } + + if (config == EGL_NO_CONFIG) { + NS_WARNING("No acceptable EGLConfig found."); + return EGL_NO_CONFIG; + } if (gl->DebugMode()) { egl->DumpEGLConfig(config); @@ -218,73 +313,6 @@ ChooseConfig(GLContext* gl, return config; } -// Returns `EGL_NO_SURFACE` (`0`) on error. -static EGLSurface -CreatePBufferSurface(GLLibraryEGL* egl, - EGLDisplay display, - EGLConfig config, - const gfx::IntSize& size) -{ - auto width = size.width; - auto height = size.height; - - EGLint attribs[] = { - LOCAL_EGL_WIDTH, width, - LOCAL_EGL_HEIGHT, height, - LOCAL_EGL_NONE - }; - - DebugOnly preCallErr = egl->fGetError(); - MOZ_ASSERT(preCallErr == LOCAL_EGL_SUCCESS); - EGLSurface surface = egl->fCreatePbufferSurface(display, config, attribs); - EGLint err = egl->fGetError(); - if (err != LOCAL_EGL_SUCCESS) - return 0; - - return surface; -} - -/*static*/ UniquePtr -SharedSurface_ANGLEShareHandle::Create(GLContext* gl, - EGLContext context, EGLConfig config, - const gfx::IntSize& size, bool hasAlpha) -{ - GLLibraryEGL* egl = &sEGLLibrary; - MOZ_ASSERT(egl); - MOZ_ASSERT(egl->IsExtensionSupported( - GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle)); - - if (!context || !config) - return nullptr; - - EGLDisplay display = egl->Display(); - EGLSurface pbuffer = CreatePBufferSurface(egl, display, config, size); - if (!pbuffer) - return nullptr; - - // Declare everything before 'goto's. - HANDLE shareHandle = nullptr; - bool ok = egl->fQuerySurfacePointerANGLE(display, - pbuffer, - LOCAL_EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, - &shareHandle); - if (!ok) { - egl->fDestroySurface(egl->Display(), pbuffer); - return nullptr; - } - - GLuint fence = 0; - if (gl->IsExtensionSupported(GLContext::NV_fence)) { - gl->MakeCurrent(); - gl->fGenFences(1, &fence); - } - - typedef SharedSurface_ANGLEShareHandle ptrT; - UniquePtr ret( new ptrT(gl, egl, size, hasAlpha, context, - pbuffer, shareHandle, fence) ); - return Move(ret); -} - /*static*/ UniquePtr SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, const SurfaceCaps& caps) @@ -295,25 +323,36 @@ SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, auto ext = GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle; if (!egl->IsExtensionSupported(ext)) - { return nullptr; - } + bool success; typedef SurfaceFactory_ANGLEShareHandle ptrT; - UniquePtr ret( new ptrT(gl, egl, caps) ); + UniquePtr ret( new ptrT(gl, egl, caps, &success) ); + + if (!success) + return nullptr; + return Move(ret); } SurfaceFactory_ANGLEShareHandle::SurfaceFactory_ANGLEShareHandle(GLContext* gl, GLLibraryEGL* egl, - const SurfaceCaps& caps) + const SurfaceCaps& caps, + bool* const out_success) : SurfaceFactory(gl, SharedSurfaceType::EGLSurfaceANGLE, caps) , mProdGL(gl) , mEGL(egl) { - mConfig = ChooseConfig(mProdGL, mEGL, mReadCaps); + MOZ_ASSERT(out_success); + *out_success = false; + mContext = GLContextEGL::Cast(mProdGL)->GetEGLContext(); + mConfig = ChooseConfig(mProdGL, mEGL, mReadCaps); + if (mConfig == EGL_NO_CONFIG) + return; + MOZ_ASSERT(mConfig && mContext); + *out_success = true; } } /* namespace gl */ diff --git a/gfx/gl/SharedSurfaceANGLE.h b/gfx/gl/SharedSurfaceANGLE.h index 334d7b6dfecb..d13c7771a605 100644 --- a/gfx/gl/SharedSurfaceANGLE.h +++ b/gfx/gl/SharedSurfaceANGLE.h @@ -88,7 +88,8 @@ public: protected: SurfaceFactory_ANGLEShareHandle(GLContext* gl, GLLibraryEGL* egl, - const SurfaceCaps& caps); + const SurfaceCaps& caps, + bool* const out_success); virtual UniquePtr CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE { bool hasAlpha = mReadCaps.alpha; diff --git a/gfx/src/nsDeviceContext.cpp b/gfx/src/nsDeviceContext.cpp index 708f10f2d64d..631bcc4d342a 100644 --- a/gfx/src/nsDeviceContext.cpp +++ b/gfx/src/nsDeviceContext.cpp @@ -143,7 +143,7 @@ nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage, mFontMetrics.RemoveElementAt(i); mFontMetrics.AppendElement(fm); } - fm->GetThebesFontGroup()->UpdateFontList(); + fm->GetThebesFontGroup()->UpdateUserFonts(); NS_ADDREF(aMetrics = fm); return NS_OK; } diff --git a/gfx/src/nsFontMetrics.cpp b/gfx/src/nsFontMetrics.cpp index 4cba05af8fda..1e1a902b4acf 100644 --- a/gfx/src/nsFontMetrics.cpp +++ b/gfx/src/nsFontMetrics.cpp @@ -132,9 +132,6 @@ nsFontMetrics::Init(const nsFont& aFont, nsIAtom* aLanguage, mFontGroup = gfxPlatform::GetPlatform()-> CreateFontGroup(aFont.fontlist, &style, aUserFontSet); mFontGroup->SetTextPerfMetrics(aTextPerf); - if (mFontGroup->FontListLength() < 1) - return NS_ERROR_UNEXPECTED; - return NS_OK; } @@ -150,7 +147,7 @@ nsFontMetrics::Destroy() const gfxFont::Metrics& nsFontMetrics::GetMetrics() const { - return mFontGroup->GetFontAt(0)->GetMetrics(); + return mFontGroup->GetFirstValidFont()->GetMetrics(); } nscoord diff --git a/gfx/thebes/gfxASurface.h b/gfx/thebes/gfxASurface.h index 33aaf7e0c02b..4cefa659fa53 100644 --- a/gfx/thebes/gfxASurface.h +++ b/gfx/thebes/gfxASurface.h @@ -126,12 +126,6 @@ public: */ static int32_t FormatStrideForWidth(gfxImageFormat format, int32_t width); - /* Return the default set of context flags for this surface; these are - * hints to the context about any special rendering considerations. See - * gfxContext::SetFlag for documentation. - */ - virtual int32_t GetDefaultContextFlags() const { return 0; } - static gfxContentType ContentFromFormat(gfxImageFormat format); void SetSubpixelAntialiasingEnabled(bool aEnabled); diff --git a/gfx/thebes/gfxPDFSurface.h b/gfx/thebes/gfxPDFSurface.h index 6d889b6151d8..15eb6c209d49 100644 --- a/gfx/thebes/gfxPDFSurface.h +++ b/gfx/thebes/gfxPDFSurface.h @@ -34,13 +34,6 @@ public: return gfxIntSize(mSize.width, mSize.height); } - virtual int32_t GetDefaultContextFlags() const - { - return gfxContext::FLAG_SIMPLIFY_OPERATORS | - gfxContext::FLAG_DISABLE_SNAPPING | - gfxContext::FLAG_DISABLE_COPY_BACKGROUND; - } - private: nsCOMPtr mStream; double mXDPI; diff --git a/gfx/thebes/gfxPSSurface.h b/gfx/thebes/gfxPSSurface.h index 7eca6dc7caca..805ce9418105 100644 --- a/gfx/thebes/gfxPSSurface.h +++ b/gfx/thebes/gfxPSSurface.h @@ -41,12 +41,6 @@ public: return mSize; } - virtual int32_t GetDefaultContextFlags() const - { - return gfxContext::FLAG_SIMPLIFY_OPERATORS | - gfxContext::FLAG_DISABLE_SNAPPING; - } - private: nsCOMPtr mStream; double mXDPI; diff --git a/gfx/thebes/gfxPangoFonts.cpp b/gfx/thebes/gfxPangoFonts.cpp index 7f24b3bc3163..be3eb1c319e2 100644 --- a/gfx/thebes/gfxPangoFonts.cpp +++ b/gfx/thebes/gfxPangoFonts.cpp @@ -813,8 +813,8 @@ FindFontPatterns(gfxUserFontSet *mUserFontSet, gfxFontFamily *family = mUserFontSet->LookupFamily(utf16Family); if (family) { gfxUserFontEntry* userFontEntry = - mUserFontSet->FindUserFontEntry(family, style, needsBold, - aWaitForUserFont); + mUserFontSet->FindUserFontEntryAndLoad(family, style, needsBold, + aWaitForUserFont); if (userFontEntry) { fontEntry = static_cast (userFontEntry->GetPlatformFontEntry()); @@ -826,9 +826,10 @@ FindFontPatterns(gfxUserFontSet *mUserFontSet, // and probably never use it if (!fontEntry && aStyle != NS_FONT_STYLE_NORMAL) { style.style = NS_FONT_STYLE_NORMAL; - userFontEntry = mUserFontSet->FindUserFontEntry(family, style, - needsBold, - aWaitForUserFont); + userFontEntry = + mUserFontSet->FindUserFontEntryAndLoad(family, style, + needsBold, + aWaitForUserFont); if (userFontEntry) { fontEntry = static_cast (userFontEntry->GetPlatformFontEntry()); @@ -1308,16 +1309,22 @@ gfxPangoFontGroup::GetBaseFont() return static_cast(mFonts[0].Font()); } +gfxFont* +gfxPangoFontGroup::GetFirstValidFont() +{ + return GetFontAt(0); +} + gfxFont * gfxPangoFontGroup::GetFontAt(int32_t i) { // If it turns out to be hard for all clients that cache font - // groups to call UpdateFontList at appropriate times, we could - // instead consider just calling UpdateFontList from someplace + // groups to call UpdateUserFonts at appropriate times, we could + // instead consider just calling UpdateUserFonts from someplace // more central (such as here). NS_ASSERTION(!mUserFontSet || mCurrGeneration == GetGeneration(), "Whoever was caching this font group should have " - "called UpdateFontList on it"); + "called UpdateUserFonts on it"); NS_PRECONDITION(i == 0, "Only have one font"); @@ -1325,7 +1332,7 @@ gfxPangoFontGroup::GetFontAt(int32_t i) } void -gfxPangoFontGroup::UpdateFontList() +gfxPangoFontGroup::UpdateUserFonts() { uint64_t newGeneration = GetGeneration(); if (newGeneration == mCurrGeneration) diff --git a/gfx/thebes/gfxPangoFonts.h b/gfx/thebes/gfxPangoFonts.h index 04175a083b72..a8cad6353f99 100644 --- a/gfx/thebes/gfxPangoFonts.h +++ b/gfx/thebes/gfxPangoFonts.h @@ -30,9 +30,11 @@ public: virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle); + virtual gfxFont* GetFirstValidFont(); + virtual gfxFont *GetFontAt(int32_t i); - virtual void UpdateFontList(); + virtual void UpdateUserFonts(); virtual already_AddRefed FindFontForChar(uint32_t aCh, uint32_t aPrevCh, int32_t aRunScript, diff --git a/gfx/thebes/gfxQuartzSurface.cpp b/gfx/thebes/gfxQuartzSurface.cpp index 446d7ecf391a..7887cc820e6d 100644 --- a/gfx/thebes/gfxQuartzSurface.cpp +++ b/gfx/thebes/gfxQuartzSurface.cpp @@ -15,9 +15,8 @@ gfxQuartzSurface::MakeInvalid() mSize = gfxIntSize(-1, -1); } -gfxQuartzSurface::gfxQuartzSurface(const gfxSize& desiredSize, gfxImageFormat format, - bool aForPrinting) - : mCGContext(nullptr), mSize(desiredSize), mForPrinting(aForPrinting) +gfxQuartzSurface::gfxQuartzSurface(const gfxSize& desiredSize, gfxImageFormat format) + : mCGContext(nullptr), mSize(desiredSize) { gfxIntSize size((unsigned int) floor(desiredSize.width), (unsigned int) floor(desiredSize.height)); @@ -41,9 +40,8 @@ gfxQuartzSurface::gfxQuartzSurface(const gfxSize& desiredSize, gfxImageFormat fo } gfxQuartzSurface::gfxQuartzSurface(CGContextRef context, - const gfxSize& desiredSize, - bool aForPrinting) - : mCGContext(context), mSize(desiredSize), mForPrinting(aForPrinting) + const gfxSize& desiredSize) + : mCGContext(context), mSize(desiredSize) { gfxIntSize size((unsigned int) floor(desiredSize.width), (unsigned int) floor(desiredSize.height)); @@ -66,9 +64,8 @@ gfxQuartzSurface::gfxQuartzSurface(CGContextRef context, } gfxQuartzSurface::gfxQuartzSurface(CGContextRef context, - const gfxIntSize& size, - bool aForPrinting) - : mCGContext(context), mSize(size), mForPrinting(aForPrinting) + const gfxIntSize& size) + : mCGContext(context), mSize(size) { if (!CheckSurfaceSize(size)) MakeInvalid(); @@ -89,9 +86,8 @@ gfxQuartzSurface::gfxQuartzSurface(CGContextRef context, } gfxQuartzSurface::gfxQuartzSurface(cairo_surface_t *csurf, - const gfxIntSize& aSize, - bool aForPrinting) : - mSize(aSize), mForPrinting(aForPrinting) + const gfxIntSize& aSize) : + mSize(aSize) { mCGContext = cairo_quartz_surface_get_cg_context (csurf); CGContextRetain (mCGContext); @@ -102,9 +98,8 @@ gfxQuartzSurface::gfxQuartzSurface(cairo_surface_t *csurf, gfxQuartzSurface::gfxQuartzSurface(unsigned char *data, const gfxSize& desiredSize, long stride, - gfxImageFormat format, - bool aForPrinting) - : mCGContext(nullptr), mSize(desiredSize), mForPrinting(aForPrinting) + gfxImageFormat format) + : mCGContext(nullptr), mSize(desiredSize) { gfxIntSize size((unsigned int) floor(desiredSize.width), (unsigned int) floor(desiredSize.height)); @@ -130,9 +125,8 @@ gfxQuartzSurface::gfxQuartzSurface(unsigned char *data, gfxQuartzSurface::gfxQuartzSurface(unsigned char *data, const gfxIntSize& aSize, long stride, - gfxImageFormat format, - bool aForPrinting) - : mCGContext(nullptr), mSize(aSize.width, aSize.height), mForPrinting(aForPrinting) + gfxImageFormat format) + : mCGContext(nullptr), mSize(aSize.width, aSize.height) { if (!CheckSurfaceSize(aSize)) MakeInvalid(); @@ -173,15 +167,6 @@ gfxQuartzSurface::GetCGContextWithClip(gfxContext *ctx) return cairo_quartz_get_cg_context_with_clip(ctx->GetCairo()); } -int32_t gfxQuartzSurface::GetDefaultContextFlags() const -{ - if (mForPrinting) - return gfxContext::FLAG_DISABLE_SNAPPING | - gfxContext::FLAG_DISABLE_COPY_BACKGROUND; - - return 0; -} - already_AddRefed gfxQuartzSurface::GetAsImageSurface() { cairo_surface_t *surface = cairo_quartz_surface_get_image(mSurface); diff --git a/gfx/thebes/gfxQuartzSurface.h b/gfx/thebes/gfxQuartzSurface.h index ec26184b7e50..368d89a05bb7 100644 --- a/gfx/thebes/gfxQuartzSurface.h +++ b/gfx/thebes/gfxQuartzSurface.h @@ -17,12 +17,12 @@ class gfxImageSurface; class gfxQuartzSurface : public gfxASurface { public: - gfxQuartzSurface(const gfxSize& size, gfxImageFormat format, bool aForPrinting = false); - gfxQuartzSurface(CGContextRef context, const gfxSize& size, bool aForPrinting = false); - gfxQuartzSurface(CGContextRef context, const gfxIntSize& size, bool aForPrinting = false); - gfxQuartzSurface(cairo_surface_t *csurf, const gfxIntSize& aSize, bool aForPrinting = false); - gfxQuartzSurface(unsigned char *data, const gfxSize& size, long stride, gfxImageFormat format, bool aForPrinting = false); - gfxQuartzSurface(unsigned char *data, const gfxIntSize& size, long stride, gfxImageFormat format, bool aForPrinting = false); + gfxQuartzSurface(const gfxSize& size, gfxImageFormat format); + gfxQuartzSurface(CGContextRef context, const gfxSize& size); + gfxQuartzSurface(CGContextRef context, const gfxIntSize& size); + gfxQuartzSurface(cairo_surface_t *csurf, const gfxIntSize& aSize); + gfxQuartzSurface(unsigned char *data, const gfxSize& size, long stride, gfxImageFormat format); + gfxQuartzSurface(unsigned char *data, const gfxIntSize& size, long stride, gfxImageFormat format); virtual ~gfxQuartzSurface(); @@ -35,8 +35,6 @@ public: CGContextRef GetCGContextWithClip(gfxContext *ctx); - virtual int32_t GetDefaultContextFlags() const; - already_AddRefed GetAsImageSurface(); protected: @@ -44,7 +42,6 @@ protected: CGContextRef mCGContext; gfxSize mSize; - bool mForPrinting; }; #endif /* GFX_QUARTZSURFACE_H */ diff --git a/gfx/thebes/gfxTextRun.cpp b/gfx/thebes/gfxTextRun.cpp index 05eee26bb40d..063a8dc93838 100644 --- a/gfx/thebes/gfxTextRun.cpp +++ b/gfx/thebes/gfxTextRun.cpp @@ -1469,11 +1469,15 @@ gfxFontGroup::gfxFontGroup(const FontFamilyList& aFontFamilyList, , mSkipDrawing(false) { // We don't use SetUserFontSet() here, as we want to unconditionally call - // BuildFontList() rather than only do UpdateFontList() if it changed. + // BuildFontList() rather than only do UpdateUserFonts() if it changed. mCurrGeneration = GetGeneration(); BuildFontList(); } +gfxFontGroup::~gfxFontGroup() +{ +} + void gfxFontGroup::FindGenericFonts(FontFamilyType aGenericType, nsIAtom *aLanguage, @@ -1611,77 +1615,7 @@ gfxFontGroup::BuildFontList() { // gfxPangoFontGroup behaves differently, so this method is a no-op on that platform #if defined(XP_MACOSX) || defined(XP_WIN) || defined(ANDROID) - EnumerateFontList(mStyle.language); - - // at this point, fontlist should have been filled in - // get a default font if none exists - if (mFonts.Length() == 0) { - bool needsBold; - gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList(); - gfxFontFamily *defaultFamily = pfl->GetDefaultFont(&mStyle); - NS_ASSERTION(defaultFamily, - "invalid default font returned by GetDefaultFont"); - - if (defaultFamily) { - gfxFontEntry *fe = defaultFamily->FindFontForStyle(mStyle, - needsBold); - if (fe) { - nsRefPtr font = fe->FindOrMakeFont(&mStyle, - needsBold); - if (font) { - mFonts.AppendElement(FamilyFace(defaultFamily, font)); - } - } - } - - if (mFonts.Length() == 0) { - // Try for a "font of last resort...." - // Because an empty font list would be Really Bad for later code - // that assumes it will be able to get valid metrics for layout, - // just look for the first usable font and put in the list. - // (see bug 554544) - nsAutoTArray,200> families; - pfl->GetFontFamilyList(families); - uint32_t count = families.Length(); - for (uint32_t i = 0; i < count; ++i) { - gfxFontEntry *fe = families[i]->FindFontForStyle(mStyle, - needsBold); - if (fe) { - nsRefPtr font = fe->FindOrMakeFont(&mStyle, - needsBold); - if (font) { - mFonts.AppendElement(FamilyFace(families[i], font)); - break; - } - } - } - } - - if (mFonts.Length() == 0) { - // an empty font list at this point is fatal; we're not going to - // be able to do even the most basic layout operations - char msg[256]; // CHECK buffer length if revising message below - nsAutoString families; - mFamilyList.ToString(families); - sprintf(msg, "unable to find a usable font (%.220s)", - NS_ConvertUTF16toUTF8(families).get()); - NS_RUNTIMEABORT(msg); - } - } - - if (!mStyle.systemFont) { - uint32_t count = mFonts.Length(); - for (uint32_t i = 0; i < count; ++i) { - gfxFont* font = mFonts[i].Font(); - if (font->GetFontEntry()->mIsBadUnderlineFont) { - gfxFloat first = mFonts[0].Font()->GetMetrics().underlineOffset; - gfxFloat bad = font->GetMetrics().underlineOffset; - mUnderlineOffset = std::min(first, bad); - break; - } - } - } #endif } @@ -1700,21 +1634,11 @@ gfxFontGroup::FindPlatformFont(const nsAString& aName, // font of the same name, even if we fail to actually get a fontEntry // here; we'll fall back to the next name in the CSS font-family list. if (mUserFontSet) { - // If the fontSet matches the family, but the font has not yet finished - // loading (nor has its load timeout fired), the fontGroup should wait - // for the download, and not actually draw its text yet. + // add the userfont to the fontlist whether it's already been loaded + // or not. loading is initiated during font matching. family = mUserFontSet->LookupFamily(aName); if (family) { - bool waitForUserFont = false; - gfxUserFontEntry* userFontEntry = - mUserFontSet->FindUserFontEntry(family, mStyle, needsBold, - waitForUserFont); - if (userFontEntry) { - fe = userFontEntry->GetPlatformFontEntry(); - } - if (!fe && waitForUserFont) { - mSkipDrawing = true; - } + fe = mUserFontSet->FindUserFontEntry(family, mStyle, needsBold); } } } @@ -1730,10 +1654,7 @@ gfxFontGroup::FindPlatformFont(const nsAString& aName, // add to the font group, unless it's already there if (fe && !HasFont(fe)) { - nsRefPtr font = fe->FindOrMakeFont(&mStyle, needsBold); - if (font) { - mFonts.AppendElement(FamilyFace(family, font)); - } + mFonts.AppendElement(FamilyFace(family, fe, needsBold)); } } @@ -1742,15 +1663,142 @@ gfxFontGroup::HasFont(const gfxFontEntry *aFontEntry) { uint32_t count = mFonts.Length(); for (uint32_t i = 0; i < count; ++i) { - if (mFonts[i].Font()->GetFontEntry() == aFontEntry) + if (mFonts[i].FontEntry() == aFontEntry) { return true; + } } return false; } -gfxFontGroup::~gfxFontGroup() +gfxFont* +gfxFontGroup::GetFontAt(int32_t i) { - mFonts.Clear(); + if (uint32_t(i) >= mFonts.Length()) { + return nullptr; + } + + FamilyFace& ff = mFonts[i]; + if (ff.IsInvalid() || ff.IsLoading()) { + return nullptr; + } + + nsRefPtr font = ff.Font(); + if (!font) { + gfxFontEntry *fe = mFonts[i].FontEntry(); + if (fe->mIsUserFontContainer) { + gfxUserFontEntry* ufe = static_cast(fe); + if (ufe->LoadState() == gfxUserFontEntry::STATUS_NOT_LOADED) { + ufe->Load(); + if (ufe->WaitForUserFont()) { + mSkipDrawing = true; + } + } + fe = ufe->GetPlatformFontEntry(); + if (!fe) { + return nullptr; + } + } + font = fe->FindOrMakeFont(&mStyle, mFonts[i].NeedsBold()); + if (font && !font->Valid()) { + ff.SetInvalid(); + return nullptr; + } + mFonts[i].SetFont(font); + } + return font.get(); +} + +gfxFont* +gfxFontGroup::GetDefaultFont() +{ + if (mDefaultFont) { + return mDefaultFont.get(); + } + + bool needsBold; + gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList(); + gfxFontFamily *defaultFamily = pfl->GetDefaultFont(&mStyle); + NS_ASSERTION(defaultFamily, + "invalid default font returned by GetDefaultFont"); + + if (defaultFamily) { + gfxFontEntry *fe = defaultFamily->FindFontForStyle(mStyle, + needsBold); + if (fe) { + mDefaultFont = fe->FindOrMakeFont(&mStyle, needsBold); + } + } + + if (!mDefaultFont) { + // Try for a "font of last resort...." + // Because an empty font list would be Really Bad for later code + // that assumes it will be able to get valid metrics for layout, + // just look for the first usable font and put in the list. + // (see bug 554544) + nsAutoTArray,200> families; + pfl->GetFontFamilyList(families); + uint32_t count = families.Length(); + for (uint32_t i = 0; i < count; ++i) { + gfxFontEntry *fe = families[i]->FindFontForStyle(mStyle, + needsBold); + if (fe) { + mDefaultFont = fe->FindOrMakeFont(&mStyle, needsBold); + } + } + } + + if (!mDefaultFont) { + // an empty font list at this point is fatal; we're not going to + // be able to do even the most basic layout operations + char msg[256]; // CHECK buffer length if revising message below + nsAutoString families; + mFamilyList.ToString(families); + sprintf(msg, "unable to find a usable font (%.220s)", + NS_ConvertUTF16toUTF8(families).get()); + NS_RUNTIMEABORT(msg); + } + + return mDefaultFont.get(); +} + + +gfxFont* +gfxFontGroup::GetFirstValidFont() +{ + uint32_t count = mFonts.Length(); + for (uint32_t i = 0; i < count; ++i) { + FamilyFace& ff = mFonts[i]; + if (ff.IsInvalid()) { + continue; + } + + // already have a font? + gfxFont* font = ff.Font(); + if (font) { + return font; + } + + // need to build a font, loading userfont if not loaded + if (ff.IsUserFont()) { + gfxUserFontEntry* ufe = + static_cast(mFonts[i].FontEntry()); + if (ufe->LoadState() == gfxUserFontEntry::STATUS_NOT_LOADED) { + ufe->Load(); + if (ufe->WaitForUserFont()) { + mSkipDrawing = true; + } + } + if (ufe->LoadState() != gfxUserFontEntry::STATUS_LOADED) { + continue; + } + } + + font = GetFontAt(i); + if (font) { + return font; + } + } + return GetDefaultFont(); } gfxFont * @@ -1759,7 +1807,7 @@ gfxFontGroup::GetFirstMathFont() uint32_t count = mFonts.Length(); for (uint32_t i = 0; i < count; ++i) { gfxFont* font = GetFontAt(i); - if (font->GetFontEntry()->TryGetMathTable()) { + if (font && font->GetFontEntry()->TryGetMathTable()) { return font; } } @@ -1818,7 +1866,7 @@ gfxFontGroup::MakeSpaceTextRun(const Parameters *aParams, uint32_t aFlags) orientation = TEXT_ORIENT_VERTICAL_UPRIGHT; } - gfxFont *font = GetFontAt(0); + gfxFont *font = GetFirstValidFont(); if (MOZ_UNLIKELY(GetStyle()->size == 0)) { // Short-circuit for size-0 fonts, as Windows and ATSUI can't handle // them, and always create at least size 1 fonts, i.e. they still @@ -1864,7 +1912,7 @@ gfxFontGroup::MakeBlankTextRun(uint32_t aLength, if (orientation == TEXT_ORIENT_VERTICAL_MIXED) { orientation = TEXT_ORIENT_VERTICAL_UPRIGHT; } - textRun->AddGlyphRun(GetFontAt(0), gfxTextRange::kFontGroup, 0, false, + textRun->AddGlyphRun(GetFirstValidFont(), gfxTextRange::kFontGroup, 0, false, orientation); return textRun; } @@ -1876,8 +1924,8 @@ gfxFontGroup::MakeHyphenTextRun(gfxContext *aCtx, uint32_t aAppUnitsPerDevUnit) // it's better to use ASCII '-' from the primary font than to fall back to // U+2010 from some other, possibly poorly-matching face static const char16_t hyphen = 0x2010; - gfxFont *font = GetFontAt(0); - if (font && font->HasCharacter(hyphen)) { + gfxFont *font = GetFirstValidFont(); + if (font->HasCharacter(hyphen)) { return MakeTextRun(&hyphen, 1, aCtx, aAppUnitsPerDevUnit, gfxFontGroup::TEXT_IS_PERSISTENT); } @@ -2147,7 +2195,15 @@ gfxFontGroup::InitScriptRun(gfxContext *aContext, NS_ASSERTION(aTextRun->GetShapingState() != gfxTextRun::eShapingState_Aborted, "don't call InitScriptRun with aborted shaping state"); - gfxFont *mainFont = GetFontAt(0); +#if defined(XP_MACOSX) || defined(XP_WIN) || defined(ANDROID) + // non-linux platforms build the fontlist lazily and include userfonts + // so need to confirm the load state of userfonts in the list + if (mUserFontSet && mCurrGeneration != mUserFontSet->GetGeneration()) { + UpdateUserFonts(); + } +#endif + + gfxFont *mainFont = GetFirstValidFont(); uint32_t runStart = 0; nsAutoTArray fontRanges; @@ -2353,7 +2409,7 @@ gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel, // Use a Unicode ellipsis if the font supports it, // otherwise use three ASCII periods as fallback. - gfxFont* firstFont = GetFontAt(0); + gfxFont* firstFont = GetFirstValidFont(); nsString ellipsis = firstFont->HasCharacter(kEllipsisChar[0]) ? nsDependentString(kEllipsisChar, ArrayLength(kEllipsisChar) - 1) @@ -2376,27 +2432,62 @@ gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel, } already_AddRefed -gfxFontGroup::TryAllFamilyMembers(gfxFontFamily* aFamily, uint32_t aCh) +gfxFontGroup::FindNonItalicFaceForChar(gfxFontFamily* aFamily, uint32_t aCh) { + NS_ASSERTION(mStyle.style != NS_FONT_STYLE_NORMAL, + "should only be called in the italic/oblique case"); + if (!aFamily->TestCharacterMap(aCh)) { return nullptr; } - // Note that we don't need the actual runScript in matchData for - // gfxFontFamily::SearchAllFontsForChar, it's only used for the - // system-fallback case. So we can just set it to 0 here. - GlobalFontMatch matchData(aCh, 0, &mStyle); - aFamily->SearchAllFontsForChar(&matchData); - gfxFontEntry *fe = matchData.mBestMatch; - if (!fe) { + gfxFontStyle regularStyle = mStyle; + regularStyle.style = NS_FONT_STYLE_NORMAL; + bool needsBold; + gfxFontEntry *fe = aFamily->FindFontForStyle(regularStyle, needsBold); + NS_ASSERTION(!fe->mIsUserFontContainer, + "should only be searching platform fonts"); + if (!fe->HasCharacter(aCh)) { return nullptr; } - bool needsBold = mStyle.weight >= 600 && !fe->IsBold(); nsRefPtr font = fe->FindOrMakeFont(&mStyle, needsBold); + if (!font->Valid()) { + return nullptr; + } return font.forget(); } +gfxFloat +gfxFontGroup::GetUnderlineOffset() +{ + if (mUnderlineOffset == UNDERLINE_OFFSET_NOT_SET) { + // if the fontlist contains a bad underline font, make the underline + // offset the min of the first valid font and bad font underline offsets + uint32_t len = mFonts.Length(); + for (uint32_t i = 0; i < len; i++) { + FamilyFace& ff = mFonts[i]; + if (!ff.IsUserFont() && ff.Family() && + ff.Family()->IsBadUnderlineFamily()) { + nsRefPtr font = GetFontAt(i); + if (!font) { + continue; + } + gfxFloat bad = font->GetMetrics().underlineOffset; + gfxFloat first = + GetFirstValidFont()->GetMetrics().underlineOffset; + mUnderlineOffset = std::min(first, bad); + return mUnderlineOffset; + } + } + + // no bad underline fonts, use the first valid font's metric + mUnderlineOffset = GetFirstValidFont()->GetMetrics().underlineOffset; + } + + return mUnderlineOffset; +} + already_AddRefed gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, int32_t aRunScript, gfxFont *aPrevMatchedFont, @@ -2410,18 +2501,26 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, bool isVarSelector = gfxFontUtils::IsVarSelector(aCh); if (!isJoinControl && !wasJoinCauser && !isVarSelector) { - nsRefPtr firstFont = mFonts[0].Font(); - if (firstFont->HasCharacter(aCh)) { - *aMatchType = gfxTextRange::kFontGroup; - return firstFont.forget(); - } - // It's possible that another font in the family (e.g. regular face, - // where the requested style was italic) will support the character - nsRefPtr font = TryAllFamilyMembers(mFonts[0].Family(), aCh); - if (font) { - *aMatchType = gfxTextRange::kFontGroup; - return font.forget(); + nsRefPtr firstFont = GetFontAt(0); + if (firstFont) { + if (firstFont->HasCharacter(aCh)) { + *aMatchType = gfxTextRange::kFontGroup; + return firstFont.forget(); + } + + // If italic, test the regular face to see if it supports character. + // Only do this for platform fonts, not userfonts. + if (mStyle.style != NS_FONT_STYLE_NORMAL && + !firstFont->GetFontEntry()->IsUserFont()) { + nsRefPtr font = + FindNonItalicFaceForChar(mFonts[0].Family(), aCh); + if (font) { + *aMatchType = gfxTextRange::kFontGroup; + return font.forget(); + } + } } + // we don't need to check the first font again below ++nextIndex; } @@ -2459,18 +2558,59 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, } // 1. check remaining fonts in the font group - uint32_t fontListLength = FontListLength(); + uint32_t fontListLength = mFonts.Length(); for (uint32_t i = nextIndex; i < fontListLength; i++) { - nsRefPtr font = mFonts[i].Font(); - if (font->HasCharacter(aCh)) { - *aMatchType = gfxTextRange::kFontGroup; - return font.forget(); + FamilyFace& ff = mFonts[i]; + if (ff.IsInvalid() || ff.IsLoading()) { + continue; } - font = TryAllFamilyMembers(mFonts[i].Family(), aCh); - if (font) { + nsRefPtr font; + + // test the font entry, build font if needed + gfxFontEntry *fe = ff.FontEntry(); + + if (fe->mIsUserFontContainer) { + // for userfonts, need to test the cmap of the platform font entry + gfxUserFontEntry* ufe = static_cast(fe); + if (ufe->LoadState() == gfxUserFontEntry::STATUS_NOT_LOADED) { + ufe->Load(); + if (ufe->WaitForUserFont()) { + mSkipDrawing = true; + } + } + gfxFontEntry* pfe = ufe->GetPlatformFontEntry(); + if (pfe && pfe->HasCharacter(aCh)) { + font = GetFontAt(i); + if (font) { + *aMatchType = gfxTextRange::kFontGroup; + return font.forget(); + } + } + } else if (fe->HasCharacter(aCh)) { + font = GetFontAt(i); + if (font) { + *aMatchType = gfxTextRange::kFontGroup; + return font.forget(); + } + } + + // If italic, test the regular face to see if it supports the character. + // Only do this for platform fonts, not userfonts. + if (mStyle.style != NS_FONT_STYLE_NORMAL && !ff.IsUserFont()) { + font = FindNonItalicFaceForChar(mFonts[i].Family(), aCh); + if (font) { + *aMatchType = gfxTextRange::kFontGroup; + return font.forget(); + } + } + } + + if (fontListLength == 0) { + nsRefPtr defaultFont = GetDefaultFont(); + if (defaultFont->HasCharacter(aCh)) { *aMatchType = gfxTextRange::kFontGroup; - return font.forget(); + return defaultFont.forget(); } } @@ -2502,7 +2642,7 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, // we'll synthesize appropriate-width spaces instead of missing-glyph boxes if (GetGeneralCategory(aCh) == HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR && - GetFontAt(0)->SynthesizeSpaceWidth(aCh) >= 0.0) + GetFirstValidFont()->SynthesizeSpaceWidth(aCh) >= 0.0) { return nullptr; } @@ -2527,7 +2667,7 @@ void gfxFontGroup::ComputeRanges(nsTArray& aRanges, // initialize prevFont to the group's primary font, so that this will be // used for string-initial control chars, etc rather than risk hitting font // fallback for these (bug 716229) - gfxFont *prevFont = GetFontAt(0); + gfxFont *prevFont = GetFirstValidFont(); // if we use the initial value of prevFont, we treat this as a match from // the font group; fixes bug 978313 @@ -2630,7 +2770,7 @@ gfxFontGroup::SetUserFontSet(gfxUserFontSet *aUserFontSet) } mUserFontSet = aUserFontSet; mCurrGeneration = GetGeneration() - 1; - UpdateFontList(); + UpdateUserFonts(); } uint64_t @@ -2641,19 +2781,60 @@ gfxFontGroup::GetGeneration() return mUserFontSet->GetGeneration(); } -// note: gfxPangoFontGroup overrides UpdateFontList, such that +uint64_t +gfxFontGroup::GetRebuildGeneration() +{ + if (!mUserFontSet) + return 0; + return mUserFontSet->GetRebuildGeneration(); +} + +// note: gfxPangoFontGroup overrides UpdateUserFonts, such that // BuildFontList is never used void -gfxFontGroup::UpdateFontList() +gfxFontGroup::UpdateUserFonts() { - if (mCurrGeneration != GetGeneration()) { - // xxx - can probably improve this to detect when all fonts were found, so no need to update list + if (mCurrGeneration < GetRebuildGeneration()) { + // fonts in userfont set changed, need to redo the fontlist mFonts.Clear(); mUnderlineOffset = UNDERLINE_OFFSET_NOT_SET; mSkipDrawing = false; BuildFontList(); mCurrGeneration = GetGeneration(); mCachedEllipsisTextRun = nullptr; + } else if (mCurrGeneration != GetGeneration()) { + // load state change occurred, verify load state and validity of fonts + mSkipDrawing = false; + mUnderlineOffset = UNDERLINE_OFFSET_NOT_SET; + mCachedEllipsisTextRun = nullptr; + + uint32_t len = mFonts.Length(); + for (uint32_t i = 0; i < len; i++) { + FamilyFace& ff = mFonts[i]; + if (ff.Font() || !ff.IsUserFont()) { + continue; + } + + // confirm status + gfxUserFontEntry *ufe = + static_cast(mFonts[i].FontEntry()); + gfxUserFontEntry::UserFontLoadState state = ufe->LoadState(); + switch (state) { + case gfxUserFontEntry::STATUS_LOADING: + ff.SetLoading(true); + break; + case gfxUserFontEntry::STATUS_FAILED: + ff.SetInvalid(); + // fall-thru to the default case + default: + ff.SetLoading(false); + } + if (ufe->WaitForUserFont()) { + mSkipDrawing = true; + } + } + + mCurrGeneration = GetGeneration(); } } diff --git a/gfx/thebes/gfxTextRun.h b/gfx/thebes/gfxTextRun.h index 06e5f12d2c32..54f1ff58d66c 100644 --- a/gfx/thebes/gfxTextRun.h +++ b/gfx/thebes/gfxTextRun.h @@ -723,27 +723,6 @@ private: class gfxFontGroup : public gfxTextRunFactory { public: - class FamilyFace { - public: - FamilyFace() { } - - FamilyFace(gfxFontFamily* aFamily, gfxFont* aFont) - : mFamily(aFamily), mFont(aFont) - { - NS_ASSERTION(aFont, "font pointer must not be null"); - NS_ASSERTION(!aFamily || - aFamily->ContainsFace(aFont->GetFontEntry()), - "font is not a member of the given family"); - } - - gfxFontFamily* Family() const { return mFamily.get(); } - gfxFont* Font() const { return mFont.get(); } - - private: - nsRefPtr mFamily; - nsRefPtr mFont; - }; - static void Shutdown(); // platform must call this to release the languageAtomService gfxFontGroup(const mozilla::FontFamilyList& aFontFamilyList, @@ -752,29 +731,15 @@ public: virtual ~gfxFontGroup(); - virtual gfxFont *GetFontAt(int32_t i) { - // If it turns out to be hard for all clients that cache font - // groups to call UpdateFontList at appropriate times, we could - // instead consider just calling UpdateFontList from someplace - // more central (such as here). - NS_ASSERTION(!mUserFontSet || mCurrGeneration == GetGeneration(), - "Whoever was caching this font group should have " - "called UpdateFontList on it"); - NS_ASSERTION(mFonts.Length() > uint32_t(i) && mFonts[i].Font(), - "Requesting a font index that doesn't exist"); - - return mFonts[i].Font(); - } + // Returns first valid font in the fontlist or default font. + // Initiates userfont loads if userfont not loaded + virtual gfxFont* GetFirstValidFont(); // Returns the first font in the font-group that has an OpenType MATH table, // or null if no such font is available. The GetMathConstant methods may be // called on the returned font. gfxFont *GetFirstMathFont(); - uint32_t FontListLength() const { - return mFonts.Length(); - } - const gfxFontStyle *GetStyle() const { return &mStyle; } virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle); @@ -845,15 +810,12 @@ public: // This returns the preferred underline for this font group. // Some CJK fonts have wrong underline offset in its metrics. - // If this group has such "bad" font, each platform's gfxFontGroup initialized mUnderlineOffset. - // The value should be lower value of first font's metrics and the bad font's metrics. - // Otherwise, this returns from first font's metrics. + // If this group has such "bad" font, each platform's gfxFontGroup + // initialized mUnderlineOffset. The value should be lower value of + // first font's metrics and the bad font's metrics. Otherwise, this + // returns from first font's metrics. enum { UNDERLINE_OFFSET_NOT_SET = INT16_MAX }; - virtual gfxFloat GetUnderlineOffset() { - if (mUnderlineOffset == UNDERLINE_OFFSET_NOT_SET) - mUnderlineOffset = GetFontAt(0)->GetMetrics().underlineOffset; - return mUnderlineOffset; - } + virtual gfxFloat GetUnderlineOffset(); virtual already_AddRefed FindFontForChar(uint32_t ch, uint32_t prevCh, int32_t aRunScript, @@ -879,16 +841,19 @@ public: // with no @font-face rule, this always returns 0. uint64_t GetGeneration(); + // generation of the latest fontset rebuild, 0 when no fontset present + uint64_t GetRebuildGeneration(); + // used when logging text performance gfxTextPerfMetrics *GetTextPerfMetrics() { return mTextPerf; } void SetTextPerfMetrics(gfxTextPerfMetrics *aTextPerf) { mTextPerf = aTextPerf; } - // This will call UpdateFontList() if the user font set is changed. + // This will call UpdateUserFonts() if the user font set is changed. void SetUserFontSet(gfxUserFontSet *aUserFontSet); // If there is a user font set, check to see whether the font list or any // caches need updating. - virtual void UpdateFontList(); + virtual void UpdateUserFonts(); bool ShouldSkipDrawing() const { return mSkipDrawing; @@ -901,7 +866,7 @@ public: // The gfxFontGroup keeps ownership of this textrun. // It is only guaranteed to exist until the next call to GetEllipsisTextRun // (which might use a different appUnitsPerDev value) for the font group, - // or until UpdateFontList is called, or the fontgroup is destroyed. + // or until UpdateUserFonts is called, or the fontgroup is destroyed. // Get it/use it/forget it :) - don't keep a reference that might go stale. gfxTextRun* GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel, LazyReferenceContextGetter& aRefContextGetter); @@ -913,9 +878,144 @@ public: nsTArray& aGenericFamilies); protected: + class FamilyFace { + public: + FamilyFace() : mFamily(nullptr), mFontEntry(nullptr), + mNeedsBold(false), mFontCreated(false), + mLoading(false), mInvalid(false) + { } + + FamilyFace(gfxFontFamily* aFamily, gfxFont* aFont) + : mFamily(aFamily), mNeedsBold(false), mFontCreated(true), + mLoading(false), mInvalid(false) + { + NS_ASSERTION(aFont, "font pointer must not be null"); + NS_ASSERTION(!aFamily || + aFamily->ContainsFace(aFont->GetFontEntry()), + "font is not a member of the given family"); + mFont = aFont; + NS_ADDREF(aFont); + } + + FamilyFace(gfxFontFamily* aFamily, gfxFontEntry* aFontEntry, + bool aNeedsBold) + : mFamily(aFamily), mNeedsBold(aNeedsBold), mFontCreated(false), + mLoading(false), mInvalid(false) + { + NS_ASSERTION(aFontEntry, "font entry pointer must not be null"); + NS_ASSERTION(!aFamily || + aFamily->ContainsFace(aFontEntry), + "font is not a member of the given family"); + mFontEntry = aFontEntry; + NS_ADDREF(aFontEntry); + } + + FamilyFace(const FamilyFace& aOtherFamilyFace) + : mFamily(aOtherFamilyFace.mFamily), + mNeedsBold(aOtherFamilyFace.mNeedsBold), + mFontCreated(aOtherFamilyFace.mFontCreated), + mLoading(aOtherFamilyFace.mLoading), + mInvalid(aOtherFamilyFace.mInvalid) + { + if (mFontCreated) { + mFont = aOtherFamilyFace.mFont; + NS_ADDREF(mFont); + } else { + mFontEntry = aOtherFamilyFace.mFontEntry; + NS_IF_ADDREF(mFontEntry); + } + } + + ~FamilyFace() + { + if (mFontCreated) { + NS_RELEASE(mFont); + } else { + NS_IF_RELEASE(mFontEntry); + } + } + + FamilyFace& operator=(const FamilyFace& aOther) + { + if (mFontCreated) { + NS_RELEASE(mFont); + } else { + NS_IF_RELEASE(mFontEntry); + } + + mFamily = aOther.mFamily; + mNeedsBold = aOther.mNeedsBold; + mFontCreated = aOther.mFontCreated; + mLoading = aOther.mLoading; + mInvalid = aOther.mInvalid; + + if (mFontCreated) { + mFont = aOther.mFont; + NS_ADDREF(mFont); + } else { + mFontEntry = aOther.mFontEntry; + NS_IF_ADDREF(mFontEntry); + } + + return *this; + } + + gfxFontFamily* Family() const { return mFamily.get(); } + gfxFont* Font() const { + return mFontCreated ? mFont : nullptr; + } + + gfxFontEntry* FontEntry() const { + return mFontCreated ? mFont->GetFontEntry() : mFontEntry; + } + + bool NeedsBold() const { return mNeedsBold; } + bool IsUserFont() const { + return FontEntry()->mIsUserFontContainer; + } + bool IsLoading() const { return mLoading; } + bool IsInvalid() const { return mInvalid; } + void SetLoading(bool aIsLoading) { mLoading = aIsLoading; } + void SetInvalid() { mInvalid = true; } + + void SetFont(gfxFont* aFont) + { + NS_ASSERTION(aFont, "font pointer must not be null"); + NS_ADDREF(aFont); + if (mFontCreated) { + NS_RELEASE(mFont); + } else { + NS_IF_RELEASE(mFontEntry); + } + mFont = aFont; + mFontCreated = true; + } + + private: + nsRefPtr mFamily; + // either a font or a font entry exists + union { + gfxFont* mFont; + gfxFontEntry* mFontEntry; + }; + bool mNeedsBold : 1; + bool mFontCreated : 1; + bool mLoading : 1; + bool mInvalid : 1; + }; + + // List of font families, either named or generic. + // Generic names map to system pref fonts based on language. mozilla::FontFamilyList mFamilyList; - gfxFontStyle mStyle; + + // Fontlist containing a font entry for each family found. gfxFont objects + // are created as needed and userfont loads are initiated when needed. + // Code should be careful about addressing this array directly. nsTArray mFonts; + + nsRefPtr mDefaultFont; + gfxFontStyle mStyle; + gfxFloat mUnderlineOffset; gfxFloat mHyphenWidth; @@ -951,6 +1051,14 @@ protected: // Initialize the list of fonts void BuildFontList(); + // Get the font at index i within the fontlist. + // Will initiate userfont load if not already loaded. + // May return null if userfont not loaded or if font invalid + virtual gfxFont* GetFontAt(int32_t i); + + // will always return a font or force a shutdown + gfxFont* GetDefaultFont(); + // Init this font group's font metrics. If there no bad fonts, you don't need to call this. // But if there are one or more bad fonts which have bad underline offset, // you should call this with the *first* bad font. @@ -975,10 +1083,11 @@ protected: int32_t aRunScript); // Helper for font-matching: - // see if aCh is supported in any of the faces from aFamily; - // if so return the best style match, else return null. - already_AddRefed TryAllFamilyMembers(gfxFontFamily* aFamily, - uint32_t aCh); + // When matching the italic case, allow use of the regular face + // if it supports a character but the italic one doesn't. + // Return null if regular face doesn't support aCh + already_AddRefed + FindNonItalicFaceForChar(gfxFontFamily* aFamily, uint32_t aCh); // helper methods for looking up fonts diff --git a/gfx/thebes/gfxUserFontSet.cpp b/gfx/thebes/gfxUserFontSet.cpp index 0a11748822b2..62d7820c9d25 100644 --- a/gfx/thebes/gfxUserFontSet.cpp +++ b/gfx/thebes/gfxUserFontSet.cpp @@ -120,7 +120,8 @@ gfxUserFontEntry::gfxUserFontEntry(gfxUserFontSet* aFontSet, uint32_t aLanguageOverride, gfxSparseBitSet* aUnicodeRanges) : gfxFontEntry(NS_LITERAL_STRING("userfont")), - mLoadingState(NOT_LOADING), + mUserFontLoadState(STATUS_NOT_LOADED), + mFontDataLoadingState(NOT_LOADING), mUnsupportedFormat(false), mLoader(nullptr), mFontSet(aFontSet) @@ -310,16 +311,21 @@ CopyWOFFMetadata(const uint8_t* aFontData, *aMetaOrigLen = woff->metaOrigLen; } -gfxUserFontEntry::LoadStatus -gfxUserFontEntry::LoadNext() +void +gfxUserFontEntry::LoadNextSrc() { uint32_t numSrc = mSrcList.Length(); NS_ASSERTION(mSrcIndex < numSrc, "already at the end of the src list for user font"); + NS_ASSERTION((mUserFontLoadState == STATUS_NOT_LOADED || + mUserFontLoadState == STATUS_LOADING) && + mFontDataLoadingState < LOADING_FAILED, + "attempting to load a font that has either completed or failed"); - if (mLoadingState == NOT_LOADING) { - mLoadingState = LOADING_STARTED; + if (mUserFontLoadState == STATUS_NOT_LOADED) { + SetLoadState(STATUS_LOADING); + mFontDataLoadingState = LOADING_STARTED; mUnsupportedFormat = false; } else { // we were already loading; move to the next source, @@ -356,7 +362,8 @@ gfxUserFontEntry::LoadNext() // local fonts are just available all the time. StoreUserFontData(fe, false, nsString(), nullptr, 0); mPlatformFontEntry = fe; - return STATUS_LOADED; + SetLoadState(STATUS_LOADED); + return; } else { LOG(("fontset (%p) [src %d] failed local: (%s) for (%s)\n", mFontSet, mSrcIndex, @@ -385,7 +392,8 @@ gfxUserFontEntry::LoadNext() mFontSet->GetPrivateBrowsing()); if (fe) { mPlatformFontEntry = fe; - return STATUS_LOADED; + SetLoadState(STATUS_LOADED); + return; } } @@ -408,8 +416,9 @@ gfxUserFontEntry::LoadNext() bufferLength); if (NS_SUCCEEDED(rv) && - LoadFont(buffer, bufferLength)) { - return STATUS_LOADED; + LoadPlatformFont(buffer, bufferLength)) { + SetLoadState(STATUS_LOADED); + return; } else { mFontSet->LogMessage(this, "font load failed", @@ -432,7 +441,7 @@ gfxUserFontEntry::LoadNext() NS_ConvertUTF16toUTF8(mFamilyName).get())); } #endif - return STATUS_LOADING; + return; } else { mFontSet->LogMessage(this, "download failed", @@ -462,14 +471,24 @@ gfxUserFontEntry::LoadNext() // all src's failed; mark this entry as unusable (so fallback will occur) LOG(("userfonts (%p) failed all src for (%s)\n", mFontSet, NS_ConvertUTF16toUTF8(mFamilyName).get())); - mLoadingState = LOADING_FAILED; + mFontDataLoadingState = LOADING_FAILED; + SetLoadState(STATUS_FAILED); +} - return STATUS_END_OF_LIST; +void +gfxUserFontEntry::SetLoadState(UserFontLoadState aLoadState) +{ + mUserFontLoadState = aLoadState; } bool -gfxUserFontEntry::LoadFont(const uint8_t* aFontData, uint32_t &aLength) +gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength) { + NS_ASSERTION((mUserFontLoadState == STATUS_NOT_LOADED || + mUserFontLoadState == STATUS_LOADING) && + mFontDataLoadingState < LOADING_FAILED, + "attempting to load a font that has either completed or failed"); + gfxFontEntry* fe = nullptr; gfxUserFontType fontType = @@ -541,6 +560,7 @@ gfxUserFontEntry::LoadFont(const uint8_t* aFontData, uint32_t &aLength) } #endif mPlatformFontEntry = fe; + SetLoadState(STATUS_LOADED); gfxUserFontSet::UserFontCache::CacheFont(fe); } else { #ifdef PR_LOGGING @@ -562,12 +582,21 @@ gfxUserFontEntry::LoadFont(const uint8_t* aFontData, uint32_t &aLength) return fe != nullptr; } +void +gfxUserFontEntry::Load() +{ + if (mUserFontLoadState == STATUS_NOT_LOADED) { + LoadNextSrc(); + } +} + // This is called when a font download finishes. // Ownership of aFontData passes in here, and the font set must // ensure that it is eventually deleted via NS_Free(). bool -gfxUserFontEntry::OnLoadComplete(const uint8_t* aFontData, uint32_t aLength, - nsresult aDownloadStatus) +gfxUserFontEntry::FontDataDownloadComplete(const uint8_t* aFontData, + uint32_t aLength, + nsresult aDownloadStatus) { // forget about the loader, as we no longer potentially need to cancel it // if the entry is obsoleted @@ -575,7 +604,7 @@ gfxUserFontEntry::OnLoadComplete(const uint8_t* aFontData, uint32_t aLength, // download successful, make platform font using font data if (NS_SUCCEEDED(aDownloadStatus)) { - bool loaded = LoadFont(aFontData, aLength); + bool loaded = LoadPlatformFont(aFontData, aLength); aFontData = nullptr; if (loaded) { @@ -595,7 +624,7 @@ gfxUserFontEntry::OnLoadComplete(const uint8_t* aFontData, uint32_t aLength, } // error occurred, load next src - LoadNext(); + LoadNextSrc(); // We ignore the status returned by LoadNext(); // even if loading failed, we need to bump the font-set generation @@ -608,7 +637,7 @@ gfxUserFontEntry::OnLoadComplete(const uint8_t* aFontData, uint32_t aLength, gfxUserFontSet::gfxUserFontSet() : mFontFamilies(4), mLocalRulesUsed(false) { - IncrementGeneration(); + IncrementGeneration(true); gfxPlatformFontList* fp = gfxPlatformFontList::PlatformFontList(); if (fp) { fp->AddUserFontSet(this); @@ -744,64 +773,57 @@ gfxUserFontSet::AddFontFace(const nsAString& aFamilyName, gfxUserFontEntry* gfxUserFontSet::FindUserFontEntry(gfxFontFamily* aFamily, const gfxFontStyle& aFontStyle, - bool& aNeedsBold, - bool& aWaitForUserFont) + bool& aNeedsBold) { - aWaitForUserFont = false; gfxUserFontFamily* family = static_cast(aFamily); - gfxFontEntry* fe = family->FindFontForStyle(aFontStyle, aNeedsBold); NS_ASSERTION(!fe || fe->mIsUserFontContainer, "should only have userfont entries in userfont families"); - // if not a userfont entry, font has already been loaded if (!fe || !fe->mIsUserFontContainer) { return nullptr; } gfxUserFontEntry* userFontEntry = static_cast (fe); + return userFontEntry; +} +gfxUserFontEntry* +gfxUserFontSet::FindUserFontEntryAndLoad(gfxFontFamily* aFamily, + const gfxFontStyle& aFontStyle, + bool& aNeedsBold, + bool& aWaitForUserFont) +{ + aWaitForUserFont = false; + gfxUserFontEntry* userFontEntry = + FindUserFontEntry(aFamily, aFontStyle, aNeedsBold); + + if (!userFontEntry) { + return nullptr; + } + + // start the load if it hasn't been loaded + userFontEntry->Load(); if (userFontEntry->GetPlatformFontEntry()) { return userFontEntry; } - // if currently loading, return null for now - if (userFontEntry->mLoadingState > gfxUserFontEntry::NOT_LOADING) { - aWaitForUserFont = - (userFontEntry->mLoadingState < gfxUserFontEntry::LOADING_SLOWLY); - return nullptr; - } - - // hasn't been loaded yet, start the load process - gfxUserFontEntry::LoadStatus status; - - // NOTE that if all sources in the entry fail, this will delete userFontEntry, - // so we cannot use it again if status==STATUS_END_OF_LIST - status = userFontEntry->LoadNext(); - - // if the load succeeded immediately, return - if (status == gfxUserFontEntry::STATUS_LOADED) { - return userFontEntry; - } - - // check whether we should wait for load to complete before painting - // a fallback font -- but not if all sources failed (bug 633500) - aWaitForUserFont = (status != gfxUserFontEntry::STATUS_END_OF_LIST) && - (userFontEntry->mLoadingState < gfxUserFontEntry::LOADING_SLOWLY); - - // if either loading or an error occurred, return null + aWaitForUserFont = userFontEntry->WaitForUserFont(); return nullptr; } void -gfxUserFontSet::IncrementGeneration() +gfxUserFontSet::IncrementGeneration(bool aIsRebuild) { // add one, increment again if zero ++sFontSetGeneration; if (sFontSetGeneration == 0) ++sFontSetGeneration; mGeneration = sFontSetGeneration; + if (aIsRebuild) { + mRebuildGeneration = mGeneration; + } } void diff --git a/gfx/thebes/gfxUserFontSet.h b/gfx/thebes/gfxUserFontSet.h index 1076fc97c661..152dfae01b39 100644 --- a/gfx/thebes/gfxUserFontSet.h +++ b/gfx/thebes/gfxUserFontSet.h @@ -189,12 +189,20 @@ public: // the given name gfxUserFontFamily* LookupFamily(const nsAString& aName) const; - // Lookup a font entry for a given style, returns null if not loaded. + // Lookup a userfont entry for a given style, loaded or not. // aFamily must be a family returned by our LookupFamily method. + // If only invalid fonts in family, returns null. gfxUserFontEntry* FindUserFontEntry(gfxFontFamily* aFamily, const gfxFontStyle& aFontStyle, - bool& aNeedsBold, - bool& aWaitForUserFont); + bool& aNeedsBold); + + // Lookup a font entry for a given style, returns null if not loaded. + // aFamily must be a family returned by our LookupFamily method. + // (only used by gfxPangoFontGroup for now) + gfxUserFontEntry* FindUserFontEntryAndLoad(gfxFontFamily* aFamily, + const gfxFontStyle& aFontStyle, + bool& aNeedsBold, + bool& aWaitForUserFont); // check whether the given source is allowed to be loaded; // returns the Principal (for use in the key when caching the loaded font), @@ -203,17 +211,22 @@ public: nsIPrincipal** aPrincipal, bool* aBypassCache) = 0; - // initialize the process that loads external font data, which upon - // completion will call OnLoadComplete method + // initialize the process that loads external font data, which upon + // completion will call FontDataDownloadComplete method virtual nsresult StartLoad(gfxUserFontEntry* aUserFontEntry, const gfxFontFaceSrc* aFontFaceSrc) = 0; // generation - each time a face is loaded, generation is - // incremented so that the change can be recognized + // incremented so that the change can be recognized uint64_t GetGeneration() { return mGeneration; } // increment the generation on font load - void IncrementGeneration(); + void IncrementGeneration(bool aIsRebuild = false); + + // Generation is bumped on font loads but that doesn't affect name-style + // mappings. Rebuilds do however affect name-style mappings so need to + // lookup fontlists again when that happens. + uint64_t GetRebuildGeneration() { return mRebuildGeneration; } // rebuild if local rules have been used void RebuildLocalRules(); @@ -448,7 +461,8 @@ protected: // font families defined by @font-face rules nsRefPtrHashtable mFontFamilies; - uint64_t mGeneration; + uint64_t mGeneration; // bumped on any font load change + uint64_t mRebuildGeneration; // only bumped on rebuilds // true when local names have been looked up, false otherwise bool mLocalRulesUsed; @@ -465,12 +479,11 @@ class gfxUserFontEntry : public gfxFontEntry { friend class gfxOTSContext; public: - enum LoadStatus { - STATUS_LOADING = 0, + enum UserFontLoadState { + STATUS_NOT_LOADED = 0, + STATUS_LOADING, STATUS_LOADED, - STATUS_FORMAT_NOT_SUPPORTED, - STATUS_ERROR, - STATUS_END_OF_LIST + STATUS_FAILED }; gfxUserFontEntry(gfxUserFontSet* aFontSet, @@ -493,18 +506,23 @@ public: uint32_t aLanguageOverride, gfxSparseBitSet* aUnicodeRanges); - virtual gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle, bool aNeedsBold); + virtual gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle, + bool aNeedsBold); gfxFontEntry* GetPlatformFontEntry() { return mPlatformFontEntry; } - // when download has been completed, pass back data here - // aDownloadStatus == NS_OK ==> download succeeded, error otherwise - // returns true if platform font creation sucessful (or local() - // reference was next in line) - // Ownership of aFontData is passed in here; the font set must - // ensure that it is eventually deleted with NS_Free(). - bool OnLoadComplete(const uint8_t* aFontData, uint32_t aLength, - nsresult aDownloadStatus); + // is the font loading or loaded, or did it fail? + UserFontLoadState LoadState() const { return mUserFontLoadState; } + + // whether to wait before using fallback font or not + bool WaitForUserFont() const { + return mUserFontLoadState == STATUS_LOADING && + mFontDataLoadingState < LOADING_SLOWLY; + } + + // load the font - starts the loading of sources which continues until + // a valid font resource is found or all sources fail + void Load(); protected: const uint8_t* SanitizeOpenTypeData(const uint8_t* aData, @@ -512,14 +530,26 @@ protected: uint32_t& aSaneLength, bool aIsCompressed); - // Attempt to load the next resource in the src list. - LoadStatus LoadNext(); + // attempt to load the next resource in the src list. + void LoadNextSrc(); + + // change the load state + void SetLoadState(UserFontLoadState aLoadState); + + // when download has been completed, pass back data here + // aDownloadStatus == NS_OK ==> download succeeded, error otherwise + // returns true if platform font creation sucessful (or local() + // reference was next in line) + // Ownership of aFontData is passed in here; the font set must + // ensure that it is eventually deleted with NS_Free(). + bool FontDataDownloadComplete(const uint8_t* aFontData, uint32_t aLength, + nsresult aDownloadStatus); // helper method for creating a platform font // returns true if platform font creation successful // Ownership of aFontData is passed in here; the font must // ensure that it is eventually deleted with NS_Free(). - bool LoadFont(const uint8_t* aFontData, uint32_t &aLength); + bool LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength); // store metadata and src details for current src into aFontEntry void StoreUserFontData(gfxFontEntry* aFontEntry, @@ -528,8 +558,13 @@ protected: FallibleTArray* aMetadata, uint32_t aMetaOrigLen); + // general load state + UserFontLoadState mUserFontLoadState; + + // detailed load state while font data is loading + // used to determine whether to use fallback font or not // note that code depends on the ordering of these values! - enum LoadingState { + enum FontDataLoadingState { NOT_LOADING = 0, // not started to load any font resources yet LOADING_STARTED, // loading has started; hide fallback font LOADING_ALMOST_DONE, // timeout happened but we're nearly done, @@ -538,7 +573,8 @@ protected: // so use the fallback font LOADING_FAILED // failed to load any source: use fallback }; - LoadingState mLoadingState; + FontDataLoadingState mFontDataLoadingState; + bool mUnsupportedFormat; nsRefPtr mPlatformFontEntry; diff --git a/gfx/thebes/gfxWindowsSurface.cpp b/gfx/thebes/gfxWindowsSurface.cpp index 58c9100520f2..0c3cc0009cf7 100644 --- a/gfx/thebes/gfxWindowsSurface.cpp +++ b/gfx/thebes/gfxWindowsSurface.cpp @@ -283,17 +283,6 @@ gfxWindowsSurface::EndPage() #endif } -int32_t -gfxWindowsSurface::GetDefaultContextFlags() const -{ - if (mForPrinting) - return gfxContext::FLAG_SIMPLIFY_OPERATORS | - gfxContext::FLAG_DISABLE_SNAPPING | - gfxContext::FLAG_DISABLE_COPY_BACKGROUND; - - return 0; -} - const gfxIntSize gfxWindowsSurface::GetSize() const { diff --git a/gfx/thebes/gfxWindowsSurface.h b/gfx/thebes/gfxWindowsSurface.h index 8b8bf1ad23a1..9fced2feba65 100644 --- a/gfx/thebes/gfxWindowsSurface.h +++ b/gfx/thebes/gfxWindowsSurface.h @@ -63,8 +63,6 @@ public: nsresult BeginPage(); nsresult EndPage(); - virtual int32_t GetDefaultContextFlags() const; - const gfxIntSize GetSize() const; // The memory used by this surface lives in this process's address space, diff --git a/image/src/RasterImage.cpp b/image/src/RasterImage.cpp index ac12cb4886fe..93dc18d6faf5 100644 --- a/image/src/RasterImage.cpp +++ b/image/src/RasterImage.cpp @@ -612,8 +612,10 @@ RasterImage::GetFrame(uint32_t aFrameNum) if (!ref) { // The OS threw this frame away. We need to discard and redecode. MOZ_ASSERT(!mAnim, "Animated frames should be locked"); - ForceDiscard(); - WantDecodedFrames(); + if (CanForciblyDiscardAndRedecode()) { + ForceDiscard(); + WantDecodedFrames(); + } return DrawableFrameRef(); } diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index fe1e7ae2db68..07798feab1bb 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -1708,7 +1708,7 @@ ObjectAddress(JSContext *cx, unsigned argc, jsval *vp) } #ifdef JS_MORE_DETERMINISTIC - args.rval().setInt(0); + args.rval().setInt32(0); #else char buffer[64]; JS_snprintf(buffer, sizeof(buffer), "%p", &args[0].toObject()); diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 55a2636573d7..bad6e34f981b 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -1639,9 +1639,9 @@ GetCompartmentName(JSCompartment *c, nsCString &name, int *anonymizeID, } } - // We might have a file:// URL that includes paths from the local - // filesystem, which should be omitted if we're anonymizing. if (*anonymizeID) { + // We might have a file:// URL that includes a path from the local + // filesystem, which should be omitted if we're anonymizing. static const char *filePrefix = "file://"; int filePos = name.Find(filePrefix); if (filePos >= 0) { @@ -1662,6 +1662,24 @@ GetCompartmentName(JSCompartment *c, nsCString &name, int *anonymizeID, name += ""; } } + + // We might have a location like this: + // inProcessTabChildGlobal?ownedBy=http://www.example.com/ + // The owner should be omitted if it's not a chrome: URI and we're + // anonymizing. + static const char *ownedByPrefix = + "inProcessTabChildGlobal?ownedBy="; + int ownedByPos = name.Find(ownedByPrefix); + if (ownedByPos >= 0) { + const char *chrome = "chrome:"; + int ownerPos = ownedByPos + strlen(ownedByPrefix); + const nsDependentCSubstring& ownerFirstPart = + Substring(name, ownerPos, strlen(chrome)); + if (!ownerFirstPart.EqualsASCII(chrome)) { + name.Truncate(ownerPos); + name += ""; + } + } } // A hack: replace forward slashes with '\\' so they aren't diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index 0252f97ab177..68b8b888bfd9 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -1701,10 +1701,15 @@ XrayToString(JSContext *cx, unsigned argc, Value *vp) } RootedObject obj(cx, XrayTraits::getTargetObject(wrapper)); - - if (UseDOMXray(obj)) + XrayType type = GetXrayType(obj); + if (type == XrayForDOMObject) return NativeToString(cx, wrapper, obj, args.rval()); + if (type != XrayForWrappedNative) { + JS_ReportError(cx, "XrayToString called on an incompatible object"); + return false; + } + static const char start[] = "[object XrayWrapper "; static const char end[] = "]"; nsAutoString result; @@ -2304,12 +2309,13 @@ template class SCSecurityXrayXPCWN; static nsQueryInterface do_QueryInterfaceNative(JSContext* cx, HandleObject wrapper) { - nsISupports* nativeSupports; + nsISupports* nativeSupports = nullptr; if (IsWrapper(wrapper) && WrapperFactory::IsXrayWrapper(wrapper)) { RootedObject target(cx, XrayTraits::getTargetObject(wrapper)); - if (GetXrayType(target) == XrayForDOMObject) { + XrayType type = GetXrayType(target); + if (type == XrayForDOMObject) { nativeSupports = UnwrapDOMObjectToISupports(target); - } else { + } else if (type == XrayForWrappedNative) { XPCWrappedNative *wn = XPCWrappedNative::Get(target); nativeSupports = wn->Native(); } diff --git a/layout/base/RestyleLogging.h b/layout/base/RestyleLogging.h new file mode 100644 index 000000000000..7276e8fbc159 --- /dev/null +++ b/layout/base/RestyleLogging.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Macros used to log restyle events. + */ + +#ifndef mozilla_RestyleLogging_h +#define mozilla_RestyleLogging_h + +#include "mozilla/AutoRestore.h" + +#ifdef DEBUG +#define RESTYLE_LOGGING +#endif + +#ifdef RESTYLE_LOGGING +#define LOG_RESTYLE_IF(object_, cond_, message_, ...) \ + PR_BEGIN_MACRO \ + if (object_->ShouldLogRestyle() && (cond_)) { \ + nsCString line; \ + for (int32_t restyle_depth_##__LINE__ = 0; \ + restyle_depth_##__LINE__ < object_->LoggingDepth(); \ + restyle_depth_##__LINE__++) { \ + line.AppendLiteral(" "); \ + } \ + line.AppendPrintf(message_, ##__VA_ARGS__); \ + printf_stderr("%s\n", line.get()); \ + } \ + PR_END_MACRO +#define LOG_RESTYLE(message_, ...) \ + LOG_RESTYLE_IF(this, true, message_, ##__VA_ARGS__) +// Beware that LOG_RESTYLE_INDENT is two statements not wrapped in a block. +#define LOG_RESTYLE_INDENT() \ + AutoRestore ar_depth_##__LINE__(LoggingDepth()); \ + ++LoggingDepth(); +#else +#define LOG_RESTYLE_IF(cond_, message_, ...) /* nothing */ +#define LOG_RESTYLE(message_, ...) /* nothing */ +#define LOG_RESTYLE_INDENT() /* nothing */ +#endif + +#endif /* mozilla_RestyleLogging_h */ diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 8e929ad4a875..ffd2f3dfcdc7 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -36,6 +36,7 @@ #include "nsIFrameInlines.h" #include "ActiveLayerTracker.h" #include "nsDisplayList.h" +#include "RestyleTrackerInlines.h" #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" @@ -45,6 +46,19 @@ namespace mozilla { using namespace layers; +#define LOG_RESTYLE_CONTINUE(reason_, ...) \ + LOG_RESTYLE("continuing restyle since " reason_, ##__VA_ARGS__) + +#ifdef RESTYLE_LOGGING +static nsCString +FrameTagToString(const nsIFrame* aFrame) +{ + nsCString result; + aFrame->ListTag(result); + return result; +} +#endif + RestyleManager::RestyleManager(nsPresContext* aPresContext) : mPresContext(aPresContext) , mRebuildAllStyleData(false) @@ -60,6 +74,9 @@ RestyleManager::RestyleManager(nsPresContext* aPresContext) ELEMENT_IS_POTENTIAL_RESTYLE_ROOT) , mPendingAnimationRestyles(ELEMENT_HAS_PENDING_ANIMATION_RESTYLE | ELEMENT_IS_POTENTIAL_ANIMATION_RESTYLE_ROOT) +#ifdef RESTYLE_LOGGING + , mLoggingDepth(0) +#endif { mPendingRestyles.Init(this); mPendingAnimationRestyles.Init(this); @@ -2257,6 +2274,9 @@ ElementRestyler::ElementRestyler(nsPresContext* aPresContext, , mOurA11yNotification(eDontNotify) , mVisibleKidsOfHiddenElement(aVisibleKidsOfHiddenElement) #endif +#ifdef RESTYLE_LOGGING + , mLoggingDepth(aRestyleTracker.LoggingDepth() + 1) +#endif { } @@ -2284,6 +2304,9 @@ ElementRestyler::ElementRestyler(const ElementRestyler& aParentRestyler, , mOurA11yNotification(eDontNotify) , mVisibleKidsOfHiddenElement(aParentRestyler.mVisibleKidsOfHiddenElement) #endif +#ifdef RESTYLE_LOGGING + , mLoggingDepth(aParentRestyler.mLoggingDepth + 1) +#endif { if (aConstructorFlags & FOR_OUT_OF_FLOW_CHILD) { // Note that the out-of-flow may not be a geometric descendant of @@ -2325,6 +2348,9 @@ ElementRestyler::ElementRestyler(ParentContextFromChildFrame, , mOurA11yNotification(eDontNotify) , mVisibleKidsOfHiddenElement(aParentRestyler.mVisibleKidsOfHiddenElement) #endif +#ifdef RESTYLE_LOGGING + , mLoggingDepth(aParentRestyler.mLoggingDepth + 1) +#endif { } @@ -2351,6 +2377,11 @@ ElementRestyler::CaptureChange(nsStyleContext* aOldContext, (ourChange & nsChangeHint_NeedReflow), "Reflow hint bits set without actually asking for a reflow"); + LOG_RESTYLE("CaptureChange, ourChange = %s, aChangeToAssume = %s", + RestyleManager::ChangeHintToString(ourChange).get(), + RestyleManager::ChangeHintToString(aChangeToAssume).get()); + LOG_RESTYLE_INDENT(); + // nsChangeHint_UpdateEffects is inherited, but it can be set due to changes // in inherited properties (fill and stroke). Avoid propagating it into // text nodes. @@ -2362,11 +2393,17 @@ ElementRestyler::CaptureChange(nsStyleContext* aOldContext, NS_UpdateHint(ourChange, aChangeToAssume); if (NS_UpdateHint(mHintsHandled, ourChange)) { if (!(ourChange & nsChangeHint_ReconstructFrame) || mContent) { + LOG_RESTYLE("appending change %s", + RestyleManager::ChangeHintToString(ourChange).get()); mChangeList->AppendChange(mFrame, mContent, ourChange); + } else { + LOG_RESTYLE("change has already been handled"); } } NS_UpdateHint(mHintsNotHandledForDescendants, NS_HintsNotHandledForDescendantsIn(ourChange)); + LOG_RESTYLE("mHintsNotHandledForDescendants = %s", + RestyleManager::ChangeHintToString(mHintsNotHandledForDescendants).get()); } /** @@ -2449,14 +2486,12 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) // overall decision. RestyleResult result = RestyleResult(0); uint32_t swappedStructs = 0; - nsIFrame* providerFrame = nullptr; nsRestyleHint thisRestyleHint = aRestyleHint; bool haveMoreContinuations = false; for (nsIFrame* f = mFrame; f; ) { - RestyleResult thisResult = - RestyleSelf(f, thisRestyleHint, &swappedStructs, &providerFrame); + RestyleResult thisResult = RestyleSelf(f, thisRestyleHint, &swappedStructs); if (thisResult != eRestyleResult_Stop) { // Calls to RestyleSelf for later same-style continuations must not @@ -2495,15 +2530,15 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) MOZ_ASSERT(mFrame->StyleContext() == oldContext, "frame should have been left with its old style context"); - MOZ_ASSERT(providerFrame, "RestyleSelf should have supplied a providerFrame " - "if it returned eRestyleResult_Stop"); - - nsStyleContext* newParent = providerFrame->StyleContext(); + nsStyleContext* newParent = + mFrame->GetParentStyleContextFrame()->StyleContext(); if (oldContext->GetParent() != newParent) { // If we received eRestyleResult_Stop, then the old style context was // left on mFrame. Since we ended up restyling our parent, change // this old style context to point to its new parent. + LOG_RESTYLE("moving style context %p from old parent %p to new parent %p", + oldContext.get(), oldContext->GetParent(), newParent); oldContext->MoveTo(newParent); } @@ -2568,6 +2603,7 @@ ElementRestyler::ComputeRestyleResultFromFrame(nsIFrame* aSelf) // have, so we don't considering stopping if this frame has any additional // style contexts. if (aSelf->GetAdditionalStyleContext(0)) { + LOG_RESTYLE_CONTINUE("there are additional style contexts"); return eRestyleResult_Continue; } @@ -2577,7 +2613,14 @@ ElementRestyler::ComputeRestyleResultFromFrame(nsIFrame* aSelf) // that they get the correct style context parent. Similarly for // nsLineFrames. nsIAtom* type = aSelf->GetType(); - if (type == nsGkAtoms::letterFrame || type == nsGkAtoms::lineFrame) { + + if (type == nsGkAtoms::letterFrame) { + LOG_RESTYLE_CONTINUE("frame is a letter frame"); + return eRestyleResult_Continue; + } + + if (type == nsGkAtoms::lineFrame) { + LOG_RESTYLE_CONTINUE("frame is a line frame"); return eRestyleResult_Continue; } @@ -2590,16 +2633,19 @@ ElementRestyler::ComputeRestyleResultFromFrame(nsIFrame* aSelf) // and we need to recompute the child's 'inherit' to that new value. nsStyleContext* oldContext = aSelf->StyleContext(); if (oldContext->HasChildThatUsesGrandancestorStyle()) { + LOG_RESTYLE_CONTINUE("the old context uses grandancestor style"); return eRestyleResult_Continue; } // We ignore all situations that involve :visited style. if (oldContext->GetStyleIfVisited()) { + LOG_RESTYLE_CONTINUE("the old style context has StyleIfVisited"); return eRestyleResult_Continue; } nsStyleContext* parentContext = oldContext->GetParent(); if (parentContext && parentContext->GetStyleIfVisited()) { + LOG_RESTYLE_CONTINUE("the old style context's parent has StyleIfVisited"); return eRestyleResult_Continue; } @@ -2610,6 +2656,7 @@ ElementRestyler::ComputeRestyleResultFromFrame(nsIFrame* aSelf) // pseudos. nsIAtom* pseudoTag = oldContext->GetPseudo(); if (pseudoTag && pseudoTag != nsCSSAnonBoxes::mozNonElement) { + LOG_RESTYLE_CONTINUE("the old style context is for a pseudo"); return eRestyleResult_Continue; } @@ -2621,6 +2668,7 @@ ElementRestyler::ComputeRestyleResultFromFrame(nsIFrame* aSelf) // ancestor). nsIAtom* parentPseudoTag = parent->StyleContext()->GetPseudo(); if (parentPseudoTag && parentPseudoTag != nsCSSAnonBoxes::mozNonElement) { + LOG_RESTYLE_CONTINUE("the old style context's parent is for a pseudo"); return eRestyleResult_Continue; } } @@ -2636,6 +2684,7 @@ ElementRestyler::ComputeRestyleResultFromNewContext(nsIFrame* aSelf, // that we can avoid the style context tree surgery having to deal to deal // with visited styles. if (aNewContext->GetStyleIfVisited()) { + LOG_RESTYLE_CONTINUE("the new style context has StyleIfVisited"); return eRestyleResult_Continue; } @@ -2648,6 +2697,8 @@ ElementRestyler::ComputeRestyleResultFromNewContext(nsIFrame* aSelf, oldContext->GetPseudo() != aNewContext->GetPseudo() || oldContext->GetPseudoType() != aNewContext->GetPseudoType() || oldContext->RuleNode() != aNewContext->RuleNode()) { + LOG_RESTYLE_CONTINUE("the old and new style contexts have different link/" + "visited/pseudo/rulenodes"); return eRestyleResult_Continue; } @@ -2656,9 +2707,16 @@ ElementRestyler::ComputeRestyleResultFromNewContext(nsIFrame* aSelf, // bits, then we must keep restyling so that those new bit values are // propagated. if (oldContext->HasTextDecorationLines() != - aNewContext->HasTextDecorationLines() || - oldContext->HasPseudoElementData() != + aNewContext->HasTextDecorationLines()) { + LOG_RESTYLE_CONTINUE("NS_STYLE_HAS_TEXT_DECORATION_LINES differs between old" + " and new style contexts"); + return eRestyleResult_Continue; + } + + if (oldContext->HasPseudoElementData() != aNewContext->HasPseudoElementData()) { + LOG_RESTYLE_CONTINUE("NS_STYLE_HAS_PSEUDO_ELEMENT_DATA differs between old" + " and new style contexts"); return eRestyleResult_Continue; } @@ -2668,8 +2726,7 @@ ElementRestyler::ComputeRestyleResultFromNewContext(nsIFrame* aSelf, ElementRestyler::RestyleResult ElementRestyler::RestyleSelf(nsIFrame* aSelf, nsRestyleHint aRestyleHint, - uint32_t* aSwappedStructs, - nsIFrame** aProviderFrame) + uint32_t* aSwappedStructs) { MOZ_ASSERT(!(aRestyleHint & eRestyle_LaterSiblings), "eRestyle_LaterSiblings must not be part of aRestyleHint"); @@ -2682,6 +2739,11 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, // We do need a reference to oldContext for the lifetime of this function, and it's possible // that the frame has the last reference to it, so AddRef it here. + LOG_RESTYLE("RestyleSelf %s, aRestyleHint = %s", + FrameTagToString(aSelf).get(), + RestyleManager::RestyleHintToString(aRestyleHint).get()); + LOG_RESTYLE_INDENT(); + RestyleResult result; if (aRestyleHint & eRestyle_ForceDescendants) { @@ -2707,7 +2769,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, nsStyleContext* parentContext; // Get the frame providing the parent style context. If it is a // child, then resolve the provider first. - nsIFrame* const providerFrame = aSelf->GetParentStyleContextFrame(); + nsIFrame* providerFrame = aSelf->GetParentStyleContextFrame(); bool isChild = providerFrame && providerFrame->GetParent() == aSelf; if (!isChild) { if (providerFrame) @@ -2722,6 +2784,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, "ancestor filter."); // resolve the provider here (before aSelf below). + LOG_RESTYLE("resolving child provider frame"); // assumeDifferenceHint forces the parent's change to be also // applied to this frame, no matter what @@ -2741,6 +2804,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, // Set |mResolvedChild| so we don't bother resolving the // provider again. mResolvedChild = providerFrame; + LOG_RESTYLE_CONTINUE("we had a provider frame"); // Continue restyling past the odd style context inheritance. result = eRestyleResult_Continue; } @@ -2752,13 +2816,6 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, nsChangeHint_Hints_NotHandledForDescendants; } - if (*aProviderFrame && *aProviderFrame != providerFrame) { - // XXX Uncomment when bug 979133 (restyle logging) lands. - // LOG_RESTYLE_CONTINUE("we had different provider frame from the previous " - // "same-style continuation"); - result = eRestyleResult_Continue; - } - // We don't support using eRestyle_StyleAttribute when pseudo-elements // are involved. This is mostly irrelevant since style attribute // changes on pseudo-elements are very rare, though it does mean we @@ -2768,6 +2825,8 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, aRestyleHint = (aRestyleHint & ~eRestyle_StyleAttribute) | eRestyle_Self; } + LOG_RESTYLE("parentContext = %p", parentContext); + // do primary context nsRefPtr newContext; nsIFrame *prevContinuation = @@ -2781,6 +2840,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, if (copyFromContinuation) { // Just use the style context from the frame's previous // continuation. + LOG_RESTYLE("using previous continuation's context"); newContext = prevContinuationContext; } else if (pseudoTag == nsCSSAnonBoxes::mozNonElement) { @@ -2796,6 +2856,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, Element* pseudoElement = (pseudoElementContent && pseudoElementContent->IsElement()) ? pseudoElementContent->AsElement() : nullptr; + LOG_RESTYLE("reparenting style context"); newContext = styleSet->ReparentStyleContext(oldContext, parentContext, element, pseudoElement); @@ -2805,6 +2866,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, // ReparentStyleContext that rebuilds the path in the rule tree // rather than reusing the rule node, as we need to do during a // rule tree reconstruct. + LOG_RESTYLE("resolving style with replacement"); newContext = styleSet->ResolveStyleWithReplacement(element, parentContext, oldContext, aRestyleHint); @@ -2882,12 +2944,20 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, // we can use FindChildWithRules to keep a lot of the old // style contexts around. However, we need to start from the // same root. + LOG_RESTYLE("restyling root and keeping old context"); + LOG_RESTYLE_IF(this, result != eRestyleResult_Continue, + "continuing restyle since this is the root"); newContext = oldContext; // Never consider stopping restyling at the root. result = eRestyleResult_Continue; } } + LOG_RESTYLE("oldContext = %p, newContext = %p%s", + oldContext.get(), newContext.get(), + oldContext == newContext ? (const char*) " (same)" : + (const char*) ""); + if (newContext != oldContext) { if (result == eRestyleResult_Stop) { if (oldContext->IsShared()) { @@ -2895,6 +2965,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, // eRestyleResult_Stop and patch its parent to point to the // new parent style context, as that change might not be valid // for the other frames sharing the style context. + LOG_RESTYLE_CONTINUE("the old style context is shared"); result = eRestyleResult_Continue; } else { // Look at some details of the new style context to see if it would @@ -2918,6 +2989,9 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, if (equalStructs != NS_STYLE_INHERIT_MASK) { // At least one struct had different data in it, so we must // continue restyling children. + LOG_RESTYLE_CONTINUE("there is different style data: %s", + RestyleManager::StructNamesToString( + ~equalStructs & NS_STYLE_INHERIT_MASK).get()); result = eRestyleResult_Continue; } } @@ -2930,6 +3004,9 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, if (equalStructs != NS_STYLE_INHERIT_MASK) { // At least one struct had different data in it, so we must // continue restyling children. + LOG_RESTYLE_CONTINUE("there is different style data: %s", + RestyleManager::StructNamesToString( + ~equalStructs & NS_STYLE_INHERIT_MASK).get()); result = eRestyleResult_Continue; } } @@ -2958,6 +3035,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, sid = nsStyleStructID(sid + 1)) { if (oldContext->HasCachedInheritedStyleData(sid) && !oldContext->HasSameCachedStyleData(newContext, sid)) { + LOG_RESTYLE_CONTINUE("there are different struct pointers"); result = eRestyleResult_Continue; break; } @@ -2974,12 +3052,29 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, // previous continuation, so newContext == oldContext. if (result != eRestyleResult_Stop) { - if (!oldContext->IsShared() && !newContext->IsShared()) { + if (copyFromContinuation) { + LOG_RESTYLE("not swapping style structs, since we copied from a " + "continuation"); + } else if (oldContext->IsShared() && newContext->IsShared()) { + LOG_RESTYLE("not swapping style structs, since both old and contexts " + "are shared"); + } else if (oldContext->IsShared()) { + LOG_RESTYLE("not swapping style structs, since the old context is " + "shared"); + } else if (newContext->IsShared()) { + LOG_RESTYLE("not swapping style structs, since the new context is " + "shared"); + } else { + LOG_RESTYLE("swapping style structs between %p and %p", + oldContext.get(), newContext.get()); oldContext->SwapStyleData(newContext, equalStructs); *aSwappedStructs |= equalStructs; } + LOG_RESTYLE("setting new style context"); aSelf->SetStyleContext(newContext); } + } else { + LOG_RESTYLE("not setting new style context, since we'll reframe"); } } oldContext = nullptr; @@ -2991,6 +3086,8 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, for (nsStyleContext* oldExtraContext; (oldExtraContext = aSelf->GetAdditionalStyleContext(contextIndex)); ++contextIndex) { + LOG_RESTYLE("extra context %d", contextIndex); + LOG_RESTYLE_INDENT(); nsRefPtr newExtraContext; nsIAtom* const extraPseudoTag = oldExtraContext->GetPseudo(); const nsCSSPseudoElements::Type extraPseudoType = @@ -3036,19 +3133,22 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, MOZ_ASSERT(newExtraContext); + LOG_RESTYLE("newExtraContext = %p", newExtraContext.get()); + if (oldExtraContext != newExtraContext) { uint32_t equalStructs; CaptureChange(oldExtraContext, newExtraContext, assumeDifferenceHint, &equalStructs); if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) { + LOG_RESTYLE("setting new extra style context"); aSelf->SetAdditionalStyleContext(contextIndex, newExtraContext); + } else { + LOG_RESTYLE("not setting new extra style context, since we'll reframe"); } } } - if (result == eRestyleResult_Stop) { - *aProviderFrame = providerFrame; - } + LOG_RESTYLE("returning %s", RestyleResultToString(result).get()); return result; } @@ -3153,6 +3253,9 @@ ElementRestyler::RestyleUndisplayedChildren(nsRestyleHint aChildRestyleHint) "Shouldn't have random pseudo style contexts in the " "undisplayed map"); + LOG_RESTYLE("RestyleUndisplayedChildren: undisplayed->mContent = %p", + undisplayed->mContent.get()); + // Get the parent of the undisplayed content and check if it is a XBL // children element. Push the children element as an ancestor here because it does // not have a frame and would not otherwise be pushed as an ancestor. @@ -3234,6 +3337,8 @@ ElementRestyler::MaybeReframeForBeforePseudo() nsCSSPseudoElements::ePseudo_before, mPresContext)) { // Have to create the new :before frame + LOG_RESTYLE("MaybeReframeForBeforePseudo, appending " + "nsChangeHint_ReconstructFrame"); NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame); mChangeList->AppendChange(mFrame, mContent, nsChangeHint_ReconstructFrame); @@ -3270,6 +3375,8 @@ ElementRestyler::MaybeReframeForAfterPseudo(nsIFrame* aFrame) mPresContext) && !nsLayoutUtils::GetAfterFrame(aFrame)) { // have to create the new :after frame + LOG_RESTYLE("MaybeReframeForAfterPseudo, appending " + "nsChangeHint_ReconstructFrame"); NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame); mChangeList->AppendChange(aFrame, mContent, nsChangeHint_ReconstructFrame); @@ -3322,6 +3429,8 @@ void ElementRestyler::RestyleContentChildren(nsIFrame* aParent, nsRestyleHint aChildRestyleHint) { + LOG_RESTYLE("RestyleContentChildren"); + nsIFrame::ChildListIterator lists(aParent); TreeMatchContext::AutoAncestorPusher ancestorPusher(mTreeMatchContext); if (!lists.IsDone()) { @@ -3527,4 +3636,138 @@ RestyleManager::ComputeStyleChangeFor(nsIFrame* aFrame, } } +#ifdef DEBUG +/* static */ nsCString +RestyleManager::RestyleHintToString(nsRestyleHint aHint) +{ + nsCString result; + bool any = false; + const char* names[] = { "Self", "Subtree", "LaterSiblings", "CSSTransitions", + "CSSAnimations", "SVGAttrAnimations", "StyleAttribute", + "ChangeAnimationPhase", "Force", "ForceDescendants" }; + uint32_t hint = aHint & ((1 << ArrayLength(names)) - 1); + uint32_t rest = aHint & ~((1 << ArrayLength(names)) - 1); + for (uint32_t i = 0; i < ArrayLength(names); i++) { + if (hint & (1 << i)) { + if (any) { + result.AppendLiteral(" | "); + } + result.AppendPrintf("eRestyle_%s", names[i]); + any = true; + } + } + if (rest) { + if (any) { + result.AppendLiteral(" | "); + } + result.AppendPrintf("0x%0x", rest); + } else { + if (!any) { + result.AppendLiteral("0"); + } + } + return result; +} + +/* static */ nsCString +RestyleManager::ChangeHintToString(nsChangeHint aHint) +{ + nsCString result; + bool any = false; + const char* names[] = { + "RepaintFrame", "NeedReflow", "ClearAncestorIntrinsics", + "ClearDescendantIntrinsics", "NeedDirtyReflow", "SyncFrameView", + "UpdateCursor", "UpdateEffects", "UpdateOpacityLayer", + "UpdateTransformLayer", "ReconstructFrame", "UpdateOverflow", + "UpdateSubtreeOverflow", "UpdatePostTransformOverflow", + "ChildrenOnlyTransform", "RecomputePosition", "AddOrRemoveTransform", + "BorderStyleNoneChange", "UpdateTextPath", "NeutralChange" + }; + uint32_t hint = aHint & ((1 << ArrayLength(names)) - 1); + uint32_t rest = aHint & ~((1 << ArrayLength(names)) - 1); + if (hint == nsChangeHint_Hints_NotHandledForDescendants) { + result.AppendLiteral("nsChangeHint_Hints_NotHandledForDescendants"); + hint = 0; + any = true; + } else { + if ((hint & NS_STYLE_HINT_FRAMECHANGE) == NS_STYLE_HINT_FRAMECHANGE) { + result.AppendLiteral("NS_STYLE_HINT_FRAMECHANGE"); + hint = hint & ~NS_STYLE_HINT_FRAMECHANGE; + any = true; + } else if ((hint & NS_STYLE_HINT_REFLOW) == NS_STYLE_HINT_REFLOW) { + result.AppendLiteral("NS_STYLE_HINT_REFLOW"); + hint = hint & ~NS_STYLE_HINT_REFLOW; + any = true; + } else if ((hint & nsChangeHint_AllReflowHints) == nsChangeHint_AllReflowHints) { + result.AppendLiteral("nsChangeHint_AllReflowHints"); + hint = hint & ~nsChangeHint_AllReflowHints; + any = true; + } else if ((hint & NS_STYLE_HINT_VISUAL) == NS_STYLE_HINT_VISUAL) { + result.AppendLiteral("NS_STYLE_HINT_VISUAL"); + hint = hint & ~NS_STYLE_HINT_VISUAL; + any = true; + } + } + for (uint32_t i = 0; i < ArrayLength(names); i++) { + if (hint & (1 << i)) { + if (any) { + result.AppendLiteral(" | "); + } + result.AppendPrintf("nsChangeHint_%s", names[i]); + any = true; + } + } + if (rest) { + if (any) { + result.AppendLiteral(" | "); + } + result.AppendPrintf("0x%0x", rest); + } else { + if (!any) { + result.AppendLiteral("NS_STYLE_HINT_NONE"); + } + } + return result; +} + +/* static */ nsCString +RestyleManager::StructNamesToString(uint32_t aSIDs) +{ + nsCString result; + bool any = false; + for (nsStyleStructID sid = nsStyleStructID(0); + sid < nsStyleStructID_Length; + sid = nsStyleStructID(sid + 1)) { + if (aSIDs & nsCachedStyleData::GetBitForSID(sid)) { + if (any) { + result.AppendLiteral(","); + } + result.AppendPrintf("%s", nsStyleContext::StructName(sid)); + any = true; + } + } + return result; +} + +/* static */ nsCString +ElementRestyler::RestyleResultToString(RestyleResult aRestyleResult) +{ + nsCString result; + switch (aRestyleResult) { + case eRestyleResult_Stop: + result.AssignLiteral("eRestyleResult_Stop"); + break; + case eRestyleResult_Continue: + result.AssignLiteral("eRestyleResult_Continue"); + break; + case eRestyleResult_ContinueAndForceDescendants: + result.AssignLiteral("eRestyleResult_ContinueAndForceDescendants"); + break; + default: + result.AppendPrintf("RestyleResult(%d)", aRestyleResult); + } + return result; +} +#endif + } // namespace mozilla diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index a997bcbc0126..66b3bad69d79 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -11,6 +11,7 @@ #ifndef mozilla_RestyleManager_h #define mozilla_RestyleManager_h +#include "mozilla/RestyleLogging.h" #include "nsISupportsImpl.h" #include "nsChangeHint.h" #include "RestyleTracker.h" @@ -316,6 +317,11 @@ public: mOverflowChangedTracker.Flush(); } +#ifdef DEBUG + static nsCString RestyleHintToString(nsRestyleHint aHint); + static nsCString ChangeHintToString(nsChangeHint aHint); +#endif + private: /** * Notify the frame constructor that an element needs to have its @@ -351,6 +357,39 @@ public: */ void PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint); +#ifdef RESTYLE_LOGGING + /** + * Returns whether a restyle event currently being processed by this + * RestyleManager should be logged. + */ + bool ShouldLogRestyle() { + return ShouldLogRestyle(mPresContext); + } + + /** + * Returns whether a restyle event currently being processed for the + * document with the specified nsPresContext should be logged. + */ + static bool ShouldLogRestyle(nsPresContext* aPresContext) { + return aPresContext->RestyleLoggingEnabled() && + (!aPresContext->IsProcessingAnimationStyleChange() || + AnimationRestyleLoggingEnabled()); + } + + static bool RestyleLoggingInitiallyEnabled() { + static bool enabled = getenv("MOZ_DEBUG_RESTYLE") != 0; + return enabled; + } + + static bool AnimationRestyleLoggingEnabled() { + static bool animations = getenv("MOZ_DEBUG_RESTYLE_ANIMATIONS") != 0; + return animations; + } + + static nsCString StructNamesToString(uint32_t aSIDs); + int32_t& LoggingDepth() { return mLoggingDepth; } +#endif + private: /* aMinHint is the minimal change that should be made to the element */ // XXXbz do we really need the aPrimaryFrame argument here? @@ -393,6 +432,10 @@ private: RestyleTracker mPendingRestyles; RestyleTracker mPendingAnimationRestyles; + +#ifdef RESTYLE_LOGGING + int32_t mLoggingDepth; +#endif }; /** @@ -451,6 +494,12 @@ public: */ nsChangeHint HintsHandledForFrame() { return mHintsHandled; } +#ifdef RESTYLE_LOGGING + bool ShouldLogRestyle() { + return RestyleManager::ShouldLogRestyle(mPresContext); + } +#endif + private: // Enum for the result of RestyleSelf, which indicates whether the // restyle procedure should continue to the children, and how. @@ -474,8 +523,7 @@ private: */ RestyleResult RestyleSelf(nsIFrame* aSelf, nsRestyleHint aRestyleHint, - uint32_t* aSwappedStructs, - nsIFrame** aProviderFrame); + uint32_t* aSwappedStructs); /** * Restyle the children of this frame (and, in turn, their children). @@ -518,6 +566,14 @@ private: eNotifyHidden }; +#ifdef RESTYLE_LOGGING + int32_t& LoggingDepth() { return mLoggingDepth; } +#endif + +#ifdef DEBUG + static nsCString RestyleResultToString(RestyleResult aRestyleResult); +#endif + private: nsPresContext* const mPresContext; nsIFrame* const mFrame; @@ -547,6 +603,10 @@ private: nsTArray& mVisibleKidsOfHiddenElement; bool mWasFrameVisible; #endif + +#ifdef RESTYLE_LOGGING + int32_t mLoggingDepth; +#endif }; } // namespace mozilla diff --git a/layout/base/RestyleTracker.cpp b/layout/base/RestyleTracker.cpp index 606e45804800..b516c7670db5 100644 --- a/layout/base/RestyleTracker.cpp +++ b/layout/base/RestyleTracker.cpp @@ -12,9 +12,38 @@ #include "nsStyleChangeList.h" #include "RestyleManager.h" #include "GeckoProfiler.h" +#include "nsIDocument.h" +#include "RestyleTrackerInlines.h" namespace mozilla { +#ifdef RESTYLE_LOGGING +static nsCString +GetDocumentURI(nsIDocument* aDocument) +{ + nsCString result; + nsString url; + aDocument->GetDocumentURI(url); + result.Append(NS_ConvertUTF16toUTF8(url).get()); + return result; +} + +static nsCString +FrameTagToString(dom::Element* aElement) +{ + nsCString result; + nsIFrame* frame = aElement->GetPrimaryFrame(); + if (frame) { + nsFrame::ListTag(result, frame); + } else { + nsAutoString buf; + aElement->Tag()->ToString(buf); + result.AppendPrintf("(%s@%p)", NS_ConvertUTF16toUTF8(buf).get(), aElement); + } + return result; +} +#endif + inline nsIDocument* RestyleTracker::Document() const { return mRestyleManager->PresContext()->Document(); @@ -56,6 +85,9 @@ struct RestyleEnumerateData : RestyleTracker::Hints { struct RestyleCollector { RestyleTracker* tracker; RestyleEnumerateData** restyleArrayPtr; +#ifdef RESTYLE_LOGGING + uint32_t count; +#endif }; static PLDHashOperator @@ -73,6 +105,9 @@ CollectRestyles(nsISupports* aElement, // document. if (element->GetCrossShadowCurrentDoc() != collector->tracker->Document() || !element->HasFlag(collector->tracker->RestyleBit())) { + LOG_RESTYLE_IF(collector->tracker, true, + "skipping pending restyle %s, already restyled or no longer " + "in the document", FrameTagToString(element).get()); return PL_DHASH_NEXT; } @@ -101,6 +136,10 @@ CollectRestyles(nsISupports* aElement, currentRestyle->mRestyleHint = aData->mRestyleHint; currentRestyle->mChangeHint = aData->mChangeHint; +#ifdef RESTYLE_LOGGING + collector->count++; +#endif + // Increment to the next slot in the array *restyleArrayPtr = currentRestyle + 1; @@ -118,6 +157,10 @@ RestyleTracker::ProcessOneRestyle(Element* aElement, NS_PRECONDITION(aElement->GetCrossShadowCurrentDoc() == Document(), "Element has unexpected document"); + LOG_RESTYLE("aRestyleHint = %s, aChangeHint = %s", + RestyleManager::RestyleHintToString(aRestyleHint).get(), + RestyleManager::ChangeHintToString(aChangeHint).get()); + nsIFrame* primaryFrame = aElement->GetPrimaryFrame(); if (aRestyleHint & ~eRestyle_LaterSiblings) { mRestyleManager->RestyleElement(aElement, primaryFrame, aChangeHint, @@ -140,6 +183,14 @@ RestyleTracker::DoProcessRestyles() mRestyleManager->BeginProcessingRestyles(); + LOG_RESTYLE("Processing %d pending %srestyles with %d restyle roots for %s", + mPendingRestyles.Count(), + mRestyleManager->PresContext()->IsProcessingAnimationStyleChange() + ? (const char*) "animation " : (const char*) "", + static_cast(mRestyleRoots.Length()), + GetDocumentURI(Document()).get()); + LOG_RESTYLE_INDENT(); + // loop so that we process any restyle events generated by processing while (mPendingRestyles.Count()) { if (mHaveLaterSiblingRestyles) { @@ -152,12 +203,17 @@ RestyleTracker::DoProcessRestyles() for (nsIContent* sibling = element->GetNextSibling(); sibling; sibling = sibling->GetNextSibling()) { - if (sibling->IsElement() && - AddPendingRestyle(sibling->AsElement(), eRestyle_Subtree, - NS_STYLE_HINT_NONE)) { - // Nothing else to do here; we'll handle the following - // siblings when we get to |sibling| in laterSiblingArr. - break; + if (sibling->IsElement()) { + LOG_RESTYLE("adding pending restyle for %s due to " + "eRestyle_LaterSiblings hint on %s", + FrameTagToString(sibling->AsElement()).get(), + FrameTagToString(element->AsElement()).get()); + if (AddPendingRestyle(sibling->AsElement(), eRestyle_Subtree, + NS_STYLE_HINT_NONE)) { + // Nothing else to do here; we'll handle the following + // siblings when we get to |sibling| in laterSiblingArr. + break; + } } } } @@ -176,6 +232,9 @@ RestyleTracker::DoProcessRestyles() nsRestyleHint(data->mRestyleHint & ~eRestyle_LaterSiblings); } + LOG_RESTYLE("%d pending restyles after expanding out " + "eRestyle_LaterSiblings", mPendingRestyles.Count()); + mHaveLaterSiblingRestyles = false; } @@ -188,17 +247,23 @@ RestyleTracker::DoProcessRestyles() element.swap(mRestyleRoots[rootCount - 1]); mRestyleRoots.RemoveElementAt(rootCount - 1); + LOG_RESTYLE("processing style root %s at index %d", + FrameTagToString(element).get(), rootCount - 1); + LOG_RESTYLE_INDENT(); + // Do the document check before calling GetRestyleData, since we // don't want to do the sibling-processing GetRestyleData does if // the node is no longer relevant. if (element->GetCrossShadowCurrentDoc() != Document()) { // Content node has been removed from our document; nothing else // to do here + LOG_RESTYLE("skipping, no longer in the document"); continue; } nsAutoPtr data; if (!GetRestyleData(element, data)) { + LOG_RESTYLE("skipping, already restyled"); continue; } @@ -227,9 +292,16 @@ RestyleTracker::DoProcessRestyles() // Clear the hashtable now that we don't need it anymore mPendingRestyles.Clear(); +#ifdef RESTYLE_LOGGING + uint32_t index = 0; +#endif for (RestyleEnumerateData* currentRestyle = restylesToProcess; currentRestyle != lastRestyle; ++currentRestyle) { + LOG_RESTYLE("processing pending restyle %s at index %d/%d", + FrameTagToString(currentRestyle->mElement).get(), + index++, collector.count); + LOG_RESTYLE_INDENT(); ProcessOneRestyle(currentRestyle->mElement, currentRestyle->mRestyleHint, currentRestyle->mChangeHint); diff --git a/layout/base/RestyleTracker.h b/layout/base/RestyleTracker.h index f9b7f31518ef..c1d59a1cf7e2 100644 --- a/layout/base/RestyleTracker.h +++ b/layout/base/RestyleTracker.h @@ -15,6 +15,7 @@ #include "nsClassHashtable.h" #include "nsContainerFrame.h" #include "mozilla/SplayTree.h" +#include "mozilla/RestyleLogging.h" namespace mozilla { @@ -233,9 +234,9 @@ public: friend class ElementRestyler; // for AddPendingRestyleToTable - explicit RestyleTracker(Element::FlagsType aRestyleBits) : - mRestyleBits(aRestyleBits), - mHaveLaterSiblingRestyles(false) + explicit RestyleTracker(Element::FlagsType aRestyleBits) + : mRestyleBits(aRestyleBits) + , mHaveLaterSiblingRestyles(false) { NS_PRECONDITION((mRestyleBits & ~ELEMENT_ALL_RESTYLE_FLAGS) == 0, "Why do we have these bits set?"); @@ -342,6 +343,12 @@ public: */ inline nsIDocument* Document() const; +#ifdef RESTYLE_LOGGING + // Defined in RestyleTrackerInlines.h. + inline bool ShouldLogRestyle(); + inline int32_t& LoggingDepth(); +#endif + private: bool AddPendingRestyleToTable(Element* aElement, nsRestyleHint aRestyleHint, nsChangeHint aMinChangeHint); diff --git a/layout/base/RestyleTrackerInlines.h b/layout/base/RestyleTrackerInlines.h new file mode 100644 index 000000000000..b147afa2ca1b --- /dev/null +++ b/layout/base/RestyleTrackerInlines.h @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_RestyleTrackerInlines_h +#define mozilla_RestyleTrackerInlines_h + +#ifdef RESTYLE_LOGGING +bool +mozilla::RestyleTracker::ShouldLogRestyle() +{ + return mRestyleManager->ShouldLogRestyle(); +} + +int32_t& +mozilla::RestyleTracker::LoggingDepth() +{ + return mRestyleManager->LoggingDepth(); +} +#endif + +#endif // !defined(mozilla_RestyleTrackerInlines_h) diff --git a/layout/base/moz.build b/layout/base/moz.build index 60ebd7ef9779..819bf6710654 100644 --- a/layout/base/moz.build +++ b/layout/base/moz.build @@ -59,6 +59,7 @@ EXPORTS += [ EXPORTS.mozilla += [ 'GeometryUtils.h', 'PaintTracker.h', + 'RestyleLogging.h', ] UNIFIED_SOURCES += [ diff --git a/layout/base/nsChangeHint.h b/layout/base/nsChangeHint.h index 98d5c3da4413..0aee4d2c1dec 100644 --- a/layout/base/nsChangeHint.h +++ b/layout/base/nsChangeHint.h @@ -153,7 +153,8 @@ enum nsChangeHint { nsChangeHint_NeutralChange = 0x100000 // IMPORTANT NOTE: When adding new hints, consider whether you need to - // add them to NS_HintsNotHandledForDescendantsIn() below. + // add them to NS_HintsNotHandledForDescendantsIn() below. Please also + // add them to RestyleManager::ChangeHintToString. }; // Redefine these operators to return nothing. This will catch any use @@ -277,6 +278,9 @@ inline nsChangeHint NS_HintsNotHandledForDescendantsIn(nsChangeHint aChangeHint) * Similarly, eRestyle_ForceDescendants will cause the frame and all of its * descendants to be traversed and for the new style contexts that are created * to be set on the frames. + * + * NOTE: When adding new restyle hints, please also add them to + * RestyleManager::RestyleHintToString. */ enum nsRestyleHint { // Rerun selector matching on the element. If a new style context diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 8224783318cf..6981ecb39e08 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -270,6 +270,11 @@ public: */ void SetAccurateVisibleRegions() { mAccurateVisibleRegions = true; } bool GetAccurateVisibleRegions() { return mAccurateVisibleRegions; } + /** + * @return Returns true if we should include the caret in any display lists + * that we make. + */ + bool IsBuildingCaret() { return mBuildCaret; } /** * Allows callers to selectively override the regular paint suppression checks, * so that methods like GetFrameForPoint work when painting is suppressed. diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index ab741c3dd398..e58be6b1447f 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -41,7 +41,7 @@ #include "nsFontFaceLoader.h" #include "mozilla/EventListenerManager.h" #include "prenv.h" -#include "nsObjectFrame.h" +#include "nsPluginFrame.h" #include "nsTransitionManager.h" #include "nsAnimationManager.h" #include "CounterStyleManager.h" @@ -1074,6 +1074,10 @@ nsPresContext::Init(nsDeviceContext* aDeviceContext) mEventManager->SetPresContext(this); +#ifdef RESTYLE_LOGGING + mRestyleLoggingEnabled = RestyleManager::RestyleLoggingInitiallyEnabled(); +#endif + #ifdef DEBUG mInitialized = true; #endif @@ -2856,7 +2860,7 @@ static PLDHashOperator SetPluginHidden(nsRefPtrHashKey* aEntry, void* userArg) { nsIFrame* root = static_cast(userArg); - nsObjectFrame* f = static_cast(aEntry->GetKey()->GetPrimaryFrame()); + nsPluginFrame* f = static_cast(aEntry->GetKey()->GetPrimaryFrame()); if (!f) { NS_WARNING("Null frame in SetPluginHidden"); return PL_DHASH_NEXT; @@ -3016,7 +3020,7 @@ SortConfigurations(nsTArray* aConfigurations) static PLDHashOperator PluginDidSetGeometryEnumerator(nsRefPtrHashKey* aEntry, void* userArg) { - nsObjectFrame* f = static_cast(aEntry->GetKey()->GetPrimaryFrame()); + nsPluginFrame* f = static_cast(aEntry->GetKey()->GetPrimaryFrame()); if (!f) { NS_WARNING("Null frame in PluginDidSetGeometryEnumerator"); return PL_DHASH_NEXT; @@ -3033,7 +3037,7 @@ PluginGetGeometryUpdate(nsRefPtrHashKey* aEntry, void* userArg) { PluginGetGeometryUpdateClosure* closure = static_cast(userArg); - nsObjectFrame* f = static_cast(aEntry->GetKey()->GetPrimaryFrame()); + nsPluginFrame* f = static_cast(aEntry->GetKey()->GetPrimaryFrame()); if (!f) { NS_WARNING("Null frame in GetPluginGeometryUpdate"); return PL_DHASH_NEXT; diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index c6664c931679..a496e32581fd 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -37,6 +37,7 @@ #include "nsThreadUtils.h" #include "ScrollbarStyles.h" #include "nsIMessageManager.h" +#include "mozilla/RestyleLogging.h" class nsBidiPresUtils; class nsAString; @@ -59,7 +60,7 @@ class gfxUserFontSet; class gfxTextPerfMetrics; class nsUserFontSet; struct nsFontFaceRuleContainer; -class nsObjectFrame; +class nsPluginFrame; class nsTransitionManager; class nsAnimationManager; class nsRefreshDriver; @@ -1151,6 +1152,14 @@ public: */ bool MayHavePaintEventListenerInSubDocument(); +#ifdef RESTYLE_LOGGING + // Controls for whether debug information about restyling in this + // document should be output. + bool RestyleLoggingEnabled() const { return mRestyleLoggingEnabled; } + void StartRestyleLogging() { mRestyleLoggingEnabled = true; } + void StopRestyleLogging() { mRestyleLoggingEnabled = false; } +#endif + protected: void InvalidateThebesLayers(); void AppUnitsPerDevPixelChanged(); @@ -1352,6 +1361,11 @@ protected: unsigned mHasWarnedAboutPositionedTableParts : 1; +#ifdef RESTYLE_LOGGING + // Should we output debug information about restyling for this document? + bool mRestyleLoggingEnabled; +#endif + #ifdef DEBUG bool mInitialized; #endif @@ -1431,7 +1445,7 @@ public: * Compute geometry updates for each plugin given that aList is the display * list for aFrame. The updates are not yet applied; * ApplyPluginGeometryUpdates is responsible for that. In the meantime they - * are stored on each nsObjectFrame. + * are stored on each nsPluginFrame. * This needs to be called even when aFrame is a popup, since although * windowed plugins aren't allowed in popups, windowless plugins are * and ComputePluginGeometryUpdates needs to be called for them. diff --git a/layout/base/tests/mochitest.ini b/layout/base/tests/mochitest.ini index 40122486dd90..51b6fbcb9e5f 100644 --- a/layout/base/tests/mochitest.ini +++ b/layout/base/tests/mochitest.ini @@ -490,3 +490,4 @@ support-files = bug687297_b.html bug687297_c.html [test_bug990340.html] +[test_bug1070851.html] diff --git a/layout/base/tests/test_bug1070851.html b/layout/base/tests/test_bug1070851.html new file mode 100644 index 000000000000..94c0d25f7881 --- /dev/null +++ b/layout/base/tests/test_bug1070851.html @@ -0,0 +1,59 @@ + + + + + + Test for Bug 1070851 + + + + + + + + + + Mozilla Bug 1070851 + + +
test
+ + diff --git a/layout/generic/moz.build b/layout/generic/moz.build index 4c2efb7b93f9..590ff0412576 100644 --- a/layout/generic/moz.build +++ b/layout/generic/moz.build @@ -27,7 +27,7 @@ EXPORTS += [ 'nsIScrollableFrame.h', 'nsIScrollPositionListener.h', 'nsIStatefulFrame.h', - 'nsObjectFrame.h', + 'nsPluginFrame.h', 'nsQueryFrame.h', 'nsSplittableFrame.h', 'nsSubDocumentFrame.h', @@ -100,10 +100,10 @@ UNIFIED_SOURCES += [ ] # nsLineLayout.cpp needs to be built separately because it uses plarena.h. -# nsObjectFrame.cpp needs to be built separately because of name clashes in the OS X headers. +# nsPluginFrame.cpp needs to be built separately because of name clashes in the OS X headers. SOURCES += [ 'nsLineLayout.cpp', - 'nsObjectFrame.cpp', + 'nsPluginFrame.cpp', ] if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index 03dc5dd083d7..12aa2cf10ea3 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -416,6 +416,11 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* kid; for (kid = GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) { + // Skip touch caret frame if we do not build caret. + if (!aBuilder->IsBuildingCaret() && kid->GetContent() == mTouchCaretElement) { + continue; + } + // Put our child into its own pseudo-stack. BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); } diff --git a/layout/generic/nsFrameIdList.h b/layout/generic/nsFrameIdList.h index d370d442c97d..59a3a9d192df 100644 --- a/layout/generic/nsFrameIdList.h +++ b/layout/generic/nsFrameIdList.h @@ -103,7 +103,7 @@ FRAME_ID(nsMenuFrame) FRAME_ID(nsMenuPopupFrame) FRAME_ID(nsMeterFrame) FRAME_ID(nsNumberControlFrame) -FRAME_ID(nsObjectFrame) +FRAME_ID(nsPluginFrame) FRAME_ID(nsPageBreakFrame) FRAME_ID(nsPageContentFrame) FRAME_ID(nsPageFrame) diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 47f63f1d8479..7bbd6f810226 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -488,9 +488,9 @@ nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState* aState, *aMetrics, &kidReflowState, 0, 0, NS_FRAME_NO_MOVE_FRAME | NS_FRAME_NO_SIZE_VIEW); - // XXX Some frames (e.g., nsObjectFrame, nsFrameFrame, nsTextFrame) don't bother + // XXX Some frames (e.g., nsPluginFrame, nsFrameFrame, nsTextFrame) don't bother // setting their mOverflowArea. This is wrong because every frame should - // always set mOverflowArea. In fact nsObjectFrame and nsFrameFrame don't + // always set mOverflowArea. In fact nsPluginFrame and nsFrameFrame don't // support the 'outline' property because of this. Rather than fix the world // right now, just fix up the overflow area if necessary. Note that we don't // check HasOverflowRect() because it could be set even though the diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsPluginFrame.cpp similarity index 93% rename from layout/generic/nsObjectFrame.cpp rename to layout/generic/nsPluginFrame.cpp index 90f0f5edb892..ae26192e8711 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsPluginFrame.cpp @@ -6,7 +6,7 @@ /* rendering objects for replaced elements implemented by a plugin */ -#include "nsObjectFrame.h" +#include "nsPluginFrame.h" #include "gfx2DGlue.h" #include "gfxMatrix.h" @@ -97,7 +97,7 @@ GetObjectFrameLog() { static PRLogModuleInfo *sLog; if (!sLog) - sLog = PR_NewLogModule("nsObjectFrame"); + sLog = PR_NewLogModule("nsPluginFrame"); return sLog; } #endif /* PR_LOGGING */ @@ -145,7 +145,7 @@ using namespace mozilla::layers; class PluginBackgroundSink : public ReadbackSink { public: - PluginBackgroundSink(nsObjectFrame* aFrame, uint64_t aStartSequenceNumber) + PluginBackgroundSink(nsPluginFrame* aFrame, uint64_t aStartSequenceNumber) : mLastSequenceNumber(aStartSequenceNumber), mFrame(aFrame) {} ~PluginBackgroundSink() { @@ -187,37 +187,37 @@ protected: } uint64_t mLastSequenceNumber; - nsObjectFrame* mFrame; + nsPluginFrame* mFrame; }; -nsObjectFrame::nsObjectFrame(nsStyleContext* aContext) - : nsObjectFrameSuper(aContext) +nsPluginFrame::nsPluginFrame(nsStyleContext* aContext) + : nsPluginFrameSuper(aContext) , mReflowCallbackPosted(false) { PR_LOG(GetObjectFrameLog(), PR_LOG_DEBUG, - ("Created new nsObjectFrame %p\n", this)); + ("Created new nsPluginFrame %p\n", this)); } -nsObjectFrame::~nsObjectFrame() +nsPluginFrame::~nsPluginFrame() { PR_LOG(GetObjectFrameLog(), PR_LOG_DEBUG, - ("nsObjectFrame %p deleted\n", this)); + ("nsPluginFrame %p deleted\n", this)); } -NS_QUERYFRAME_HEAD(nsObjectFrame) - NS_QUERYFRAME_ENTRY(nsObjectFrame) +NS_QUERYFRAME_HEAD(nsPluginFrame) + NS_QUERYFRAME_ENTRY(nsPluginFrame) NS_QUERYFRAME_ENTRY(nsIObjectFrame) -NS_QUERYFRAME_TAIL_INHERITING(nsObjectFrameSuper) +NS_QUERYFRAME_TAIL_INHERITING(nsPluginFrameSuper) #ifdef ACCESSIBILITY a11y::AccType -nsObjectFrame::AccessibleType() +nsPluginFrame::AccessibleType() { return a11y::ePluginType; } #ifdef XP_WIN -NS_IMETHODIMP nsObjectFrame::GetPluginPort(HWND *aPort) +NS_IMETHODIMP nsPluginFrame::GetPluginPort(HWND *aPort) { *aPort = (HWND) mInstanceOwner->GetPluginPortFromWidget(); return NS_OK; @@ -226,18 +226,18 @@ NS_IMETHODIMP nsObjectFrame::GetPluginPort(HWND *aPort) #endif void -nsObjectFrame::Init(nsIContent* aContent, +nsPluginFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, nsIFrame* aPrevInFlow) { PR_LOG(GetObjectFrameLog(), PR_LOG_DEBUG, - ("Initializing nsObjectFrame %p for content %p\n", this, aContent)); + ("Initializing nsPluginFrame %p for content %p\n", this, aContent)); - nsObjectFrameSuper::Init(aContent, aParent, aPrevInFlow); + nsPluginFrameSuper::Init(aContent, aParent, aPrevInFlow); } void -nsObjectFrame::DestroyFrom(nsIFrame* aDestructRoot) +nsPluginFrame::DestroyFrom(nsIFrame* aDestructRoot) { if (mReflowCallbackPosted) { PresContext()->PresShell()->CancelReflowCallback(this); @@ -259,11 +259,11 @@ nsObjectFrame::DestroyFrom(nsIFrame* aDestructRoot) mBackgroundSink->Destroy(); } - nsObjectFrameSuper::DestroyFrom(aDestructRoot); + nsPluginFrameSuper::DestroyFrom(aDestructRoot); } /* virtual */ void -nsObjectFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) +nsPluginFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) { if (HasView()) { nsView* view = GetView(); @@ -275,25 +275,25 @@ nsObjectFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) } } - nsObjectFrameSuper::DidSetStyleContext(aOldStyleContext); + nsPluginFrameSuper::DidSetStyleContext(aOldStyleContext); } nsIAtom* -nsObjectFrame::GetType() const +nsPluginFrame::GetType() const { return nsGkAtoms::objectFrame; } #ifdef DEBUG_FRAME_DUMP nsresult -nsObjectFrame::GetFrameName(nsAString& aResult) const +nsPluginFrame::GetFrameName(nsAString& aResult) const { - return MakeFrameName(NS_LITERAL_STRING("ObjectFrame"), aResult); + return MakeFrameName(NS_LITERAL_STRING("PluginFrame"), aResult); } #endif nsresult -nsObjectFrame::PrepForDrawing(nsIWidget *aWidget) +nsPluginFrame::PrepForDrawing(nsIWidget *aWidget) { mWidget = aWidget; @@ -411,7 +411,7 @@ nsObjectFrame::PrepForDrawing(nsIWidget *aWidget) #define EMBED_DEF_HEIGHT 200 /* virtual */ nscoord -nsObjectFrame::GetMinISize(nsRenderingContext *aRenderingContext) +nsPluginFrame::GetMinISize(nsRenderingContext *aRenderingContext) { nscoord result = 0; @@ -427,13 +427,13 @@ nsObjectFrame::GetMinISize(nsRenderingContext *aRenderingContext) } /* virtual */ nscoord -nsObjectFrame::GetPrefISize(nsRenderingContext *aRenderingContext) +nsPluginFrame::GetPrefISize(nsRenderingContext *aRenderingContext) { - return nsObjectFrame::GetMinISize(aRenderingContext); + return nsPluginFrame::GetMinISize(aRenderingContext); } void -nsObjectFrame::GetDesiredSize(nsPresContext* aPresContext, +nsPluginFrame::GetDesiredSize(nsPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aMetrics) { @@ -498,12 +498,12 @@ nsObjectFrame::GetDesiredSize(nsPresContext* aPresContext, } void -nsObjectFrame::Reflow(nsPresContext* aPresContext, +nsPluginFrame::Reflow(nsPresContext* aPresContext, nsHTMLReflowMetrics& aMetrics, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { - DO_GLOBAL_REFLOW_COUNT("nsObjectFrame"); + DO_GLOBAL_REFLOW_COUNT("nsPluginFrame"); DISPLAY_REFLOW(aPresContext, this, aReflowState, aMetrics, aStatus); // Get our desired size @@ -548,7 +548,7 @@ nsObjectFrame::Reflow(nsPresContext* aPresContext, ///////////// nsIReflowCallback /////////////// bool -nsObjectFrame::ReflowFinished() +nsPluginFrame::ReflowFinished() { mReflowCallbackPosted = false; CallSetWindow(); @@ -556,13 +556,13 @@ nsObjectFrame::ReflowFinished() } void -nsObjectFrame::ReflowCallbackCanceled() +nsPluginFrame::ReflowCallbackCanceled() { mReflowCallbackPosted = false; } void -nsObjectFrame::FixupWindow(const nsSize& aSize) +nsPluginFrame::FixupWindow(const nsSize& aSize) { nsPresContext* presContext = PresContext(); @@ -613,7 +613,7 @@ nsObjectFrame::FixupWindow(const nsSize& aSize) } nsresult -nsObjectFrame::CallSetWindow(bool aCheckIsHidden) +nsPluginFrame::CallSetWindow(bool aCheckIsHidden) { NPWindow *win = nullptr; @@ -683,7 +683,7 @@ nsObjectFrame::CallSetWindow(bool aCheckIsHidden) } void -nsObjectFrame::RegisterPluginForGeometryUpdates() +nsPluginFrame::RegisterPluginForGeometryUpdates() { nsRootPresContext* rpc = PresContext()->GetRootPresContext(); NS_ASSERTION(rpc, "We should have a root pres context!"); @@ -702,7 +702,7 @@ nsObjectFrame::RegisterPluginForGeometryUpdates() } void -nsObjectFrame::UnregisterPluginForGeometryUpdates() +nsPluginFrame::UnregisterPluginForGeometryUpdates() { if (!mRootPresContextRegisteredWith) { // Not registered... @@ -713,7 +713,7 @@ nsObjectFrame::UnregisterPluginForGeometryUpdates() } void -nsObjectFrame::SetInstanceOwner(nsPluginInstanceOwner* aOwner) +nsPluginFrame::SetInstanceOwner(nsPluginInstanceOwner* aOwner) { // The ownership model here is historically fuzzy. This should only be called // by nsPluginInstanceOwner when it is given a new frame, and @@ -743,15 +743,15 @@ nsObjectFrame::SetInstanceOwner(nsPluginInstanceOwner* aOwner) } bool -nsObjectFrame::IsFocusable(int32_t *aTabIndex, bool aWithMouse) +nsPluginFrame::IsFocusable(int32_t *aTabIndex, bool aWithMouse) { if (aTabIndex) *aTabIndex = -1; - return nsObjectFrameSuper::IsFocusable(aTabIndex, aWithMouse); + return nsPluginFrameSuper::IsFocusable(aTabIndex, aWithMouse); } bool -nsObjectFrame::IsHidden(bool aCheckVisibilityStyle) const +nsPluginFrame::IsHidden(bool aCheckVisibilityStyle) const { if (aCheckVisibilityStyle) { if (!StyleVisibility()->IsVisibleOrCollapsed()) @@ -780,7 +780,7 @@ nsObjectFrame::IsHidden(bool aCheckVisibilityStyle) const return false; } -nsIntPoint nsObjectFrame::GetWindowOriginInPixels(bool aWindowless) +nsIntPoint nsPluginFrame::GetWindowOriginInPixels(bool aWindowless) { nsView * parentWithView; nsPoint origin(0,0); @@ -801,7 +801,7 @@ nsIntPoint nsObjectFrame::GetWindowOriginInPixels(bool aWindowless) } void -nsObjectFrame::DidReflow(nsPresContext* aPresContext, +nsPluginFrame::DidReflow(nsPresContext* aPresContext, const nsHTMLReflowState* aReflowState, nsDidReflowStatus aStatus) { @@ -814,7 +814,7 @@ nsObjectFrame::DidReflow(nsPresContext* aPresContext, objContent->HasNewFrame(this); } - nsObjectFrameSuper::DidReflow(aPresContext, aReflowState, aStatus); + nsPluginFrameSuper::DidReflow(aPresContext, aReflowState, aStatus); // The view is created hidden; once we have reflowed it and it has been // positioned then we show it. @@ -830,7 +830,7 @@ nsObjectFrame::DidReflow(nsPresContext* aPresContext, } /* static */ void -nsObjectFrame::PaintPrintPlugin(nsIFrame* aFrame, nsRenderingContext* aCtx, +nsPluginFrame::PaintPrintPlugin(nsIFrame* aFrame, nsRenderingContext* aCtx, const nsRect& aDirtyRect, nsPoint aPt) { gfxContext* ctx = aCtx->ThebesContext(); @@ -845,7 +845,7 @@ nsObjectFrame::PaintPrintPlugin(nsIFrame* aFrame, nsRenderingContext* aCtx, // FIXME - Bug 385435: Doesn't aDirtyRect need translating too? - static_cast(aFrame)->PrintPlugin(*aCtx, aDirtyRect); + static_cast(aFrame)->PrintPlugin(*aCtx, aDirtyRect); } /** @@ -876,7 +876,7 @@ public: LayerManager* aManager, const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE { - return static_cast(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters); + return static_cast(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters); } virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, @@ -925,7 +925,7 @@ public: LayerManager* aManager, const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE { - return static_cast(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters); + return static_cast(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters); } virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, @@ -961,7 +961,7 @@ void nsDisplayPlugin::Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) { - nsObjectFrame* f = static_cast(mFrame); + nsPluginFrame* f = static_cast(mFrame); bool snap; f->PaintPlugin(aBuilder, *aCtx, mVisibleRect, GetBounds(aBuilder, &snap)); } @@ -971,7 +971,7 @@ nsDisplayPlugin::ComputeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion) { if (aBuilder->IsForPluginGeometry()) { - nsObjectFrame* f = static_cast(mFrame); + nsPluginFrame* f = static_cast(mFrame); if (!aBuilder->IsInTransform() || f->IsPaintedByGecko()) { // Since transforms induce reference frames, we don't need to worry // about this method fluffing out due to non-rectilinear transforms. @@ -1016,7 +1016,7 @@ nsDisplayPlugin::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, { *aSnap = false; nsRegion result; - nsObjectFrame* f = static_cast(mFrame); + nsPluginFrame* f = static_cast(mFrame); if (!aBuilder->IsForPluginGeometry()) { nsIWidget* widget = f->GetWidget(); if (widget) { @@ -1045,7 +1045,7 @@ nsDisplayPlugin::GetOpaqueRegion(nsDisplayListBuilder* aBuilder, } nsresult -nsObjectFrame::PluginEventNotifier::Run() { +nsPluginFrame::PluginEventNotifier::Run() { nsCOMPtr obsSvc = mozilla::services::GetObserverService(); obsSvc->NotifyObservers(nullptr, "plugin-changed-event", mEventType.get()); @@ -1053,13 +1053,13 @@ nsObjectFrame::PluginEventNotifier::Run() { } void -nsObjectFrame::NotifyPluginReflowObservers() +nsPluginFrame::NotifyPluginReflowObservers() { nsContentUtils::AddScriptRunner(new PluginEventNotifier(NS_LITERAL_STRING("reflow"))); } void -nsObjectFrame::DidSetWidgetGeometry() +nsPluginFrame::DidSetWidgetGeometry() { #if defined(XP_MACOSX) if (mInstanceOwner) { @@ -1080,7 +1080,7 @@ nsObjectFrame::DidSetWidgetGeometry() } bool -nsObjectFrame::IsOpaque() const +nsPluginFrame::IsOpaque() const { #if defined(XP_MACOSX) // ??? @@ -1094,7 +1094,7 @@ nsObjectFrame::IsOpaque() const } bool -nsObjectFrame::IsTransparentMode() const +nsPluginFrame::IsTransparentMode() const { #if defined(XP_MACOSX) // ??? @@ -1125,7 +1125,7 @@ nsObjectFrame::IsTransparentMode() const } void -nsObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, +nsPluginFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { @@ -1141,7 +1141,7 @@ nsObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, if (type == nsPresContext::eContext_PrintPreview) return; - DO_GLOBAL_REFLOW_COUNT_DSP("nsObjectFrame"); + DO_GLOBAL_REFLOW_COUNT_DSP("nsPluginFrame"); #ifndef XP_MACOSX if (mWidget && aBuilder->IsInTransform()) { @@ -1207,7 +1207,7 @@ nsObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } void -nsObjectFrame::PrintPlugin(nsRenderingContext& aRenderingContext, +nsPluginFrame::PrintPlugin(nsRenderingContext& aRenderingContext, const nsRect& aDirtyRect) { nsCOMPtr obj(do_QueryInterface(mContent)); @@ -1420,7 +1420,7 @@ nsObjectFrame::PrintPlugin(nsRenderingContext& aRenderingContext, } nsRect -nsObjectFrame::GetPaintedRect(nsDisplayPlugin* aItem) +nsPluginFrame::GetPaintedRect(nsDisplayPlugin* aItem) { if (!mInstanceOwner) return nsRect(); @@ -1436,7 +1436,7 @@ nsObjectFrame::GetPaintedRect(nsDisplayPlugin* aItem) } LayerState -nsObjectFrame::GetLayerState(nsDisplayListBuilder* aBuilder, +nsPluginFrame::GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager) { if (!mInstanceOwner) @@ -1456,7 +1456,7 @@ nsObjectFrame::GetLayerState(nsDisplayListBuilder* aBuilder, } already_AddRefed -nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder, +nsPluginFrame::BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, nsDisplayItem* aItem, const ContainerLayerParameters& aContainerParameters) @@ -1594,7 +1594,7 @@ nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder, } void -nsObjectFrame::PaintPlugin(nsDisplayListBuilder* aBuilder, +nsPluginFrame::PaintPlugin(nsDisplayListBuilder* aBuilder, nsRenderingContext& aRenderingContext, const nsRect& aDirtyRect, const nsRect& aPluginRect) { @@ -1826,7 +1826,7 @@ nsObjectFrame::PaintPlugin(nsDisplayListBuilder* aBuilder, } nsresult -nsObjectFrame::HandleEvent(nsPresContext* aPresContext, +nsPluginFrame::HandleEvent(nsPresContext* aPresContext, WidgetGUIEvent* anEvent, nsEventStatus* anEventStatus) { @@ -1869,7 +1869,7 @@ nsObjectFrame::HandleEvent(nsPresContext* aPresContext, } #ifdef XP_WIN - rv = nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus); + rv = nsPluginFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus); return rv; #endif @@ -1893,10 +1893,10 @@ nsObjectFrame::HandleEvent(nsPresContext* aPresContext, } #endif - rv = nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus); + rv = nsPluginFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus); // We need to be careful from this point because the call to - // nsObjectFrameSuper::HandleEvent() might have killed us. + // nsPluginFrameSuper::HandleEvent() might have killed us. #ifdef XP_MACOSX if (anEvent->message == NS_MOUSE_BUTTON_UP) { @@ -1908,7 +1908,7 @@ nsObjectFrame::HandleEvent(nsPresContext* aPresContext, } nsresult -nsObjectFrame::GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance) +nsPluginFrame::GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance) { *aPluginInstance = nullptr; @@ -1920,7 +1920,7 @@ nsObjectFrame::GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance) } nsresult -nsObjectFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor) +nsPluginFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor) { if (!mInstanceOwner) { return NS_ERROR_FAILURE; @@ -1937,11 +1937,11 @@ nsObjectFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor) return NS_ERROR_FAILURE; } - return nsObjectFrameSuper::GetCursor(aPoint, aCursor); + return nsPluginFrameSuper::GetCursor(aPoint, aCursor); } void -nsObjectFrame::SetIsDocumentActive(bool aIsActive) +nsPluginFrame::SetIsDocumentActive(bool aIsActive) { #ifndef XP_MACOSX if (mInstanceOwner) { @@ -1952,7 +1952,7 @@ nsObjectFrame::SetIsDocumentActive(bool aIsActive) // static nsIObjectFrame * -nsObjectFrame::GetNextObjectFrame(nsPresContext* aPresContext, nsIFrame* aRoot) +nsPluginFrame::GetNextObjectFrame(nsPresContext* aPresContext, nsIFrame* aRoot) { nsIFrame* child = aRoot->GetFirstPrincipalChild(); @@ -1975,7 +1975,7 @@ nsObjectFrame::GetNextObjectFrame(nsPresContext* aPresContext, nsIFrame* aRoot) } /*static*/ void -nsObjectFrame::BeginSwapDocShells(nsISupports* aSupports, void*) +nsPluginFrame::BeginSwapDocShells(nsISupports* aSupports, void*) { NS_PRECONDITION(aSupports, ""); nsCOMPtr content(do_QueryInterface(aSupports)); @@ -1984,19 +1984,19 @@ nsObjectFrame::BeginSwapDocShells(nsISupports* aSupports, void*) } // This function is called from a document content enumerator so we need - // to filter out the nsObjectFrames and ignore the rest. + // to filter out the nsPluginFrames and ignore the rest. nsIObjectFrame* obj = do_QueryFrame(content->GetPrimaryFrame()); if (!obj) return; - nsObjectFrame* objectFrame = static_cast(obj); + nsPluginFrame* objectFrame = static_cast(obj); NS_ASSERTION(!objectFrame->mWidget || objectFrame->mWidget->GetParent(), "Plugin windows must not be toplevel"); objectFrame->UnregisterPluginForGeometryUpdates(); } /*static*/ void -nsObjectFrame::EndSwapDocShells(nsISupports* aSupports, void*) +nsPluginFrame::EndSwapDocShells(nsISupports* aSupports, void*) { NS_PRECONDITION(aSupports, ""); nsCOMPtr content(do_QueryInterface(aSupports)); @@ -2005,12 +2005,12 @@ nsObjectFrame::EndSwapDocShells(nsISupports* aSupports, void*) } // This function is called from a document content enumerator so we need - // to filter out the nsObjectFrames and ignore the rest. + // to filter out the nsPluginFrames and ignore the rest. nsIObjectFrame* obj = do_QueryFrame(content->GetPrimaryFrame()); if (!obj) return; - nsObjectFrame* objectFrame = static_cast(obj); + nsPluginFrame* objectFrame = static_cast(obj); nsRootPresContext* rootPC = objectFrame->PresContext()->GetRootPresContext(); NS_ASSERTION(rootPC, "unable to register the plugin frame"); nsIWidget* widget = objectFrame->mWidget; @@ -2038,11 +2038,11 @@ nsObjectFrame::EndSwapDocShells(nsISupports* aSupports, void*) nsIFrame* NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsObjectFrame(aContext); + return new (aPresShell) nsPluginFrame(aContext); } bool -nsObjectFrame::IsPaintedByGecko() const +nsPluginFrame::IsPaintedByGecko() const { #ifdef XP_MACOSX return true; @@ -2051,4 +2051,4 @@ nsObjectFrame::IsPaintedByGecko() const #endif } -NS_IMPL_FRAMEARENA_HELPERS(nsObjectFrame) +NS_IMPL_FRAMEARENA_HELPERS(nsPluginFrame) diff --git a/layout/generic/nsObjectFrame.h b/layout/generic/nsPluginFrame.h similarity index 94% rename from layout/generic/nsObjectFrame.h rename to layout/generic/nsPluginFrame.h index 9972e5586210..accd0a1c6074 100644 --- a/layout/generic/nsObjectFrame.h +++ b/layout/generic/nsPluginFrame.h @@ -5,8 +5,8 @@ /* rendering objects for replaced elements implemented by a plugin */ -#ifndef nsObjectFrame_h___ -#define nsObjectFrame_h___ +#ifndef nsPluginFrame_h___ +#define nsPluginFrame_h___ #include "mozilla/Attributes.h" #include "nsIObjectFrame.h" @@ -40,9 +40,9 @@ class LayerManager; } } -typedef nsFrame nsObjectFrameSuper; +typedef nsFrame nsPluginFrameSuper; -class nsObjectFrame : public nsObjectFrameSuper, +class nsPluginFrame : public nsPluginFrameSuper, public nsIObjectFrame, public nsIReflowCallback { public: @@ -57,7 +57,7 @@ public: friend nsIFrame* NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); NS_DECL_QUERYFRAME - NS_DECL_QUERYFRAME_TARGET(nsObjectFrame) + NS_DECL_QUERYFRAME_TARGET(nsPluginFrame) virtual void Init(nsIContent* aContent, nsContainerFrame* aParent, @@ -83,7 +83,7 @@ public: virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE { - return nsObjectFrameSuper::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced)); + return nsPluginFrameSuper::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced)); } virtual bool NeedsView() MOZ_OVERRIDE { return true; } @@ -183,14 +183,14 @@ public: nsRect GetPaintedRect(nsDisplayPlugin* aItem); /** - * If aSupports has a nsObjectFrame, then prepare it for a DocShell swap. + * If aSupports has a nsPluginFrame, then prepare it for a DocShell swap. * @see nsSubDocumentFrame::BeginSwapDocShells. * There will be a call to EndSwapDocShells after we were moved to the * new view tree. */ static void BeginSwapDocShells(nsISupports* aSupports, void*); /** - * If aSupports has a nsObjectFrame, then set it up after a DocShell swap. + * If aSupports has a nsPluginFrame, then set it up after a DocShell swap. * @see nsSubDocumentFrame::EndSwapDocShells. */ static void EndSwapDocShells(nsISupports* aSupports, void*); @@ -211,8 +211,8 @@ public: void SetInstanceOwner(nsPluginInstanceOwner* aOwner); protected: - explicit nsObjectFrame(nsStyleContext* aContext); - virtual ~nsObjectFrame(); + explicit nsPluginFrame(nsStyleContext* aContext); + virtual ~nsPluginFrame(); // NOTE: This frame class does not inherit from |nsLeafFrame|, so // this is not a virtual method implementation. @@ -273,7 +273,7 @@ private: nsCOMPtr mWidget; nsIntRect mWindowlessRect; /** - * This is owned by the ReadbackLayer for this nsObjectFrame. It is + * This is owned by the ReadbackLayer for this nsPluginFrame. It is * automatically cleared if the PluginBackgroundSink is destroyed. */ PluginBackgroundSink* mBackgroundSink; @@ -327,7 +327,7 @@ public: LayerManager* aManager, const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE { - return static_cast(mFrame)->BuildLayer(aBuilder, + return static_cast(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters); @@ -337,9 +337,9 @@ public: LayerManager* aManager, const ContainerLayerParameters& aParameters) MOZ_OVERRIDE { - return static_cast(mFrame)->GetLayerState(aBuilder, + return static_cast(mFrame)->GetLayerState(aBuilder, aManager); } }; -#endif /* nsObjectFrame_h___ */ +#endif /* nsPluginFrame_h___ */ diff --git a/layout/generic/nsSubDocumentFrame.cpp b/layout/generic/nsSubDocumentFrame.cpp index f03e28c858ff..5d578d9fc448 100644 --- a/layout/generic/nsSubDocumentFrame.cpp +++ b/layout/generic/nsSubDocumentFrame.cpp @@ -34,7 +34,7 @@ #include "nsIObjectLoadingContent.h" #include "nsLayoutUtils.h" #include "FrameLayerBuilder.h" -#include "nsObjectFrame.h" +#include "nsPluginFrame.h" #include "nsContentUtils.h" #include "nsIPermissionManager.h" #include "nsServiceManagerUtils.h" @@ -1021,7 +1021,7 @@ BeginSwapDocShellsForDocument(nsIDocument* aDocument, void*) } } aDocument->EnumerateActivityObservers( - nsObjectFrame::BeginSwapDocShells, nullptr); + nsPluginFrame::BeginSwapDocShells, nullptr); aDocument->EnumerateSubDocuments(BeginSwapDocShellsForDocument, nullptr); return true; } @@ -1118,7 +1118,7 @@ EndSwapDocShellsForDocument(nsIDocument* aDocument, void*) } aDocument->EnumerateActivityObservers( - nsObjectFrame::EndSwapDocShells, nullptr); + nsPluginFrame::EndSwapDocShells, nullptr); aDocument->EnumerateSubDocuments(EndSwapDocShellsForDocument, nullptr); return true; } diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 2f4010c075f7..cb54c2eb28de 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -1795,7 +1795,7 @@ GetFirstFontMetrics(gfxFontGroup* aFontGroup) { if (!aFontGroup) return gfxFont::Metrics(); - gfxFont* font = aFontGroup->GetFontAt(0); + gfxFont* font = aFontGroup->GetFirstValidFont(); if (!font) return gfxFont::Metrics(); return font->GetMetrics(); @@ -5660,7 +5660,7 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx, sdptr = sdptr->mNext; } - gfxFont* firstFont = aProvider.GetFontGroup()->GetFontAt(0); + gfxFont* firstFont = aProvider.GetFontGroup()->GetFirstValidFont(); if (!firstFont) return; // OOM gfxFont::Metrics decorationMetrics(firstFont->GetMetrics()); @@ -6341,7 +6341,7 @@ nsTextFrame::CombineSelectionUnderlineRect(nsPresContext* aPresContext, nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm), GetFontSizeInflation()); gfxFontGroup* fontGroup = fm->GetThebesFontGroup(); - gfxFont* firstFont = fontGroup->GetFontAt(0); + gfxFont* firstFont = fontGroup->GetFirstValidFont(); if (!firstFont) return false; // OOM const gfxFont::Metrics& metrics = firstFont->GetMetrics(); diff --git a/layout/generic/nsVideoFrame.cpp b/layout/generic/nsVideoFrame.cpp index 572f91f6d561..88ca14bc90ba 100644 --- a/layout/generic/nsVideoFrame.cpp +++ b/layout/generic/nsVideoFrame.cpp @@ -57,7 +57,7 @@ NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame) nsresult nsVideoFrame::CreateAnonymousContent(nsTArray& aElements) { - nsNodeInfoManager *nodeInfoManager = GetContent()->GetCurrentDoc()->NodeInfoManager(); + nsNodeInfoManager *nodeInfoManager = GetContent()->GetComposedDoc()->NodeInfoManager(); nsRefPtr nodeInfo; Element *element; diff --git a/layout/mathml/nsMathMLChar.cpp b/layout/mathml/nsMathMLChar.cpp index 75e737d2e54d..34821b64c163 100644 --- a/layout/mathml/nsMathMLChar.cpp +++ b/layout/mathml/nsMathMLChar.cpp @@ -555,7 +555,8 @@ nsOpenTypeTable::MakeTextRun(gfxContext* aThebesContext, aThebesContext, nullptr, nullptr, nullptr, 0, aAppUnitsPerDevPixel }; gfxTextRun* textRun = gfxTextRun::Create(¶ms, 1, aFontGroup, 0); - textRun->AddGlyphRun(aFontGroup->GetFontAt(0), gfxTextRange::kFontGroup, 0, + textRun->AddGlyphRun(aFontGroup->GetFirstValidFont(), + gfxTextRange::kFontGroup, 0, false, gfxTextRunFactory::TEXT_ORIENT_HORIZONTAL); // We don't care about CSS writing mode here; // math runs are assumed to be horizontal. @@ -563,7 +564,7 @@ nsOpenTypeTable::MakeTextRun(gfxContext* aThebesContext, detailedGlyph.mGlyphID = aGlyph.glyphID; detailedGlyph.mAdvance = NSToCoordRound(aAppUnitsPerDevPixel * - aFontGroup->GetFontAt(0)-> + aFontGroup->GetFirstValidFont()-> GetGlyphHAdvance(aThebesContext, aGlyph.glyphID)); detailedGlyph.mXOffset = detailedGlyph.mYOffset = 0; gfxShapedText::CompressedGlyph g; @@ -993,7 +994,7 @@ nsMathMLChar::SetFontFamily(nsPresContext* aPresContext, *getter_AddRefs(fm)); // Set the font if it is an unicode table // or if the same family name has been found - gfxFont *firstFont = fm->GetThebesFontGroup()->GetFontAt(0); + gfxFont *firstFont = fm->GetThebesFontGroup()->GetFirstValidFont(); FontFamilyList firstFontList; if (firstFont) { firstFontList.Append( @@ -1439,7 +1440,7 @@ nsMathMLChar::StretchEnumContext::EnumCallback(const FontFamilyName& aFamily, glyphTable = &gGlyphTableList->mUnicodeTable; } else { // If the font contains an Open Type MATH table, use it. - openTypeTable = nsOpenTypeTable::Create(fontGroup->GetFontAt(0)); + openTypeTable = nsOpenTypeTable::Create(fontGroup->GetFirstValidFont()); if (openTypeTable) { glyphTable = openTypeTable; } else { diff --git a/layout/mathml/nsMathMLmactionFrame.cpp b/layout/mathml/nsMathMLmactionFrame.cpp index 226ae457abc6..5ff699013bfe 100644 --- a/layout/mathml/nsMathMLmactionFrame.cpp +++ b/layout/mathml/nsMathMLmactionFrame.cpp @@ -240,7 +240,7 @@ NS_IMPL_ISUPPORTS(nsMathMLmactionFrame::MouseListener, // helper to show a msg on the status bar -// curled from nsObjectFrame.cpp ... +// curled from nsPluginFrame.cpp ... void ShowStatus(nsPresContext* aPresContext, nsString& aStatusMsg) { diff --git a/layout/reftests/scoped-style/scoped-style-font-face-ref.html b/layout/reftests/scoped-style/scoped-style-font-face-ref.html index a2943b30a699..02d6971e0aee 100644 --- a/layout/reftests/scoped-style/scoped-style-font-face-ref.html +++ b/layout/reftests/scoped-style/scoped-style-font-face-ref.html @@ -3,7 +3,7 @@ diff --git a/layout/reftests/scoped-style/scoped-style-font-face.html b/layout/reftests/scoped-style/scoped-style-font-face.html index 0fe34db057f6..e79e255f7fc1 100644 --- a/layout/reftests/scoped-style/scoped-style-font-face.html +++ b/layout/reftests/scoped-style/scoped-style-font-face.html @@ -3,7 +3,7 @@ diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp index 27def311eaea..264f06628db0 100644 --- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -78,7 +78,8 @@ nsAnimationManager::GetEventsForCurrentTime(AnimationPlayerCollection* TimeDuration elapsedTime = std::max(iterationStart, anim->InitialAdvance()); AnimationEventInfo ei(aCollection->mElement, player->Name(), message, - elapsedTime, aCollection->PseudoElement()); + StickyTimeDuration(elapsedTime), + aCollection->PseudoElement()); aEventsToDispatch.AppendElement(ei); } break; @@ -91,8 +92,9 @@ nsAnimationManager::GetEventsForCurrentTime(AnimationPlayerCollection* // (This is overwritten below but we set it here to maintain // internal consistency.) anim->SetLastNotification(0); - TimeDuration elapsedTime = - std::min(anim->InitialAdvance(), computedTiming.mActiveDuration); + StickyTimeDuration elapsedTime = + std::min(StickyTimeDuration(anim->InitialAdvance()), + computedTiming.mActiveDuration); AnimationEventInfo ei(aCollection->mElement, player->Name(), NS_ANIMATION_START, elapsedTime, aCollection->PseudoElement()); diff --git a/layout/style/nsAnimationManager.h b/layout/style/nsAnimationManager.h index 930e8dfa4f62..159913f4b1ca 100644 --- a/layout/style/nsAnimationManager.h +++ b/layout/style/nsAnimationManager.h @@ -27,7 +27,8 @@ struct AnimationEventInfo { AnimationEventInfo(mozilla::dom::Element *aElement, const nsSubstring& aAnimationName, - uint32_t aMessage, mozilla::TimeDuration aElapsedTime, + uint32_t aMessage, + const mozilla::StickyTimeDuration& aElapsedTime, const nsAString& aPseudoElement) : mElement(aElement), mEvent(true, aMessage) { diff --git a/layout/style/nsCSSRules.cpp b/layout/style/nsCSSRules.cpp index 8c1403a9645b..4fb335d61048 100644 --- a/layout/style/nsCSSRules.cpp +++ b/layout/style/nsCSSRules.cpp @@ -1397,14 +1397,30 @@ DOMCI_DATA(CSSNameSpaceRule, css::NameSpaceRule) // nsCSSFontFaceStyleDecl and related routines // -// Mapping from nsCSSFontDesc codes to nsCSSFontFaceStyleDecl fields. -nsCSSValue nsCSSFontFaceStyleDecl::* const -nsCSSFontFaceStyleDecl::Fields[] = { -#define CSS_FONT_DESC(name_, method_) &nsCSSFontFaceStyleDecl::m##method_, +// Mapping from nsCSSFontDesc codes to CSSFontFaceDescriptors fields. +nsCSSValue CSSFontFaceDescriptors::* const +CSSFontFaceDescriptors::Fields[] = { +#define CSS_FONT_DESC(name_, method_) &CSSFontFaceDescriptors::m##method_, #include "nsCSSFontDescList.h" #undef CSS_FONT_DESC }; +const nsCSSValue& +CSSFontFaceDescriptors::Get(nsCSSFontDesc aFontDescID) const +{ + MOZ_ASSERT(aFontDescID > eCSSFontDesc_UNKNOWN && + aFontDescID < eCSSFontDesc_COUNT); + return this->*CSSFontFaceDescriptors::Fields[aFontDescID]; +} + +nsCSSValue& +CSSFontFaceDescriptors::Get(nsCSSFontDesc aFontDescID) +{ + MOZ_ASSERT(aFontDescID > eCSSFontDesc_UNKNOWN && + aFontDescID < eCSSFontDesc_COUNT); + return this->*CSSFontFaceDescriptors::Fields[aFontDescID]; +} + // QueryInterface implementation for nsCSSFontFaceStyleDecl NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceStyleDecl) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY @@ -1435,7 +1451,7 @@ nsCSSFontFaceStyleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID, if (aFontDescID == eCSSFontDesc_UNKNOWN) return NS_OK; - const nsCSSValue& val = this->*nsCSSFontFaceStyleDecl::Fields[aFontDescID]; + const nsCSSValue& val = mDescriptors.Get(aFontDescID); if (val.GetUnit() == eCSSUnit_Null) { // Avoid having to check no-value in the Family and Src cases below. @@ -1505,8 +1521,7 @@ nsCSSFontFaceStyleDecl::GetCssText(nsAString & aCssText) for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1); id < eCSSFontDesc_COUNT; id = nsCSSFontDesc(id + 1)) { - if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() - != eCSSUnit_Null && + if (mDescriptors.Get(id).GetUnit() != eCSSUnit_Null && NS_SUCCEEDED(GetPropertyValue(id, descStr))) { NS_ASSERTION(descStr.Length() > 0, "GetCssText: non-null unit, empty property value"); @@ -1568,7 +1583,7 @@ nsCSSFontFaceStyleDecl::RemoveProperty(const nsAString & propertyName, } else { nsresult rv = GetPropertyValue(descID, aResult); NS_ENSURE_SUCCESS(rv, rv); - (this->*nsCSSFontFaceStyleDecl::Fields[descID]).Reset(); + mDescriptors.Get(descID).Reset(); } return NS_OK; } @@ -1601,7 +1616,7 @@ nsCSSFontFaceStyleDecl::GetLength(uint32_t *aLength) for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1); id < eCSSFontDesc_COUNT; id = nsCSSFontDesc(id + 1)) - if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() != eCSSUnit_Null) + if (mDescriptors.Get(id).GetUnit() != eCSSUnit_Null) len++; *aLength = len; @@ -1627,8 +1642,7 @@ nsCSSFontFaceStyleDecl::IndexedGetter(uint32_t index, bool& aFound, nsAString & for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1); id < eCSSFontDesc_COUNT; id = nsCSSFontDesc(id + 1)) { - if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() - != eCSSUnit_Null) { + if (mDescriptors.Get(id).GetUnit() != eCSSUnit_Null) { nset++; if (nset == int32_t(index)) { aFound = true; @@ -1744,8 +1758,7 @@ nsCSSFontFaceRule::List(FILE* out, int32_t aIndent) const for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1); id < eCSSFontDesc_COUNT; id = nsCSSFontDesc(id + 1)) - if ((mDecl.*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() - != eCSSUnit_Null) { + if (mDecl.mDescriptors.Get(id).GetUnit() != eCSSUnit_Null) { if (NS_FAILED(mDecl.GetPropertyValue(id, descStr))) descStr.AssignLiteral("#"); else if (descStr.Length() == 0) @@ -1824,7 +1837,7 @@ nsCSSFontFaceRule::SetDesc(nsCSSFontDesc aDescID, nsCSSValue const & aValue) // FIXME: handle dynamic changes - mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID] = aValue; + mDecl.mDescriptors.Get(aDescID) = aValue; } void @@ -1834,7 +1847,7 @@ nsCSSFontFaceRule::GetDesc(nsCSSFontDesc aDescID, nsCSSValue & aValue) aDescID < eCSSFontDesc_COUNT, "aDescID out of range in nsCSSFontFaceRule::GetDesc"); - aValue = mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID]; + aValue = mDecl.mDescriptors.Get(aDescID); } /* virtual */ size_t diff --git a/layout/style/nsCSSRules.h b/layout/style/nsCSSRules.h index bf62ed2dcc57..8d61e8727b0d 100644 --- a/layout/style/nsCSSRules.h +++ b/layout/style/nsCSSRules.h @@ -180,6 +180,20 @@ protected: }; } // namespace css + +struct CSSFontFaceDescriptors +{ +#define CSS_FONT_DESC(name_, method_) nsCSSValue m##method_; +#include "nsCSSFontDescList.h" +#undef CSS_FONT_DESC + + const nsCSSValue& Get(nsCSSFontDesc aFontDescID) const; + nsCSSValue& Get(nsCSSFontDesc aFontDescID); + +private: + static nsCSSValue CSSFontFaceDescriptors::* const Fields[]; +}; + } // namespace mozilla // A nsCSSFontFaceStyleDecl is always embedded in a nsCSSFontFaceRule. @@ -212,14 +226,12 @@ protected: ~nsCSSFontFaceStyleDecl() {} friend class nsCSSFontFaceRule; -#define CSS_FONT_DESC(name_, method_) nsCSSValue m##method_; -#include "nsCSSFontDescList.h" -#undef CSS_FONT_DESC - static nsCSSValue nsCSSFontFaceStyleDecl::* const Fields[]; inline nsCSSFontFaceRule* ContainingRule(); inline const nsCSSFontFaceRule* ContainingRule() const; + mozilla::CSSFontFaceDescriptors mDescriptors; + private: // NOT TO BE IMPLEMENTED // This object cannot be allocated on its own, only as part of diff --git a/layout/style/nsFontFaceLoader.cpp b/layout/style/nsFontFaceLoader.cpp index 8f4be37736a7..ceccbe7629a5 100644 --- a/layout/style/nsFontFaceLoader.cpp +++ b/layout/style/nsFontFaceLoader.cpp @@ -94,7 +94,7 @@ nsFontFaceLoader::StartedLoading(nsIStreamLoader* aStreamLoader) nsITimer::TYPE_ONE_SHOT); } } else { - mUserFontEntry->mLoadingState = gfxUserFontEntry::LOADING_SLOWLY; + mUserFontEntry->mFontDataLoadingState = gfxUserFontEntry::LOADING_SLOWLY; } mStreamLoader = aStreamLoader; } @@ -114,7 +114,7 @@ nsFontFaceLoader::LoadTimerCallback(nsITimer* aTimer, void* aClosure) // If the entry is loading, check whether it's >75% done; if so, // we allow another timeout period before showing a fallback font. - if (ufe->mLoadingState == gfxUserFontEntry::LOADING_STARTED) { + if (ufe->mFontDataLoadingState == gfxUserFontEntry::LOADING_STARTED) { int64_t contentLength; uint32_t numBytesRead; if (NS_SUCCEEDED(loader->mChannel->GetContentLength(&contentLength)) && @@ -126,7 +126,7 @@ nsFontFaceLoader::LoadTimerCallback(nsITimer* aTimer, void* aClosure) // More than 3/4 the data has been downloaded, so allow 50% extra // time and hope the remainder will arrive before the additional // time expires. - ufe->mLoadingState = gfxUserFontEntry::LOADING_ALMOST_DONE; + ufe->mFontDataLoadingState = gfxUserFontEntry::LOADING_ALMOST_DONE; uint32_t delay; loader->mLoadTimer->GetDelay(&delay); loader->mLoadTimer->InitWithFuncCallback(LoadTimerCallback, @@ -142,7 +142,7 @@ nsFontFaceLoader::LoadTimerCallback(nsITimer* aTimer, void* aClosure) // before, we mark this entry as "loading slowly", so the fallback // font will be used in the meantime, and tell the context to refresh. if (updateUserFontSet) { - ufe->mLoadingState = gfxUserFontEntry::LOADING_SLOWLY; + ufe->mFontDataLoadingState = gfxUserFontEntry::LOADING_SLOWLY; gfxUserFontSet* fontSet = loader->mFontSet; nsPresContext* ctx = loader->mFontSet->GetPresContext(); NS_ASSERTION(ctx, "userfontset doesn't have a presContext?"); @@ -209,12 +209,12 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader, // The userFontEntry is responsible for freeing the downloaded data // (aString) when finished with it; the pointer is no longer valid - // after OnLoadComplete returns. + // after FontDataDownloadComplete returns. // This is called even in the case of a failed download (HTTP 404, etc), // as there may still be data to be freed (e.g. an error page), - // and we need the fontSet to initiate loading the next source. - bool fontUpdate = mUserFontEntry->OnLoadComplete(aString, - aStringLen, aStatus); + // and we need to load the next source. + bool fontUpdate = + mUserFontEntry->FontDataDownloadComplete(aString, aStringLen, aStatus); // when new font loaded, need to reflow if (fontUpdate) { @@ -237,7 +237,7 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader, void nsFontFaceLoader::Cancel() { - mUserFontEntry->mLoadingState = gfxUserFontEntry::NOT_LOADING; + mUserFontEntry->mFontDataLoadingState = gfxUserFontEntry::NOT_LOADING; mUserFontEntry->mLoader = nullptr; mFontSet = nullptr; if (mLoadTimer) { @@ -486,7 +486,7 @@ nsUserFontSet::UpdateRules(const nsTArray& aRules) } if (modified) { - IncrementGeneration(); + IncrementGeneration(true); } // local rules have been rebuilt, so clear the flag diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index dd5a72b8b6fe..ab105170ef6f 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -500,7 +500,7 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue, nsRefPtr fm = GetMetricsFor(aPresContext, aStyleContext, styleFont, aFontSize, aUseUserFontSet); - gfxFloat zeroWidth = (fm->GetThebesFontGroup()->GetFontAt(0) + gfxFloat zeroWidth = (fm->GetThebesFontGroup()->GetFirstValidFont() ->GetMetrics().zeroOrAveCharWidth); return ScaleCoordRound(aValue, ceil(aPresContext->AppUnitsPerDevPixel() * diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index 11e2e495b33e..6af26d43f844 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -144,10 +144,10 @@ nsStyleContext::AssertStructsNotUsedElsewhere( if (data && \ !(aDestroyingContext->mBits & NS_STYLE_INHERIT_BIT(name_)) && \ (mCachedInheritedData.mStyleStructs[eStyleStruct_##name_] == data)) { \ - printf("style struct %p found on style context %p\n", data, this); \ + printf_stderr("style struct %p found on style context %p\n", data, this);\ nsString url; \ PresContext()->Document()->GetURL(url); \ - printf(" in %s\n", NS_LossyConvertUTF16toASCII(url).get()); \ + printf_stderr(" in %s\n", NS_ConvertUTF16toUTF8(url).get()); \ MOZ_ASSERT(false, "destroying " #name_ " style struct still present " \ "in style context tree"); \ } @@ -168,10 +168,11 @@ nsStyleContext::AssertStructsNotUsedElsewhere( if (data && \ !(aDestroyingContext->mBits & NS_STYLE_INHERIT_BIT(name_)) && \ (mCachedResetData->mStyleStructs[eStyleStruct_##name_] == data)) { \ - printf("style struct %p found on style context %p\n", data, this); \ + printf_stderr("style struct %p found on style context %p\n", data, \ + this); \ nsString url; \ PresContext()->Document()->GetURL(url); \ - printf(" in %s\n", NS_LossyConvertUTF16toASCII(url).get()); \ + printf_stderr(" in %s\n", NS_ConvertUTF16toUTF8(url).get()); \ MOZ_ASSERT(false, "destroying " #name_ " style struct still present "\ "in style context tree"); \ } @@ -1033,6 +1034,20 @@ nsStyleContext::AssertStyleStructMaxDifferenceValid() #include "nsStyleStructList.h" #undef STYLE_STRUCT } + +/* static */ const char* +nsStyleContext::StructName(nsStyleStructID aSID) +{ + switch (aSID) { +#define STYLE_STRUCT(name_, checkdata_cb) \ + case eStyleStruct_##name_: \ + return #name_; +#include "nsStyleStructList.h" +#undef STYLE_STRUCT + default: + return "Unknown"; + } +} #endif bool diff --git a/layout/style/nsStyleContext.h b/layout/style/nsStyleContext.h index 50de463a6aee..18116b6789db 100644 --- a/layout/style/nsStyleContext.h +++ b/layout/style/nsStyleContext.h @@ -396,6 +396,7 @@ public: #ifdef DEBUG void List(FILE* out, int32_t aIndent); static void AssertStyleStructMaxDifferenceValid(); + static const char* StructName(nsStyleStructID aSID); #endif private: diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 5c5c77ca2eb8..f803c7bcca07 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -2614,6 +2614,10 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const } } + if (mMixBlendMode != aOther.mMixBlendMode) { + NS_UpdateHint(hint, nsChangeHint_RepaintFrame); + } + /* If we've added or removed the transform property, we need to reconstruct the frame to add * or remove the view object, and also to handle abs-pos and fixed-pos containers. */ @@ -2711,7 +2715,6 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const (!mClip.IsEqualEdges(aOther.mClip) || mOriginalDisplay != aOther.mOriginalDisplay || mOriginalFloats != aOther.mOriginalFloats || - mMixBlendMode != aOther.mMixBlendMode || mTransitions != aOther.mTransitions || mTransitionTimingFunctionCount != aOther.mTransitionTimingFunctionCount || diff --git a/media/gmp-clearkey/0.1/ClearKeyDecryptionManager.h b/media/gmp-clearkey/0.1/ClearKeyDecryptionManager.h index 01b12307ceff..554ec3206d44 100644 --- a/media/gmp-clearkey/0.1/ClearKeyDecryptionManager.h +++ b/media/gmp-clearkey/0.1/ClearKeyDecryptionManager.h @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef __ClearKeyDecryptor_h__ -#define __ClearKeyDecryptor_h_ +#define __ClearKeyDecryptor_h__ #include #include diff --git a/media/gmp-clearkey/0.1/moz.build b/media/gmp-clearkey/0.1/moz.build index 2f00fce949fc..6640c0c2f161 100644 --- a/media/gmp-clearkey/0.1/moz.build +++ b/media/gmp-clearkey/0.1/moz.build @@ -6,7 +6,7 @@ SharedLibrary('clearkey') -SOURCES += [ +UNIFIED_SOURCES += [ 'ClearKeyDecryptionManager.cpp', 'ClearKeySession.cpp', 'ClearKeyUtils.cpp', diff --git a/testing/marionette/client/marionette/chrome/test_nested_iframe.xul b/testing/marionette/client/marionette/chrome/test_nested_iframe.xul index d4b07f91e2da..0bec83cbe672 100644 --- a/testing/marionette/client/marionette/chrome/test_nested_iframe.xul +++ b/testing/marionette/client/marionette/chrome/test_nested_iframe.xul @@ -7,4 +7,3 @@ ]>