mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 00:35:44 +00:00
Merge inbound to central, a=merge
This commit is contained in:
commit
c033991528
@ -131,10 +131,12 @@ var FullScreen = {
|
||||
let topWin = event.target.ownerDocument.defaultView.top;
|
||||
browser = gBrowser.getBrowserForContentWindow(topWin);
|
||||
}
|
||||
TelemetryStopwatch.start("FULLSCREEN_CHANGE_MS");
|
||||
this.enterDomFullscreen(browser);
|
||||
break;
|
||||
}
|
||||
case "MozDOMFullscreen:Exited":
|
||||
TelemetryStopwatch.start("FULLSCREEN_CHANGE_MS");
|
||||
this.cleanupDomFullscreen();
|
||||
break;
|
||||
}
|
||||
@ -157,6 +159,7 @@ var FullScreen = {
|
||||
}
|
||||
case "DOMFullscreen:Painted": {
|
||||
Services.obs.notifyObservers(window, "fullscreen-painted", "");
|
||||
TelemetryStopwatch.finish("FULLSCREEN_CHANGE_MS");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ tags = mcb
|
||||
tags = mcb
|
||||
[browser_bug906190.js]
|
||||
tags = mcb
|
||||
skip-if = buildapp == "mulet" || e10s # Bug 1093642 - test manipulates content and relies on content focus
|
||||
skip-if = buildapp == "mulet" # Bug 1093642 - test manipulates content and relies on content focus
|
||||
[browser_mixedContentFromOnunload.js]
|
||||
tags = mcb
|
||||
[browser_mixedContentFramesOnHttp.js]
|
||||
|
@ -192,8 +192,6 @@ add_task(function* test_same_origin_metarefresh_different_origin() {
|
||||
* - Doorhanger to disable protection appears - we disable it
|
||||
* - Load a new page from the same origin in a new tab simulating a click
|
||||
* - Redirect to another page from the same origin using 302 redirect
|
||||
* - Doorhanger >> APPEARS << , but should >> NOT << appear again!
|
||||
* - FOLLOW UP BUG 914860!
|
||||
*/
|
||||
add_task(function* test_same_origin_302redirect_same_origin() {
|
||||
// the sjs files returns a 302 redirect- note, same origins
|
||||
@ -201,10 +199,10 @@ add_task(function* test_same_origin_302redirect_same_origin() {
|
||||
gHttpTestRoot1 + "file_bug906190.sjs", function* () {
|
||||
// The doorhanger should appear but activeBlocked should be >> NOT << true.
|
||||
// Currently it is >> TRUE << - see follow up bug 914860
|
||||
todo(!gIdentityHandler._identityBox.classList.contains("mixedActiveBlocked"),
|
||||
ok(!gIdentityHandler._identityBox.classList.contains("mixedActiveBlocked"),
|
||||
"OK: Mixed Content is NOT being blocked");
|
||||
|
||||
todo_is(content.document.getElementById('mctestdiv').innerHTML,
|
||||
is(content.document.getElementById('mctestdiv').innerHTML,
|
||||
"Mixed Content Blocker disabled", "OK: Executed mixed script");
|
||||
});
|
||||
});
|
||||
@ -214,7 +212,6 @@ add_task(function* test_same_origin_302redirect_same_origin() {
|
||||
* - Doorhanger to disable protection appears - we disable it
|
||||
* - Load a new page from the same origin in a new tab simulating a click
|
||||
* - Redirect to another page from a different origin using 302 redirect
|
||||
* - Doorhanger >> SHOULD << appear again!
|
||||
*/
|
||||
add_task(function* test_same_origin_302redirect_different_origin() {
|
||||
// the sjs files returns a 302 redirect - note, different origins
|
||||
@ -229,3 +226,15 @@ add_task(function* test_same_origin_302redirect_different_origin() {
|
||||
"Mixed Content Blocker enabled", "OK: Blocked mixed script");
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* 7. - Test memory leak issue on redirection error. See Bug 1269426.
|
||||
*/
|
||||
add_task(function* test_bad_redirection() {
|
||||
// the sjs files returns a 302 redirect - note, different origins
|
||||
yield doTest(gHttpTestRoot2 + "file_bug906190_1.html",
|
||||
gHttpTestRoot2 + "file_bug906190.sjs?bad-redirection=1", function* () {
|
||||
// Nothing to do. Just see if memory leak is reported in the end.
|
||||
ok(true, "Nothing to do");
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +1,13 @@
|
||||
function handleRequest(request, response) {
|
||||
var page = "<!DOCTYPE html><html><body>bug 906190</body></html>";
|
||||
var path = "https://test1.example.com/browser/browser/base/content/test/general/";
|
||||
var url = path + "file_bug906190_redirected.html";
|
||||
var url;
|
||||
|
||||
if (request.queryString.includes('bad-redirection=1')) {
|
||||
url = path + "this_page_does_not_exist.html";
|
||||
} else {
|
||||
url = path + "file_bug906190_redirected.html";
|
||||
}
|
||||
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
|
@ -7353,6 +7353,19 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel,
|
||||
{
|
||||
NS_ASSERTION(aStateFlags & STATE_REDIRECTING,
|
||||
"Calling OnRedirectStateChange when there is no redirect");
|
||||
|
||||
// If mixed content is allowed for the old channel, we forward
|
||||
// the permission to the new channel if it has the same origin
|
||||
// as the old one.
|
||||
if (mMixedContentChannel && mMixedContentChannel == aOldChannel) {
|
||||
nsresult rv = nsContentUtils::CheckSameOrigin(mMixedContentChannel, aNewChannel);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
SetMixedContentChannel(aNewChannel); // Same origin: forward permission.
|
||||
} else {
|
||||
SetMixedContentChannel(nullptr); // Different origin: clear mMixedContentChannel.
|
||||
}
|
||||
}
|
||||
|
||||
if (!(aStateFlags & STATE_IS_DOCUMENT)) {
|
||||
return; // not a toplevel document
|
||||
}
|
||||
|
@ -690,6 +690,14 @@ KeyframeEffectReadOnly::SetIsRunningOnCompositor(nsCSSProperty aProperty,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
KeyframeEffectReadOnly::ResetIsRunningOnCompositor()
|
||||
{
|
||||
for (AnimationProperty& property : mProperties) {
|
||||
property.mIsRunningOnCompositor = false;
|
||||
}
|
||||
}
|
||||
|
||||
KeyframeEffectReadOnly::~KeyframeEffectReadOnly()
|
||||
{
|
||||
}
|
||||
@ -750,14 +758,6 @@ KeyframeEffectReadOnly::ConstructKeyframeEffect(
|
||||
return effect.forget();
|
||||
}
|
||||
|
||||
void
|
||||
KeyframeEffectReadOnly::ResetIsRunningOnCompositor()
|
||||
{
|
||||
for (AnimationProperty& property : mProperties) {
|
||||
property.mIsRunningOnCompositor = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
KeyframeEffectReadOnly::ResetWinsInCascade()
|
||||
{
|
||||
|
@ -312,6 +312,7 @@ public:
|
||||
// Returns true if at least one property is being animated on compositor.
|
||||
bool IsRunningOnCompositor() const;
|
||||
void SetIsRunningOnCompositor(nsCSSProperty aProperty, bool aIsRunning);
|
||||
void ResetIsRunningOnCompositor();
|
||||
|
||||
// Returns true if this effect, applied to |aFrame|, contains properties
|
||||
// that mean we shouldn't run transform compositor animations on this element.
|
||||
@ -352,7 +353,6 @@ protected:
|
||||
const OptionsType& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void ResetIsRunningOnCompositor();
|
||||
void ResetWinsInCascade();
|
||||
|
||||
// This effect is registered with its target element so long as:
|
||||
|
@ -421,7 +421,7 @@ waitForAllPaints(function() {
|
||||
'Opacity script animations keep running even when the target element ' +
|
||||
'has "display: none" style');
|
||||
|
||||
todo(!animation.isRunningOnCompositor,
|
||||
ok(!animation.isRunningOnCompositor,
|
||||
'Opacity script animations on "display:none" element should not ' +
|
||||
'run on the compositor');
|
||||
|
||||
|
@ -103,6 +103,11 @@
|
||||
#include "nsXULPopupManager.h"
|
||||
#endif
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
#include "mozilla/embedding/printingui/PrintingParent.h"
|
||||
#include "nsIWebBrowserPrint.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::hal;
|
||||
using namespace mozilla::dom;
|
||||
@ -3102,6 +3107,46 @@ nsFrameLoader::RequestNotifyLayerTreeCleared()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::Print(nsIPrintSettings* aPrintSettings,
|
||||
nsIWebProgressListener* aProgressListener)
|
||||
{
|
||||
#if defined(NS_PRINTING)
|
||||
if (mRemoteBrowser) {
|
||||
RefPtr<embedding::PrintingParent> printingParent =
|
||||
mRemoteBrowser->Manager()->AsContentParent()->GetPrintingParent();
|
||||
|
||||
embedding::PrintData printData;
|
||||
nsresult rv = printingParent->SerializeAndEnsureRemotePrintJob(
|
||||
aPrintSettings, aProgressListener, nullptr, &printData);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool success = mRemoteBrowser->SendPrint(printData);
|
||||
return success ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (mDocShell) {
|
||||
nsCOMPtr<nsIContentViewer> viewer;
|
||||
mDocShell->GetContentViewer(getter_AddRefs(viewer));
|
||||
if (!viewer) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint = do_QueryInterface(viewer);
|
||||
if (!webBrowserPrint) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return webBrowserPrint->Print(aPrintSettings, aProgressListener);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* [infallible] */ NS_IMETHODIMP
|
||||
nsFrameLoader::SetVisible(bool aVisible)
|
||||
{
|
||||
|
@ -6248,6 +6248,7 @@ private:
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
nsCOMPtr<nsISupports> mTransitionData;
|
||||
|
||||
TimeStamp mFullscreenChangeStartTime;
|
||||
FullscreenTransitionDuration mDuration;
|
||||
Stage mStage;
|
||||
bool mFullscreen;
|
||||
@ -6274,6 +6275,7 @@ FullscreenTransitionTask::Run()
|
||||
this);
|
||||
} else if (stage == eToggleFullscreen) {
|
||||
PROFILER_MARKER("Fullscreen toggle start");
|
||||
mFullscreenChangeStartTime = TimeStamp::Now();
|
||||
if (MOZ_UNLIKELY(mWindow->mFullScreen != mFullscreen)) {
|
||||
// This could happen in theory if several fullscreen requests in
|
||||
// different direction happen continuously in a short time. We
|
||||
@ -6310,6 +6312,8 @@ FullscreenTransitionTask::Run()
|
||||
Preferences::GetUint("full-screen-api.transition.timeout", 500);
|
||||
mTimer->Init(observer, timeout, nsITimer::TYPE_ONE_SHOT);
|
||||
} else if (stage == eAfterToggle) {
|
||||
Telemetry::AccumulateTimeDelta(Telemetry::FULLSCREEN_TRANSITION_BLACK_MS,
|
||||
mFullscreenChangeStartTime);
|
||||
mWidget->PerformFullscreenTransition(nsIWidget::eAfterFullscreenToggle,
|
||||
mDuration.mFadeOut, mTransitionData,
|
||||
this);
|
||||
|
@ -16,6 +16,8 @@ interface nsIVariant;
|
||||
interface nsIDOMElement;
|
||||
interface nsITabParent;
|
||||
interface nsILoadContext;
|
||||
interface nsIPrintSettings;
|
||||
interface nsIWebProgressListener;
|
||||
|
||||
[scriptable, builtinclass, uuid(1645af04-1bc7-4363-8f2c-eb9679220ab1)]
|
||||
interface nsIFrameLoader : nsISupports
|
||||
@ -139,6 +141,16 @@ interface nsIFrameLoader : nsISupports
|
||||
void requestNotifyLayerTreeReady();
|
||||
void requestNotifyLayerTreeCleared();
|
||||
|
||||
/**
|
||||
* Print the current document.
|
||||
*
|
||||
* @param aPrintSettings optional print settings to use; printSilent can be
|
||||
* set to prevent prompting.
|
||||
* @param aProgressListener optional print progress listener.
|
||||
*/
|
||||
void print(in nsIPrintSettings aPrintSettings,
|
||||
in nsIWebProgressListener aProgressListener);
|
||||
|
||||
/**
|
||||
* The default event mode automatically forwards the events
|
||||
* handled in EventStateManager::HandleCrossProcessEvent to
|
||||
|
@ -1186,9 +1186,8 @@ nsDOMCameraControl::NotifyRecordingStatusChange(const nsString& aMsg)
|
||||
// Camera app will stop recording when it falls to the background, so no callback is necessary.
|
||||
mAudioChannelAgent->Init(mWindow, (int32_t)AudioChannel::Content, nullptr);
|
||||
// Video recording doesn't output any sound, so it's not necessary to check canPlay.
|
||||
float volume = 0.0;
|
||||
bool muted = true;
|
||||
rv = mAudioChannelAgent->NotifyStartedPlaying(&volume, &muted);
|
||||
AudioPlaybackConfig config;
|
||||
rv = mAudioChannelAgent->NotifyStartedPlaying(&config, AudioChannelService::AudibleState::eAudible);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -107,6 +107,7 @@
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsContentPermissionHelper.h"
|
||||
#include "nsPrintingProxy.h"
|
||||
|
||||
#include "IHistory.h"
|
||||
#include "nsNetUtil.h"
|
||||
@ -711,6 +712,11 @@ ContentChild::Init(MessageLoop* aIOLoop,
|
||||
NuwaAddConstructor(ResetTransports, nullptr);
|
||||
}
|
||||
#endif
|
||||
#ifdef NS_PRINTING
|
||||
// Force the creation of the nsPrintingProxy so that it's IPC counterpart,
|
||||
// PrintingParent, is always available for printing initiated from the parent.
|
||||
RefPtr<nsPrintingProxy> printingProxy = nsPrintingProxy::GetInstance();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -930,13 +936,13 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
||||
renderFrame = nullptr;
|
||||
}
|
||||
|
||||
ShowInfo showInfo(EmptyString(), false, false, true, 0, 0);
|
||||
ShowInfo showInfo(EmptyString(), false, false, true, false, 0, 0);
|
||||
auto* opener = nsPIDOMWindowOuter::From(aParent);
|
||||
nsIDocShell* openerShell;
|
||||
if (opener && (openerShell = opener->GetDocShell())) {
|
||||
nsCOMPtr<nsILoadContext> context = do_QueryInterface(openerShell);
|
||||
showInfo = ShowInfo(EmptyString(), false,
|
||||
context->UsePrivateBrowsing(), true,
|
||||
context->UsePrivateBrowsing(), true, false,
|
||||
aTabOpener->mDPI, aTabOpener->mDefaultScale);
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,7 @@
|
||||
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
|
||||
#include "mozilla/layers/PAPZParent.h"
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/ImageBridgeParent.h"
|
||||
#include "mozilla/layers/SharedBufferManagerParent.h"
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
@ -2558,7 +2559,7 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
|
||||
// PBrowsers are created, because they rely on the Compositor
|
||||
// already being around. (Creation is async, so can't happen
|
||||
// on demand.)
|
||||
bool useOffMainThreadCompositing = !!CompositorBridgeParent::CompositorLoop();
|
||||
bool useOffMainThreadCompositing = !!CompositorThreadHolder::Loop();
|
||||
if (useOffMainThreadCompositing) {
|
||||
DebugOnly<bool> opened = PCompositorBridge::Open(this);
|
||||
MOZ_ASSERT(opened);
|
||||
@ -3819,24 +3820,42 @@ PPrintingParent*
|
||||
ContentParent::AllocPPrintingParent()
|
||||
{
|
||||
#ifdef NS_PRINTING
|
||||
return new PrintingParent();
|
||||
MOZ_ASSERT(!mPrintingParent,
|
||||
"Only one PrintingParent should be created per process.");
|
||||
|
||||
// Create the printing singleton for this process.
|
||||
mPrintingParent = new PrintingParent();
|
||||
return mPrintingParent.get();
|
||||
#else
|
||||
MOZ_ASSERT_UNREACHABLE("Should never be created if no printing.");
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvPPrintingConstructor(PPrintingParent* aActor)
|
||||
ContentParent::DeallocPPrintingParent(PPrintingParent* printing)
|
||||
{
|
||||
#ifdef NS_PRINTING
|
||||
MOZ_ASSERT(mPrintingParent == printing,
|
||||
"Only one PrintingParent should have been created per process.");
|
||||
|
||||
mPrintingParent = nullptr;
|
||||
#else
|
||||
MOZ_ASSERT_UNREACHABLE("Should never have been created if no printing.");
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::DeallocPPrintingParent(PPrintingParent* printing)
|
||||
#ifdef NS_PRINTING
|
||||
already_AddRefed<embedding::PrintingParent>
|
||||
ContentParent::GetPrintingParent()
|
||||
{
|
||||
delete printing;
|
||||
return true;
|
||||
MOZ_ASSERT(mPrintingParent);
|
||||
|
||||
RefPtr<embedding::PrintingParent> printingParent = mPrintingParent;
|
||||
return printingParent.forget();
|
||||
}
|
||||
#endif
|
||||
|
||||
PSendStreamParent*
|
||||
ContentParent::AllocPSendStreamParent()
|
||||
|
@ -49,6 +49,10 @@ class SandboxBroker;
|
||||
class SandboxBrokerPolicyFactory;
|
||||
#endif
|
||||
|
||||
namespace embedding {
|
||||
class PrintingParent;
|
||||
}
|
||||
|
||||
namespace ipc {
|
||||
class OptionalURIParams;
|
||||
class PFileDescriptorSetParent;
|
||||
@ -380,10 +384,15 @@ public:
|
||||
|
||||
virtual PPrintingParent* AllocPPrintingParent() override;
|
||||
|
||||
virtual bool RecvPPrintingConstructor(PPrintingParent* aActor) override;
|
||||
|
||||
virtual bool DeallocPPrintingParent(PPrintingParent* aActor) override;
|
||||
|
||||
#if defined(NS_PRINTING)
|
||||
/**
|
||||
* @return the PrintingParent for this ContentParent.
|
||||
*/
|
||||
already_AddRefed<embedding::PrintingParent> GetPrintingParent();
|
||||
#endif
|
||||
|
||||
virtual PSendStreamParent* AllocPSendStreamParent() override;
|
||||
virtual bool DeallocPSendStreamParent(PSendStreamParent* aActor) override;
|
||||
|
||||
@ -1200,6 +1209,10 @@ private:
|
||||
static mozilla::UniquePtr<SandboxBrokerPolicyFactory>
|
||||
sSandboxBrokerPolicyFactory;
|
||||
#endif
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
RefPtr<embedding::PrintingParent> mPrintingParent;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -15,10 +15,12 @@ include protocol PFilePicker;
|
||||
include protocol PIndexedDBPermissionRequest;
|
||||
include protocol PRenderFrame;
|
||||
include protocol PPluginWidget;
|
||||
include protocol PRemotePrintJob;
|
||||
include DOMTypes;
|
||||
include JavaScriptTypes;
|
||||
include URIParams;
|
||||
include BrowserConfiguration;
|
||||
include PPrintingTypes;
|
||||
include PTabContext;
|
||||
|
||||
|
||||
@ -92,6 +94,7 @@ struct ShowInfo
|
||||
bool fullscreenAllowed;
|
||||
bool isPrivate;
|
||||
bool fakeShowInfo;
|
||||
bool isTransparent;
|
||||
float dpi;
|
||||
double defaultScale;
|
||||
};
|
||||
@ -781,6 +784,13 @@ child:
|
||||
async HandledWindowedPluginKeyEvent(NativeEventData aKeyEventData,
|
||||
bool aIsConsumed);
|
||||
|
||||
/**
|
||||
* Tell the child to print the current page with the given settings.
|
||||
*
|
||||
* @param aPrintData the serialized settings to print with
|
||||
*/
|
||||
async Print(PrintData aPrintData);
|
||||
|
||||
/*
|
||||
* FIXME: write protocol!
|
||||
|
||||
|
@ -112,6 +112,13 @@
|
||||
#include "nsDeviceContext.h"
|
||||
#include "FrameLayerBuilder.h"
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
#include "nsIPrintSession.h"
|
||||
#include "nsIPrintSettings.h"
|
||||
#include "nsIPrintSettingsService.h"
|
||||
#include "nsIWebBrowserPrint.h"
|
||||
#endif
|
||||
|
||||
#define BROWSER_ELEMENT_CHILD_SCRIPT \
|
||||
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
|
||||
|
||||
@ -591,6 +598,7 @@ TabChild::TabChild(nsIContentChild* aManager,
|
||||
, mUniqueId(aTabId)
|
||||
, mDPI(0)
|
||||
, mDefaultScale(0)
|
||||
, mIsTransparent(false)
|
||||
, mIPCOpen(true)
|
||||
, mParentIsActive(false)
|
||||
, mDidSetRealShowInfo(false)
|
||||
@ -1302,30 +1310,6 @@ TabChild::SetProcessNameToAppName()
|
||||
ContentChild::GetSingleton()->SetProcessName(appName, true);
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::IsRootContentDocument() const
|
||||
{
|
||||
// A TabChild is a "root content document" if it's
|
||||
//
|
||||
// - <iframe mozapp> not inside another <iframe mozapp>,
|
||||
// - <iframe mozbrowser> (not mozapp), or
|
||||
// - a vanilla remote frame (<html:iframe remote=true> or <xul:browser
|
||||
// remote=true>).
|
||||
//
|
||||
// Put another way, an iframe is /not/ a "root content document" iff it's a
|
||||
// mozapp inside a mozapp. (This corresponds exactly to !HasAppOwnerApp.)
|
||||
//
|
||||
// Note that we're lying through our teeth here (thus the scare quotes).
|
||||
// <html:iframe remote=true> or <xul:browser remote=true> inside another
|
||||
// content iframe is not actually a root content document, but we say it is.
|
||||
//
|
||||
// We do this because we make a remote frame opaque iff
|
||||
// IsRootContentDocument(), and making vanilla remote frames transparent
|
||||
// breaks our remote reftests.
|
||||
|
||||
return !HasAppOwnerApp();
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvLoadURL(const nsCString& aURI,
|
||||
const BrowserConfiguration& aConfiguration,
|
||||
@ -1564,6 +1548,7 @@ TabChild::ApplyShowInfo(const ShowInfo& aInfo)
|
||||
}
|
||||
mDPI = aInfo.dpi();
|
||||
mDefaultScale = aInfo.defaultScale();
|
||||
mIsTransparent = aInfo.isTransparent();
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
@ -2457,6 +2442,45 @@ TabChild::RecvSetUseGlobalHistory(const bool& aUse)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvPrint(const PrintData& aPrintData)
|
||||
{
|
||||
#ifdef NS_PRINTING
|
||||
nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint = do_GetInterface(mWebNav);
|
||||
if (NS_WARN_IF(!webBrowserPrint)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
|
||||
do_GetService("@mozilla.org/gfx/printsettings-service;1");
|
||||
if (NS_WARN_IF(!printSettingsSvc)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrintSettings> printSettings;
|
||||
nsresult rv =
|
||||
printSettingsSvc->GetNewPrintSettings(getter_AddRefs(printSettings));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrintSession> printSession =
|
||||
do_CreateInstance("@mozilla.org/gfx/printsession;1", &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
printSettings->SetPrintSession(printSession);
|
||||
printSettingsSvc->DeserializeToPrintSettings(aPrintData, printSettings);
|
||||
rv = webBrowserPrint->Print(printSettings, nullptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvDestroy()
|
||||
{
|
||||
@ -2994,7 +3018,7 @@ TabChild::InvalidateLayers()
|
||||
void
|
||||
TabChild::CompositorUpdated(const TextureFactoryIdentifier& aNewIdentifier)
|
||||
{
|
||||
gfxPlatform::GetPlatform()->UpdateRenderModeIfDeviceReset();
|
||||
gfxPlatform::GetPlatform()->CompositorUpdated();
|
||||
|
||||
RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();
|
||||
ClientLayerManager* clm = lm->AsClientLayerManager();
|
||||
|
@ -194,12 +194,12 @@ public:
|
||||
// Get the Document for the top-level window in this tab.
|
||||
already_AddRefed<nsIDocument> GetDocument() const;
|
||||
|
||||
protected:
|
||||
virtual ~TabChildBase();
|
||||
|
||||
// Get the pres-shell of the document for the top-level window in this tab.
|
||||
already_AddRefed<nsIPresShell> GetPresShell() const;
|
||||
|
||||
protected:
|
||||
virtual ~TabChildBase();
|
||||
|
||||
// Wraps up a JSON object as a structured clone and sends it to the browser
|
||||
// chrome script.
|
||||
//
|
||||
@ -265,8 +265,6 @@ public:
|
||||
Create(nsIContentChild* aManager, const TabId& aTabId,
|
||||
const TabContext& aContext, uint32_t aChromeFlags);
|
||||
|
||||
bool IsRootContentDocument() const;
|
||||
|
||||
// Let managees query if it is safe to send messages.
|
||||
bool IsDestroyed() const{ return mDestroyed; }
|
||||
|
||||
@ -476,6 +474,8 @@ public:
|
||||
|
||||
void GetDefaultScale(double *aScale);
|
||||
|
||||
bool IsTransparent() const { return mIsTransparent; }
|
||||
|
||||
void GetMaxTouchPoints(uint32_t* aTouchPoints);
|
||||
|
||||
ScreenOrientationInternal GetOrientation() const { return mOrientation; }
|
||||
@ -580,6 +580,8 @@ public:
|
||||
const mozilla::NativeEventData& aKeyEventData,
|
||||
const bool& aIsConsumed) override;
|
||||
|
||||
virtual bool RecvPrint(const PrintData& aPrintData) override;
|
||||
|
||||
/**
|
||||
* Native widget remoting protocol for use with windowed plugins with e10s.
|
||||
*/
|
||||
@ -751,6 +753,8 @@ private:
|
||||
float mDPI;
|
||||
double mDefaultScale;
|
||||
|
||||
bool mIsTransparent;
|
||||
|
||||
bool mIPCOpen;
|
||||
bool mParentIsActive;
|
||||
bool mAsyncPanZoomEnabled;
|
||||
|
@ -3325,12 +3325,15 @@ TabParent::GetShowInfo()
|
||||
mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
|
||||
mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozallowfullscreen);
|
||||
bool isPrivate = mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozprivatebrowsing);
|
||||
bool isTransparent =
|
||||
nsContentUtils::IsChromeDoc(mFrameElement->OwnerDoc()) &&
|
||||
mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::transparent);
|
||||
return ShowInfo(name, allowFullscreen, isPrivate, false,
|
||||
mDPI, mDefaultScale.scale);
|
||||
isTransparent, mDPI, mDefaultScale.scale);
|
||||
}
|
||||
|
||||
return ShowInfo(EmptyString(), false, false, false,
|
||||
mDPI, mDefaultScale.scale);
|
||||
false, mDPI, mDefaultScale.scale);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -187,6 +187,7 @@ WidevineDecryptor::DecryptingComplete()
|
||||
{
|
||||
Log("WidevineDecryptor::DecryptingComplete() this=%p", this);
|
||||
mCDM = nullptr;
|
||||
mCallback = nullptr;
|
||||
Release();
|
||||
}
|
||||
|
||||
|
@ -1969,6 +1969,32 @@ TrackBuffersManager::SkipToNextRandomAccessPoint(TrackInfo::TrackType aTrack,
|
||||
return parsed;
|
||||
}
|
||||
|
||||
const MediaRawData*
|
||||
TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
||||
size_t aIndex,
|
||||
const TimeUnit& aExpectedDts,
|
||||
const TimeUnit& aExpectedPts,
|
||||
const TimeUnit& aFuzz)
|
||||
{
|
||||
const TrackBuffer& track = GetTrackBuffer(aTrack);
|
||||
|
||||
if (aIndex >= track.Length()) {
|
||||
// reached the end.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const RefPtr<MediaRawData>& sample = track[aIndex];
|
||||
if (!aIndex || sample->mTimecode <= (aExpectedDts + aFuzz).ToMicroseconds() ||
|
||||
sample->mTime <= (aExpectedPts + aFuzz).ToMicroseconds()) {
|
||||
return sample;
|
||||
}
|
||||
|
||||
// Gap is too big. End of Stream or Waiting for Data.
|
||||
// TODO, check that we have continuous data based on the sanitized buffered
|
||||
// range instead.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<MediaRawData>
|
||||
TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
||||
const TimeUnit& aFuzz,
|
||||
@ -1980,9 +2006,7 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
||||
|
||||
aError = false;
|
||||
|
||||
if (!track.Length() ||
|
||||
(trackData.mNextGetSampleIndex.isSome() &&
|
||||
trackData.mNextGetSampleIndex.ref() >= track.Length())) {
|
||||
if (!track.Length()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (trackData.mNextGetSampleIndex.isNothing() &&
|
||||
@ -1992,11 +2016,13 @@ TrackBuffersManager::GetSample(TrackInfo::TrackType aTrack,
|
||||
}
|
||||
|
||||
if (trackData.mNextGetSampleIndex.isSome()) {
|
||||
const RefPtr<MediaRawData>& sample =
|
||||
track[trackData.mNextGetSampleIndex.ref()];
|
||||
if (trackData.mNextGetSampleIndex.ref() &&
|
||||
sample->mTimecode > (trackData.mNextSampleTimecode + aFuzz).ToMicroseconds()) {
|
||||
// Gap is too big. End of Stream or Waiting for Data.
|
||||
const MediaRawData* sample =
|
||||
GetSample(aTrack,
|
||||
trackData.mNextGetSampleIndex.ref(),
|
||||
trackData.mNextSampleTimecode,
|
||||
trackData.mNextSampleTime,
|
||||
aFuzz);
|
||||
if (!sample) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -2078,11 +2104,12 @@ TrackBuffersManager::GetNextRandomAccessPoint(TrackInfo::TrackType aTrack,
|
||||
|
||||
uint32_t i = trackData.mNextGetSampleIndex.ref();
|
||||
TimeUnit nextSampleTimecode = trackData.mNextSampleTimecode;
|
||||
TimeUnit nextSampleTime = trackData.mNextSampleTime;
|
||||
|
||||
for (; i < track.Length(); i++) {
|
||||
const RefPtr<MediaRawData>& sample = track[i];
|
||||
if (sample->mTimecode > (nextSampleTimecode + aFuzz).ToMicroseconds()) {
|
||||
// Gap is too big. End of Stream or Waiting for Data.
|
||||
const MediaRawData* sample =
|
||||
GetSample(aTrack, i, nextSampleTimecode, nextSampleTime, aFuzz);
|
||||
if (!sample) {
|
||||
break;
|
||||
}
|
||||
if (sample->mKeyframe) {
|
||||
@ -2090,6 +2117,7 @@ TrackBuffersManager::GetNextRandomAccessPoint(TrackInfo::TrackType aTrack,
|
||||
}
|
||||
nextSampleTimecode =
|
||||
TimeUnit::FromMicroseconds(sample->mTimecode + sample->mDuration);
|
||||
nextSampleTime = TimeUnit::FromMicroseconds(sample->GetEndTime());
|
||||
}
|
||||
return TimeUnit::FromInfinity();
|
||||
}
|
||||
|
@ -340,6 +340,11 @@ private:
|
||||
// Find index of sample. Return a negative value if not found.
|
||||
uint32_t FindSampleIndex(const TrackBuffer& aTrackBuffer,
|
||||
const media::TimeInterval& aInterval);
|
||||
const MediaRawData* GetSample(TrackInfo::TrackType aTrack,
|
||||
size_t aIndex,
|
||||
const media::TimeUnit& aExpectedDts,
|
||||
const media::TimeUnit& aExpectedPts,
|
||||
const media::TimeUnit& aFuzz);
|
||||
void UpdateBufferedRanges();
|
||||
void RejectProcessing(nsresult aRejectValue, const char* aName);
|
||||
void ResolveProcessing(bool aResolveValue, const char* aName);
|
||||
|
@ -5,7 +5,7 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "MediaSystemResourceManagerParent.h"
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
#include "MediaSystemResourceService.h"
|
||||
@ -46,7 +46,7 @@ MediaSystemResourceService::Shutdown()
|
||||
MediaSystemResourceService::MediaSystemResourceService()
|
||||
: mDestroyed(false)
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// The maximum number of hardware resoureces available.
|
||||
// XXX need to hange to a dynamic way.
|
||||
@ -82,7 +82,7 @@ MediaSystemResourceService::Acquire(media::MediaSystemResourceManagerParent* aPa
|
||||
MediaSystemResourceType aResourceType,
|
||||
bool aWillWait)
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
MOZ_ASSERT(aParent);
|
||||
|
||||
if (mDestroyed) {
|
||||
@ -123,7 +123,7 @@ MediaSystemResourceService::ReleaseResource(media::MediaSystemResourceManagerPar
|
||||
uint32_t aId,
|
||||
MediaSystemResourceType aResourceType)
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
MOZ_ASSERT(aParent);
|
||||
|
||||
if (mDestroyed) {
|
||||
|
@ -23,6 +23,7 @@ sync protocol PPrinting
|
||||
parent:
|
||||
sync ShowProgress(PBrowser browser,
|
||||
PPrintProgressDialog printProgressDialog,
|
||||
PRemotePrintJob remotePrintJob,
|
||||
bool isForPrinting)
|
||||
returns(bool notifyOnOpen,
|
||||
nsresult rv);
|
||||
|
@ -6,14 +6,15 @@
|
||||
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "nsIPrintOptions.h"
|
||||
#include "nsIPrintProgressParams.h"
|
||||
#include "nsIPrintSettingsService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "PrintingParent.h"
|
||||
#include "PrintDataUtils.h"
|
||||
@ -30,6 +31,7 @@ namespace embedding {
|
||||
bool
|
||||
PrintingParent::RecvShowProgress(PBrowserParent* parent,
|
||||
PPrintProgressDialogParent* printProgressDialog,
|
||||
PRemotePrintJobParent* remotePrintJob,
|
||||
const bool& isForPrinting,
|
||||
bool* notifyOnOpen,
|
||||
nsresult* result)
|
||||
@ -62,7 +64,15 @@ PrintingParent::RecvShowProgress(PBrowserParent* parent,
|
||||
notifyOnOpen);
|
||||
NS_ENSURE_SUCCESS(*result, true);
|
||||
|
||||
if (remotePrintJob) {
|
||||
// If we have a RemotePrintJob use that as a more general forwarder for
|
||||
// print progress listeners.
|
||||
static_cast<RemotePrintJobParent*>(remotePrintJob)
|
||||
->RegisterListener(printProgressListener);
|
||||
} else {
|
||||
dialogParent->SetWebProgressListener(printProgressListener);
|
||||
}
|
||||
|
||||
dialogParent->SetPrintProgressParams(printProgressParams);
|
||||
|
||||
return true;
|
||||
@ -88,25 +98,22 @@ PrintingParent::ShowPrintDialog(PBrowserParent* aParent,
|
||||
// nsIWebBrowserPrint to keep the dialogs happy.
|
||||
nsCOMPtr<nsIWebBrowserPrint> wbp = new MockWebBrowserPrint(aData);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrintOptions> po = do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPrintSettings> settings;
|
||||
rv = po->CreatePrintSettings(getter_AddRefs(settings));
|
||||
nsresult rv = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(settings));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = po->DeserializeToPrintSettings(aData, settings);
|
||||
rv = mPrintSettingsSvc->DeserializeToPrintSettings(aData, settings);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = pps->ShowPrintDialog(parentWin, wbp, settings);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// And send it back.
|
||||
rv = po->SerializeToPrintData(settings, nullptr, aResult);
|
||||
|
||||
PRemotePrintJobParent* remotePrintJob = new RemotePrintJobParent(settings);
|
||||
aResult->remotePrintJobParent() = SendPRemotePrintJobConstructor(remotePrintJob);
|
||||
// Serialize back to aResult. Use the existing RemotePrintJob if we have one
|
||||
// otherwise SerializeAndEnsureRemotePrintJob() will create a new one.
|
||||
RemotePrintJobParent* remotePrintJob =
|
||||
static_cast<RemotePrintJobParent*>(aData.remotePrintJobParent());
|
||||
rv = SerializeAndEnsureRemotePrintJob(settings, nullptr, remotePrintJob,
|
||||
aResult);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -137,21 +144,16 @@ PrintingParent::RecvSavePrintSettings(const PrintData& aData,
|
||||
const uint32_t& aFlags,
|
||||
nsresult* aResult)
|
||||
{
|
||||
nsCOMPtr<nsIPrintSettingsService> pss =
|
||||
do_GetService("@mozilla.org/gfx/printsettings-service;1", aResult);
|
||||
NS_ENSURE_SUCCESS(*aResult, true);
|
||||
|
||||
nsCOMPtr<nsIPrintOptions> po = do_QueryInterface(pss, aResult);
|
||||
NS_ENSURE_SUCCESS(*aResult, true);
|
||||
|
||||
nsCOMPtr<nsIPrintSettings> settings;
|
||||
*aResult = po->CreatePrintSettings(getter_AddRefs(settings));
|
||||
*aResult = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(settings));
|
||||
NS_ENSURE_SUCCESS(*aResult, true);
|
||||
|
||||
*aResult = po->DeserializeToPrintSettings(aData, settings);
|
||||
*aResult = mPrintSettingsSvc->DeserializeToPrintSettings(aData, settings);
|
||||
NS_ENSURE_SUCCESS(*aResult, true);
|
||||
|
||||
*aResult = pss->SavePrintSettingsToPrefs(settings, aUsePrinterNamePrefix, aFlags);
|
||||
*aResult = mPrintSettingsSvc->SavePrintSettingsToPrefs(settings,
|
||||
aUsePrinterNamePrefix,
|
||||
aFlags);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -238,9 +240,53 @@ PrintingParent::DOMWindowFromBrowserParent(PBrowserParent* parent)
|
||||
return parentWin;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PrintingParent::SerializeAndEnsureRemotePrintJob(
|
||||
nsIPrintSettings* aPrintSettings, nsIWebProgressListener* aListener,
|
||||
layout::RemotePrintJobParent* aRemotePrintJob, PrintData* aPrintData)
|
||||
{
|
||||
MOZ_ASSERT(aPrintData);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrintSettings> printSettings;
|
||||
if (aPrintSettings) {
|
||||
printSettings = aPrintSettings;
|
||||
} else {
|
||||
rv = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(printSettings));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
rv = mPrintSettingsSvc->SerializeToPrintData(aPrintSettings, nullptr,
|
||||
aPrintData);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
RemotePrintJobParent* remotePrintJob;
|
||||
if (aRemotePrintJob) {
|
||||
remotePrintJob = aRemotePrintJob;
|
||||
aPrintData->remotePrintJobParent() = remotePrintJob;
|
||||
} else {
|
||||
remotePrintJob = new RemotePrintJobParent(aPrintSettings);
|
||||
aPrintData->remotePrintJobParent() =
|
||||
SendPRemotePrintJobConstructor(remotePrintJob);
|
||||
}
|
||||
if (aListener) {
|
||||
remotePrintJob->RegisterListener(aListener);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PrintingParent::PrintingParent()
|
||||
{
|
||||
MOZ_COUNT_CTOR(PrintingParent);
|
||||
|
||||
mPrintSettingsSvc =
|
||||
do_GetService("@mozilla.org/gfx/printsettings-service;1");
|
||||
MOZ_ASSERT(mPrintSettingsSvc);
|
||||
}
|
||||
|
||||
PrintingParent::~PrintingParent()
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "mozilla/dom/PBrowserParent.h"
|
||||
#include "mozilla/embedding/PPrintingParent.h"
|
||||
|
||||
class nsIPrintSettingsService;
|
||||
class nsIWebProgressListener;
|
||||
class nsPIDOMWindowOuter;
|
||||
class PPrintProgressDialogParent;
|
||||
class PPrintSettingsDialogParent;
|
||||
@ -17,6 +19,7 @@ class PPrintSettingsDialogParent;
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
class PRemotePrintJobParent;
|
||||
class RemotePrintJobParent;
|
||||
}
|
||||
|
||||
namespace embedding {
|
||||
@ -24,9 +27,12 @@ namespace embedding {
|
||||
class PrintingParent final : public PPrintingParent
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(PrintingParent)
|
||||
|
||||
virtual bool
|
||||
RecvShowProgress(PBrowserParent* parent,
|
||||
PPrintProgressDialogParent* printProgressDialog,
|
||||
PRemotePrintJobParent* remotePrintJob,
|
||||
const bool& isForPrinting,
|
||||
bool* notifyOnOpen,
|
||||
nsresult* result);
|
||||
@ -63,9 +69,29 @@ public:
|
||||
ActorDestroy(ActorDestroyReason aWhy);
|
||||
|
||||
MOZ_IMPLICIT PrintingParent();
|
||||
virtual ~PrintingParent();
|
||||
|
||||
/**
|
||||
* Serialize nsIPrintSettings to PrintData ready for sending to a child
|
||||
* process. A RemotePrintJob will be created and added to the PrintData.
|
||||
* An optional progress listener can be given, which will be registered
|
||||
* with the RemotePrintJob, so that progress can be tracked in the parent.
|
||||
*
|
||||
* @param aPrintSettings optional print settings to serialize, otherwise a
|
||||
* default print settings will be used.
|
||||
* @param aProgressListener optional print progress listener.
|
||||
* @param aRemotePrintJob optional remote print job, so that an existing
|
||||
* one can be used.
|
||||
* @param aPrintData PrintData to populate.
|
||||
*/
|
||||
nsresult
|
||||
SerializeAndEnsureRemotePrintJob(nsIPrintSettings* aPrintSettings,
|
||||
nsIWebProgressListener* aListener,
|
||||
layout::RemotePrintJobParent* aRemotePrintJob,
|
||||
PrintData* aPrintData);
|
||||
|
||||
private:
|
||||
virtual ~PrintingParent();
|
||||
|
||||
nsPIDOMWindowOuter*
|
||||
DOMWindowFromBrowserParent(PBrowserParent* parent);
|
||||
|
||||
@ -73,6 +99,8 @@ private:
|
||||
ShowPrintDialog(PBrowserParent* parent,
|
||||
const PrintData& data,
|
||||
PrintData* result);
|
||||
|
||||
nsCOMPtr<nsIPrintSettingsService> mPrintSettingsSvc;
|
||||
};
|
||||
|
||||
} // namespace embedding
|
||||
|
@ -14,10 +14,13 @@
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "nsIPrintSession.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPrintOptionsImpl.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "PrintDataUtils.h"
|
||||
#include "PrintProgressDialogChild.h"
|
||||
#include "PrintSettingsDialogChild.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -87,12 +90,13 @@ nsPrintingProxy::ShowPrintDialog(mozIDOMWindowProxy *parent,
|
||||
|
||||
// Next, serialize the nsIWebBrowserPrint and nsIPrintSettings we were given.
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIPrintOptions> po =
|
||||
nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
|
||||
do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PrintData inSettings;
|
||||
rv = po->SerializeToPrintData(printSettings, webBrowserPrint, &inSettings);
|
||||
rv = printSettingsSvc->SerializeToPrintData(printSettings, webBrowserPrint,
|
||||
&inSettings);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Now, the waiting game. The parent process should be showing
|
||||
@ -112,7 +116,8 @@ nsPrintingProxy::ShowPrintDialog(mozIDOMWindowProxy *parent,
|
||||
rv = dialog->result();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = po->DeserializeToPrintSettings(dialog->data(), printSettings);
|
||||
rv = printSettingsSvc->DeserializeToPrintSettings(dialog->data(),
|
||||
printSettings);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -145,14 +150,29 @@ nsPrintingProxy::ShowProgress(mozIDOMWindowProxy* parent,
|
||||
|
||||
SendPPrintProgressDialogConstructor(dialogChild);
|
||||
|
||||
// Get the RemotePrintJob if we have one available.
|
||||
RefPtr<mozilla::layout::RemotePrintJobChild> remotePrintJob;
|
||||
if (printSettings) {
|
||||
nsCOMPtr<nsIPrintSession> printSession;
|
||||
nsresult rv = printSettings->GetPrintSession(getter_AddRefs(printSession));
|
||||
if (NS_SUCCEEDED(rv) && printSession) {
|
||||
printSession->GetRemotePrintJob(getter_AddRefs(remotePrintJob));
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
mozilla::Unused << SendShowProgress(pBrowser, dialogChild,
|
||||
mozilla::Unused << SendShowProgress(pBrowser, dialogChild, remotePrintJob,
|
||||
isForPrinting, notifyOnOpen, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// If we have a RemotePrintJob that will be being used as a more general
|
||||
// forwarder for print progress listeners. Once we always have one we can
|
||||
// remove the interface from PrintProgressDialogChild.
|
||||
if (!remotePrintJob) {
|
||||
NS_ADDREF(*webProgressListener = dialogChild);
|
||||
}
|
||||
NS_ADDREF(*printProgressParams = dialogChild);
|
||||
|
||||
return NS_OK;
|
||||
@ -180,12 +200,12 @@ nsPrintingProxy::SavePrintSettings(nsIPrintSettings* aPS,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrintOptions> po =
|
||||
nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
|
||||
do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PrintData settings;
|
||||
rv = po->SerializeToPrintData(aPS, nullptr, &settings);
|
||||
rv = printSettingsSvc->SerializeToPrintData(aPS, nullptr, &settings);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
Unused << SendSavePrintSettings(settings, aUsePrinterNamePrefix, aFlags,
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "base/message_loop.h" // for MessageLoop
|
||||
#include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent
|
||||
#include "mozilla/layers/Effects.h" // for Effect, EffectChain, etc
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/mozalloc.h" // for operator delete, etc
|
||||
#include "gfx2DGlue.h"
|
||||
#include "nsAppRunner.h"
|
||||
@ -25,8 +26,8 @@ namespace layers {
|
||||
/* static */ void
|
||||
Compositor::AssertOnCompositorThread()
|
||||
{
|
||||
MOZ_ASSERT(!CompositorBridgeParent::CompositorLoop() ||
|
||||
CompositorBridgeParent::CompositorLoop() == MessageLoop::current(),
|
||||
MOZ_ASSERT(!CompositorThreadHolder::Loop() ||
|
||||
CompositorThreadHolder::Loop() == MessageLoop::current(),
|
||||
"Can only call this from the compositor thread!");
|
||||
}
|
||||
|
||||
|
@ -195,6 +195,8 @@ public:
|
||||
: mCompositorID(0)
|
||||
, mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC)
|
||||
, mParent(aParent)
|
||||
, mPixelsPerFrame(0)
|
||||
, mPixelsFilled(0)
|
||||
, mScreenRotation(ROTATION_0)
|
||||
, mWidget(aWidget)
|
||||
{
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#include "TexturePoolOGL.h"
|
||||
#include "mozilla/layers/CompositorOGL.h"
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/LayerManagerComposite.h"
|
||||
#include "mozilla/layers/TextureHostOGL.h"
|
||||
|
||||
@ -1899,7 +1899,7 @@ bool
|
||||
LayerScope::CheckSendable()
|
||||
{
|
||||
// Only compositor threads check LayerScope status
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread() || gIsGtest);
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread() || gIsGtest);
|
||||
|
||||
if (!gfxPrefs::LayerScopeEnabled()) {
|
||||
return false;
|
||||
|
@ -503,6 +503,14 @@ CanvasClientSharedSurface::Updated()
|
||||
forwarder->UseTextures(this, textures);
|
||||
}
|
||||
|
||||
void
|
||||
CanvasClientSharedSurface::OnDetach() {
|
||||
if (mShSurfClient) {
|
||||
mShSurfClient->CancelWaitForCompositorRecycle();
|
||||
}
|
||||
ClearSurfaces();
|
||||
}
|
||||
|
||||
void
|
||||
CanvasClientSharedSurface::ClearSurfaces()
|
||||
{
|
||||
|
@ -160,9 +160,7 @@ public:
|
||||
|
||||
virtual void Updated() override;
|
||||
|
||||
virtual void OnDetach() override {
|
||||
ClearSurfaces();
|
||||
}
|
||||
virtual void OnDetach() override;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -205,6 +205,7 @@ ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
|
||||
|
||||
if (DependsOnStaleDevice()) {
|
||||
FrameLayerBuilder::InvalidateAllLayers(this);
|
||||
mDeviceCounter = gfxPlatform::GetPlatform()->GetDeviceCounter();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mKeepAlive.IsEmpty(), "uncommitted txn?");
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "mozilla/layers/APZUtils.h" // for CompleteAsyncTransform
|
||||
#include "mozilla/layers/Compositor.h" // for Compositor
|
||||
#include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent, etc
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/LayerAnimationUtils.h" // for TimingFunctionToComputedTimingFunction
|
||||
#include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
|
||||
#include "nsCoord.h" // for NSAppUnitsToFloatPixels, etc
|
||||
@ -706,7 +707,7 @@ void
|
||||
AsyncCompositionManager::RecordShadowTransforms(Layer* aLayer)
|
||||
{
|
||||
MOZ_ASSERT(gfxPrefs::CollectScrollTransforms());
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
|
||||
ForEachNodePostOrder<ForwardIterator>(
|
||||
aLayer,
|
||||
@ -1439,7 +1440,7 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
|
||||
void
|
||||
AsyncCompositionManager::GetFrameUniformity(FrameUniformityData* aOutData)
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
mLayerTransformRecorder.EndTest(aOutData);
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include <stddef.h> // for size_t
|
||||
#include "ClientLayerManager.h" // for ClientLayerManager
|
||||
#include "base/message_loop.h" // for MessageLoop
|
||||
@ -180,7 +181,7 @@ CompositorBridgeChild::OpenSameProcess(CompositorBridgeParent* aParent)
|
||||
|
||||
mCompositorBridgeParent = aParent;
|
||||
mCanSend = Open(mCompositorBridgeParent->GetIPCChannel(),
|
||||
CompositorBridgeParent::CompositorLoop(),
|
||||
CompositorThreadHolder::Loop(),
|
||||
ipc::ChildSide);
|
||||
return mCanSend;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "mozilla/layers/Compositor.h" // for Compositor
|
||||
#include "mozilla/layers/CompositorLRU.h" // for CompositorLRU
|
||||
#include "mozilla/layers/CompositorOGL.h" // for CompositorOGL
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
#include "mozilla/layers/FrameUniformityData.h"
|
||||
#include "mozilla/layers/ImageBridgeParent.h"
|
||||
@ -90,11 +91,6 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace gfx {
|
||||
// See VRManagerChild.cpp
|
||||
void ReleaseVRManagerParentSingleton();
|
||||
} // namespace gfx
|
||||
|
||||
namespace layers {
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
@ -155,99 +151,30 @@ CompositorBridgeParent::ForEachIndirectLayerTree(const Lambda& aCallback)
|
||||
* compositor
|
||||
*/
|
||||
typedef map<uint64_t,CompositorBridgeParent*> CompositorMap;
|
||||
static CompositorMap* sCompositorMap;
|
||||
static StaticAutoPtr<CompositorMap> sCompositorMap;
|
||||
|
||||
static void CreateCompositorMap()
|
||||
void
|
||||
CompositorBridgeParent::Initialize()
|
||||
{
|
||||
EnsureLayerTreeMapReady();
|
||||
|
||||
MOZ_ASSERT(!sCompositorMap);
|
||||
sCompositorMap = new CompositorMap;
|
||||
}
|
||||
|
||||
static void DestroyCompositorMap()
|
||||
void
|
||||
CompositorBridgeParent::Shutdown()
|
||||
{
|
||||
MOZ_ASSERT(sCompositorMap);
|
||||
MOZ_ASSERT(sCompositorMap->empty());
|
||||
delete sCompositorMap;
|
||||
sCompositorMap = nullptr;
|
||||
}
|
||||
|
||||
// See ImageBridgeChild.cpp
|
||||
void ReleaseImageBridgeParentSingleton();
|
||||
|
||||
CompositorThreadHolder::CompositorThreadHolder()
|
||||
: mCompositorThread(CreateCompositorThread())
|
||||
void
|
||||
CompositorBridgeParent::FinishShutdown()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_COUNT_CTOR(CompositorThreadHolder);
|
||||
}
|
||||
|
||||
CompositorThreadHolder::~CompositorThreadHolder()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MOZ_COUNT_DTOR(CompositorThreadHolder);
|
||||
|
||||
DestroyCompositorThread(mCompositorThread);
|
||||
}
|
||||
|
||||
static StaticRefPtr<CompositorThreadHolder> sCompositorThreadHolder;
|
||||
static bool sFinishedCompositorShutDown = false;
|
||||
|
||||
CompositorThreadHolder* GetCompositorThreadHolder()
|
||||
{
|
||||
return sCompositorThreadHolder;
|
||||
}
|
||||
|
||||
/* static */ Thread*
|
||||
CompositorThreadHolder::CreateCompositorThread()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MOZ_ASSERT(!sCompositorThreadHolder, "The compositor thread has already been started!");
|
||||
|
||||
Thread* compositorThread = new Thread("Compositor");
|
||||
|
||||
Thread::Options options;
|
||||
/* Timeout values are powers-of-two to enable us get better data.
|
||||
128ms is chosen for transient hangs because 8Hz should be the minimally
|
||||
acceptable goal for Compositor responsiveness (normal goal is 60Hz). */
|
||||
options.transient_hang_timeout = 128; // milliseconds
|
||||
/* 2048ms is chosen for permanent hangs because it's longer than most
|
||||
* Compositor hangs seen in the wild, but is short enough to not miss getting
|
||||
* native hang stacks. */
|
||||
options.permanent_hang_timeout = 2048; // milliseconds
|
||||
#if defined(_WIN32)
|
||||
/* With d3d9 the compositor thread creates native ui, see DeviceManagerD3D9. As
|
||||
* such the thread is a gui thread, and must process a windows message queue or
|
||||
* risk deadlocks. Chromium message loop TYPE_UI does exactly what we need. */
|
||||
options.message_loop_type = MessageLoop::TYPE_UI;
|
||||
#endif
|
||||
|
||||
if (!compositorThread->StartWithOptions(options)) {
|
||||
delete compositorThread;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EnsureLayerTreeMapReady();
|
||||
CreateCompositorMap();
|
||||
|
||||
return compositorThread;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
CompositorThreadHolder::DestroyCompositorThread(Thread* aCompositorThread)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MOZ_ASSERT(!sCompositorThreadHolder, "We shouldn't be destroying the compositor thread yet.");
|
||||
|
||||
DestroyCompositorMap();
|
||||
delete aCompositorThread;
|
||||
sFinishedCompositorShutDown = true;
|
||||
}
|
||||
|
||||
static Thread* CompositorThread() {
|
||||
return sCompositorThreadHolder ? sCompositorThreadHolder->GetCompositorThread() : nullptr;
|
||||
// TODO: this should be empty by now...
|
||||
sIndirectLayerTrees.clear();
|
||||
}
|
||||
|
||||
static void SetThreadPriority()
|
||||
@ -358,7 +285,7 @@ CompositorVsyncScheduler::SetDisplay(bool aDisplayEnable)
|
||||
{
|
||||
// SetDisplay() is usually called from nsScreenManager at main thread. Post
|
||||
// to compositor thread if needs.
|
||||
if (!CompositorBridgeParent::IsInCompositorThread()) {
|
||||
if (!CompositorThreadHolder::IsInCompositorThread()) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MonitorAutoLock lock(mSetDisplayMonitor);
|
||||
RefPtr<CancelableRunnable> task =
|
||||
@ -385,7 +312,7 @@ CompositorVsyncScheduler::SetDisplay(bool aDisplayEnable)
|
||||
void
|
||||
CompositorVsyncScheduler::CancelSetDisplayTask()
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
MonitorAutoLock lock(mSetDisplayMonitor);
|
||||
if (mSetDisplayTask) {
|
||||
mSetDisplayTask->Cancel();
|
||||
@ -406,7 +333,7 @@ CompositorVsyncScheduler::Destroy()
|
||||
// Destroy was already called on this object.
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
UnobserveVsync();
|
||||
mVsyncObserver->Destroy();
|
||||
mVsyncObserver = nullptr;
|
||||
@ -437,7 +364,7 @@ CompositorVsyncScheduler::PostCompositeTask(TimeStamp aCompositeTimestamp)
|
||||
void
|
||||
CompositorVsyncScheduler::ScheduleComposition()
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
if (mAsapScheduling) {
|
||||
// Used only for performance testing purposes
|
||||
PostCompositeTask(TimeStamp::Now());
|
||||
@ -459,7 +386,7 @@ CompositorVsyncScheduler::ScheduleComposition()
|
||||
void
|
||||
CompositorVsyncScheduler::CancelCurrentSetNeedsCompositeTask()
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
MonitorAutoLock lock(mSetNeedsCompositeMonitor);
|
||||
if (mSetNeedsCompositeTask) {
|
||||
mSetNeedsCompositeTask->Cancel();
|
||||
@ -478,7 +405,7 @@ CompositorVsyncScheduler::CancelCurrentSetNeedsCompositeTask()
|
||||
void
|
||||
CompositorVsyncScheduler::SetNeedsComposite()
|
||||
{
|
||||
if (!CompositorBridgeParent::IsInCompositorThread()) {
|
||||
if (!CompositorThreadHolder::IsInCompositorThread()) {
|
||||
MonitorAutoLock lock(mSetNeedsCompositeMonitor);
|
||||
RefPtr<CancelableRunnable> task =
|
||||
NewCancelableRunnableMethod(this, &CompositorVsyncScheduler::SetNeedsComposite);
|
||||
@ -509,7 +436,7 @@ bool
|
||||
CompositorVsyncScheduler::NotifyVsync(TimeStamp aVsyncTimestamp)
|
||||
{
|
||||
// Called from the vsync dispatch thread
|
||||
MOZ_ASSERT(!CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(!CompositorThreadHolder::IsInCompositorThread());
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
PostCompositeTask(aVsyncTimestamp);
|
||||
return true;
|
||||
@ -518,7 +445,7 @@ CompositorVsyncScheduler::NotifyVsync(TimeStamp aVsyncTimestamp)
|
||||
void
|
||||
CompositorVsyncScheduler::CancelCurrentCompositeTask()
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread() || NS_IsMainThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread() || NS_IsMainThread());
|
||||
MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
|
||||
if (mCurrentCompositeTask) {
|
||||
mCurrentCompositeTask->Cancel();
|
||||
@ -529,7 +456,7 @@ CompositorVsyncScheduler::CancelCurrentCompositeTask()
|
||||
void
|
||||
CompositorVsyncScheduler::Composite(TimeStamp aVsyncTimestamp)
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
{
|
||||
MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
|
||||
mCurrentCompositeTask = nullptr;
|
||||
@ -572,14 +499,14 @@ CompositorVsyncScheduler::OnForceComposeToTarget()
|
||||
* free and this oscillating behavior causes a performance hit. In order to avoid this problem,
|
||||
* we reset the mVsyncNotificationsSkipped counter to keep vsync enabled.
|
||||
*/
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
mVsyncNotificationsSkipped = 0;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorVsyncScheduler::ForceComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
OnForceComposeToTarget();
|
||||
mLastCompose = TimeStamp::Now();
|
||||
ComposeToTarget(aTarget, aRect);
|
||||
@ -588,14 +515,14 @@ CompositorVsyncScheduler::ForceComposeToTarget(gfx::DrawTarget* aTarget, const I
|
||||
bool
|
||||
CompositorVsyncScheduler::NeedsComposite()
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
return mNeedsComposite;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorVsyncScheduler::ObserveVsync()
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
mCompositorVsyncDispatcher->SetCompositorVsyncObserver(mVsyncObserver);
|
||||
mIsObservingVsync = true;
|
||||
}
|
||||
@ -603,7 +530,7 @@ CompositorVsyncScheduler::ObserveVsync()
|
||||
void
|
||||
CompositorVsyncScheduler::UnobserveVsync()
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
mCompositorVsyncDispatcher->SetCompositorVsyncObserver(nullptr);
|
||||
mIsObservingVsync = false;
|
||||
}
|
||||
@ -619,59 +546,25 @@ CompositorVsyncScheduler::DispatchTouchEvents(TimeStamp aVsyncTimestamp)
|
||||
void
|
||||
CompositorVsyncScheduler::DispatchVREvents(TimeStamp aVsyncTimestamp)
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
|
||||
VRManager* vm = VRManager::Get();
|
||||
vm->NotifyVsync(aVsyncTimestamp);
|
||||
}
|
||||
|
||||
void CompositorBridgeParent::StartUp()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");
|
||||
MOZ_ASSERT(!sCompositorThreadHolder, "The compositor thread has already been started!");
|
||||
|
||||
sCompositorThreadHolder = new CompositorThreadHolder();
|
||||
}
|
||||
|
||||
void CompositorBridgeParent::ShutDown()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");
|
||||
MOZ_ASSERT(sCompositorThreadHolder, "The compositor thread has already been shut down!");
|
||||
|
||||
ReleaseImageBridgeParentSingleton();
|
||||
ReleaseVRManagerParentSingleton();
|
||||
MediaSystemResourceService::Shutdown();
|
||||
|
||||
sCompositorThreadHolder = nullptr;
|
||||
|
||||
// No locking is needed around sFinishedCompositorShutDown because it is only
|
||||
// ever accessed on the main thread.
|
||||
while (!sFinishedCompositorShutDown) {
|
||||
NS_ProcessNextEvent(nullptr, true);
|
||||
}
|
||||
|
||||
// TODO: this should be empty by now...
|
||||
sIndirectLayerTrees.clear();
|
||||
}
|
||||
|
||||
MessageLoop* CompositorBridgeParent::CompositorLoop()
|
||||
{
|
||||
return CompositorThread() ? CompositorThread()->message_loop() : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorVsyncScheduler::ScheduleTask(already_AddRefed<CancelableRunnable> aTask,
|
||||
int aTime)
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::CompositorLoop());
|
||||
MOZ_ASSERT(CompositorThreadHolder::Loop());
|
||||
MOZ_ASSERT(aTime >= 0);
|
||||
CompositorBridgeParent::CompositorLoop()->PostDelayedTask(Move(aTask), aTime);
|
||||
CompositorThreadHolder::Loop()->PostDelayedTask(Move(aTask), aTime);
|
||||
}
|
||||
|
||||
void
|
||||
CompositorVsyncScheduler::ResumeComposition()
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
mLastCompose = TimeStamp::Now();
|
||||
ComposeToTarget(nullptr);
|
||||
}
|
||||
@ -679,11 +572,17 @@ CompositorVsyncScheduler::ResumeComposition()
|
||||
void
|
||||
CompositorVsyncScheduler::ComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
|
||||
{
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
MOZ_ASSERT(mCompositorBridgeParent);
|
||||
mCompositorBridgeParent->CompositeToTarget(aTarget, aRect);
|
||||
}
|
||||
|
||||
static inline MessageLoop*
|
||||
CompositorLoop()
|
||||
{
|
||||
return CompositorThreadHolder::Loop();
|
||||
}
|
||||
|
||||
CompositorBridgeParent::CompositorBridgeParent(widget::CompositorWidgetProxy* aWidget,
|
||||
CSSToLayoutDeviceScale aScale,
|
||||
bool aUseAPZ,
|
||||
@ -701,7 +600,7 @@ CompositorBridgeParent::CompositorBridgeParent(widget::CompositorWidgetProxy* aW
|
||||
, mRootLayerTreeID(AllocateLayerTreeId())
|
||||
, mOverrideComposeReadiness(false)
|
||||
, mForceCompositionTask(nullptr)
|
||||
, mCompositorThreadHolder(sCompositorThreadHolder)
|
||||
, mCompositorThreadHolder(CompositorThreadHolder::GetSingleton())
|
||||
, mCompositorScheduler(nullptr)
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
||||
, mLastPluginUpdateLayerTreeId(0)
|
||||
@ -744,12 +643,6 @@ CompositorBridgeParent::CompositorBridgeParent(widget::CompositorWidgetProxy* aW
|
||||
mSelfRef = this;
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeParent::IsInCompositorThread()
|
||||
{
|
||||
return CompositorThread() && CompositorThread()->thread_id() == PlatformThread::CurrentId();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
CompositorBridgeParent::RootLayerTreeId()
|
||||
{
|
||||
@ -1015,7 +908,7 @@ CompositorBridgeParent::InvalidateOnCompositorThread()
|
||||
void
|
||||
CompositorBridgeParent::PauseComposition()
|
||||
{
|
||||
MOZ_ASSERT(IsInCompositorThread(),
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread(),
|
||||
"PauseComposition() can only be called on the compositor thread");
|
||||
|
||||
MonitorAutoLock lock(mPauseCompositionMonitor);
|
||||
@ -1036,7 +929,7 @@ CompositorBridgeParent::PauseComposition()
|
||||
void
|
||||
CompositorBridgeParent::ResumeComposition()
|
||||
{
|
||||
MOZ_ASSERT(IsInCompositorThread(),
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread(),
|
||||
"ResumeComposition() can only be called on the compositor thread");
|
||||
|
||||
MonitorAutoLock lock(mResumeCompositionMonitor);
|
||||
@ -1170,7 +1063,7 @@ CompositorBridgeParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstP
|
||||
void
|
||||
CompositorBridgeParent::ScheduleComposition()
|
||||
{
|
||||
MOZ_ASSERT(IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
if (mPaused) {
|
||||
return;
|
||||
}
|
||||
@ -1213,7 +1106,7 @@ CompositorBridgeParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRec
|
||||
PROFILER_LABEL("CompositorBridgeParent", "Composite",
|
||||
js::ProfileEntry::Category::GRAPHICS);
|
||||
|
||||
MOZ_ASSERT(IsInCompositorThread(),
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread(),
|
||||
"Composite can only be called on the compositor thread");
|
||||
TimeStamp start = TimeStamp::Now();
|
||||
|
||||
@ -1373,7 +1266,7 @@ void
|
||||
CompositorBridgeParent::ScheduleRotationOnCompositorThread(const TargetConfig& aTargetConfig,
|
||||
bool aIsFirstPaint)
|
||||
{
|
||||
MOZ_ASSERT(IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
|
||||
if (!aIsFirstPaint &&
|
||||
!mCompositionManager->IsFirstPaint() &&
|
||||
@ -1872,7 +1765,7 @@ static void
|
||||
InsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
|
||||
{
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
MOZ_ASSERT(CompositorBridgeParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
VsyncPayload* payload = new VsyncPayload(aVsyncTimestamp);
|
||||
PROFILER_MARKER_PAYLOAD("VsyncTimestamp", payload);
|
||||
#endif
|
||||
@ -1882,7 +1775,7 @@ InsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
|
||||
CompositorBridgeParent::PostInsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
|
||||
{
|
||||
// Called in the vsync thread
|
||||
if (profiler_is_active() && sCompositorThreadHolder) {
|
||||
if (profiler_is_active() && CompositorThreadHolder::IsActive()) {
|
||||
CompositorLoop()->PostTask(
|
||||
NewRunnableFunction(InsertVsyncProfilerMarker, aVsyncTimestamp));
|
||||
}
|
||||
@ -2072,7 +1965,9 @@ public:
|
||||
virtual void DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
|
||||
|
||||
protected:
|
||||
void OnChannelConnected(int32_t pid) override { mCompositorThreadHolder = sCompositorThreadHolder; }
|
||||
void OnChannelConnected(int32_t pid) override {
|
||||
mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
|
||||
}
|
||||
private:
|
||||
// Private destructor, to discourage deletion outside of Release():
|
||||
virtual ~CrossProcessCompositorBridgeParent();
|
||||
|
@ -17,9 +17,6 @@
|
||||
|
||||
#include <stdint.h> // for uint64_t
|
||||
#include "Layers.h" // for Layer
|
||||
#include "base/basictypes.h" // for DISALLOW_EVIL_CONSTRUCTORS
|
||||
#include "base/platform_thread.h" // for PlatformThreadId
|
||||
#include "base/thread.h" // for Thread
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
|
||||
#include "mozilla/Attributes.h" // for override
|
||||
#include "mozilla/Maybe.h"
|
||||
@ -68,6 +65,7 @@ class LayerManagerComposite;
|
||||
class LayerTransactionParent;
|
||||
class PAPZParent;
|
||||
class CrossProcessCompositorBridgeParent;
|
||||
class CompositorThreadHolder;
|
||||
|
||||
struct ScopedLayerTreeRegistration
|
||||
{
|
||||
@ -81,28 +79,6 @@ private:
|
||||
uint64_t mLayersId;
|
||||
};
|
||||
|
||||
class CompositorThreadHolder final
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorThreadHolder)
|
||||
|
||||
public:
|
||||
CompositorThreadHolder();
|
||||
|
||||
base::Thread* GetCompositorThread() const {
|
||||
return mCompositorThread;
|
||||
}
|
||||
|
||||
private:
|
||||
~CompositorThreadHolder();
|
||||
|
||||
base::Thread* const mCompositorThread;
|
||||
|
||||
static base::Thread* CreateCompositorThread();
|
||||
static void DestroyCompositorThread(base::Thread* aCompositorThread);
|
||||
|
||||
friend class CompositorBridgeParent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Manages the vsync (de)registration and tracking on behalf of the
|
||||
* compositor when it need to paint.
|
||||
@ -231,6 +207,7 @@ class CompositorBridgeParent final : public PCompositorBridgeParent,
|
||||
public ShmemAllocator
|
||||
{
|
||||
friend class CompositorVsyncScheduler;
|
||||
friend class CompositorThreadHolder;
|
||||
|
||||
public:
|
||||
explicit CompositorBridgeParent(widget::CompositorWidgetProxy* aWidget,
|
||||
@ -395,27 +372,6 @@ public:
|
||||
*/
|
||||
static CompositorBridgeParent* GetCompositor(uint64_t id);
|
||||
|
||||
/**
|
||||
* Returns the compositor thread's message loop.
|
||||
*
|
||||
* This message loop is used by CompositorBridgeParent, ImageBridgeParent,
|
||||
* and VRManagerParent
|
||||
*/
|
||||
static MessageLoop* CompositorLoop();
|
||||
|
||||
/**
|
||||
* Creates the compositor thread and the global compositor map.
|
||||
*/
|
||||
static void StartUp();
|
||||
|
||||
/**
|
||||
* Waits for all [CrossProcess]CompositorBridgeParent's to be gone,
|
||||
* and destroys the compositor thread and global compositor map.
|
||||
*
|
||||
* Does not return until all of that has completed.
|
||||
*/
|
||||
static void ShutDown();
|
||||
|
||||
/**
|
||||
* Allocate an ID that can be used to refer to a layer tree and
|
||||
* associated resources that live only on the compositor thread.
|
||||
@ -519,11 +475,6 @@ public:
|
||||
|
||||
float ComputeRenderIntegrity();
|
||||
|
||||
/**
|
||||
* Returns true if the calling thread is the compositor thread.
|
||||
*/
|
||||
static bool IsInCompositorThread();
|
||||
|
||||
widget::CompositorWidgetProxy* GetWidgetProxy() { return mWidgetProxy; }
|
||||
|
||||
void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr);
|
||||
@ -584,6 +535,21 @@ protected:
|
||||
*/
|
||||
static CompositorBridgeParent* RemoveCompositor(uint64_t id);
|
||||
|
||||
/**
|
||||
* Creates the global compositor map.
|
||||
*/
|
||||
static void Initialize();
|
||||
|
||||
/**
|
||||
* Destroys the compositor thread and global compositor map.
|
||||
*/
|
||||
static void Shutdown();
|
||||
|
||||
/**
|
||||
* Finish the shutdown operation on the compositor thread.
|
||||
*/
|
||||
static void FinishShutdown();
|
||||
|
||||
/**
|
||||
* Return true if current state allows compositing, that is
|
||||
* finishing a layers transaction.
|
||||
|
153
gfx/layers/ipc/CompositorThread.cpp
Normal file
153
gfx/layers/ipc/CompositorThread.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 sts=2 ts=8 et tw=99 : */
|
||||
/* 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/. */
|
||||
#include "CompositorThread.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "CompositorBridgeParent.h"
|
||||
#include "mozilla/media/MediaSystemResourceService.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace gfx {
|
||||
// See VRManagerChild.cpp
|
||||
void ReleaseVRManagerParentSingleton();
|
||||
} // namespace gfx
|
||||
|
||||
namespace layers {
|
||||
|
||||
static StaticRefPtr<CompositorThreadHolder> sCompositorThreadHolder;
|
||||
static bool sFinishedCompositorShutDown = false;
|
||||
|
||||
// See ImageBridgeChild.cpp
|
||||
void ReleaseImageBridgeParentSingleton();
|
||||
|
||||
CompositorThreadHolder* GetCompositorThreadHolder()
|
||||
{
|
||||
return sCompositorThreadHolder;
|
||||
}
|
||||
|
||||
base::Thread*
|
||||
CompositorThread()
|
||||
{
|
||||
return sCompositorThreadHolder
|
||||
? sCompositorThreadHolder->GetCompositorThread()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
/* static */ MessageLoop*
|
||||
CompositorThreadHolder::Loop()
|
||||
{
|
||||
return CompositorThread() ? CompositorThread()->message_loop() : nullptr;
|
||||
}
|
||||
|
||||
CompositorThreadHolder*
|
||||
CompositorThreadHolder::GetSingleton()
|
||||
{
|
||||
return sCompositorThreadHolder;
|
||||
}
|
||||
|
||||
CompositorThreadHolder::CompositorThreadHolder()
|
||||
: mCompositorThread(CreateCompositorThread())
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_COUNT_CTOR(CompositorThreadHolder);
|
||||
}
|
||||
|
||||
CompositorThreadHolder::~CompositorThreadHolder()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MOZ_COUNT_DTOR(CompositorThreadHolder);
|
||||
|
||||
DestroyCompositorThread(mCompositorThread);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
CompositorThreadHolder::DestroyCompositorThread(base::Thread* aCompositorThread)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MOZ_ASSERT(!sCompositorThreadHolder, "We shouldn't be destroying the compositor thread yet.");
|
||||
|
||||
CompositorBridgeParent::Shutdown();
|
||||
delete aCompositorThread;
|
||||
sFinishedCompositorShutDown = true;
|
||||
}
|
||||
|
||||
/* static */ base::Thread*
|
||||
CompositorThreadHolder::CreateCompositorThread()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MOZ_ASSERT(!sCompositorThreadHolder, "The compositor thread has already been started!");
|
||||
|
||||
base::Thread* compositorThread = new base::Thread("Compositor");
|
||||
|
||||
base::Thread::Options options;
|
||||
/* Timeout values are powers-of-two to enable us get better data.
|
||||
128ms is chosen for transient hangs because 8Hz should be the minimally
|
||||
acceptable goal for Compositor responsiveness (normal goal is 60Hz). */
|
||||
options.transient_hang_timeout = 128; // milliseconds
|
||||
/* 2048ms is chosen for permanent hangs because it's longer than most
|
||||
* Compositor hangs seen in the wild, but is short enough to not miss getting
|
||||
* native hang stacks. */
|
||||
options.permanent_hang_timeout = 2048; // milliseconds
|
||||
#if defined(_WIN32)
|
||||
/* With d3d9 the compositor thread creates native ui, see DeviceManagerD3D9. As
|
||||
* such the thread is a gui thread, and must process a windows message queue or
|
||||
* risk deadlocks. Chromium message loop TYPE_UI does exactly what we need. */
|
||||
options.message_loop_type = MessageLoop::TYPE_UI;
|
||||
#endif
|
||||
|
||||
if (!compositorThread->StartWithOptions(options)) {
|
||||
delete compositorThread;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CompositorBridgeParent::Initialize();
|
||||
|
||||
return compositorThread;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorThreadHolder::Start()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");
|
||||
MOZ_ASSERT(!sCompositorThreadHolder, "The compositor thread has already been started!");
|
||||
|
||||
sCompositorThreadHolder = new CompositorThreadHolder();
|
||||
}
|
||||
|
||||
void
|
||||
CompositorThreadHolder::Shutdown()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");
|
||||
MOZ_ASSERT(sCompositorThreadHolder, "The compositor thread has already been shut down!");
|
||||
|
||||
ReleaseImageBridgeParentSingleton();
|
||||
gfx::ReleaseVRManagerParentSingleton();
|
||||
MediaSystemResourceService::Shutdown();
|
||||
|
||||
sCompositorThreadHolder = nullptr;
|
||||
|
||||
// No locking is needed around sFinishedCompositorShutDown because it is only
|
||||
// ever accessed on the main thread.
|
||||
while (!sFinishedCompositorShutDown) {
|
||||
NS_ProcessNextEvent(nullptr, true);
|
||||
}
|
||||
|
||||
CompositorBridgeParent::FinishShutdown();
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
CompositorThreadHolder::IsInCompositorThread()
|
||||
{
|
||||
return CompositorThread() &&
|
||||
CompositorThread()->thread_id() == PlatformThread::CurrentId();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
} // namespace layers
|
68
gfx/layers/ipc/CompositorThread.h
Normal file
68
gfx/layers/ipc/CompositorThread.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 sts=2 ts=8 et tw=99 : */
|
||||
/* 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_layers_CompositorThread_h
|
||||
#define mozilla_layers_CompositorThread_h
|
||||
|
||||
#include "base/basictypes.h" // for DISALLOW_EVIL_CONSTRUCTORS
|
||||
#include "base/platform_thread.h" // for PlatformThreadId
|
||||
#include "base/thread.h" // for Thread
|
||||
#include "base/message_loop.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class CompositorThreadHolder final
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorThreadHolder)
|
||||
|
||||
public:
|
||||
CompositorThreadHolder();
|
||||
|
||||
base::Thread* GetCompositorThread() const {
|
||||
return mCompositorThread;
|
||||
}
|
||||
|
||||
static CompositorThreadHolder* GetSingleton();
|
||||
|
||||
static bool IsActive() {
|
||||
return !!GetSingleton();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the compositor thread and the global compositor map.
|
||||
*/
|
||||
static void Start();
|
||||
|
||||
/*
|
||||
* Waits for all [CrossProcess]CompositorBridgeParents to shutdown and
|
||||
* releases compositor-thread owned resources.
|
||||
*/
|
||||
static void Shutdown();
|
||||
|
||||
static MessageLoop* Loop();
|
||||
|
||||
// Returns true if the calling thread is the compositor thread.
|
||||
static bool IsInCompositorThread();
|
||||
|
||||
private:
|
||||
~CompositorThreadHolder();
|
||||
|
||||
base::Thread* const mCompositorThread;
|
||||
|
||||
static base::Thread* CreateCompositorThread();
|
||||
static void DestroyCompositorThread(base::Thread* aCompositorThread);
|
||||
|
||||
friend class CompositorBridgeParent;
|
||||
};
|
||||
|
||||
base::Thread* CompositorThread();
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_layers_CompositorThread_h
|
@ -24,7 +24,7 @@
|
||||
#include "mozilla/media/MediaSystemResourceManager.h" // for MediaSystemResourceManager
|
||||
#include "mozilla/media/MediaSystemResourceManagerChild.h" // for MediaSystemResourceManagerChild
|
||||
#include "mozilla/layers/CompositableClient.h" // for CompositableChild, etc
|
||||
#include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator
|
||||
#include "mozilla/layers/ImageClient.h" // for ImageClient
|
||||
#include "mozilla/layers/LayersMessages.h" // for CompositableOperation
|
||||
@ -844,7 +844,7 @@ bool ImageBridgeChild::StartUpOnThread(Thread* aThread)
|
||||
}
|
||||
sImageBridgeChildSingleton = new ImageBridgeChild();
|
||||
sImageBridgeParentSingleton = new ImageBridgeParent(
|
||||
CompositorBridgeParent::CompositorLoop(), nullptr, base::GetCurrentProcId());
|
||||
CompositorThreadHolder::Loop(), nullptr, base::GetCurrentProcId());
|
||||
sImageBridgeChildSingleton->ConnectAsync(sImageBridgeParentSingleton);
|
||||
sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
|
||||
NewRunnableFunction(CallSendImageBridgeThreadId,
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "mozilla/media/MediaSystemResourceManagerParent.h" // for MediaSystemResourceManagerParent
|
||||
#include "mozilla/layers/CompositableTransactionParent.h"
|
||||
#include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/LayerManagerComposite.h"
|
||||
#include "mozilla/layers/LayersMessages.h" // for EditReply
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for PGrallocBufferParent
|
||||
@ -200,7 +201,7 @@ ConnectImageBridgeInParentProcess(ImageBridgeParent* aBridge,
|
||||
/*static*/ PImageBridgeParent*
|
||||
ImageBridgeParent::Create(Transport* aTransport, ProcessId aChildProcessId, GeckoChildProcessHost* aProcessHost)
|
||||
{
|
||||
MessageLoop* loop = CompositorBridgeParent::CompositorLoop();
|
||||
MessageLoop* loop = CompositorThreadHolder::Loop();
|
||||
RefPtr<ImageBridgeParent> bridge = new ImageBridgeParent(loop, aTransport, aChildProcessId);
|
||||
|
||||
if (aProcessHost) {
|
||||
|
@ -158,6 +158,7 @@ EXPORTS.mozilla.layers += [
|
||||
'ipc/CompositorBridgeChild.h',
|
||||
'ipc/CompositorBridgeParent.h',
|
||||
'ipc/CompositorLRU.h',
|
||||
'ipc/CompositorThread.h',
|
||||
'ipc/FenceUtils.h',
|
||||
'ipc/GonkNativeHandle.h',
|
||||
'ipc/GonkNativeHandleUtils.h',
|
||||
@ -343,6 +344,7 @@ UNIFIED_SOURCES += [
|
||||
'ipc/CompositorBridgeChild.cpp',
|
||||
'ipc/CompositorBridgeParent.cpp',
|
||||
'ipc/CompositorLRU.cpp',
|
||||
'ipc/CompositorThread.cpp',
|
||||
'ipc/FenceUtils.cpp',
|
||||
'ipc/ImageBridgeChild.cpp',
|
||||
'ipc/ImageBridgeParent.cpp',
|
||||
|
@ -1247,23 +1247,12 @@ CompositorOGL::DrawQuad(const Rect& aRect,
|
||||
didSetBlendMode = SetBlendMode(gl(), blendMode, texturedEffect->mPremultiplied);
|
||||
|
||||
gfx::Filter filter = texturedEffect->mFilter;
|
||||
Matrix4x4 textureTransform = source->AsSourceOGL()->GetTextureTransform();
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
gfx::Matrix textureTransform2D;
|
||||
if (filter != gfx::Filter::POINT &&
|
||||
aTransform.Is2DIntegerTranslation() &&
|
||||
textureTransform.Is2D(&textureTransform2D) &&
|
||||
textureTransform2D.HasOnlyIntegerTranslation()) {
|
||||
// On Android we encounter small resampling errors in what should be
|
||||
// pixel-aligned compositing operations. This works around them. This
|
||||
// code should not be needed!
|
||||
filter = gfx::Filter::POINT;
|
||||
}
|
||||
#endif
|
||||
source->AsSourceOGL()->BindTexture(LOCAL_GL_TEXTURE0, filter);
|
||||
|
||||
program->SetTextureUnit(0);
|
||||
|
||||
Matrix4x4 textureTransform = source->AsSourceOGL()->GetTextureTransform();
|
||||
program->SetTextureTransform(textureTransform);
|
||||
|
||||
if (maskType != MaskType::MaskNone) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
|
||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/ImageBridgeChild.h"
|
||||
#include "mozilla/layers/SharedBufferManagerChild.h"
|
||||
#include "mozilla/layers/ISurfaceAllocator.h" // for GfxMemoryImageReporter
|
||||
@ -868,7 +868,7 @@ gfxPlatform::InitLayersIPC()
|
||||
|
||||
if (XRE_IsParentProcess())
|
||||
{
|
||||
mozilla::layers::CompositorBridgeParent::StartUp();
|
||||
layers::CompositorThreadHolder::Start();
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
SharedBufferManagerChild::StartUp();
|
||||
#endif
|
||||
@ -905,7 +905,7 @@ gfxPlatform::ShutdownLayersIPC()
|
||||
#endif
|
||||
|
||||
// This has to happen after shutting down the child protocols.
|
||||
layers::CompositorBridgeParent::ShutDown();
|
||||
layers::CompositorThreadHolder::Shutdown();
|
||||
} else {
|
||||
// TODO: There are other kind of processes and we should make sure gfx
|
||||
// stuff is either not created there or shut down properly.
|
||||
|
@ -136,7 +136,8 @@ enum class DeviceResetReason
|
||||
|
||||
enum class ForcedDeviceResetReason
|
||||
{
|
||||
OPENSHAREDHANDLE = 0
|
||||
OPENSHAREDHANDLE = 0,
|
||||
COMPOSITOR_UPDATED,
|
||||
};
|
||||
|
||||
class gfxPlatform {
|
||||
@ -633,6 +634,8 @@ public:
|
||||
return mCompositorBackend;
|
||||
}
|
||||
|
||||
virtual void CompositorUpdated() {}
|
||||
|
||||
// Return information on how child processes should initialize graphics
|
||||
// devices. Currently this is only used on Windows.
|
||||
virtual void GetDeviceInitData(mozilla::gfx::DeviceInitData* aOut);
|
||||
|
@ -1331,18 +1331,20 @@ gfxUserFontSet::UserFontCache::Entry::ReportMemory(nsIMemoryReporterCallback* aC
|
||||
if (mPrincipal) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
mPrincipal->GetURI(getter_AddRefs(uri));
|
||||
if (uri) {
|
||||
nsCString spec;
|
||||
uri->GetSpec(spec);
|
||||
if (!spec.IsEmpty()) {
|
||||
// Include a clue as to who loaded this resource. (Note that
|
||||
// because of font entry sharing, other pages may now be using
|
||||
// this resource, and the original page may not even be loaded
|
||||
// any longer.)
|
||||
// Include a clue as to who loaded this resource. (Note
|
||||
// that because of font entry sharing, other pages may now
|
||||
// be using this resource, and the original page may not
|
||||
// even be loaded any longer.)
|
||||
spec.ReplaceChar('/', '\\');
|
||||
path.AppendPrintf(", principal=%s", spec.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
path.Append(')');
|
||||
|
||||
return aCb->
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "gfxGDIFontList.h"
|
||||
#include "gfxGDIFont.h"
|
||||
|
||||
#include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent::IsInCompositorThread
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "DeviceManagerD3D9.h"
|
||||
#include "mozilla/layers/ReadbackManagerD3D11.h"
|
||||
|
||||
@ -67,10 +67,10 @@
|
||||
#include <winternl.h>
|
||||
#include "d3dkmtQueryStatistics.h"
|
||||
|
||||
#include "base/thread.h"
|
||||
#include "SurfaceCache.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "gfxConfig.h"
|
||||
|
||||
#include "VsyncSource.h"
|
||||
#include "DriverCrashGuard.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
@ -947,6 +947,13 @@ static DeviceResetReason HResultToResetReason(HRESULT hr)
|
||||
return DeviceResetReason::UNKNOWN;
|
||||
}
|
||||
|
||||
void
|
||||
gfxWindowsPlatform::CompositorUpdated()
|
||||
{
|
||||
ForceDeviceReset(ForcedDeviceResetReason::COMPOSITOR_UPDATED);
|
||||
UpdateRenderMode();
|
||||
}
|
||||
|
||||
bool
|
||||
gfxWindowsPlatform::IsDeviceReset(HRESULT hr, DeviceResetReason* aResetReason)
|
||||
{
|
||||
@ -1410,7 +1417,7 @@ gfxWindowsPlatform::GetD3D9DeviceManager()
|
||||
RefPtr<DeviceManagerD3D9> result;
|
||||
if (!mDeviceManager &&
|
||||
(!gfxPlatform::UsesOffMainThreadCompositing() ||
|
||||
CompositorBridgeParent::IsInCompositorThread())) {
|
||||
CompositorThreadHolder::IsInCompositorThread())) {
|
||||
mDeviceManager = new DeviceManagerD3D9();
|
||||
if (!mDeviceManager->Init()) {
|
||||
gfxCriticalError() << "[D3D9] Could not Initialize the DeviceManagerD3D9";
|
||||
|
@ -178,6 +178,8 @@ public:
|
||||
*/
|
||||
virtual bool IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags) override;
|
||||
|
||||
virtual void CompositorUpdated() override;
|
||||
|
||||
bool DidRenderingDeviceReset(DeviceResetReason* aResetReason = nullptr) override;
|
||||
void SchedulePaintIfDeviceReset() override;
|
||||
void UpdateRenderModeIfDeviceReset() override;
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "VRDeviceProxy.h"
|
||||
#include "VRDeviceProxyOrientationFallBack.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent
|
||||
#include "mozilla/layers/CompositorThread.h" // for CompositorThread
|
||||
#include "mozilla/dom/Navigator.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -77,7 +77,7 @@ VRManagerChild::StartUpSameProcess()
|
||||
sVRManagerChildSingleton = new VRManagerChild();
|
||||
sVRManagerParentSingleton = VRManagerParent::CreateSameProcess();
|
||||
sVRManagerChildSingleton->Open(sVRManagerParentSingleton->GetIPCChannel(),
|
||||
mozilla::layers::CompositorBridgeParent::CompositorLoop(),
|
||||
mozilla::layers::CompositorThreadHolder::Loop(),
|
||||
mozilla::ipc::ChildSide);
|
||||
}
|
||||
}
|
||||
|
@ -10,18 +10,11 @@
|
||||
#include "mozilla/ipc/ProtocolTypes.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h" // for IToplevelProtocol
|
||||
#include "mozilla/TimeStamp.h" // for TimeStamp
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "VRManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
// defined in CompositorBridgeParent.cpp
|
||||
CompositorThreadHolder* GetCompositorThreadHolder();
|
||||
|
||||
} // namespace layers
|
||||
|
||||
namespace gfx {
|
||||
|
||||
VRManagerParent::VRManagerParent(MessageLoop* aLoop,
|
||||
@ -76,7 +69,7 @@ VRManagerParent::ConnectVRManagerInParentProcess(VRManagerParent* aVRManager,
|
||||
/*static*/ VRManagerParent*
|
||||
VRManagerParent::CreateCrossProcess(Transport* aTransport, ProcessId aChildProcessId)
|
||||
{
|
||||
MessageLoop* loop = mozilla::layers::CompositorBridgeParent::CompositorLoop();
|
||||
MessageLoop* loop = mozilla::layers::CompositorThreadHolder::Loop();
|
||||
RefPtr<VRManagerParent> vmp = new VRManagerParent(loop, aTransport, aChildProcessId);
|
||||
vmp->mSelfRef = vmp;
|
||||
loop->PostTask(NewRunnableFunction(ConnectVRManagerInParentProcess,
|
||||
@ -93,9 +86,9 @@ VRManagerParent::RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager
|
||||
/*static*/ VRManagerParent*
|
||||
VRManagerParent::CreateSameProcess()
|
||||
{
|
||||
MessageLoop* loop = mozilla::layers::CompositorBridgeParent::CompositorLoop();
|
||||
MessageLoop* loop = mozilla::layers::CompositorThreadHolder::Loop();
|
||||
RefPtr<VRManagerParent> vmp = new VRManagerParent(loop, nullptr, base::GetCurrentProcId());
|
||||
vmp->mCompositorThreadHolder = layers::GetCompositorThreadHolder();
|
||||
vmp->mCompositorThreadHolder = layers::CompositorThreadHolder::GetSingleton();
|
||||
vmp->mSelfRef = vmp;
|
||||
loop->PostTask(NewRunnableFunction(RegisterVRManagerInCompositorThread, vmp.get()));
|
||||
return vmp.get();
|
||||
@ -139,7 +132,7 @@ VRManagerParent::CloneToplevel(const InfallibleTArray<mozilla::ipc::ProtocolFdMa
|
||||
void
|
||||
VRManagerParent::OnChannelConnected(int32_t aPid)
|
||||
{
|
||||
mCompositorThreadHolder = layers::GetCompositorThreadHolder();
|
||||
mCompositorThreadHolder = layers::CompositorThreadHolder::GetSingleton();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef MOZILLA_GFX_VR_VRMANAGERPARENT_H
|
||||
#define MOZILLA_GFX_VR_VRMANAGERPARENT_H
|
||||
|
||||
#include "mozilla/layers/CompositorBridgeParent.h" // for CompositorThreadHolder
|
||||
#include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
|
||||
#include "mozilla/gfx/PVRManagerParent.h" // for PVRManagerParent
|
||||
#include "mozilla/ipc/ProtocolUtils.h" // for IToplevelProtocol
|
||||
#include "mozilla/TimeStamp.h" // for TimeStamp
|
||||
|
@ -586,7 +586,8 @@ class JS_PUBLIC_API(AutoCheckCannotGC) : public AutoAssertOnGC
|
||||
|
||||
/**
|
||||
* Unsets the gray bit for anything reachable from |thing|. |kind| should not be
|
||||
* JS::TraceKind::Shape. |thing| should be non-null.
|
||||
* JS::TraceKind::Shape. |thing| should be non-null. The return value indicates
|
||||
* if anything was unmarked.
|
||||
*/
|
||||
extern JS_FRIEND_API(bool)
|
||||
UnmarkGrayGCThingRecursively(GCCellPtr thing);
|
||||
|
@ -71,16 +71,34 @@ class JS_PUBLIC_API(JSTracer)
|
||||
bool isTenuringTracer() const { return tag_ == TracerKindTag::Tenuring; }
|
||||
bool isCallbackTracer() const { return tag_ == TracerKindTag::Callback; }
|
||||
inline JS::CallbackTracer* asCallbackTracer();
|
||||
#ifdef DEBUG
|
||||
bool checkEdges() { return checkEdges_; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
JSTracer(JSRuntime* rt, TracerKindTag tag,
|
||||
WeakMapTraceKind weakTraceKind = TraceWeakMapValues)
|
||||
: runtime_(rt), weakMapAction_(weakTraceKind), tag_(tag)
|
||||
: runtime_(rt)
|
||||
, weakMapAction_(weakTraceKind)
|
||||
#ifdef DEBUG
|
||||
, checkEdges_(true)
|
||||
#endif
|
||||
, tag_(tag)
|
||||
{}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Set whether to check edges are valid in debug builds.
|
||||
void setCheckEdges(bool check) {
|
||||
checkEdges_ = check;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
JSRuntime* runtime_;
|
||||
WeakMapTraceKind weakMapAction_;
|
||||
#ifdef DEBUG
|
||||
bool checkEdges_;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
TracerKindTag tag_;
|
||||
|
@ -85,7 +85,12 @@ class MOZ_RAII AutoStopVerifyingBarriers
|
||||
AutoStopVerifyingBarriers(JSRuntime* rt, bool isShutdown)
|
||||
: gc(&rt->gc)
|
||||
{
|
||||
restartPreVerifier = gc->endVerifyPreBarriers() && !isShutdown;
|
||||
if (gc->isVerifyPreBarriersEnabled()) {
|
||||
gc->endVerifyPreBarriers();
|
||||
restartPreVerifier = !isShutdown;
|
||||
} else {
|
||||
restartPreVerifier = false;
|
||||
}
|
||||
}
|
||||
|
||||
~AutoStopVerifyingBarriers() {
|
||||
@ -115,8 +120,8 @@ struct MOZ_RAII AutoStopVerifyingBarriers
|
||||
#endif /* JS_GC_ZEAL */
|
||||
|
||||
#ifdef JSGC_HASH_TABLE_CHECKS
|
||||
void
|
||||
CheckHashTablesAfterMovingGC(JSRuntime* rt);
|
||||
void CheckHashTablesAfterMovingGC(JSRuntime* rt);
|
||||
void CheckHeapAfterMovingGC(JSRuntime* rt);
|
||||
#endif
|
||||
|
||||
struct MovingTracer : JS::CallbackTracer
|
||||
|
@ -194,7 +194,7 @@ class GCSchedulingTunables
|
||||
unsigned minEmptyChunkCount(const AutoLockGC&) const { return minEmptyChunkCount_; }
|
||||
unsigned maxEmptyChunkCount() const { return maxEmptyChunkCount_; }
|
||||
|
||||
bool setParameter(JSGCParamKey key, uint32_t value, const AutoLockGC& lock);
|
||||
MOZ_MUST_USE bool setParameter(JSGCParamKey key, uint32_t value, const AutoLockGC& lock);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -584,7 +584,7 @@ class GCRuntime
|
||||
{
|
||||
public:
|
||||
explicit GCRuntime(JSRuntime* rt);
|
||||
bool init(uint32_t maxbytes, uint32_t maxNurseryBytes);
|
||||
MOZ_MUST_USE bool init(uint32_t maxbytes, uint32_t maxNurseryBytes);
|
||||
void finishRoots();
|
||||
void finish();
|
||||
|
||||
@ -593,17 +593,18 @@ class GCRuntime
|
||||
inline bool upcomingZealousGC();
|
||||
inline bool needZealousGC();
|
||||
|
||||
bool addRoot(Value* vp, const char* name);
|
||||
MOZ_MUST_USE bool addRoot(Value* vp, const char* name);
|
||||
void removeRoot(Value* vp);
|
||||
void setMarkStackLimit(size_t limit, AutoLockGC& lock);
|
||||
|
||||
bool setParameter(JSGCParamKey key, uint32_t value, AutoLockGC& lock);
|
||||
MOZ_MUST_USE bool setParameter(JSGCParamKey key, uint32_t value, AutoLockGC& lock);
|
||||
uint32_t getParameter(JSGCParamKey key, const AutoLockGC& lock);
|
||||
|
||||
bool triggerGC(JS::gcreason::Reason reason);
|
||||
MOZ_MUST_USE bool triggerGC(JS::gcreason::Reason reason);
|
||||
void maybeAllocTriggerZoneGC(Zone* zone, const AutoLockGC& lock);
|
||||
// The return value indicates if we were able to do the GC.
|
||||
bool triggerZoneGC(Zone* zone, JS::gcreason::Reason reason);
|
||||
bool maybeGC(Zone* zone);
|
||||
MOZ_MUST_USE bool maybeGC(Zone* zone);
|
||||
void maybePeriodicFullGC();
|
||||
void minorGC(JS::gcreason::Reason reason) {
|
||||
gcstats::AutoPhase ap(stats, gcstats::PHASE_MINOR_GC);
|
||||
@ -614,6 +615,7 @@ class GCRuntime
|
||||
gcstats::AutoPhase ap(stats, gcstats::PHASE_EVICT_NURSERY);
|
||||
minorGCImpl(reason, nullptr);
|
||||
}
|
||||
// The return value indicates whether a major GC was performed.
|
||||
bool gcIfRequested(JSContext* cx = nullptr);
|
||||
void gc(JSGCInvocationKind gckind, JS::gcreason::Reason reason);
|
||||
void startGC(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis = 0);
|
||||
@ -626,7 +628,7 @@ class GCRuntime
|
||||
void triggerFullGCForAtoms() {
|
||||
MOZ_ASSERT(fullGCForAtomsRequested_);
|
||||
fullGCForAtomsRequested_ = false;
|
||||
triggerGC(JS::gcreason::ALLOC_TRIGGER);
|
||||
MOZ_RELEASE_ASSERT(triggerGC(JS::gcreason::ALLOC_TRIGGER));
|
||||
}
|
||||
|
||||
void runDebugGC();
|
||||
@ -755,7 +757,7 @@ class GCRuntime
|
||||
bool isCompactingGCEnabled() const;
|
||||
|
||||
void setGrayRootsTracer(JSTraceDataOp traceOp, void* data);
|
||||
bool addBlackRootsTracer(JSTraceDataOp traceOp, void* data);
|
||||
MOZ_MUST_USE bool addBlackRootsTracer(JSTraceDataOp traceOp, void* data);
|
||||
void removeBlackRootsTracer(JSTraceDataOp traceOp, void* data);
|
||||
|
||||
void setMaxMallocBytes(size_t value);
|
||||
@ -770,11 +772,13 @@ class GCRuntime
|
||||
void setObjectsTenuredCallback(JSObjectsTenuredCallback callback,
|
||||
void* data);
|
||||
void callObjectsTenuredCallback();
|
||||
bool addFinalizeCallback(JSFinalizeCallback callback, void* data);
|
||||
MOZ_MUST_USE bool addFinalizeCallback(JSFinalizeCallback callback, void* data);
|
||||
void removeFinalizeCallback(JSFinalizeCallback func);
|
||||
bool addWeakPointerZoneGroupCallback(JSWeakPointerZoneGroupCallback callback, void* data);
|
||||
MOZ_MUST_USE bool addWeakPointerZoneGroupCallback(JSWeakPointerZoneGroupCallback callback,
|
||||
void* data);
|
||||
void removeWeakPointerZoneGroupCallback(JSWeakPointerZoneGroupCallback callback);
|
||||
bool addWeakPointerCompartmentCallback(JSWeakPointerCompartmentCallback callback, void* data);
|
||||
MOZ_MUST_USE bool addWeakPointerCompartmentCallback(JSWeakPointerCompartmentCallback callback,
|
||||
void* data);
|
||||
void removeWeakPointerCompartmentCallback(JSWeakPointerCompartmentCallback callback);
|
||||
JS::GCSliceCallback setSliceCallback(JS::GCSliceCallback callback);
|
||||
JS::GCNurseryCollectionCallback setNurseryCollectionCallback(
|
||||
@ -841,7 +845,7 @@ class GCRuntime
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
void startVerifyPreBarriers();
|
||||
bool endVerifyPreBarriers();
|
||||
void endVerifyPreBarriers();
|
||||
void finishVerifier();
|
||||
bool isVerifyPreBarriersEnabled() const { return !!verifyPreData; }
|
||||
#else
|
||||
@ -860,7 +864,7 @@ class GCRuntime
|
||||
|
||||
// Allocator
|
||||
template <AllowGC allowGC>
|
||||
bool checkAllocatorState(JSContext* cx, AllocKind kind);
|
||||
MOZ_MUST_USE bool checkAllocatorState(JSContext* cx, AllocKind kind);
|
||||
template <AllowGC allowGC>
|
||||
JSObject* tryNewNurseryObject(JSContext* cx, size_t thingSize, size_t nDynamicSlots,
|
||||
const Class* clasp);
|
||||
@ -888,7 +892,7 @@ class GCRuntime
|
||||
void arenaAllocatedDuringGC(JS::Zone* zone, Arena* arena);
|
||||
|
||||
// Allocator internals
|
||||
bool gcIfNeededPerAllocation(JSContext* cx);
|
||||
MOZ_MUST_USE bool gcIfNeededPerAllocation(JSContext* cx);
|
||||
template <typename T>
|
||||
static void checkIncrementalZoneState(ExclusiveContext* cx, T* t);
|
||||
static void* refillFreeListFromAnyThread(ExclusiveContext* cx, AllocKind thingKind,
|
||||
@ -921,16 +925,17 @@ class GCRuntime
|
||||
|
||||
// Check if the system state is such that GC has been supressed
|
||||
// or otherwise delayed.
|
||||
bool checkIfGCAllowedInCurrentState(JS::gcreason::Reason reason);
|
||||
MOZ_MUST_USE bool checkIfGCAllowedInCurrentState(JS::gcreason::Reason reason);
|
||||
|
||||
gcstats::ZoneGCStats scanZonesBeforeGC();
|
||||
void collect(bool nonincrementalByAPI, SliceBudget budget, JS::gcreason::Reason reason) JS_HAZ_GC_CALL;
|
||||
bool gcCycle(bool nonincrementalByAPI, SliceBudget& budget, JS::gcreason::Reason reason);
|
||||
MOZ_MUST_USE bool gcCycle(bool nonincrementalByAPI, SliceBudget& budget,
|
||||
JS::gcreason::Reason reason);
|
||||
void incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason reason);
|
||||
|
||||
void pushZealSelectedObjects();
|
||||
void purgeRuntime();
|
||||
bool beginMarkPhase(JS::gcreason::Reason reason);
|
||||
MOZ_MUST_USE bool beginMarkPhase(JS::gcreason::Reason reason);
|
||||
bool shouldPreserveJITCode(JSCompartment* comp, int64_t currentTime,
|
||||
JS::gcreason::Reason reason);
|
||||
void bufferGrayRoots();
|
||||
@ -946,7 +951,7 @@ class GCRuntime
|
||||
|
||||
void beginSweepPhase(bool lastGC);
|
||||
void findZoneGroups();
|
||||
bool findZoneEdgesForWeakMaps();
|
||||
MOZ_MUST_USE bool findZoneEdgesForWeakMaps();
|
||||
void getNextZoneGroup();
|
||||
void endMarkingZoneGroup();
|
||||
void beginSweepingZoneGroup();
|
||||
@ -967,8 +972,8 @@ class GCRuntime
|
||||
void endCompactPhase(JS::gcreason::Reason reason);
|
||||
void sweepTypesAfterCompacting(Zone* zone);
|
||||
void sweepZoneAfterCompacting(Zone* zone);
|
||||
bool relocateArenas(Zone* zone, JS::gcreason::Reason reason, Arena*& relocatedListOut,
|
||||
SliceBudget& sliceBudget);
|
||||
MOZ_MUST_USE bool relocateArenas(Zone* zone, JS::gcreason::Reason reason,
|
||||
Arena*& relocatedListOut, SliceBudget& sliceBudget);
|
||||
void updateTypeDescrObjects(MovingTracer* trc, Zone* zone);
|
||||
void updateCellPointers(MovingTracer* trc, Zone* zone, AllocKinds kinds, size_t bgTaskCount);
|
||||
void updateAllCellPointers(MovingTracer* trc, Zone* zone);
|
||||
@ -1047,6 +1052,8 @@ class GCRuntime
|
||||
*/
|
||||
mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire> numArenasFreeCommitted;
|
||||
VerifyPreTracer* verifyPreData;
|
||||
|
||||
private:
|
||||
bool chunkAllocationSinceLastGC;
|
||||
int64_t nextFullGCTime;
|
||||
int64_t lastGCTime;
|
||||
|
@ -17,7 +17,7 @@ namespace gc {
|
||||
|
||||
#ifdef JS_GC_TRACE
|
||||
|
||||
extern bool InitTrace(GCRuntime& gc);
|
||||
extern MOZ_MUST_USE bool InitTrace(GCRuntime& gc);
|
||||
extern void FinishTrace();
|
||||
extern bool TraceEnabled();
|
||||
extern void TraceNurseryAlloc(Cell* thing, size_t size);
|
||||
@ -33,7 +33,7 @@ extern void TraceTypeNewScript(js::ObjectGroup* group);
|
||||
|
||||
#else
|
||||
|
||||
inline bool InitTrace(GCRuntime& gc) { return true; }
|
||||
inline MOZ_MUST_USE bool InitTrace(GCRuntime& gc) { return true; }
|
||||
inline void FinishTrace() {}
|
||||
inline bool TraceEnabled() { return false; }
|
||||
inline void TraceNurseryAlloc(Cell* thing, size_t size) {}
|
||||
|
@ -53,6 +53,7 @@ extern bool
|
||||
CurrentThreadIsIonCompiling();
|
||||
#endif
|
||||
|
||||
// The return value indicates if anything was unmarked.
|
||||
extern bool
|
||||
UnmarkGrayCellRecursively(gc::Cell* cell, JS::TraceKind kind);
|
||||
|
||||
@ -295,6 +296,7 @@ class TenuredCell : public Cell
|
||||
|
||||
// Mark bit management.
|
||||
MOZ_ALWAYS_INLINE bool isMarked(uint32_t color = BLACK) const;
|
||||
// The return value indicates if the cell went from unmarked to marked.
|
||||
MOZ_ALWAYS_INLINE bool markIfUnmarked(uint32_t color = BLACK) const;
|
||||
MOZ_ALWAYS_INLINE void unmark(uint32_t color) const;
|
||||
MOZ_ALWAYS_INLINE void copyMarkBitsFrom(const TenuredCell* src);
|
||||
@ -877,6 +879,7 @@ struct ChunkBitmap
|
||||
return *word & mask;
|
||||
}
|
||||
|
||||
// The return value indicates if the cell went from unmarked to marked.
|
||||
MOZ_ALWAYS_INLINE bool markIfUnmarked(const Cell* cell, uint32_t color) {
|
||||
uintptr_t* word, mask;
|
||||
getMarkWordAndMask(cell, BLACK, &word, &mask);
|
||||
@ -995,7 +998,7 @@ struct Chunk
|
||||
void releaseArena(JSRuntime* rt, Arena* arena, const AutoLockGC& lock);
|
||||
void recycleArena(Arena* arena, SortedArenaList& dest, size_t thingsPerArena);
|
||||
|
||||
bool decommitOneFreeArena(JSRuntime* rt, AutoLockGC& lock);
|
||||
MOZ_MUST_USE bool decommitOneFreeArena(JSRuntime* rt, AutoLockGC& lock);
|
||||
void decommitAllArenasWithoutUnlocking(const AutoLockGC& lock);
|
||||
|
||||
static Chunk* allocate(JSRuntime* rt);
|
||||
|
@ -181,6 +181,9 @@ js::CheckTracedThing(JSTracer* trc, T* thing)
|
||||
MOZ_ASSERT(trc);
|
||||
MOZ_ASSERT(thing);
|
||||
|
||||
if (!trc->checkEdges())
|
||||
return;
|
||||
|
||||
thing = MaybeForwarded(thing);
|
||||
|
||||
/* This function uses data that's not available in the nursery. */
|
||||
|
@ -87,13 +87,13 @@ class MarkStack
|
||||
end_ = stack + capacity;
|
||||
}
|
||||
|
||||
bool init(JSGCMode gcMode);
|
||||
MOZ_MUST_USE bool init(JSGCMode gcMode);
|
||||
|
||||
void setBaseCapacity(JSGCMode mode);
|
||||
size_t maxCapacity() const { return maxCapacity_; }
|
||||
void setMaxCapacity(size_t maxCapacity);
|
||||
|
||||
bool push(uintptr_t item) {
|
||||
MOZ_MUST_USE bool push(uintptr_t item) {
|
||||
if (tos_ == end_) {
|
||||
if (!enlarge(1))
|
||||
return false;
|
||||
@ -103,7 +103,7 @@ class MarkStack
|
||||
return true;
|
||||
}
|
||||
|
||||
bool push(uintptr_t item1, uintptr_t item2, uintptr_t item3) {
|
||||
MOZ_MUST_USE bool push(uintptr_t item1, uintptr_t item2, uintptr_t item3) {
|
||||
uintptr_t* nextTos = tos_ + 3;
|
||||
if (nextTos > end_) {
|
||||
if (!enlarge(3))
|
||||
@ -130,7 +130,7 @@ class MarkStack
|
||||
void reset();
|
||||
|
||||
/* Grow the stack, ensuring there is space for at least count elements. */
|
||||
bool enlarge(unsigned count);
|
||||
MOZ_MUST_USE bool enlarge(unsigned count);
|
||||
|
||||
void setGCMode(JSGCMode gcMode);
|
||||
|
||||
@ -168,7 +168,7 @@ class GCMarker : public JSTracer
|
||||
{
|
||||
public:
|
||||
explicit GCMarker(JSRuntime* rt);
|
||||
bool init(JSGCMode gcMode);
|
||||
MOZ_MUST_USE bool init(JSGCMode gcMode);
|
||||
|
||||
void setMaxCapacity(size_t maxCap) { stack.setMaxCapacity(maxCap); }
|
||||
size_t maxCapacity() const { return stack.maxCapacity(); }
|
||||
@ -216,7 +216,7 @@ class GCMarker : public JSTracer
|
||||
void delayMarkingArena(gc::Arena* arena);
|
||||
void delayMarkingChildren(const void* thing);
|
||||
void markDelayedChildren(gc::Arena* arena);
|
||||
bool markDelayedChildren(SliceBudget& budget);
|
||||
MOZ_MUST_USE bool markDelayedChildren(SliceBudget& budget);
|
||||
bool hasDelayedChildren() const {
|
||||
return !!unmarkedArenaStackTop;
|
||||
}
|
||||
@ -225,7 +225,7 @@ class GCMarker : public JSTracer
|
||||
return isMarkStackEmpty() && !unmarkedArenaStackTop;
|
||||
}
|
||||
|
||||
bool drainMarkStack(SliceBudget& budget);
|
||||
MOZ_MUST_USE bool drainMarkStack(SliceBudget& budget);
|
||||
|
||||
void setGCMode(JSGCMode mode) { stack.setGCMode(mode); }
|
||||
|
||||
@ -289,7 +289,7 @@ class GCMarker : public JSTracer
|
||||
// Mark the given GC thing, but do not trace its children. Return true
|
||||
// if the thing became marked.
|
||||
template <typename T>
|
||||
bool mark(T* thing);
|
||||
MOZ_MUST_USE bool mark(T* thing);
|
||||
|
||||
void pushTaggedPtr(StackTag tag, void* ptr) {
|
||||
checkZone(ptr);
|
||||
@ -319,7 +319,7 @@ class GCMarker : public JSTracer
|
||||
return stack.isEmpty();
|
||||
}
|
||||
|
||||
bool restoreValueArray(JSObject* obj, void** vpp, void** endp);
|
||||
MOZ_MUST_USE bool restoreValueArray(JSObject* obj, void** vpp, void** endp);
|
||||
void saveValueRanges();
|
||||
inline void processMarkStackTop(SliceBudget& budget);
|
||||
|
||||
@ -451,6 +451,7 @@ struct RewrapTaggedPointer<Value, T>
|
||||
|
||||
} /* namespace gc */
|
||||
|
||||
// The return value indicates if anything was unmarked.
|
||||
bool
|
||||
UnmarkGrayShapeRecursively(Shape* shape);
|
||||
|
||||
|
@ -262,14 +262,13 @@ MarkPagesUnused(void* p, size_t size)
|
||||
return p2 == p;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
MarkPagesInUse(void* p, size_t size)
|
||||
{
|
||||
if (!DecommitEnabled())
|
||||
return true;
|
||||
return;
|
||||
|
||||
MOZ_ASSERT(OffsetFromAligned(p, pageSize) == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t
|
||||
@ -320,7 +319,6 @@ bool
|
||||
MarkPagesInUse(void* p, size_t size)
|
||||
{
|
||||
MOZ_ASSERT(OffsetFromAligned(p, pageSize) == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t
|
||||
@ -399,10 +397,9 @@ bool
|
||||
MarkPagesInUse(void* p, size_t size)
|
||||
{
|
||||
if (!DecommitEnabled())
|
||||
return true;
|
||||
return;
|
||||
|
||||
MOZ_ASSERT(OffsetFromAligned(p, pageSize) == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t
|
||||
@ -667,14 +664,13 @@ MarkPagesUnused(void* p, size_t size)
|
||||
return result != -1;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
MarkPagesInUse(void* p, size_t size)
|
||||
{
|
||||
if (!DecommitEnabled())
|
||||
return true;
|
||||
return;
|
||||
|
||||
MOZ_ASSERT(OffsetFromAligned(p, pageSize) == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -29,7 +29,7 @@ bool MarkPagesUnused(void* p, size_t size);
|
||||
// Undo |MarkPagesUnused|: tell the OS that the given pages are of interest
|
||||
// and should be paged in and out normally. This may be a no-op on some
|
||||
// platforms.
|
||||
bool MarkPagesInUse(void* p, size_t size);
|
||||
void MarkPagesInUse(void* p, size_t size);
|
||||
|
||||
// Returns #(hard faults) + #(soft faults)
|
||||
size_t GetPageFaultCount();
|
||||
|
@ -502,6 +502,13 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList
|
||||
#endif
|
||||
TIME_END(checkHashTables);
|
||||
|
||||
TIME_START(checkHeap);
|
||||
#ifdef JS_GC_ZEAL
|
||||
if (rt->hasZealMode(ZealMode::CheckHeapOnMovingGC))
|
||||
CheckHeapAfterMovingGC(rt);
|
||||
#endif
|
||||
TIME_END(checkHeap);
|
||||
|
||||
// Resize the nursery.
|
||||
TIME_START(resize);
|
||||
double promotionRate = mover.tenuredSize / double(allocationEnd() - start());
|
||||
@ -552,6 +559,7 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList
|
||||
{"mcWCll", TIME_TOTAL(traceWholeCells)},
|
||||
{"mkGnrc", TIME_TOTAL(traceGenericEntries)},
|
||||
{"ckTbls", TIME_TOTAL(checkHashTables)},
|
||||
{"ckHeap", TIME_TOTAL(checkHeap)},
|
||||
{"mkRntm", TIME_TOTAL(markRuntime)},
|
||||
{"mkDbgr", TIME_TOTAL(markDebugger)},
|
||||
{"clrNOC", TIME_TOTAL(clearNewObjectCache)},
|
||||
|
@ -110,7 +110,7 @@ class Nursery
|
||||
{}
|
||||
~Nursery();
|
||||
|
||||
bool init(uint32_t maxNurseryBytes);
|
||||
MOZ_MUST_USE bool init(uint32_t maxNurseryBytes);
|
||||
|
||||
bool exists() const { return numNurseryChunks_ != 0; }
|
||||
size_t numChunks() const { return numNurseryChunks_; }
|
||||
@ -171,7 +171,7 @@ class Nursery
|
||||
* sets |*ref| to the new location of the object and returns true. Otherwise
|
||||
* returns false and leaves |*ref| unset.
|
||||
*/
|
||||
MOZ_ALWAYS_INLINE bool getForwardedPointer(JSObject** ref) const;
|
||||
MOZ_ALWAYS_INLINE MOZ_MUST_USE bool getForwardedPointer(JSObject** ref) const;
|
||||
|
||||
/* Forward a slots/elements pointer stored in an Ion frame. */
|
||||
void forwardBufferPointer(HeapSlot** pSlotsElems);
|
||||
@ -188,7 +188,7 @@ class Nursery
|
||||
|
||||
void waitBackgroundFreeEnd();
|
||||
|
||||
bool addedUniqueIdToCell(gc::Cell* cell) {
|
||||
MOZ_MUST_USE bool addedUniqueIdToCell(gc::Cell* cell) {
|
||||
if (!IsInsideNursery(cell) || !isEnabled())
|
||||
return true;
|
||||
MOZ_ASSERT(cellsWithUid_.initialized());
|
||||
|
@ -160,7 +160,7 @@ struct Statistics
|
||||
/* Create a convenient type for referring to tables of phase times. */
|
||||
using PhaseTimeTable = int64_t[NumTimingArrays][PHASE_LIMIT];
|
||||
|
||||
static bool initialize();
|
||||
static MOZ_MUST_USE bool initialize();
|
||||
|
||||
explicit Statistics(JSRuntime* rt);
|
||||
~Statistics();
|
||||
@ -174,8 +174,8 @@ struct Statistics
|
||||
void endSlice();
|
||||
void setSliceCycleCount(unsigned cycleCount);
|
||||
|
||||
bool startTimingMutator();
|
||||
bool stopTimingMutator(double& mutator_ms, double& gc_ms);
|
||||
MOZ_MUST_USE bool startTimingMutator();
|
||||
MOZ_MUST_USE bool stopTimingMutator(double& mutator_ms, double& gc_ms);
|
||||
|
||||
void reset(const char* reason) {
|
||||
if (!aborted)
|
||||
|
@ -66,11 +66,11 @@ StoreBuffer::disable()
|
||||
enabled_ = false;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
StoreBuffer::clear()
|
||||
{
|
||||
if (!enabled_)
|
||||
return true;
|
||||
return;
|
||||
|
||||
aboutToOverflow_ = false;
|
||||
cancelIonCompilations_ = false;
|
||||
@ -80,8 +80,6 @@ StoreBuffer::clear()
|
||||
bufferSlot.clear();
|
||||
bufferWholeCell.clear();
|
||||
bufferGeneric.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -74,7 +74,7 @@ class StoreBuffer
|
||||
explicit MonoTypeBuffer() : last_(T()) {}
|
||||
~MonoTypeBuffer() { stores_.finish(); }
|
||||
|
||||
bool init() {
|
||||
MOZ_MUST_USE bool init() {
|
||||
if (!stores_.initialized() && !stores_.init())
|
||||
return false;
|
||||
clear();
|
||||
@ -141,7 +141,7 @@ class StoreBuffer
|
||||
explicit GenericBuffer() : storage_(nullptr) {}
|
||||
~GenericBuffer() { js_delete(storage_); }
|
||||
|
||||
bool init() {
|
||||
MOZ_MUST_USE bool init() {
|
||||
if (!storage_)
|
||||
storage_ = js_new<LifoAlloc>(LifoAllocBlockSize);
|
||||
clear();
|
||||
@ -410,7 +410,7 @@ class StoreBuffer
|
||||
void disable();
|
||||
bool isEnabled() const { return enabled_; }
|
||||
|
||||
bool clear();
|
||||
void clear();
|
||||
|
||||
/* Get the overflowed status. */
|
||||
bool isAboutToOverflow() const { return aboutToOverflow_; }
|
||||
|
@ -8,6 +8,8 @@
|
||||
# include <valgrind/memcheck.h>
|
||||
#endif
|
||||
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jsgc.h"
|
||||
#include "jsprf.h"
|
||||
@ -302,13 +304,13 @@ AssertMarkedOrAllocated(const EdgeValue& edge)
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
gc::GCRuntime::endVerifyPreBarriers()
|
||||
{
|
||||
VerifyPreTracer* trc = verifyPreData;
|
||||
|
||||
if (!trc)
|
||||
return false;
|
||||
return;
|
||||
|
||||
MOZ_ASSERT(!JS::IsGenerationalGCEnabled(rt));
|
||||
|
||||
@ -357,7 +359,6 @@ gc::GCRuntime::endVerifyPreBarriers()
|
||||
marker.stop();
|
||||
|
||||
js_delete(trc);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*** Barrier Verifier Scheduling ***/
|
||||
@ -414,3 +415,123 @@ js::gc::GCRuntime::finishVerifier()
|
||||
}
|
||||
|
||||
#endif /* JS_GC_ZEAL */
|
||||
|
||||
#ifdef JSGC_HASH_TABLE_CHECKS
|
||||
|
||||
class CheckHeapTracer : public JS::CallbackTracer
|
||||
{
|
||||
public:
|
||||
explicit CheckHeapTracer(JSRuntime* rt);
|
||||
bool init();
|
||||
bool check();
|
||||
|
||||
private:
|
||||
void onChild(const JS::GCCellPtr& thing) override;
|
||||
|
||||
struct WorkItem {
|
||||
WorkItem(JS::GCCellPtr thing, const char* name, int parentIndex)
|
||||
: thing(thing), name(name), parentIndex(parentIndex), processed(false)
|
||||
{}
|
||||
|
||||
JS::GCCellPtr thing;
|
||||
const char* name;
|
||||
int parentIndex;
|
||||
bool processed;
|
||||
};
|
||||
|
||||
JSRuntime* rt;
|
||||
bool oom;
|
||||
size_t failures;
|
||||
HashSet<Cell*, DefaultHasher<Cell*>, SystemAllocPolicy> visited;
|
||||
Vector<WorkItem, 0, SystemAllocPolicy> stack;
|
||||
int parentIndex;
|
||||
};
|
||||
|
||||
CheckHeapTracer::CheckHeapTracer(JSRuntime* rt)
|
||||
: CallbackTracer(rt, TraceWeakMapKeysValues),
|
||||
rt(rt),
|
||||
oom(false),
|
||||
failures(0),
|
||||
parentIndex(-1)
|
||||
{
|
||||
setCheckEdges(false);
|
||||
}
|
||||
|
||||
bool
|
||||
CheckHeapTracer::init()
|
||||
{
|
||||
return visited.init();
|
||||
}
|
||||
|
||||
void
|
||||
CheckHeapTracer::onChild(const JS::GCCellPtr& thing)
|
||||
{
|
||||
Cell* cell = thing.asCell();
|
||||
if (visited.lookup(cell))
|
||||
return;
|
||||
|
||||
if (!visited.put(cell)) {
|
||||
oom = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsGCThingValidAfterMovingGC(cell)) {
|
||||
failures++;
|
||||
fprintf(stderr, "Stale pointer %p\n", cell);
|
||||
const char* name = contextName();
|
||||
for (int index = parentIndex; index != -1; index = stack[index].parentIndex) {
|
||||
const WorkItem& parent = stack[index];
|
||||
cell = parent.thing.asCell();
|
||||
fprintf(stderr, " from %s %p %s edge\n",
|
||||
GCTraceKindToAscii(cell->getTraceKind()), cell, name);
|
||||
name = parent.name;
|
||||
}
|
||||
fprintf(stderr, " from root %s\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
WorkItem item(thing, contextName(), parentIndex);
|
||||
if (!stack.append(item))
|
||||
oom = true;
|
||||
}
|
||||
|
||||
bool
|
||||
CheckHeapTracer::check()
|
||||
{
|
||||
// The analysis thinks that markRuntime might GC by calling a GC callback.
|
||||
JS::AutoSuppressGCAnalysis nogc(rt);
|
||||
rt->gc.markRuntime(this, GCRuntime::TraceRuntime);
|
||||
|
||||
while (!stack.empty()) {
|
||||
WorkItem item = stack.back();
|
||||
if (item.processed) {
|
||||
stack.popBack();
|
||||
} else {
|
||||
parentIndex = stack.length() - 1;
|
||||
TraceChildren(this, item.thing);
|
||||
stack.back().processed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (oom)
|
||||
return false;
|
||||
|
||||
if (failures) {
|
||||
fprintf(stderr, "Heap check: %zu failure(s) out of %" PRIu32 " pointers checked\n",
|
||||
failures, visited.count());
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(failures == 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
js::gc::CheckHeapAfterMovingGC(JSRuntime* rt)
|
||||
{
|
||||
MOZ_ASSERT(rt->isHeapCollecting());
|
||||
CheckHeapTracer tracer(rt);
|
||||
if (!tracer.init() || !tracer.check())
|
||||
fprintf(stderr, "OOM checking heap\n");
|
||||
}
|
||||
|
||||
#endif /* JSGC_HASH_TABLE_CHECKS */
|
||||
|
@ -672,7 +672,7 @@ class ZoneAllocPolicy
|
||||
void free_(void* p) { js_free(p); }
|
||||
void reportAllocOverflow() const {}
|
||||
|
||||
bool checkSimulatedOOM() const {
|
||||
MOZ_MUST_USE bool checkSimulatedOOM() const {
|
||||
return !js::oom::ShouldFailWithOOM();
|
||||
}
|
||||
};
|
||||
|
@ -1214,7 +1214,8 @@ const char* gc::ZealModeHelpText =
|
||||
" 11: (IncrementalMarkingValidator) Verify incremental marking\n"
|
||||
" 12: (ElementsBarrier) Always use the individual element post-write barrier, regardless of elements size\n"
|
||||
" 13: (CheckHashTablesOnMinorGC) Check internal hashtables on minor GC\n"
|
||||
" 14: (Compact) Perform a shrinking collection every N allocations\n";
|
||||
" 14: (Compact) Perform a shrinking collection every N allocations\n"
|
||||
" 15: (CheckHeapOnMovingGC) Walk the heap to check all pointers have been updated\n";
|
||||
|
||||
void
|
||||
GCRuntime::setZeal(uint8_t zeal, uint32_t frequency)
|
||||
@ -3382,7 +3383,7 @@ GCRuntime::triggerZoneGC(Zone* zone, JS::gcreason::Reason reason)
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
if (hasZealMode(ZealMode::Alloc)) {
|
||||
triggerGC(reason);
|
||||
MOZ_RELEASE_ASSERT(triggerGC(reason));
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@ -3395,7 +3396,7 @@ GCRuntime::triggerZoneGC(Zone* zone, JS::gcreason::Reason reason)
|
||||
fullGCForAtomsRequested_ = true;
|
||||
return false;
|
||||
}
|
||||
triggerGC(reason);
|
||||
MOZ_RELEASE_ASSERT(triggerGC(reason));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -4360,8 +4361,8 @@ GCRuntime::markWeakReferences(gcstats::Phase phase)
|
||||
marker.enterWeakMarkingMode();
|
||||
|
||||
// TODO bug 1167452: Make weak marking incremental
|
||||
SliceBudget budget = SliceBudget::unlimited();
|
||||
marker.drainMarkStack(budget);
|
||||
auto unlimited = SliceBudget::unlimited();
|
||||
MOZ_RELEASE_ASSERT(marker.drainMarkStack(unlimited));
|
||||
|
||||
for (;;) {
|
||||
bool markedAny = false;
|
||||
@ -4380,7 +4381,7 @@ GCRuntime::markWeakReferences(gcstats::Phase phase)
|
||||
break;
|
||||
|
||||
auto unlimited = SliceBudget::unlimited();
|
||||
marker.drainMarkStack(unlimited);
|
||||
MOZ_RELEASE_ASSERT(marker.drainMarkStack(unlimited));
|
||||
}
|
||||
MOZ_ASSERT(marker.isDrained());
|
||||
|
||||
@ -4407,7 +4408,7 @@ GCRuntime::markGrayReferences(gcstats::Phase phase)
|
||||
(*op)(&marker, grayRootTracer.data);
|
||||
}
|
||||
auto unlimited = SliceBudget::unlimited();
|
||||
marker.drainMarkStack(unlimited);
|
||||
MOZ_RELEASE_ASSERT(marker.drainMarkStack(unlimited));
|
||||
}
|
||||
|
||||
void
|
||||
@ -4568,9 +4569,9 @@ js::gc::MarkingValidator::nonIncrementalMark()
|
||||
|
||||
gc->markRuntime(gcmarker, GCRuntime::MarkRuntime);
|
||||
|
||||
auto unlimited = SliceBudget::unlimited();
|
||||
gc->incrementalState = MARK;
|
||||
gc->marker.drainMarkStack(unlimited);
|
||||
auto unlimited = SliceBudget::unlimited();
|
||||
MOZ_RELEASE_ASSERT(gc->marker.drainMarkStack(unlimited));
|
||||
}
|
||||
|
||||
gc->incrementalState = SWEEP;
|
||||
@ -5031,7 +5032,7 @@ MarkIncomingCrossCompartmentPointers(JSRuntime* rt, const uint32_t color)
|
||||
}
|
||||
|
||||
auto unlimited = SliceBudget::unlimited();
|
||||
rt->gc.marker.drainMarkStack(unlimited);
|
||||
MOZ_RELEASE_ASSERT(rt->gc.marker.drainMarkStack(unlimited));
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -5893,6 +5894,10 @@ GCRuntime::compactPhase(JS::gcreason::Reason reason, SliceBudget& sliceBudget)
|
||||
#ifdef DEBUG
|
||||
CheckHashTablesAfterMovingGC(rt);
|
||||
#endif
|
||||
#ifdef JS_GC_ZEAL
|
||||
if (rt->hasZealMode(ZealMode::CheckHeapOnMovingGC))
|
||||
CheckHeapAfterMovingGC(rt);
|
||||
#endif
|
||||
|
||||
return zonesToMaybeCompact.isEmpty() ? Finished : NotFinished;
|
||||
}
|
||||
|
@ -1185,14 +1185,19 @@ MaybeForwarded(T t)
|
||||
|
||||
#ifdef JSGC_HASH_TABLE_CHECKS
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
IsGCThingValidAfterMovingGC(T* t)
|
||||
{
|
||||
return !IsInsideNursery(t) && !RelocationOverlay::isCellForwarded(t);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
CheckGCThingAfterMovingGC(T* t)
|
||||
{
|
||||
if (t) {
|
||||
MOZ_RELEASE_ASSERT(!IsInsideNursery(t));
|
||||
MOZ_RELEASE_ASSERT(!RelocationOverlay::isCellForwarded(t));
|
||||
}
|
||||
if (t)
|
||||
MOZ_RELEASE_ASSERT(IsGCThingValidAfterMovingGC(t));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -1228,13 +1233,14 @@ CheckValueAfterMovingGC(const JS::Value& value)
|
||||
D(IncrementalMarkingValidator, 11) \
|
||||
D(ElementsBarrier, 12) \
|
||||
D(CheckHashTablesOnMinorGC, 13) \
|
||||
D(Compact, 14)
|
||||
D(Compact, 14) \
|
||||
D(CheckHeapOnMovingGC, 15)
|
||||
|
||||
enum class ZealMode {
|
||||
#define ZEAL_MODE(name, value) name = value,
|
||||
JS_FOR_EACH_ZEAL_MODE(ZEAL_MODE)
|
||||
#undef ZEAL_MODE
|
||||
Limit = 14
|
||||
Limit = 15
|
||||
};
|
||||
|
||||
enum VerifierType {
|
||||
|
@ -1155,6 +1155,15 @@ RestyleManager::AnimationsWithDestroyedFrame::StopAnimationsWithoutFrame(
|
||||
|
||||
animationManager->StopAnimationsForElement(element, aPseudoType);
|
||||
transitionManager->StopTransitionsForElement(element, aPseudoType);
|
||||
|
||||
// All other animations should keep running but not running on the
|
||||
// *compositor* at this point.
|
||||
EffectSet* effectSet = EffectSet::GetEffectSet(element, aPseudoType);
|
||||
if (effectSet) {
|
||||
for (KeyframeEffectReadOnly* effect : *effectSet) {
|
||||
effect->ResetIsRunningOnCompositor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,15 +101,9 @@
|
||||
|
||||
// Print Options
|
||||
#include "nsIPrintSettings.h"
|
||||
#include "nsIPrintOptions.h"
|
||||
#include "nsIPrintSettingsService.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
// PrintOptions is now implemented by PrintSettingsService
|
||||
static const char sPrintOptionsContractID[] =
|
||||
"@mozilla.org/gfx/printsettings-service;1";
|
||||
#endif // DEBUG
|
||||
|
||||
#include "nsIPluginDocument.h"
|
||||
|
||||
#endif // NS_PRINTING
|
||||
@ -2725,11 +2719,12 @@ nsDocumentViewer::Print(bool aSilent,
|
||||
// if they don't pass in a PrintSettings, then make one
|
||||
// it will have all the default values
|
||||
printSettings = aPrintSettings;
|
||||
nsCOMPtr<nsIPrintOptions> printOptions = do_GetService(sPrintOptionsContractID, &rv);
|
||||
nsCOMPtr<nsIPrintSettingsService> printSettingsSvc
|
||||
= do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// if they don't pass in a PrintSettings, then make one
|
||||
if (printSettings == nullptr) {
|
||||
printOptions->CreatePrintSettings(getter_AddRefs(printSettings));
|
||||
printSettingsSvc->GetNewPrintSettings(getter_AddRefs(printSettings));
|
||||
}
|
||||
NS_ASSERTION(printSettings, "You can't PrintPreview without a PrintSettings!");
|
||||
}
|
||||
|
@ -2734,21 +2734,6 @@ nsPresContext::IsRootContentDocument() const
|
||||
return (f && f->PresContext()->IsChrome());
|
||||
}
|
||||
|
||||
bool
|
||||
nsPresContext::IsCrossProcessRootContentDocument()
|
||||
{
|
||||
if (!IsRootContentDocument()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
TabChild* tabChild = TabChild::GetFrom(mShell);
|
||||
return (tabChild && tabChild->IsRootContentDocument());
|
||||
}
|
||||
|
||||
bool nsPresContext::GetPaintFlashing() const
|
||||
{
|
||||
if (!mPaintFlashingInitialized) {
|
||||
|
@ -1039,7 +1039,6 @@ public:
|
||||
}
|
||||
|
||||
bool IsRootContentDocument() const;
|
||||
bool IsCrossProcessRootContentDocument();
|
||||
|
||||
bool IsGlyph() const {
|
||||
return mIsGlyph;
|
||||
|
@ -5373,8 +5373,21 @@ static bool IsTransparentContainerElement(nsPresContext* aPresContext)
|
||||
if (!pwin)
|
||||
return false;
|
||||
nsCOMPtr<Element> containerElement = pwin->GetFrameElementInternal();
|
||||
return containerElement &&
|
||||
containerElement->HasAttr(kNameSpaceID_None, nsGkAtoms::transparent);
|
||||
|
||||
TabChild* tab = TabChild::GetFrom(docShell);
|
||||
if (tab) {
|
||||
// Check if presShell is the top PresShell. Only the top can
|
||||
// influence the canvas background color.
|
||||
nsCOMPtr<nsIPresShell> presShell = aPresContext->GetPresShell();
|
||||
nsCOMPtr<nsIPresShell> topPresShell = tab->GetPresShell();
|
||||
if (presShell != topPresShell) {
|
||||
tab = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return (containerElement &&
|
||||
containerElement->HasAttr(kNameSpaceID_None, nsGkAtoms::transparent))
|
||||
|| (tab && tab->IsTransparent());
|
||||
}
|
||||
|
||||
nscolor PresShell::GetDefaultBackgroundColorToDraw()
|
||||
@ -5406,7 +5419,7 @@ void PresShell::UpdateCanvasBackground()
|
||||
drawBackgroundImage,
|
||||
drawBackgroundColor);
|
||||
mHasCSSBackgroundColor = drawBackgroundColor;
|
||||
if (GetPresContext()->IsCrossProcessRootContentDocument() &&
|
||||
if (mPresContext->IsRootContentDocument() &&
|
||||
!IsTransparentContainerElement(mPresContext)) {
|
||||
mCanvasBackgroundColor =
|
||||
NS_ComposeColors(GetDefaultBackgroundColorToDraw(), mCanvasBackgroundColor);
|
||||
|
@ -92,6 +92,7 @@
|
||||
|
||||
#include "mozilla/AsyncEventDispatcher.h"
|
||||
#include "mozilla/EffectCompositor.h"
|
||||
#include "mozilla/EffectSet.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "mozilla/EventStateManager.h"
|
||||
#include "mozilla/EventStates.h"
|
||||
@ -700,7 +701,7 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
}
|
||||
}
|
||||
|
||||
if (HasCSSAnimations() || HasCSSTransitions()) {
|
||||
if (EffectSet::GetEffectSet(this)) {
|
||||
// If no new frame for this element is created by the end of the
|
||||
// restyling process, stop animations and transitions for this frame
|
||||
if (presContext->RestyleManager()->IsGecko()) {
|
||||
|
@ -31,6 +31,18 @@ parent:
|
||||
// the actual print.
|
||||
async FinalizePrint();
|
||||
|
||||
// Report a state change to listeners in the parent process.
|
||||
async StateChange(long aStateFlags,
|
||||
nsresult aStatus);
|
||||
|
||||
// Report a progress change to listeners in the parent process.
|
||||
async ProgressChange(long aCurSelfProgress,
|
||||
long aMaxSelfProgress,
|
||||
long aCurTotalProgress,
|
||||
long aMaxTotalProgress);
|
||||
|
||||
// Report a status change to listeners in the parent process.
|
||||
async StatusChange(nsresult aStatus);
|
||||
|
||||
child:
|
||||
// Inform the child that the print has been initialized in the parent or has
|
||||
|
@ -13,6 +13,9 @@
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
NS_IMPL_ISUPPORTS(RemotePrintJobChild,
|
||||
nsIWebProgressListener)
|
||||
|
||||
RemotePrintJobChild::RemotePrintJobChild()
|
||||
{
|
||||
MOZ_COUNT_CTOR(RemotePrintJobChild);
|
||||
@ -86,6 +89,56 @@ RemotePrintJobChild::SetPrintEngine(nsPrintEngine* aPrintEngine)
|
||||
mPrintEngine = aPrintEngine;
|
||||
}
|
||||
|
||||
// nsIWebProgressListener
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemotePrintJobChild::OnStateChange(nsIWebProgress* aProgress,
|
||||
nsIRequest* aRequest, uint32_t aStateFlags,
|
||||
nsresult aStatus)
|
||||
{
|
||||
Unused << SendStateChange(aStateFlags, aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemotePrintJobChild::OnProgressChange(nsIWebProgress * aProgress,
|
||||
nsIRequest * aRequest,
|
||||
int32_t aCurSelfProgress,
|
||||
int32_t aMaxSelfProgress,
|
||||
int32_t aCurTotalProgress,
|
||||
int32_t aMaxTotalProgress)
|
||||
{
|
||||
Unused << SendProgressChange(aCurSelfProgress, aMaxSelfProgress,
|
||||
aCurTotalProgress, aMaxTotalProgress);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemotePrintJobChild::OnLocationChange(nsIWebProgress* aProgress,
|
||||
nsIRequest* aRequest, nsIURI* aURI,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemotePrintJobChild::OnStatusChange(nsIWebProgress* aProgress,
|
||||
nsIRequest* aRequest, nsresult aStatus,
|
||||
const char16_t* aMessage)
|
||||
{
|
||||
Unused << SendStatusChange(aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemotePrintJobChild::OnSecurityChange(nsIWebProgress* aProgress,
|
||||
nsIRequest* aRequest, uint32_t aState)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// End of nsIWebProgressListener
|
||||
|
||||
RemotePrintJobChild::~RemotePrintJobChild()
|
||||
{
|
||||
MOZ_COUNT_DTOR(RemotePrintJobChild);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozilla/layout/PRemotePrintJobChild.h"
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
|
||||
class nsPagePrintTimer;
|
||||
class nsPrintEngine;
|
||||
@ -18,9 +19,11 @@ namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
class RemotePrintJobChild final : public PRemotePrintJobChild
|
||||
, public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(RemotePrintJobChild)
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
RemotePrintJobChild();
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsIDeviceContextSpec.h"
|
||||
#include "nsIPrintSettings.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "PrintTranslator.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -149,6 +150,56 @@ RemotePrintJobParent::RecvAbortPrint(const nsresult& aRv)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RemotePrintJobParent::RecvStateChange(const long& aStateFlags,
|
||||
const nsresult& aStatus)
|
||||
{
|
||||
uint32_t numberOfListeners = mPrintProgressListeners.Length();
|
||||
for (uint32_t i = 0; i < numberOfListeners; ++i) {
|
||||
nsIWebProgressListener* listener = mPrintProgressListeners.SafeElementAt(i);
|
||||
listener->OnStateChange(nullptr, nullptr, aStateFlags, aStatus);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RemotePrintJobParent::RecvProgressChange(const long& aCurSelfProgress,
|
||||
const long& aMaxSelfProgress,
|
||||
const long& aCurTotalProgress,
|
||||
const long& aMaxTotalProgress)
|
||||
{
|
||||
uint32_t numberOfListeners = mPrintProgressListeners.Length();
|
||||
for (uint32_t i = 0; i < numberOfListeners; ++i) {
|
||||
nsIWebProgressListener* listener = mPrintProgressListeners.SafeElementAt(i);
|
||||
listener->OnProgressChange(nullptr, nullptr,
|
||||
aCurSelfProgress, aMaxSelfProgress,
|
||||
aCurTotalProgress, aMaxTotalProgress);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RemotePrintJobParent::RecvStatusChange(const nsresult& aStatus)
|
||||
{
|
||||
uint32_t numberOfListeners = mPrintProgressListeners.Length();
|
||||
for (uint32_t i = 0; i < numberOfListeners; ++i) {
|
||||
nsIWebProgressListener* listener = mPrintProgressListeners.SafeElementAt(i);
|
||||
listener->OnStatusChange(nullptr, nullptr, aStatus, nullptr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RemotePrintJobParent::RegisterListener(nsIWebProgressListener* aListener)
|
||||
{
|
||||
MOZ_ASSERT(aListener);
|
||||
|
||||
mPrintProgressListeners.AppendElement(aListener);
|
||||
}
|
||||
|
||||
RemotePrintJobParent::~RemotePrintJobParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(RemotePrintJobParent);
|
||||
|
@ -9,12 +9,14 @@
|
||||
|
||||
#include "mozilla/layout/PRemotePrintJobParent.h"
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
class nsDeviceContext;
|
||||
class nsIPrintSettings;
|
||||
class nsIWebProgressListener;
|
||||
class PrintTranslator;
|
||||
|
||||
namespace mozilla {
|
||||
@ -38,6 +40,23 @@ public:
|
||||
|
||||
bool RecvAbortPrint(const nsresult& aRv) final;
|
||||
|
||||
bool RecvStateChange(const long& aStateFlags,
|
||||
const nsresult& aStatus) final;
|
||||
|
||||
bool RecvProgressChange(const long& aCurSelfProgress,
|
||||
const long& aMaxSelfProgress,
|
||||
const long& aCurTotalProgress,
|
||||
const long& aMaxTotalProgress) final;
|
||||
|
||||
bool RecvStatusChange(const nsresult& aStatus) final;
|
||||
|
||||
/**
|
||||
* Register a progress listener to receive print progress updates.
|
||||
*
|
||||
* @param aListener the progress listener to register. Must not be null.
|
||||
*/
|
||||
void RegisterListener(nsIWebProgressListener* aListener);
|
||||
|
||||
private:
|
||||
~RemotePrintJobParent() final;
|
||||
|
||||
@ -51,6 +70,7 @@ private:
|
||||
nsCOMPtr<nsIPrintSettings> mPrintSettings;
|
||||
RefPtr<nsDeviceContext> mPrintDeviceContext;
|
||||
UniquePtr<PrintTranslator> mPrintTranslator;
|
||||
nsCOMArray<nsIWebProgressListener> mPrintProgressListeners;
|
||||
};
|
||||
|
||||
} // namespace layout
|
||||
|
@ -120,3 +120,15 @@ nsPrintData::DoOnProgressChange(int32_t aProgress,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsPrintData::DoOnStatusChange(nsresult aStatus)
|
||||
{
|
||||
uint32_t numberOfListeners = mPrintProgressListeners.Length();
|
||||
for (uint32_t i = 0; i < numberOfListeners; ++i) {
|
||||
nsIWebProgressListener* listener = mPrintProgressListeners.SafeElementAt(i);
|
||||
if (listener) {
|
||||
listener->OnStatusChange(nullptr, nullptr, aStatus, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,8 @@ public:
|
||||
bool aDoStartStop,
|
||||
int32_t aFlag);
|
||||
|
||||
void DoOnStatusChange(nsresult aStatus);
|
||||
|
||||
|
||||
ePrintDataType mType; // the type of data this is (Printing or Print Preview)
|
||||
RefPtr<nsDeviceContext> mPrintDC;
|
||||
|
@ -475,14 +475,29 @@ nsPrintEngine::DoCommonPrint(bool aIsPrintPreview,
|
||||
}
|
||||
|
||||
// Create a print session and let the print settings know about it.
|
||||
// Don't overwrite an existing print session.
|
||||
// The print settings hold an nsWeakPtr to the session so it does not
|
||||
// need to be cleared from the settings at the end of the job.
|
||||
// XXX What lifetime does the printSession need to have?
|
||||
nsCOMPtr<nsIPrintSession> printSession;
|
||||
bool remotePrintJobListening = false;
|
||||
if (!aIsPrintPreview) {
|
||||
rv = mPrt->mPrintSettings->GetPrintSession(getter_AddRefs(printSession));
|
||||
if (NS_FAILED(rv) || !printSession) {
|
||||
printSession = do_CreateInstance("@mozilla.org/gfx/printsession;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mPrt->mPrintSettings->SetPrintSession(printSession);
|
||||
} else {
|
||||
RefPtr<mozilla::layout::RemotePrintJobChild> remotePrintJob;
|
||||
printSession->GetRemotePrintJob(getter_AddRefs(remotePrintJob));
|
||||
if (NS_SUCCEEDED(rv) && remotePrintJob) {
|
||||
// If we have a RemotePrintJob add it to the print progress listeners,
|
||||
// so it can forward to the parent.
|
||||
mPrt->mPrintProgressListeners.AppendElement(remotePrintJob);
|
||||
remotePrintJobListening = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (aWebProgressListener != nullptr) {
|
||||
@ -612,6 +627,17 @@ nsPrintEngine::DoCommonPrint(bool aIsPrintPreview,
|
||||
if (mPrt->mPrintSettings) {
|
||||
// The user might have changed shrink-to-fit in the print dialog, so update our copy of its state
|
||||
mPrt->mPrintSettings->GetShrinkToFit(&mPrt->mShrinkToFit);
|
||||
|
||||
// If we haven't already added the RemotePrintJob as a listener,
|
||||
// add it now if there is one.
|
||||
if (!remotePrintJobListening) {
|
||||
RefPtr<mozilla::layout::RemotePrintJobChild> remotePrintJob;
|
||||
printSession->GetRemotePrintJob(getter_AddRefs(remotePrintJob));
|
||||
if (NS_SUCCEEDED(rv) && remotePrintJob) {
|
||||
mPrt->mPrintProgressListeners.AppendElement(remotePrintJob);
|
||||
remotePrintJobListening = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (rv == NS_ERROR_NOT_IMPLEMENTED) {
|
||||
// This means the Dialog service was there,
|
||||
@ -1531,6 +1557,9 @@ nsPrintEngine::FirePrintingErrorEvent(nsresult aPrintError)
|
||||
new AsyncEventDispatcher(doc, event);
|
||||
asyncDispatcher->mOnlyChromeDispatch = true;
|
||||
asyncDispatcher->RunDOMEventWhenSafe();
|
||||
|
||||
// Inform any progress listeners of the Error.
|
||||
mPrt->DoOnStatusChange(aPrintError);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
@ -361,7 +361,7 @@ pref("media.gmp.storage.version.expected", 1);
|
||||
|
||||
// Filter what triggers user notifications.
|
||||
// See DecoderDoctorDocumentWatcher::ReportAnalysis for details.
|
||||
pref("media.decoder-doctor.notifications-allowed", "MediaWidevineNoWMFNoSilverlight");
|
||||
pref("media.decoder-doctor.notifications-allowed", "MediaWMFNeeded,MediaWidevineNoWMFNoSilverlight");
|
||||
// Whether we report partial failures.
|
||||
pref("media.decoder-doctor.verbose", false);
|
||||
|
||||
|
@ -824,11 +824,10 @@ class Artifacts(object):
|
||||
return candidate_pushheads
|
||||
|
||||
def _get_hg_revisions_from_git(self):
|
||||
|
||||
# First commit is HEAD, next is HEAD~1, etc.
|
||||
rev_list = subprocess.check_output([
|
||||
self._git, 'rev-list', '--topo-order',
|
||||
'HEAD~{num}..HEAD'.format(num=NUM_REVISIONS_TO_QUERY),
|
||||
'--max-count={num}'.format(num=NUM_REVISIONS_TO_QUERY),
|
||||
'HEAD',
|
||||
])
|
||||
|
||||
hg_hash_list = subprocess.check_output([
|
||||
|
@ -184,6 +184,81 @@ config = {
|
||||
},
|
||||
},
|
||||
},
|
||||
'mozilla-esr45': {
|
||||
'enable_release_promotion': True,
|
||||
'repo_path': 'releases/mozilla-esr45',
|
||||
'update_channel': 'esr',
|
||||
'branch_uses_per_checkin_strategy': True,
|
||||
'use_branch_in_symbols_extra_buildid': False,
|
||||
'stage_server': 'upload.ffxbld.productdelivery.prod.mozaws.net',
|
||||
'platform_overrides': {
|
||||
'linux': {
|
||||
'src_mozconfig': 'browser/config/mozconfigs/linux32/release',
|
||||
'force_clobber': True,
|
||||
},
|
||||
'linux64': {
|
||||
'src_mozconfig': 'browser/config/mozconfigs/linux64/release',
|
||||
'force_clobber': True,
|
||||
},
|
||||
'macosx64': {
|
||||
'src_mozconfig': 'browser/config/mozconfigs/macosx-universal/release',
|
||||
'force_clobber': True,
|
||||
},
|
||||
'win32': {
|
||||
'src_mozconfig': 'browser/config/mozconfigs/win32/release',
|
||||
'force_clobber': True,
|
||||
},
|
||||
'win64': {
|
||||
'src_mozconfig': 'browser/config/mozconfigs/win64/release',
|
||||
'force_clobber': True,
|
||||
},
|
||||
'linux-debug': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
'linux64-debug': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
'linux64-asan-debug': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
'linux64-asan': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
'linux64-cc': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
'linux64-st-an-debug': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
'linux64-st-an': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
'linux64-tsan': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
'macosx64-debug': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
'macosx64-st-an': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
'macosx64-mulet': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
'macosx64-st-an-debug': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
'win32-debug': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
'win32-mulet': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
'win64-debug': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
},
|
||||
},
|
||||
'mozilla-aurora': {
|
||||
'repo_path': 'releases/mozilla-aurora',
|
||||
'update_channel': 'aurora',
|
||||
|
@ -0,0 +1,18 @@
|
||||
config = {
|
||||
"log_name": "bump_esr45",
|
||||
"version_files": [
|
||||
{"file": "browser/config/version.txt"},
|
||||
{"file": "browser/config/version_display.txt"},
|
||||
{"file": "config/milestone.txt"},
|
||||
],
|
||||
"repo": {
|
||||
"repo": "https://hg.mozilla.org/releases/mozilla-esr45",
|
||||
"revision": "default",
|
||||
"dest": "mozilla-esr45",
|
||||
"vcs": "hg",
|
||||
},
|
||||
"push_dest": "ssh://hg.mozilla.org/releases/mozilla-esr45",
|
||||
"ignore_no_changes": True,
|
||||
"ssh_user": "ffxbld",
|
||||
"ssh_key": "~/.ssh/ffxbld_rsa",
|
||||
}
|
34
testing/mozharness/configs/releases/updates_firefox_esr45.py
Normal file
34
testing/mozharness/configs/releases/updates_firefox_esr45.py
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
config = {
|
||||
"log_name": "updates_esr45",
|
||||
"repo": {
|
||||
"repo": "https://hg.mozilla.org/build/tools",
|
||||
"revision": "default",
|
||||
"dest": "tools",
|
||||
"vcs": "hg",
|
||||
},
|
||||
"push_dest": "ssh://hg.mozilla.org/build/tools",
|
||||
"shipped-locales-url": "https://hg.mozilla.org/releases/mozilla-esr45/raw-file/{revision}/browser/locales/shipped-locales",
|
||||
"ignore_no_changes": True,
|
||||
"ssh_user": "ffxbld",
|
||||
"ssh_key": "~/.ssh/ffxbld_rsa",
|
||||
"archive_domain": "archive.mozilla.org",
|
||||
"archive_prefix": "https://archive.mozilla.org/pub",
|
||||
"previous_archive_prefix": "https://archive.mozilla.org/pub",
|
||||
"download_domain": "download.mozilla.org",
|
||||
"balrog_url": "https://aus5.mozilla.org",
|
||||
"balrog_username": "ffxbld",
|
||||
"update_channels": {
|
||||
"esr": {
|
||||
"version_regex": r".*",
|
||||
"requires_mirrors": True,
|
||||
"patcher_config": "mozEsr45-branch-patcher2.cfg",
|
||||
"update_verify_channel": "esr-localtest",
|
||||
"mar_channel_ids": [],
|
||||
"channel_names": ["esr", "esr-localtest", "esr-cdntest"],
|
||||
"rules_to_update": ["esr45-cdntest", "esr45-localtest"],
|
||||
"publish_rules": ["esr"],
|
||||
},
|
||||
},
|
||||
"balrog_use_dummy_suffix": False,
|
||||
}
|
40
testing/mozharness/configs/single_locale/mozilla-esr45.py
Normal file
40
testing/mozharness/configs/single_locale/mozilla-esr45.py
Normal file
@ -0,0 +1,40 @@
|
||||
config = {
|
||||
"nightly_build": True,
|
||||
"branch": "mozilla-esr45",
|
||||
"en_us_binary_url": "http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-mozilla-esr45/",
|
||||
"update_channel": "esr",
|
||||
"latest_mar_dir": '/pub/mozilla.org/firefox/nightly/latest-mozilla-esr45-l10n',
|
||||
|
||||
# l10n
|
||||
"hg_l10n_base": "https://hg.mozilla.org/releases/l10n/mozilla-release",
|
||||
|
||||
# repositories
|
||||
"mozilla_dir": "mozilla-esr45",
|
||||
"repos": [{
|
||||
"vcs": "hg",
|
||||
"repo": "https://hg.mozilla.org/build/tools",
|
||||
"revision": "default",
|
||||
"dest": "tools",
|
||||
}, {
|
||||
"vcs": "hgtool",
|
||||
"repo": "https://hg.mozilla.org/releases/mozilla-esr45",
|
||||
"revision": "default",
|
||||
"dest": "mozilla-esr45",
|
||||
}, {
|
||||
"vcs": "hgtool",
|
||||
"repo": "https://hg.mozilla.org/build/compare-locales",
|
||||
"revision": "RELEASE_AUTOMATION"
|
||||
}],
|
||||
# purge options
|
||||
'purge_minsize': 12,
|
||||
'is_automation': True,
|
||||
'default_actions': [
|
||||
"clobber",
|
||||
"pull",
|
||||
"list-locales",
|
||||
"setup",
|
||||
"repack",
|
||||
"taskcluster-upload",
|
||||
"summary",
|
||||
],
|
||||
}
|
@ -336,6 +336,26 @@
|
||||
"n_buckets": 50,
|
||||
"description": "Max time spent on one forget skippable (ms)"
|
||||
},
|
||||
"FULLSCREEN_TRANSITION_BLACK_MS": {
|
||||
"alert_emails": ["xquan@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "exponential",
|
||||
"low": 100,
|
||||
"high": 5000,
|
||||
"n_buckets": 50,
|
||||
"bug_numbers": [1271160],
|
||||
"description": "The time spent in the fully-black screen in fullscreen transition"
|
||||
},
|
||||
"FULLSCREEN_CHANGE_MS": {
|
||||
"alert_emails": ["xquan@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "exponential",
|
||||
"low": 100,
|
||||
"high": 5000,
|
||||
"n_buckets": 50,
|
||||
"bug_numbers": [1271160],
|
||||
"description": "The time content uses to enter/exit fullscreen regardless of fullscreen transition timeout"
|
||||
},
|
||||
"GC_REASON_2": {
|
||||
"alert_emails": ["dev-telemetry-gc-alerts@mozilla.org"],
|
||||
"expires_in_version": "never",
|
||||
|
245
toolkit/components/url-classifier/tests/unit/test_listmanager.js
Normal file
245
toolkit/components/url-classifier/tests/unit/test_listmanager.js
Normal file
@ -0,0 +1,245 @@
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
// These tables share the same updateURL.
|
||||
const TEST_TABLE_DATA_LIST = [
|
||||
// 0:
|
||||
{
|
||||
tableName: "test-listmanager0-digest256",
|
||||
providerName: "google",
|
||||
updateUrl: "http://localhost:4444/safebrowsing/update",
|
||||
gethashUrl: "http://localhost:4444/safebrowsing/gethash0",
|
||||
},
|
||||
|
||||
// 1:
|
||||
{
|
||||
tableName: "test-listmanager1-digest256",
|
||||
providerName: "google",
|
||||
updateUrl: "http://localhost:4444/safebrowsing/update",
|
||||
gethashUrl: "http://localhost:4444/safebrowsing/gethash1",
|
||||
},
|
||||
|
||||
// 2.
|
||||
{
|
||||
tableName: "test-listmanager2-digest256",
|
||||
providerName: "google",
|
||||
updateUrl: "http://localhost:4444/safebrowsing/update",
|
||||
gethashUrl: "http://localhost:4444/safebrowsing/gethash2",
|
||||
}
|
||||
];
|
||||
|
||||
// This table has a different update URL.
|
||||
const TEST_TABLE_DATA_ANOTHER = {
|
||||
tableName: "test-listmanageranother-digest256",
|
||||
providerName: "google",
|
||||
updateUrl: "http://localhost:5555/safebrowsing/update",
|
||||
gethashUrl: "http://localhost:5555/safebrowsing/gethash-another",
|
||||
};
|
||||
|
||||
const PREF_NEXTUPDATETIME = "browser.safebrowsing.provider.google.nextupdatetime";
|
||||
|
||||
let gListManager = Cc["@mozilla.org/url-classifier/listmanager;1"]
|
||||
.getService(Ci.nsIUrlListManager);
|
||||
|
||||
// Global test server for serving safebrowsing updates.
|
||||
let gHttpServ = null;
|
||||
let gUpdateResponse = "";
|
||||
let gExpectedUpdateRequest = "";
|
||||
|
||||
// Handles request for TEST_TABLE_DATA_ANOTHER.
|
||||
let gHttpServAnother = null;
|
||||
|
||||
// These two variables are used to synchronize the last two racing updates
|
||||
// (in terms of "update URL") in test_update_all_tables().
|
||||
let gUpdatedCntForTableData = 0; // For TEST_TABLE_DATA_LIST.
|
||||
let gIsAnotherUpdated = false; // For TEST_TABLE_DATA_ANOTHER.
|
||||
|
||||
prefBranch.setBoolPref("browser.safebrowsing.debug", true);
|
||||
|
||||
// Register tables.
|
||||
TEST_TABLE_DATA_LIST.forEach(function(t) {
|
||||
gListManager.registerTable(t.tableName,
|
||||
t.providerName,
|
||||
t.updateUrl,
|
||||
t.gethashUrl);
|
||||
});
|
||||
gListManager.registerTable(TEST_TABLE_DATA_ANOTHER.tableName,
|
||||
TEST_TABLE_DATA_ANOTHER.providerName,
|
||||
TEST_TABLE_DATA_ANOTHER.updateUrl,
|
||||
TEST_TABLE_DATA_ANOTHER.gethashUrl);
|
||||
|
||||
const SERVER_INVOLVED_TEST_CASE_LIST = [
|
||||
// - Do table0 update.
|
||||
// - Server would respond "a:5:32:32\n[DATA]".
|
||||
function test_update_table0() {
|
||||
disableAllUpdates();
|
||||
|
||||
gListManager.enableUpdate(TEST_TABLE_DATA_LIST[0].tableName);
|
||||
gExpectedUpdateRequest = TEST_TABLE_DATA_LIST[0].tableName + ";\n";
|
||||
|
||||
gUpdateResponse = "n:1000\ni:" + TEST_TABLE_DATA_LIST[0].tableName + "\n";
|
||||
gUpdateResponse += readFileToString("data/digest2.chunk");
|
||||
|
||||
forceTableUpdate();
|
||||
},
|
||||
|
||||
// - Do table0 update again. Since chunk 5 was added to table0 in the last
|
||||
// update, the expected request contains "a:5".
|
||||
// - Server would respond "s;2-12\n[DATA]".
|
||||
function test_update_table0_with_existing_chunks() {
|
||||
disableAllUpdates();
|
||||
|
||||
gListManager.enableUpdate(TEST_TABLE_DATA_LIST[0].tableName);
|
||||
gExpectedUpdateRequest = TEST_TABLE_DATA_LIST[0].tableName + ";a:5\n";
|
||||
|
||||
gUpdateResponse = "n:1000\ni:" + TEST_TABLE_DATA_LIST[0].tableName + "\n";
|
||||
gUpdateResponse += readFileToString("data/digest1.chunk");
|
||||
|
||||
forceTableUpdate();
|
||||
},
|
||||
|
||||
// - Do all-table update.
|
||||
// - Server would respond no chunk control.
|
||||
//
|
||||
// Note that this test MUST be the last one in the array since we rely on
|
||||
// the number of sever-involved test case to synchronize the racing last
|
||||
// two udpates for different URL.
|
||||
function test_update_all_tables() {
|
||||
disableAllUpdates();
|
||||
|
||||
// Enable all tables including TEST_TABLE_DATA_ANOTHER!
|
||||
TEST_TABLE_DATA_LIST.forEach(function(t) {
|
||||
gListManager.enableUpdate(t.tableName);
|
||||
});
|
||||
gListManager.enableUpdate(TEST_TABLE_DATA_ANOTHER.tableName);
|
||||
|
||||
gExpectedUpdateRequest = TEST_TABLE_DATA_LIST[0].tableName + ";a:5:s:2-12\n" +
|
||||
TEST_TABLE_DATA_LIST[1].tableName + ";\n" +
|
||||
TEST_TABLE_DATA_LIST[2].tableName + ";\n";
|
||||
gUpdateResponse = "n:1000\n";
|
||||
|
||||
forceTableUpdate();
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
SERVER_INVOLVED_TEST_CASE_LIST.forEach(t => add_test(t));
|
||||
|
||||
// Tests nsIUrlListManager.getGethashUrl.
|
||||
add_test(function test_getGethashUrl() {
|
||||
TEST_TABLE_DATA_LIST.forEach(function (t) {
|
||||
equal(gListManager.getGethashUrl(t.tableName), t.gethashUrl);
|
||||
});
|
||||
equal(gListManager.getGethashUrl(TEST_TABLE_DATA_ANOTHER.tableName),
|
||||
TEST_TABLE_DATA_ANOTHER.gethashUrl);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
// Setup primary testing server.
|
||||
gHttpServ = new HttpServer();
|
||||
gHttpServ.registerDirectory("/", do_get_cwd());
|
||||
|
||||
gHttpServ.registerPathHandler("/safebrowsing/update", function(request, response) {
|
||||
let body = NetUtil.readInputStreamToString(request.bodyInputStream,
|
||||
request.bodyInputStream.available());
|
||||
|
||||
// Verify if the request is as expected.
|
||||
equal(body, gExpectedUpdateRequest);
|
||||
|
||||
// Respond the update which is controlled by the test case.
|
||||
response.setHeader("Content-Type",
|
||||
"application/vnd.google.safebrowsing-update", false);
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.bodyOutputStream.write(gUpdateResponse, gUpdateResponse.length);
|
||||
|
||||
gUpdatedCntForTableData++;
|
||||
|
||||
if (gUpdatedCntForTableData !== SERVER_INVOLVED_TEST_CASE_LIST.length) {
|
||||
// This is not the last test case so run the next once upon the
|
||||
// the update success.
|
||||
waitForUpdateSuccess(run_next_test);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gIsAnotherUpdated) {
|
||||
run_next_test(); // All tests are done. Just finish.
|
||||
return;
|
||||
}
|
||||
|
||||
do_print("Waiting for TEST_TABLE_DATA_ANOTHER to be tested ...");
|
||||
});
|
||||
|
||||
gHttpServ.start(4444);
|
||||
|
||||
// Setup another testing server for the different update URL.
|
||||
gHttpServAnother = new HttpServer();
|
||||
gHttpServAnother.registerDirectory("/", do_get_cwd());
|
||||
|
||||
gHttpServAnother.registerPathHandler("/safebrowsing/update", function(request, response) {
|
||||
let body = NetUtil.readInputStreamToString(request.bodyInputStream,
|
||||
request.bodyInputStream.available());
|
||||
|
||||
// Verify if the request is as expected.
|
||||
equal(body, TEST_TABLE_DATA_ANOTHER.tableName + ";\n");
|
||||
|
||||
// Respond with no chunk control.
|
||||
response.setHeader("Content-Type",
|
||||
"application/vnd.google.safebrowsing-update", false);
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
|
||||
let content = "n:1000\n";
|
||||
response.bodyOutputStream.write(content, content.length);
|
||||
|
||||
gIsAnotherUpdated = true;
|
||||
|
||||
if (gUpdatedCntForTableData === SERVER_INVOLVED_TEST_CASE_LIST.length) {
|
||||
// All tests are done!
|
||||
run_next_test();
|
||||
return;
|
||||
}
|
||||
|
||||
do_print("Wait for all sever-involved tests to be done ...");
|
||||
});
|
||||
|
||||
gHttpServAnother.start(5555);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
// A trick to force updating tables. However, before calling this, we have to
|
||||
// call disableAllUpdates() first to clean up the updateCheckers in listmanager.
|
||||
function forceTableUpdate() {
|
||||
prefBranch.setCharPref(PREF_NEXTUPDATETIME, "1");
|
||||
gListManager.maybeToggleUpdateChecking();
|
||||
}
|
||||
|
||||
function disableAllUpdates() {
|
||||
TEST_TABLE_DATA_LIST.forEach(t => gListManager.disableUpdate(t.tableName));
|
||||
gListManager.disableUpdate(TEST_TABLE_DATA_ANOTHER.tableName);
|
||||
}
|
||||
|
||||
// Since there's no public interface on listmanager to know the update success,
|
||||
// we could only rely on the refresh of "nextupdatetime".
|
||||
function waitForUpdateSuccess(callback) {
|
||||
let nextupdatetime = parseInt(prefBranch.getCharPref(PREF_NEXTUPDATETIME));
|
||||
do_print("nextupdatetime: " + nextupdatetime);
|
||||
if (nextupdatetime !== 1) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
do_timeout(1000, waitForUpdateSuccess.bind(null, callback));
|
||||
}
|
||||
|
||||
// Construct an update from a file.
|
||||
function readFileToString(aFilename) {
|
||||
let f = do_get_file(aFilename);
|
||||
let stream = Cc["@mozilla.org/network/file-input-stream;1"]
|
||||
.createInstance(Ci.nsIFileInputStream);
|
||||
stream.init(f, -1, 0, 0);
|
||||
let buf = NetUtil.readInputStreamToString(stream, stream.available());
|
||||
return buf;
|
||||
}
|
@ -17,3 +17,4 @@ support-files =
|
||||
[test_provider_url.js]
|
||||
[test_streamupdater.js]
|
||||
[test_digest256.js]
|
||||
[test_listmanager.js]
|
||||
|
@ -1326,6 +1326,22 @@
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="print">
|
||||
<parameter name="aPrintSettings"/>
|
||||
<parameter name="aPrintProgressListener"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var owner = this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner);
|
||||
if (!owner.frameLoader) {
|
||||
throw Components.Exception("No frame loader.",
|
||||
Components.results.NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
owner.frameLoader.print(aPrintSettings, aPrintProgressListener);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<!-- This will go away if the binding has been removed for some reason. -->
|
||||
<field name="_alive">true</field>
|
||||
</implementation>
|
||||
|
@ -25,7 +25,8 @@ nsPrintOptionsAndroid::~nsPrintOptionsAndroid()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintOptionsAndroid::CreatePrintSettings(nsIPrintSettings **_retval)
|
||||
nsresult
|
||||
nsPrintOptionsAndroid::_CreatePrintSettings(nsIPrintSettings** _retval)
|
||||
{
|
||||
nsPrintSettings * printSettings = new nsPrintSettingsAndroid();
|
||||
NS_ENSURE_TRUE(printSettings, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
nsPrintOptionsAndroid();
|
||||
virtual ~nsPrintOptionsAndroid();
|
||||
|
||||
NS_IMETHOD CreatePrintSettings(nsIPrintSettings **_retval);
|
||||
nsresult _CreatePrintSettings(nsIPrintSettings** _retval) override;
|
||||
};
|
||||
|
||||
#endif /* nsPrintOptionsAndroid_h__ */
|
||||
|
@ -431,11 +431,6 @@ NS_IMETHODIMP nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter(const char16_
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrinterEnumeratorGTK::DisplayPropertiesDlg(const char16_t *aPrinter, nsIPrintSettings *aPrintSettings)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
nsresult GlobalPrinters::InitializeGlobalPrinters ()
|
||||
{
|
||||
|
@ -6,25 +6,7 @@
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIPrintSettings.idl"
|
||||
|
||||
%{ C++
|
||||
struct nsFont;
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
class PrintData;
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
||||
interface nsIStringEnumerator;
|
||||
interface nsIWebBrowserPrint;
|
||||
|
||||
/**
|
||||
* Native types
|
||||
*/
|
||||
[ref] native nsNativeFontRef(nsFont);
|
||||
[ref] native PrintDataRef(const mozilla::embedding::PrintData);
|
||||
[ptr] native PrintDataPtr(mozilla::embedding::PrintData);
|
||||
|
||||
/**
|
||||
* Print options interface
|
||||
@ -41,64 +23,6 @@ interface nsIPrintOptions : nsISupports
|
||||
* Show Native Print Options dialog, this may not be supported on all platforms
|
||||
*/
|
||||
void ShowPrintSetupDialog(in nsIPrintSettings aThePrintSettings);
|
||||
|
||||
/**
|
||||
* Creates a new PrintSettnigs Object
|
||||
* and initializes it from prefs
|
||||
*/
|
||||
nsIPrintSettings CreatePrintSettings();
|
||||
|
||||
/**
|
||||
* Get a prefixed integer pref
|
||||
*/
|
||||
int32_t getPrinterPrefInt(in nsIPrintSettings aPrintSettings, in wstring
|
||||
aPrefName);
|
||||
|
||||
/**
|
||||
* display Printer Job Properties dialog
|
||||
*/
|
||||
void displayJobProperties (in wstring aPrinter, in nsIPrintSettings
|
||||
aPrintSettings, out boolean aDisplayed);
|
||||
|
||||
/**
|
||||
* Native data constants
|
||||
*/
|
||||
const short kNativeDataPrintRecord = 0;
|
||||
|
||||
[noscript] voidPtr GetNativeData(in short aDataType);
|
||||
|
||||
/**
|
||||
* Given some nsIPrintSettings and (optionally) an nsIWebBrowserPrint, populates
|
||||
* a PrintData representing them which can be sent over IPC. Values are only
|
||||
* ever read from aSettings and aWBP.
|
||||
*
|
||||
* @param aSettings
|
||||
* An nsIPrintSettings for a print job.
|
||||
* @param aWBP (optional)
|
||||
* The nsIWebBrowserPrint for the print job.
|
||||
* @param data
|
||||
* Pointer to a pre-existing PrintData to populate.
|
||||
*
|
||||
* @return nsresult
|
||||
*/
|
||||
[noscript] void SerializeToPrintData(in nsIPrintSettings aPrintSettings,
|
||||
in nsIWebBrowserPrint aWebBrowserPrint,
|
||||
in PrintDataPtr data);
|
||||
|
||||
/**
|
||||
* This function is the opposite of SerializeToPrintData, in that it takes
|
||||
* a PrintData, and populates a pre-existing nsIPrintSettings with the data
|
||||
* from PrintData.
|
||||
*
|
||||
* @param PrintData
|
||||
* Printing information sent through IPC.
|
||||
* @param settings
|
||||
* A pre-existing nsIPrintSettings to populate with the PrintData.
|
||||
*
|
||||
* @return nsresult
|
||||
*/
|
||||
[noscript] void DeserializeToPrintSettings(in PrintDataRef data,
|
||||
in nsIPrintSettings aPrintSettings);
|
||||
};
|
||||
|
||||
[scriptable, uuid(5e738fff-404c-4c94-9189-e8f2cce93e94)]
|
||||
@ -126,11 +50,5 @@ interface nsIPrinterEnumerator : nsISupports
|
||||
* The list of printer names
|
||||
*/
|
||||
readonly attribute nsIStringEnumerator printerNameList;
|
||||
|
||||
/* takes printer selected and will display job properties dlg for that printer
|
||||
* returns true if dialog displays
|
||||
*/
|
||||
void displayPropertiesDlg(in wstring aPrinter, in nsIPrintSettings aPrintSettings);
|
||||
|
||||
};
|
||||
|
||||
|
@ -10,6 +10,21 @@
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIPrintSettings;
|
||||
interface nsIWebBrowserPrint;
|
||||
|
||||
%{ C++
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
class PrintData;
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
||||
/**
|
||||
* Native types
|
||||
*/
|
||||
[ref] native PrintDataRef(const mozilla::embedding::PrintData);
|
||||
[ptr] native PrintDataPtr(mozilla::embedding::PrintData);
|
||||
|
||||
[scriptable, uuid(841387C8-72E6-484b-9296-BF6EEA80D58A)]
|
||||
interface nsIPrintSettingsService : nsISupports
|
||||
@ -34,7 +49,8 @@ interface nsIPrintSettingsService : nsISupports
|
||||
* If each browse window was to use the same PrintSettings object
|
||||
* then it should use "globalPrintSettings"
|
||||
*
|
||||
* Initializes the newPrintSettings from the default printer
|
||||
* Initializes the newPrintSettings from the unprefixed printer
|
||||
* (Note: this may not happen if there is an OS specific implementation.)
|
||||
*
|
||||
*/
|
||||
readonly attribute nsIPrintSettings newPrintSettings;
|
||||
@ -97,6 +113,41 @@ interface nsIPrintSettingsService : nsISupports
|
||||
*/
|
||||
void savePrintSettingsToPrefs(in nsIPrintSettings aPrintSettings, in boolean aUsePrinterNamePrefix, in unsigned long aFlags);
|
||||
|
||||
/**
|
||||
* Given some nsIPrintSettings and (optionally) an nsIWebBrowserPrint,
|
||||
* populates a PrintData representing them which can be sent over IPC. Values
|
||||
* are only ever read from aSettings and aWBP.
|
||||
*
|
||||
* @param aSettings
|
||||
* An nsIPrintSettings for a print job.
|
||||
* @param aWBP (optional)
|
||||
* The nsIWebBrowserPrint for the print job.
|
||||
* @param data
|
||||
* Pointer to a pre-existing PrintData to populate.
|
||||
*
|
||||
* @return nsresult
|
||||
*/
|
||||
[noscript]
|
||||
void SerializeToPrintData(in nsIPrintSettings aPrintSettings,
|
||||
in nsIWebBrowserPrint aWebBrowserPrint,
|
||||
in PrintDataPtr data);
|
||||
|
||||
/**
|
||||
* This function is the opposite of SerializeToPrintData, in that it takes
|
||||
* a PrintData, and populates a pre-existing nsIPrintSettings with the data
|
||||
* from PrintData.
|
||||
*
|
||||
* @param PrintData
|
||||
* Printing information sent through IPC.
|
||||
* @param settings
|
||||
* A pre-existing nsIPrintSettings to populate with the PrintData.
|
||||
*
|
||||
* @return nsresult
|
||||
*/
|
||||
[noscript]
|
||||
void DeserializeToPrintSettings(in PrintDataRef data,
|
||||
in nsIPrintSettings aPrintSettings);
|
||||
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
@ -12,9 +12,9 @@
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsPrintSettingsImpl.h"
|
||||
#include "nsIPrintSession.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIDialogParamBlock.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
@ -105,6 +105,16 @@ nsPrintOptions::SerializeToPrintData(nsIPrintSettings* aSettings,
|
||||
nsIWebBrowserPrint* aWBP,
|
||||
PrintData* data)
|
||||
{
|
||||
nsCOMPtr<nsIPrintSession> session;
|
||||
nsresult rv = aSettings->GetPrintSession(getter_AddRefs(session));
|
||||
if (NS_SUCCEEDED(rv) && session) {
|
||||
RefPtr<RemotePrintJobChild> remotePrintJob;
|
||||
rv = session->GetRemotePrintJob(getter_AddRefs(remotePrintJob));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
data->remotePrintJobChild() = remotePrintJob;
|
||||
}
|
||||
}
|
||||
|
||||
aSettings->GetStartPageRange(&data->startPageRange());
|
||||
aSettings->GetEndPageRange(&data->endPageRange());
|
||||
|
||||
@ -965,33 +975,6 @@ nsPrintOptions::WritePrefs(nsIPrintSettings *aPS, const nsAString& aPrinterName,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintOptions::DisplayJobProperties(const char16_t *aPrinter,
|
||||
nsIPrintSettings* aPrintSettings,
|
||||
bool *aDisplayed)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPrinter);
|
||||
*aDisplayed = false;
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrinterEnumerator> propDlg =
|
||||
do_CreateInstance(NS_PRINTER_ENUMERATOR_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aPrintSettings);
|
||||
rv = propDlg->DisplayPropertiesDlg(aPrinter, aPrintSettings);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aDisplayed = true;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintOptions::GetNativeData(int16_t aDataType, void * *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult nsPrintOptions::_CreatePrintSettings(nsIPrintSettings **_retval)
|
||||
{
|
||||
// does not initially ref count
|
||||
@ -1011,17 +994,12 @@ nsresult nsPrintOptions::_CreatePrintSettings(nsIPrintSettings **_retval)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintOptions::CreatePrintSettings(nsIPrintSettings **_retval)
|
||||
{
|
||||
return _CreatePrintSettings(_retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintOptions::GetGlobalPrintSettings(nsIPrintSettings **aGlobalPrintSettings)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = CreatePrintSettings(getter_AddRefs(mGlobalPrintSettings));
|
||||
rv = _CreatePrintSettings(getter_AddRefs(mGlobalPrintSettings));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ADDREF(*aGlobalPrintSettings = mGlobalPrintSettings.get());
|
||||
@ -1032,7 +1010,7 @@ nsPrintOptions::GetGlobalPrintSettings(nsIPrintSettings **aGlobalPrintSettings)
|
||||
NS_IMETHODIMP
|
||||
nsPrintOptions::GetNewPrintSettings(nsIPrintSettings * *aNewPrintSettings)
|
||||
{
|
||||
return CreatePrintSettings(aNewPrintSettings);
|
||||
return _CreatePrintSettings(aNewPrintSettings);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1104,6 +1082,7 @@ nsPrintOptions::InitPrintSettingsFromPrinter(const char16_t *aPrinterName,
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifndef MOZ_X11
|
||||
/** ---------------------------------------------------
|
||||
* Helper function - Returns either the name or sets the length to zero
|
||||
*/
|
||||
@ -1143,31 +1122,7 @@ GetAdjustedPrinterName(nsIPrintSettings* aPS, bool aUsePNP,
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintOptions::GetPrinterPrefInt(nsIPrintSettings *aPrintSettings,
|
||||
const char16_t *aPrefName, int32_t *_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPrintSettings);
|
||||
NS_ENSURE_ARG_POINTER(aPrefName);
|
||||
|
||||
nsAutoString prtName;
|
||||
// Get the Printer Name from the PrintSettings
|
||||
// to use as a prefix for Pref Names
|
||||
GetAdjustedPrinterName(aPrintSettings, true, prtName);
|
||||
|
||||
const char* prefName =
|
||||
GetPrefName(NS_LossyConvertUTF16toASCII(aPrefName).get(), prtName);
|
||||
|
||||
NS_ENSURE_TRUE(prefName, NS_ERROR_FAILURE);
|
||||
|
||||
int32_t iVal;
|
||||
nsresult rv = Preferences::GetInt(prefName, &iVal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*_retval = iVal;
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintOptions::InitPrintSettingsFromPrefs(nsIPrintSettings* aPS,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user