Merge mozilla-central and inbound

This commit is contained in:
Ed Morley 2013-10-29 16:35:50 +00:00
commit c57c578dc0
73 changed files with 1307 additions and 413 deletions

View File

@ -764,7 +764,6 @@ var gBrowserInit = {
window.addEventListener("AppCommand", HandleAppCommandEvent, true);
messageManager.loadFrameScript("chrome://browser/content/content.js", true);
messageManager.loadFrameScript("chrome://browser/content/content-sessionStore.js", true);
// initialize observers and listeners
// and give C++ access to gBrowser

View File

@ -2253,6 +2253,10 @@
// Make sure to unregister any open URIs.
this._swapRegisteredOpenURIs(ourBrowser, aOtherBrowser);
// Give others a chance to swap state.
let event = new CustomEvent("SwapDocShells", {"detail": aOtherBrowser});
ourBrowser.dispatchEvent(event);
// Swap the docshells
ourBrowser.swapDocShells(aOtherBrowser);

View File

@ -120,6 +120,48 @@ let MessageListener = {
}
};
/**
* If session data must be collected synchronously, we do it via
* method calls to this object (rather than via messages to
* MessageListener). When using multiple processes, these methods run
* in the content process, but the parent synchronously waits on them
* using cross-process object wrappers. Without multiple processes, we
* still use this code for synchronous collection.
*/
let SyncHandler = {
init: function () {
// Send this object as a CPOW to chrome. In single-process mode,
// the synchronous send ensures that the handler object is
// available in SessionStore.jsm immediately upon loading
// content-sessionStore.js.
sendSyncMessage("SessionStore:setupSyncHandler", {}, {handler: this});
},
collectSessionHistory: function (includePrivateData) {
let history = SessionHistory.read(docShell);
if ("index" in history) {
let tabIndex = history.index - 1;
TextAndScrollData.updateFrame(history.entries[tabIndex],
content,
docShell.isAppTab,
{includePrivateData: includePrivateData});
}
return history;
},
collectSessionStorage: function () {
return SessionStorage.serialize(docShell);
},
collectDocShellCapabilities: function () {
return DocShellCapabilities.collect(docShell);
},
collectPageStyle: function () {
return PageStyle.collect(docShell);
},
};
let ProgressListener = {
init: function() {
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
@ -140,4 +182,5 @@ let ProgressListener = {
EventListener.init();
MessageListener.init();
SyncHandler.init();
ProgressListener.init();

View File

@ -65,7 +65,11 @@ const MESSAGES = [
// The content script tells us that a new page just started loading in a
// browser.
"SessionStore:loadStart"
"SessionStore:loadStart",
// The content script gives us a reference to an object that performs
// synchronous collection of session data.
"SessionStore:setupSyncHandler"
];
// These are tab events that we listen to.
@ -602,6 +606,9 @@ let SessionStoreInternal = {
case "SessionStore:loadStart":
TabStateCache.delete(browser);
break;
case "SessionStore:setupSyncHandler":
TabState.setSyncHandler(browser, aMessage.objects.handler);
break;
default:
debug("received unknown message '" + aMessage.name + "'");
break;
@ -620,17 +627,23 @@ let SessionStoreInternal = {
return;
var win = aEvent.currentTarget.ownerDocument.defaultView;
let browser;
switch (aEvent.type) {
case "load":
// If __SS_restore_data is set, then we need to restore the document
// (form data, scrolling, etc.). This will only happen when a tab is
// first restored.
let browser = aEvent.currentTarget;
browser = aEvent.currentTarget;
TabStateCache.delete(browser);
if (browser.__SS_restore_data)
this.restoreDocument(win, browser, aEvent);
this.onTabLoad(win, browser);
break;
case "SwapDocShells":
browser = aEvent.currentTarget;
let otherBrowser = aEvent.detail;
TabState.onSwapDocShells(browser, otherBrowser);
break;
case "TabOpen":
this.onTabAdd(win, aEvent.originalTarget);
break;
@ -1203,10 +1216,14 @@ let SessionStoreInternal = {
onTabAdd: function ssi_onTabAdd(aWindow, aTab, aNoNotification) {
let browser = aTab.linkedBrowser;
browser.addEventListener("load", this, true);
browser.addEventListener("SwapDocShells", this, true);
let mm = browser.messageManager;
MESSAGES.forEach(msg => mm.addMessageListener(msg, this));
// Load the frame script after registering listeners.
mm.loadFrameScript("chrome://browser/content/content-sessionStore.js", false);
if (!aNoNotification) {
this.saveStateDelayed(aWindow);
}
@ -1226,6 +1243,7 @@ let SessionStoreInternal = {
onTabRemove: function ssi_onTabRemove(aWindow, aTab, aNoNotification) {
let browser = aTab.linkedBrowser;
browser.removeEventListener("load", this, true);
browser.removeEventListener("SwapDocShells", this, true);
let mm = browser.messageManager;
MESSAGES.forEach(msg => mm.removeMessageListener(msg, this));
@ -4208,6 +4226,47 @@ let TabState = {
// their promises when collecting tab data asynchronously.
_pendingCollections: new WeakMap(),
// A map (xul:browser -> handler) that maps a tab to the
// synchronous collection handler object for that tab.
// See SyncHandler in content-sessionStore.js.
_syncHandlers: new WeakMap(),
/**
* Install the sync handler object from a given tab.
*/
setSyncHandler: function (browser, handler) {
this._syncHandlers.set(browser, handler);
},
/**
* When a docshell swap happens, a xul:browser element will be
* associated with a different content-sessionStore.js script
* global. In this case, the sync handler for the element needs to
* be swapped just like the docshell.
*/
onSwapDocShells: function (browser, otherBrowser) {
// Make sure that one or the other of these has a sync handler,
// and let it be |browser|.
if (!this._syncHandlers.has(browser)) {
[browser, otherBrowser] = [otherBrowser, browser];
if (!this._syncHandlers.has(browser)) {
return;
}
}
// At this point, browser is guaranteed to have a sync handler,
// although otherBrowser may not. Perform the swap.
let handler = this._syncHandlers.get(browser);
if (this._syncHandlers.has(otherBrowser)) {
let otherHandler = this._syncHandlers.get(otherBrowser);
this._syncHandlers.set(browser, otherHandler);
this._syncHandlers.set(otherHandler, handler);
} else {
this._syncHandlers.set(otherBrowser, handler);
this._syncHandlers.delete(browser);
}
},
/**
* Collect data related to a single tab, asynchronously.
*
@ -4226,11 +4285,10 @@ let TabState = {
return Promise.resolve(TabStateCache.get(tab));
}
// If the tab hasn't been restored yet, just return the data we
// have saved for it.
let browser = tab.linkedBrowser;
if (!browser.currentURI || (browser.__SS_data && browser.__SS_tabStillLoading)) {
let tabData = new TabData(this._collectBaseTabData(tab));
// If the tab was recently added, or if it's being restored, we
// just collect basic data about it and skip the cache.
if (!this._tabNeedsExtraCollection(tab)) {
let tabData = this._collectBaseTabData(tab);
return Promise.resolve(tabData);
}
@ -4248,10 +4306,7 @@ let TabState = {
let pageStyle = yield Messenger.send(tab, "SessionStore:collectPageStyle");
// Collect basic tab data, without session history and storage.
let options = {omitSessionHistory: true,
omitSessionStorage: true,
omitDocShellCapabilities: true};
let tabData = this._collectBaseTabData(tab, options);
let tabData = this._collectBaseTabData(tab);
// Apply collected data.
tabData.entries = history.entries;
@ -4308,8 +4363,9 @@ let TabState = {
return TabStateCache.get(tab);
}
let tabData = this._collectBaseTabData(tab);
if (this._updateTextAndScrollDataForTab(tab, tabData)) {
let tabData = this._collectSyncUncached(tab);
if (this._tabCachingAllowed(tab)) {
TabStateCache.set(tab, tabData);
}
@ -4335,34 +4391,142 @@ let TabState = {
* up-to-date.
*/
clone: function (tab) {
let options = { includePrivateData: true };
let tabData = this._collectBaseTabData(tab, options);
this._updateTextAndScrollDataForTab(tab, tabData, options);
return this._collectSyncUncached(tab, {includePrivateData: true});
},
/**
* Synchronously collect all session data for a tab. The
* TabStateCache is not consulted, and the resulting data is not put
* in the cache.
*/
_collectSyncUncached: function (tab, options = {}) {
// Collect basic tab data, without session history and storage.
let tabData = this._collectBaseTabData(tab);
// If we don't need any other data, return what we have.
if (!this._tabNeedsExtraCollection(tab)) {
return tabData;
}
// In multiprocess Firefox, there is a small window of time after
// tab creation when we haven't received a sync handler object. In
// this case the tab shouldn't have any history or cookie data, so we
// just return the base data already collected.
if (!this._syncHandlers.has(tab.linkedBrowser)) {
return tabData;
}
let syncHandler = this._syncHandlers.get(tab.linkedBrowser);
let includePrivateData = options && options.includePrivateData;
let history, storage, disallow, pageStyle;
try {
history = syncHandler.collectSessionHistory(includePrivateData);
storage = syncHandler.collectSessionStorage();
disallow = syncHandler.collectDocShellCapabilities();
pageStyle = syncHandler.collectPageStyle();
} catch (e) {
// This may happen if the tab has crashed.
Cu.reportError(e);
return tabData;
}
tabData.entries = history.entries;
if ("index" in history) {
tabData.index = history.index;
}
if (Object.keys(storage).length) {
tabData.storage = storage;
}
if (disallow.length > 0) {
tabData.disallow = disallow.join(",");
}
if (pageStyle) {
tabData.pageStyle = pageStyle;
}
return tabData;
},
/*
* Returns true if the xul:tab element is newly added (i.e., if it's
* showing about:blank with no history).
*/
_tabIsNew: function (tab) {
let browser = tab.linkedBrowser;
return (!browser || !browser.currentURI);
},
/*
* Returns true if the xul:tab element is in the process of being
* restored.
*/
_tabIsRestoring: function (tab) {
let browser = tab.linkedBrowser;
return (browser.__SS_data && browser.__SS_tabStillLoading);
},
/**
* This function returns true if we need to collect history, page
* style, and text and scroll data from the tab. Normally we do. The
* cases when we don't are:
* 1. the tab is about:blank with no history, or
* 2. the tab is waiting to be restored.
*
* @param tab A xul:tab element.
* @returns True if the tab is in the process of being restored.
*/
_tabNeedsExtraCollection: function (tab) {
if (this._tabIsNew(tab)) {
// Tab is about:blank with no history.
return false;
}
if (this._tabIsRestoring(tab)) {
// Tab is waiting to be restored.
return false;
}
// Otherwise we need the extra data.
return true;
},
/*
* Returns true if we should cache the tabData for the given the
* xul:tab element.
*/
_tabCachingAllowed: function (tab) {
if (this._tabIsNew(tab)) {
// No point in caching data for newly created tabs.
return false;
}
if (this._tabIsRestoring(tab)) {
// If the tab is being restored, we just return the data being
// restored. This data may be incomplete (if supplied by
// setBrowserState, for example), so we don't want to cache it.
return false;
}
return true;
},
/**
* Collects basic tab data for a given tab.
*
* @param tab
* tabbrowser tab
* @param options
* An object that will be passed to session history and session
* storage data collection methods.
* {omitSessionHistory: true} to skip collecting session history data
* {omitSessionStorage: true} to skip collecting session storage data
* {omitDocShellCapabilities: true} to skip collecting docShell allow* attributes
*
* The omit* options have been introduced to enable us collecting
* those parts of the tab data asynchronously. We will request basic
* tabData without the parts to omit and fill those holes later when
* the content script has responded.
*
* @returns {object} An object with the basic data for this tab.
*/
_collectBaseTabData: function (tab, options = {}) {
_collectBaseTabData: function (tab) {
let tabData = {entries: [], lastAccessed: tab.lastAccessed };
let browser = tab.linkedBrowser;
if (!browser || !browser.currentURI) {
// can happen when calling this function right after .addTab()
return tabData;
@ -4386,11 +4550,6 @@ let TabState = {
return tabData;
}
// Collection session history data.
if (!options || !options.omitSessionHistory) {
this._collectTabHistory(tab, tabData, options);
}
// If there is a userTypedValue set, then either the user has typed something
// in the URL bar, or a new tab was opened with a URI to load. userTypedClear
// is used to indicate whether the tab was in some sort of loading state with
@ -4409,14 +4568,6 @@ let TabState = {
delete tabData.pinned;
tabData.hidden = tab.hidden;
if (!options || !options.omitDocShellCapabilities) {
let disallow = DocShellCapabilities.collect(browser.docShell);
if (disallow.length > 0)
tabData.disallow = disallow.join(",");
else if (tabData.disallow)
delete tabData.disallow;
}
// Save tab attributes.
tabData.attributes = TabAttributes.get(tab);
@ -4429,105 +4580,8 @@ let TabState = {
else if (tabData.extData)
delete tabData.extData;
// Collect DOMSessionStorage data.
if (!options || !options.omitSessionStorage) {
this._collectTabSessionStorage(tab, tabData, options);
}
return tabData;
},
/**
* Collects session history data for a given tab.
*
* @param tab
* tabbrowser tab
* @param tabData
* An object that the session history data will be added to.
* @param options
* {includePrivateData: true} to always include private data
*/
_collectTabHistory: function (tab, tabData, options = {}) {
let includePrivateData = options && options.includePrivateData;
let docShell = tab.linkedBrowser.docShell;
if (docShell instanceof Ci.nsIDocShell) {
let history = SessionHistory.read(docShell, includePrivateData);
tabData.entries = history.entries;
// For blank tabs without any history entries,
// there will not be an 'index' property.
if ("index" in history) {
tabData.index = history.index;
}
}
},
/**
* Collects session history data for a given tab.
*
* @param tab
* tabbrowser tab
* @param tabData
* An object that the session storage data will be added to.
* @param options
* {includePrivateData: true} to always include private data
*/
_collectTabSessionStorage: function (tab, tabData, options = {}) {
let includePrivateData = options && options.includePrivateData;
let docShell = tab.linkedBrowser.docShell;
if (docShell instanceof Ci.nsIDocShell) {
let storageData = SessionStorage.serialize(docShell, includePrivateData)
if (Object.keys(storageData).length) {
tabData.storage = storageData;
}
}
},
/**
* Go through all frames and store the current scroll positions
* and innerHTML content of WYSIWYG editors
*
* @param tab
* tabbrowser tab
* @param tabData
* tabData object to add the information to
* @param options
* An optional object that may contain the following field:
* - includePrivateData: always return privacy sensitive data
* (use with care)
* @return false if data should not be cached because the tab
* has not been fully initialized yet.
*/
_updateTextAndScrollDataForTab: function (tab, tabData, options = null) {
let includePrivateData = options && options.includePrivateData;
let window = tab.ownerDocument.defaultView;
let browser = tab.linkedBrowser;
// we shouldn't update data for incompletely initialized tabs
if (!browser.currentURI
|| (browser.__SS_data && browser.__SS_tabStillLoading)) {
return false;
}
let tabIndex = (tabData.index || tabData.entries.length) - 1;
// entry data needn't exist for tabs just initialized with an incomplete session state
if (!tabData.entries[tabIndex]) {
return false;
}
let selectedPageStyle = PageStyle.collect(browser.docShell);
if (selectedPageStyle) {
tabData.pageStyle = selectedPageStyle;
}
TextAndScrollData.updateFrame(tabData.entries[tabIndex],
browser.contentWindow,
!!tabData.pinned,
{includePrivateData: includePrivateData});
return true;
},
};
// The state from the previous session (after restoring pinned tabs). This

View File

@ -0,0 +1,347 @@
/* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "LoadMonitor.h"
#include "nsString.h"
#include "prlog.h"
#include "prtime.h"
#include "prinrval.h"
#include "prsystem.h"
#include "nsString.h"
#include "nsThreadUtils.h"
#include "nsReadableUtils.h"
#include "nsNetUtil.h"
#include "nsILineInputStream.h"
#include "nsIObserverService.h"
#include "nsIServiceManager.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Util.h"
#include "mozilla/Services.h"
#include "mozilla/Preferences.h"
#if defined(ANDROID) || defined(LINUX) || defined(XP_MACOSX)
#include <sys/time.h>
#include <sys/resource.h>
#endif
// NSPR_LOG_MODULES=LoadMonitor:5
PRLogModuleInfo *gLoadMonitorLog = nullptr;
#if defined(PR_LOGGING)
#define LOG(args) PR_LOG(gLoadMonitorLog, PR_LOG_DEBUG, args)
#define LOG_ENABLED() PR_LOG_TEST(gLoadMonitorLog, 4)
#define LOG_MANY_ENABLED() PR_LOG_TEST(gLoadMonitorLog, 5)
#else
#define LOG(args)
#define LOG_ENABLED() (false)
#define LOG_MANY_ENABLED() (false)
#endif
using namespace mozilla;
// Update the system load every x milliseconds
static const int kLoadUpdateInterval = 1000;
NS_IMPL_ISUPPORTS1(LoadMonitor, nsIObserver)
LoadMonitor::LoadMonitor()
: mLock("LoadMonitor.mLock"),
mCondVar(mLock, "LoadMonitor.mCondVar"),
mShutdownPending(false),
mLoadInfoThread(nullptr),
mSystemLoad(0.0f),
mProcessLoad(0.0f)
{
}
LoadMonitor::~LoadMonitor()
{
Shutdown();
}
NS_IMETHODIMP
LoadMonitor::Observe(nsISupports* /* aSubject */,
const char* aTopic,
const PRUnichar* /* aData */)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
MOZ_ASSERT(!strcmp("xpcom-shutdown-threads", aTopic), "Bad topic!");
Shutdown();
return NS_OK;
}
class LoadMonitorAddObserver : public nsRunnable
{
public:
LoadMonitorAddObserver(nsRefPtr<LoadMonitor> loadMonitor)
{
mLoadMonitor = loadMonitor;
}
NS_IMETHOD Run()
{
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (!observerService)
return NS_ERROR_FAILURE;
nsresult rv = observerService->AddObserver(mLoadMonitor, "xpcom-shutdown-threads", false);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
private:
nsRefPtr<LoadMonitor> mLoadMonitor;
};
class LoadMonitorRemoveObserver : public nsRunnable
{
public:
LoadMonitorRemoveObserver(nsRefPtr<LoadMonitor> loadMonitor)
{
mLoadMonitor = loadMonitor;
}
NS_IMETHOD Run()
{
// remove xpcom shutdown observer
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (observerService)
observerService->RemoveObserver(mLoadMonitor, "xpcom-shutdown-threads");
return NS_OK;
}
private:
nsRefPtr<LoadMonitor> mLoadMonitor;
};
void LoadMonitor::Shutdown()
{
MutexAutoLock lock(mLock);
if (mLoadInfoThread) {
mShutdownPending = true;
mCondVar.Notify();
mLoadInfoThread = nullptr;
nsRefPtr<LoadMonitorRemoveObserver> remObsRunner = new LoadMonitorRemoveObserver(this);
if (!NS_IsMainThread()) {
NS_DispatchToMainThread(remObsRunner, NS_DISPATCH_NORMAL);
} else {
remObsRunner->Run();
}
}
}
class LoadStats
{
public:
LoadStats() :
mPrevTotalTimes(0),
mPrevCpuTimes(0),
mPrevLoad(0) {};
double GetLoad() { return (double)mPrevLoad; };
uint64_t mPrevTotalTimes;
uint64_t mPrevCpuTimes;
float mPrevLoad; // Previous load value.
};
class LoadInfo : public mozilla::RefCounted<LoadInfo>
{
public:
double GetSystemLoad() { return mSystemLoad.GetLoad(); };
double GetProcessLoad() { return mProcessLoad.GetLoad(); };
nsresult UpdateSystemLoad();
nsresult UpdateProcessLoad();
private:
void UpdateCpuLoad(uint64_t current_total_times,
uint64_t current_cpu_times,
LoadStats* loadStat);
LoadStats mSystemLoad;
LoadStats mProcessLoad;
};
void LoadInfo::UpdateCpuLoad(uint64_t current_total_times,
uint64_t current_cpu_times,
LoadStats *loadStat) {
float result = 0.0f;
if (current_total_times < loadStat->mPrevTotalTimes ||
current_cpu_times < loadStat->mPrevCpuTimes) {
//LOG(("Current total: %lld old total: %lld", current_total_times, loadStat->mPrevTotalTimes));
//LOG(("Current cpu: %lld old cpu: %lld", current_cpu_times, loadStat->mPrevCpuTimes));
LOG(("Inconsistent time values are passed. ignored"));
} else {
const uint64_t cpu_diff = current_cpu_times - loadStat->mPrevCpuTimes;
const uint64_t total_diff = current_total_times - loadStat->mPrevTotalTimes;
if (total_diff > 0) {
result = (float)cpu_diff / (float)total_diff;
loadStat->mPrevLoad = result;
}
}
loadStat->mPrevTotalTimes = current_total_times;
loadStat->mPrevCpuTimes = current_cpu_times;
}
nsresult LoadInfo::UpdateSystemLoad()
{
#if defined(LINUX) || defined(ANDROID)
nsCOMPtr<nsIFile> procStatFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
procStatFile->InitWithPath(NS_LITERAL_STRING("/proc/stat"));
nsCOMPtr<nsIInputStream> fileInputStream;
nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream),
procStatFile);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsILineInputStream> lineInputStream = do_QueryInterface(fileInputStream, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString buffer;
bool isMore = true;
lineInputStream->ReadLine(buffer, &isMore);
uint64_t user;
uint64_t nice;
uint64_t system;
uint64_t idle;
if (sscanf(buffer.get(), "cpu %Lu %Lu %Lu %Lu",
&user, &nice,
&system, &idle) != 4) {
LOG(("Error parsing /proc/stat"));
return NS_ERROR_FAILURE;
}
const uint64_t cpu_times = nice + system + user;
const uint64_t total_times = cpu_times + idle;
UpdateCpuLoad(total_times,
cpu_times * PR_GetNumberOfProcessors(),
&mSystemLoad);
return NS_OK;
#else
// Not implemented
return NS_OK;
#endif
}
nsresult LoadInfo::UpdateProcessLoad() {
#if defined(LINUX) || defined(ANDROID)
struct timeval tv;
gettimeofday(&tv, NULL);
const uint64_t total_times = tv.tv_sec * PR_USEC_PER_SEC + tv.tv_usec;
rusage usage;
if (getrusage(RUSAGE_SELF, &usage) < 0) {
LOG(("getrusage failed"));
return NS_ERROR_FAILURE;
}
const uint64_t cpu_times =
(usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) * PR_USEC_PER_SEC +
usage.ru_utime.tv_usec + usage.ru_stime.tv_usec;
UpdateCpuLoad(total_times,
cpu_times,
&mProcessLoad);
#endif // defined(LINUX) || defined(ANDROID)
return NS_OK;
}
class LoadInfoCollectRunner : public nsRunnable
{
public:
LoadInfoCollectRunner(nsRefPtr<LoadMonitor> loadMonitor)
{
mLoadMonitor = loadMonitor;
mLoadInfo = new LoadInfo();
mLoadNoiseCounter = 0;
}
NS_IMETHOD Run()
{
MutexAutoLock lock(mLoadMonitor->mLock);
while (!mLoadMonitor->mShutdownPending) {
mLoadInfo->UpdateSystemLoad();
mLoadInfo->UpdateProcessLoad();
float sysLoad = mLoadInfo->GetSystemLoad();
float procLoad = mLoadInfo->GetProcessLoad();
if ((++mLoadNoiseCounter % (LOG_MANY_ENABLED() ? 1 : 10)) == 0) {
LOG(("System Load: %f Process Load: %f", sysLoad, procLoad));
mLoadNoiseCounter = 0;
}
mLoadMonitor->SetSystemLoad(sysLoad);
mLoadMonitor->SetProcessLoad(procLoad);
mLoadMonitor->mCondVar.Wait(PR_MillisecondsToInterval(kLoadUpdateInterval));
}
return NS_OK;
}
private:
RefPtr<LoadInfo> mLoadInfo;
nsRefPtr<LoadMonitor> mLoadMonitor;
int mLoadNoiseCounter;
};
void
LoadMonitor::SetProcessLoad(float load) {
mLock.AssertCurrentThreadOwns();
mProcessLoad = load;
}
void
LoadMonitor::SetSystemLoad(float load) {
mLock.AssertCurrentThreadOwns();
mSystemLoad = load;
}
float
LoadMonitor::GetProcessLoad() {
MutexAutoLock lock(mLock);
float load = mProcessLoad;
return load;
}
float
LoadMonitor::GetSystemLoad() {
MutexAutoLock lock(mLock);
float load = mSystemLoad;
return load;
}
nsresult
LoadMonitor::Init(nsRefPtr<LoadMonitor> &self)
{
if (!Preferences::GetBool("media.navigator.load_adapt", false)) {
return NS_OK;
}
#if defined(PR_LOGGING)
if (!gLoadMonitorLog)
gLoadMonitorLog = PR_NewLogModule("LoadMonitor");
LOG(("Initializing LoadMonitor"));
#endif
#if defined(ANDROID) || defined(LINUX)
nsRefPtr<LoadMonitorAddObserver> addObsRunner = new LoadMonitorAddObserver(self);
NS_DispatchToMainThread(addObsRunner, NS_DISPATCH_NORMAL);
NS_NewNamedThread("Sys Load Info", getter_AddRefs(mLoadInfoThread));
nsRefPtr<LoadInfoCollectRunner> runner = new LoadInfoCollectRunner(self);
mLoadInfoThread->Dispatch(runner, NS_DISPATCH_NORMAL);
#endif
return NS_OK;
}

View File

@ -0,0 +1,50 @@
/* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 _LOADMONITOR_H_
#define _LOADMONITOR_H_
#include "mozilla/Mutex.h"
#include "mozilla/CondVar.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Atomics.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsIThread.h"
#include "nsIObserver.h"
class LoadInfoUpdateRunner;
class LoadInfoCollectRunner;
class LoadMonitor MOZ_FINAL : public nsIObserver
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIOBSERVER
LoadMonitor();
~LoadMonitor();
nsresult Init(nsRefPtr<LoadMonitor> &self);
void Shutdown();
float GetSystemLoad();
float GetProcessLoad();
friend class LoadInfoCollectRunner;
private:
void SetProcessLoad(float load);
void SetSystemLoad(float load);
mozilla::Mutex mLock;
mozilla::CondVar mCondVar;
bool mShutdownPending;
nsCOMPtr<nsIThread> mLoadInfoThread;
float mSystemLoad;
float mProcessLoad;
};
#endif /* _LOADMONITOR_H_ */

View File

@ -55,6 +55,8 @@ MediaEngineWebRTC::MediaEngineWebRTC()
if (compMgr) {
compMgr->IsContractIDRegistered(NS_TABSOURCESERVICE_CONTRACTID, &mHasTabVideoSource);
}
mLoadMonitor = new LoadMonitor();
mLoadMonitor->Init(mLoadMonitor);
}
#endif
@ -359,6 +361,8 @@ MediaEngineWebRTC::Shutdown()
mVideoEngine = nullptr;
mVoiceEngine = nullptr;
mLoadMonitor->Shutdown();
}
}

View File

@ -26,6 +26,7 @@
#include "AudioSegment.h"
#include "StreamBuffer.h"
#include "MediaStreamGraph.h"
#include "LoadMonitor.h"
// WebRTC library includes follow
@ -356,6 +357,8 @@ public:
, mHasTabVideoSource(false)
{
AsyncLatencyLogger::Get(true)->AddRef();
mLoadMonitor = new LoadMonitor();
mLoadMonitor->Init(mLoadMonitor);
}
#else
MediaEngineWebRTC();
@ -402,6 +405,8 @@ private:
nsDOMCameraManager* mCameraManager;
uint64_t mWindowId;
#endif
nsRefPtr<LoadMonitor> mLoadMonitor;
};
}

View File

@ -14,8 +14,9 @@ EXPORTS += [
]
if CONFIG['MOZ_WEBRTC']:
EXPORTS += ['MediaEngineWebRTC.h']
EXPORTS += ['LoadMonitor.h', 'MediaEngineWebRTC.h']
SOURCES += [
'LoadMonitor.cpp',
'MediaEngineTabVideoSource.cpp',
'MediaEngineWebRTC.cpp',
'MediaEngineWebRTCAudio.cpp',

View File

@ -3688,13 +3688,13 @@ nsGlobalWindow::GetContent(JSContext* aCx, ErrorResult& aError)
return nullptr;
}
JS::Rooted<JS::Value> val(aCx);
JS::Rooted<JS::Value> val(aCx, JS::NullValue());
aError = treeOwner->GetContentWindow(aCx, val.address());
if (aError.Failed()) {
return nullptr;
}
return &val.toObject();
return val.toObjectOrNull();
}
already_AddRefed<nsIDOMWindow>

View File

@ -36,3 +36,4 @@ support-files =
[test_window_indexing.html]
[test_writable-replaceable.html]
[test_urlExceptions.html]
[test_openDialogChromeOnly.html]

View File

@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=931768
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 931768</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 931768 **/
try {
openDialog("chrome://browser/content/browser.xul");
ok(false, "Calling openDialog from unprivileged script should throw.");
} catch (e) {
// FIXME e should be a ReferenceError once we switch Window to new WebIDL bindings
ok(e.name == "SecurityError",
"openDialog shouldn't be callable to unprivileged script.");
todo(e instanceof ReferenceError,
"openDialog shouldn't be available to unprivileged script.");
}
</script>
</body>
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=931768">Mozilla Bug 931768</a>
<p id="display">
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

View File

@ -3,6 +3,8 @@ support-files =
DOMTestCase.js
activity-home.css
exclusions.js
# Timeouts on OS X (bug 921635)
skip-if = os == "mac"
[test_PIsetdatanomodificationallowederrEE.html]
[test_attrcreatedocumentfragment.html]

View File

@ -2,6 +2,8 @@
support-files =
DOMTestCase.js
exclusions.js
# Timeouts on OS X (bug 921635)
skip-if = os == "mac"
[test_attrgetownerelement01.html]
[test_attrgetownerelement02.html]

View File

@ -1,5 +1,7 @@
[DEFAULT]
support-files = DOMTestCase.js
# Timeouts on OS X (bug 921635)
skip-if = os == "mac"
[test_HTMLAnchorElement01.html]
[test_HTMLAnchorElement02.html]
@ -16,28 +18,16 @@ support-files = DOMTestCase.js
[test_HTMLAnchorElement13.html]
[test_HTMLAnchorElement14.html]
[test_HTMLAppletElement01.html]
# This and the below - timeouts on OS X (bug 921635)
skip-if = os == "mac"
[test_HTMLAppletElement02.html]
skip-if = os == "mac"
[test_HTMLAppletElement03.html]
skip-if = os == "mac"
[test_HTMLAppletElement04.html]
skip-if = os == "mac"
[test_HTMLAppletElement05.html]
skip-if = os == "mac"
[test_HTMLAppletElement06.html]
skip-if = os == "mac"
[test_HTMLAppletElement07.html]
skip-if = os == "mac"
[test_HTMLAppletElement08.html]
skip-if = os == "mac"
[test_HTMLAppletElement09.html]
skip-if = os == "mac"
[test_HTMLAppletElement10.html]
skip-if = os == "mac"
[test_HTMLAppletElement11.html]
skip-if = os == "mac"
[test_HTMLAreaElement01.html]
[test_HTMLAreaElement02.html]
[test_HTMLAreaElement03.html]

View File

@ -327,12 +327,12 @@ partial interface Window {
* arguments, plus any additional arguments are passed on as
* arguments on the dialog's window object (window.arguments).
*/
[Throws] WindowProxy? openDialog(optional DOMString url = "",
optional DOMString name = "",
optional DOMString options = "",
any... extraArguments);
[Throws, ChromeOnly] WindowProxy? openDialog(optional DOMString url = "",
optional DOMString name = "",
optional DOMString options = "",
any... extraArguments);
[Replaceable, Throws] readonly attribute object content;
[Replaceable, Throws] readonly attribute object? content;
};
Window implements TouchEventHandlers;

View File

@ -122,6 +122,12 @@ public:
return resultMatrix;
}
Matrix& operator*=(const Matrix &aMatrix)
{
Matrix resultMatrix = *this * aMatrix;
return *this = resultMatrix;
}
/* Returns true if the other matrix is fuzzy-equal to this matrix.
* Note that this isn't a cheap comparison!
*/
@ -159,6 +165,13 @@ public:
_31 == 0.0f && _32 == 0.0f;
}
/* Returns true if the matrix is singular.
*/
bool IsSingular() const
{
return Determinant() == 0;
}
GFX2D_API void NudgeToIntegers();
private:

View File

@ -445,9 +445,7 @@ ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
// This is derived from the code in
// gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
const gfx3DMatrix& rootTransform = GetRoot()->GetTransform();
CSSToLayerScale paintScale = metrics.mDevPixelsPerCSSPixel
/ LayerToLayoutDeviceScale(rootTransform.GetXScale(), rootTransform.GetYScale());
CSSToLayerScale paintScale = metrics.LayersPixelsPerCSSPixel();
const CSSRect& metricsDisplayPort =
(aDrawingCritical && !metrics.mCriticalDisplayPort.IsEmpty()) ?
metrics.mCriticalDisplayPort : metrics.mDisplayPort;

View File

@ -484,14 +484,8 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
&treeTransform,
scrollOffset);
const gfx3DMatrix& rootTransform = mLayerManager->GetRoot()->GetTransform();
const FrameMetrics& metrics = container->GetFrameMetrics();
// XXX We use rootTransform instead of metrics.mResolution here because on
// Fennec the resolution is set on the root layer rather than the scrollable layer.
// The SyncFrameMetrics call and the paintScale variable are used on Fennec only
// so it doesn't affect any other platforms. See bug 732971.
CSSToLayerScale paintScale = metrics.mDevPixelsPerCSSPixel
/ LayerToLayoutDeviceScale(rootTransform.GetXScale(), rootTransform.GetYScale());
CSSToLayerScale paintScale = metrics.LayersPixelsPerCSSPixel();
CSSRect displayPort(metrics.mCriticalDisplayPort.IsEmpty() ?
metrics.mDisplayPort : metrics.mCriticalDisplayPort);
LayerMargin fixedLayerMargins(0, 0, 0, 0);
@ -522,15 +516,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
// Apply resolution scaling to the old transform - the layer tree as it is
// doesn't have the necessary transform to display correctly.
#ifdef MOZ_WIDGET_ANDROID
// XXX We use rootTransform instead of the resolution on the individual layer's
// FrameMetrics on Fennec because the resolution is set on the root layer rather
// than the scrollable layer. See bug 732971. On non-Fennec we do the right thing.
LayoutDeviceToLayerScale resolution(1.0 / rootTransform.GetXScale(),
1.0 / rootTransform.GetYScale());
#else
LayoutDeviceToLayerScale resolution = metrics.mCumulativeResolution;
#endif
oldTransform.Scale(resolution.scale, resolution.scale, 1);
AlignFixedAndStickyLayers(aLayer, aLayer, oldTransform, fixedLayerMargins);
@ -542,7 +528,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
}
void
AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const LayoutDeviceToLayerScale& aResolution)
AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
{
LayerComposite* layerComposite = aLayer->AsLayerComposite();
ContainerLayer* container = aLayer->AsContainerLayer();
@ -555,7 +541,7 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const LayoutDev
gfx3DMatrix treeTransform;
CSSToLayerScale geckoZoom = metrics.mDevPixelsPerCSSPixel * aResolution;
CSSToLayerScale geckoZoom = metrics.LayersPixelsPerCSSPixel();
LayerIntPoint scrollOffsetLayerPixels = RoundedToInt(metrics.mScrollOffset * geckoZoom);
@ -606,9 +592,9 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const LayoutDev
// transformation we need to apply.
LayerToScreenScale zoomAdjust = userZoom / geckoZoom;
LayerIntPoint geckoScroll(0, 0);
LayerPoint geckoScroll(0, 0);
if (metrics.IsScrollable()) {
geckoScroll = scrollOffsetLayerPixels;
geckoScroll = metrics.mScrollOffset * geckoZoom;
}
LayerPoint translation = (userScroll / zoomAdjust) - geckoScroll;
@ -633,7 +619,7 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const LayoutDev
// Apply resolution scaling to the old transform - the layer tree as it is
// doesn't have the necessary transform to display correctly.
oldTransform.Scale(aResolution.scale, aResolution.scale, 1);
oldTransform.Scale(metrics.mResolution.scale, metrics.mResolution.scale, 1);
// Make sure that overscroll and under-zoom are represented in the old
// transform so that fixed position content moves and scales accordingly.
@ -706,18 +692,7 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame)
for (uint32_t i = 0; i < scrollableLayers.Length(); i++) {
if (scrollableLayers[i]) {
#ifdef MOZ_WIDGET_ANDROID
// XXX We use rootTransform instead of the resolution on the individual layer's
// FrameMetrics on Fennec because the resolution is set on the root layer rather
// than the scrollable layer. See bug 732971. On non-Fennec we do the right thing.
const gfx3DMatrix& rootTransform = root->GetTransform();
LayoutDeviceToLayerScale resolution(1.0 / rootTransform.GetXScale(),
1.0 / rootTransform.GetYScale());
#else
LayoutDeviceToLayerScale resolution =
scrollableLayers[i]->AsContainerLayer()->GetFrameMetrics().mCumulativeResolution;
#endif
TransformScrollableLayer(scrollableLayers[i], resolution);
TransformScrollableLayer(scrollableLayers[i]);
}
}
}

View File

@ -117,7 +117,7 @@ public:
bool IsFirstPaint() { return mIsFirstPaint; }
private:
void TransformScrollableLayer(Layer* aLayer, const LayoutDeviceToLayerScale& aResolution);
void TransformScrollableLayer(Layer* aLayer);
// Return true if an AsyncPanZoomController content transform was
// applied for |aLayer|. *aWantNextFrame is set to true if the
// controller wants another animation frame.

View File

@ -541,14 +541,10 @@ LayerManagerComposite::ComputeRenderIntegrity()
Layer* primaryScrollable = GetPrimaryScrollableLayer();
if (primaryScrollable) {
// This is derived from the code in
// gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
const gfx3DMatrix& rootTransform = root->GetTransform();
float devPixelRatioX = 1 / rootTransform.GetXScale();
float devPixelRatioY = 1 / rootTransform.GetYScale();
gfx3DMatrix transform = primaryScrollable->GetEffectiveTransform();
transform.ScalePost(devPixelRatioX, devPixelRatioY, 1);
// AsyncCompositionManager::TransformScrollableLayer
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
gfx3DMatrix transform = primaryScrollable->GetEffectiveTransform();
transform.ScalePost(metrics.mResolution.scale, metrics.mResolution.scale, 1);
// Clip the screen rect to the document bounds
gfxRect documentBounds =

View File

@ -264,15 +264,10 @@ ThebesLayerComposite::GetCompositionBounds()
parentMetrics.mCompositionBounds.width,
parentMetrics.mCompositionBounds.height);
// Calculate the scale transform applied to the root layer to determine
// the content resolution.
Layer* rootLayer = Manager()->GetRoot();
const gfx3DMatrix& rootTransform = rootLayer->GetTransform();
LayerToCSSScale scale(rootTransform.GetXScale(),
rootTransform.GetYScale());
const FrameMetrics& metrics = scrollableLayer->GetFrameMetrics();
LayerToCSSScale scale(1 / metrics.mResolution.scale);
// Get the content document bounds, in screen-space.
const FrameMetrics& metrics = scrollableLayer->GetFrameMetrics();
const LayerIntRect content = RoundedToInt(metrics.mScrollableRect / scale);
// !!! WTF. this code is just wrong. See bug 881451.
gfx::Point scrollOffset =

View File

@ -10,6 +10,7 @@
#include <sys/types.h> // for int32_t
#include "gfxContext.h" // for gfxContext
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/UserData.h" // for UserData, UserDataKey
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsBoundingMetrics.h" // for nsBoundingMetrics
@ -37,6 +38,7 @@ class nsRenderingContext
{
typedef mozilla::gfx::UserData UserData;
typedef mozilla::gfx::UserDataKey UserDataKey;
typedef mozilla::gfx::DrawTarget DrawTarget;
public:
nsRenderingContext() : mP2A(0.) {}
@ -49,6 +51,7 @@ public:
// These accessors will never return null.
gfxContext *ThebesContext() { return mThebes; }
DrawTarget *GetDrawTarget() { return mThebes->GetDrawTarget(); }
nsDeviceContext *DeviceContext() { return mDeviceContext; }
int32_t AppUnitsPerDevPixel() { return NSToIntRound(mP2A); }

View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
@font-face {
font-family: foo;
src: url(PigLatin_Plane15.ttf);
}
body {
font-family: foo;
font-size: 24px;
}
</style>
</head>
<body>
&#xf0050;&#xf0069;&#xf0067; &#xf004c;&#xf0061;&#xf0074;&#xf0069;&#xf006e;
</body>
</html>

Binary file not shown.

View File

@ -97,5 +97,6 @@ load 783041-3.html
load 783041-4.html
asserts-if(gtk2Widget,1) load 798853.html # bug 868792
asserts-if(winWidget,0-1) skip-if(B2G) load 815489.html
load 836225-1.html
load 839745-1.html
load 856784-1.html

View File

@ -1455,6 +1455,9 @@ gfxFontCache::gfxFontCache()
obs->AddObserver(new Observer, "memory-pressure", false);
}
#ifndef RELEASE_BUILD
// Currently disabled for release builds, due to unexplained crashes
// during expiration; see bug 717175 & 894798.
mWordCacheExpirationTimer = do_CreateInstance("@mozilla.org/timer;1");
if (mWordCacheExpirationTimer) {
mWordCacheExpirationTimer->
@ -1462,6 +1465,7 @@ gfxFontCache::gfxFontCache()
SHAPED_WORD_TIMEOUT_SECONDS * 1000,
nsITimer::TYPE_REPEATING_SLACK);
}
#endif
}
gfxFontCache::~gfxFontCache()

View File

@ -156,7 +156,7 @@ gfxPattern::GetPattern(DrawTarget *aTarget, Matrix *aPatternTransform)
if (!mPattern) {
mGfxPattern = new (mSurfacePattern.addr())
SurfacePattern(mSourceSurface, EXTEND_CLAMP, mTransform);
SurfacePattern(mSourceSurface, ToExtendMode(mExtend), mTransform);
return mGfxPattern;
}

View File

@ -3664,6 +3664,8 @@ class MRandom : public MNullaryInstruction
bool possiblyCalls() const {
return true;
}
void computeRange();
};
class MMathFunction
@ -3751,6 +3753,7 @@ class MMathFunction
|| function_ == ASin || function_ == ACos || function_ == Floor;
}
void trySpecializeFloat32();
void computeRange();
};
class MAdd : public MBinaryArithInstruction
@ -5258,6 +5261,7 @@ class MBoundsCheck
virtual AliasSet getAliasSet() const {
return AliasSet::None();
}
void computeRange();
};
// Bailout if index < minimum.
@ -5615,6 +5619,7 @@ class MArrayPush
AliasSet getAliasSet() const {
return AliasSet::Store(AliasSet::Element | AliasSet::ObjectFields);
}
void computeRange();
};
// Array.prototype.concat on two dense arrays.

View File

@ -1365,6 +1365,55 @@ MArgumentsLength::computeRange()
setRange(Range::NewUInt32Range(0, SNAPSHOT_MAX_NARGS));
}
void
MBoundsCheck::computeRange()
{
// Just transfer the incoming index range to the output. The length() is
// also interesting, but it is handled as a bailout check, and we're
// computing a pre-bailout range here.
setRange(new Range(index()));
}
void
MArrayPush::computeRange()
{
// MArrayPush returns the new array length.
setRange(Range::NewUInt32Range(0, UINT32_MAX));
}
void
MMathFunction::computeRange()
{
Range opRange(getOperand(0));
switch (function()) {
case Sin:
case Cos:
if (!opRange.canBeInfiniteOrNaN())
setRange(Range::NewDoubleRange(-1.0, 1.0));
break;
case Sign:
if (!opRange.canBeNaN()) {
// Note that Math.sign(-0) is -0, and we treat -0 as equal to 0.
int32_t lower = -1;
int32_t upper = 1;
if (opRange.hasInt32LowerBound() && opRange.lower() >= 0)
lower = 0;
if (opRange.hasInt32UpperBound() && opRange.upper() <= 0)
upper = 0;
setRange(Range::NewInt32Range(lower, upper));
}
break;
default:
break;
}
}
void
MRandom::computeRange()
{
setRange(Range::NewDoubleRange(0.0, 1.0));
}
///////////////////////////////////////////////////////////////////////////////
// Range Analysis
///////////////////////////////////////////////////////////////////////////////

View File

@ -67,6 +67,9 @@ class LUnbox : public LInstructionHelper<1, 2, 0>
const LAllocation *type() {
return getOperand(1);
}
const char *extraName() const {
return StringFromMIRType(mir()->type());
}
};
class LUnboxFloatingPoint : public LInstructionHelper<1, 2, 0>

View File

@ -55,6 +55,10 @@ class LUnbox : public LUnboxBase {
LUnbox(const LAllocation &input)
: LUnboxBase(input)
{ }
const char *extraName() const {
return StringFromMIRType(mir()->type());
}
};
class LUnboxFloatingPoint : public LUnboxBase {

View File

@ -68,6 +68,9 @@ class LUnbox : public LInstructionHelper<1, 2, 0>
const LAllocation *type() {
return getOperand(1);
}
const char *extraName() const {
return StringFromMIRType(mir()->type());
}
};
class LUnboxFloatingPoint : public LInstructionHelper<1, 2, 0>

View File

@ -4417,25 +4417,6 @@ JS::CanCompileOffThread(JSContext *cx, const CompileOptions &options)
if (cx->runtime()->activeGCInAtomsZone())
return false;
// Blacklist filenames which cause mysterious assertion failures in
// graphics code on OS X. These seem to tickle some preexisting race
// condition unrelated to off thread compilation. See bug 897655.
static const char *blacklist[] = {
#ifdef XP_MACOSX
"chrome://browser/content/places/editBookmarkOverlay.js",
"chrome://browser/content/nsContextMenu.js",
"chrome://browser/content/newtab/newTab.js",
"chrome://browser/content/places/browserPlacesViews.js",
#endif
nullptr
};
const char *filename = options.filename;
for (const char **ptest = blacklist; *ptest; ptest++) {
if (!strcmp(*ptest, filename))
return false;
}
return true;
#else
return false;

View File

@ -43,6 +43,7 @@ DECLARE_DISPLAY_ITEM_TYPE(PLUGIN_VIDEO)
DECLARE_DISPLAY_ITEM_TYPE(PRINT_PLUGIN)
DECLARE_DISPLAY_ITEM_TYPE(REMOTE)
DECLARE_DISPLAY_ITEM_TYPE(REMOTE_SHADOW)
DECLARE_DISPLAY_ITEM_TYPE(RESOLUTION)
DECLARE_DISPLAY_ITEM_TYPE(SCROLL_LAYER)
DECLARE_DISPLAY_ITEM_TYPE(SCROLL_INFO_LAYER)
DECLARE_DISPLAY_ITEM_TYPE(SELECTION_OVERLAY)

View File

@ -3308,6 +3308,35 @@ nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
return layer.forget();
}
nsDisplayResolution::nsDisplayResolution(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList,
uint32_t aFlags)
: nsDisplayOwnLayer(aBuilder, aFrame, aList, aFlags) {
MOZ_COUNT_CTOR(nsDisplayResolution);
}
#ifdef NS_BUILD_REFCNT_LOGGING
nsDisplayResolution::~nsDisplayResolution() {
MOZ_COUNT_DTOR(nsDisplayResolution);
}
#endif
already_AddRefed<Layer>
nsDisplayResolution::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerParameters& aContainerParameters) {
nsIPresShell* presShell = mFrame->PresContext()->PresShell();
nsDisplayItem::ContainerParameters containerParameters(
presShell->GetXResolution(), presShell->GetYResolution(), nsIntPoint(),
aContainerParameters);
nsRefPtr<Layer> layer = nsDisplayOwnLayer::BuildLayer(
aBuilder, aManager, containerParameters);
layer->SetPostScale(1.0f / presShell->GetXResolution(),
1.0f / presShell->GetYResolution());
return layer.forget();
}
nsDisplayFixedPosition::nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
nsIFrame* aFixedPosFrame,

View File

@ -2610,6 +2610,25 @@ private:
uint32_t mFlags;
};
/**
* A display item for subdocuments to capture the resolution from the presShell
* and ensure that it gets applied to all the right elements. This item creates
* a container layer.
*/
class nsDisplayResolution : public nsDisplayOwnLayer {
public:
nsDisplayResolution(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList, uint32_t aFlags);
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayResolution();
#endif
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerParameters& aContainerParameters) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("Resolution", TYPE_RESOLUTION)
};
/**
* A display item used to represent fixed position elements. This will ensure
* the contents gets its own layer, and that the built layer will have

View File

@ -372,8 +372,10 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
nsIScrollableFrame *sf = presShell->GetRootScrollFrameAsScrollable();
bool constructResolutionItem = subdocRootFrame &&
(presShell->GetXResolution() != 1.0 || presShell->GetYResolution() != 1.0);
bool constructZoomItem = subdocRootFrame && parentAPD != subdocAPD;
bool needsOwnLayer = constructZoomItem ||
bool needsOwnLayer = constructResolutionItem || constructZoomItem ||
presContext->IsRootContentDocument() || (sf && sf->IsScrollingActive());
nsDisplayList childItems;
@ -423,13 +425,25 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
}
// Generate a resolution and/or zoom item if needed. If one or both of those is
// created, we don't need to create a separate nsDisplayOwnLayer.
if (constructResolutionItem) {
nsDisplayResolution* resolutionItem =
new (aBuilder) nsDisplayResolution(aBuilder, subdocRootFrame, &childItems,
nsDisplayOwnLayer::GENERATE_SUBDOC_INVALIDATIONS);
childItems.AppendToTop(resolutionItem);
needsOwnLayer = false;
}
if (constructZoomItem) {
nsDisplayZoom* zoomItem =
new (aBuilder) nsDisplayZoom(aBuilder, subdocRootFrame, &childItems,
subdocAPD, parentAPD,
nsDisplayOwnLayer::GENERATE_SUBDOC_INVALIDATIONS);
childItems.AppendToTop(zoomItem);
} else if (needsOwnLayer) {
needsOwnLayer = false;
}
if (needsOwnLayer) {
// We always want top level content documents to be in their own layer.
nsDisplayOwnLayer* layerItem = new (aBuilder) nsDisplayOwnLayer(
aBuilder, subdocRootFrame ? subdocRootFrame : this,

View File

@ -41,7 +41,6 @@ MOCHITEST_FILES = \
test_bug424627.html \
test_bug438840.html \
test_bug448860.html \
test_bug448987.html \
file_bug448987.html \
file_bug448987_ref.html \
file_bug448987_notref.html \
@ -108,6 +107,9 @@ MOCHITEST_FILES = \
$(srcdir)/../../base/tests/enableTestPlugin.js \
$(NULL)
# Disabled for being too sensitive to timing changes (bug 932296)
# test_bug448987.html \
# Disable the caret movement by word test on Linux because the shortcut keys
# are defined in system level. So, it depends on the environment.
ifndef MOZ_WIDGET_GTK

View File

@ -25,15 +25,15 @@ endif
ifdef MOZ_VORBIS
SHARED_LIBRARY_LIBS += \
$(DEPTH)/media/libvorbis/lib/$(LIB_PREFIX)vorbis.$(LIB_SUFFIX) \
$(DEPTH)/media/libogg/src/$(LIB_PREFIX)ogg.$(LIB_SUFFIX) \
$(DEPTH)/media/libvorbis/$(LIB_PREFIX)vorbis.$(LIB_SUFFIX) \
$(DEPTH)/media/libogg/$(LIB_PREFIX)ogg.$(LIB_SUFFIX) \
$(NULL)
endif
ifdef MOZ_TREMOR
SHARED_LIBRARY_LIBS += \
$(DEPTH)/media/libtremor/lib/$(LIB_PREFIX)tremor.$(LIB_SUFFIX) \
$(DEPTH)/media/libogg/src/$(LIB_PREFIX)ogg.$(LIB_SUFFIX) \
$(DEPTH)/media/libogg/$(LIB_PREFIX)ogg.$(LIB_SUFFIX) \
$(NULL)
endif

View File

@ -8,7 +8,7 @@ fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated&&!azur
== continuation-positioned-inline-1.html continuation-positioned-inline-ref.html
== continuation-positioned-inline-2.html continuation-positioned-inline-ref.html
== scrollframe-1.html scrollframe-1-ref.html
skip-if(B2G) fuzzy-if(Android,9,39) == scrollframe-2.html scrollframe-2-ref.html #bug 756530
skip-if(B2G) fuzzy-if(Android,9,185) == scrollframe-2.html scrollframe-2-ref.html #bug 756530
fuzzy-if(gtk2Widget,1,8) == select-1.html select-1-ref.html
fuzzy-if(gtk2Widget,1,8) == select-1-dynamic.html select-1-ref.html
== select-2.html select-2-ref.html

View File

@ -300,7 +300,7 @@ skip-if(B2G) == 273681-1.html 273681-1-ref.html
== 283686-2.html 283686-2-ref.html
== 283686-3.html about:blank
== 289384-1.xhtml 289384-ref.xhtml
random-if(d2d) fuzzy-if(Android&&AndroidVersion>=15,8,200) HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 578114 for the d2d failures
random-if(d2d) fuzzy-if(Android&&AndroidVersion>=15,8,1439) HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 578114 for the d2d failures
== 290129-1.html 290129-1-ref.html
skip-if(B2G) == 291078-1.html 291078-1-ref.html
== 291078-2.html 291078-2-ref.html

View File

@ -1,6 +1,6 @@
== 166591-dynamic-1.html 166591-dynamic-1-ref.html
fuzzy-if(Android&&AndroidVersion>=15,8,50) == 336736-1a.html 336736-1-ref.html
== 336736-1b.html 336736-1-ref.html
fuzzy-if(Android&&AndroidVersion>=15,8,50) == 336736-1b.html 336736-1-ref.html
== 406073-1.html 406073-1-ref.html
== 407016-2.html 407016-2-ref.html
fuzzy-if(Android&&AndroidVersion>=15,8,220) == 413027-4.html 413027-4-ref.html

View File

@ -48,4 +48,4 @@ fails == column-contain-1a.html column-contain-1-ref.html
== column-contain-1b.html column-contain-1-ref.html
== block-in-inline-1.html block-in-inline-1-ref.html
fuzzy-if(Android,8,1533) == block-in-inline-2.html block-in-inline-2-ref.html
fuzzy-if(Android,8,306) fuzzy-if(OSX==10.8,1,11) == block-in-inline-3.html block-in-inline-3-ref.html
fuzzy-if(Android,8,630) fuzzy-if(OSX==10.8,1,11) == block-in-inline-3.html block-in-inline-3-ref.html

View File

@ -22,8 +22,8 @@ fails-if(Android) == rotatex-perspective-3a.html rotatex-perspective-3-ref.html
skip-if(B2G) == preserve3d-4a.html green-rect.html
fuzzy-if(Android&&AndroidVersion>=15,4,300) == preserve3d-5a.html preserve3d-5-ref.html
== scale3d-z.html scalez-1-ref.html
fuzzy-if(winWidget,102,580) fuzzy-if(d2d,143,681) fails-if(Android&&AndroidVersion<15) fuzzy-if(OSX==10.8,145,752) == scale3d-all.html scale3d-1-ref.html # subpixel AA
fuzzy-if(winWidget,102,580) fuzzy-if(d2d,143,681) fails-if(Android&&AndroidVersion<15) fuzzy-if(OSX==10.8,145,752) == scale3d-all-separate.html scale3d-1-ref.html # subpixel AA
fuzzy-if(winWidget,102,580) fuzzy-if(d2d,143,681) fails-if(Android) fuzzy-if(OSX==10.8,145,752) == scale3d-all.html scale3d-1-ref.html # subpixel AA
fuzzy-if(winWidget,102,580) fuzzy-if(d2d,143,681) fails-if(Android) fuzzy-if(OSX==10.8,145,752) == scale3d-all-separate.html scale3d-1-ref.html # subpixel AA
== scale3d-xz.html scale3d-1-ref.html
== translatez-1a.html translatez-1-ref.html
!= translatez-1b.html translatez-1-ref.html

View File

@ -65,7 +65,7 @@ public:
// 290770). See bug 290852 for foreignObject complications.
NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint)=0;
// Get bounds in our gfxContext's coordinates space (in app units)
// Get bounds in our nsSVGOuterSVGFrame's coordinates space (in app units)
NS_IMETHOD_(nsRect) GetCoveredRegion()=0;
// Called on SVG child frames (except NS_FRAME_IS_NONDISPLAY frames)

View File

@ -7,10 +7,12 @@
#include "nsSVGPatternFrame.h"
// Keep others in (case-insensitive) order:
#include "gfx2DGlue.h"
#include "gfxContext.h"
#include "gfxMatrix.h"
#include "gfxPattern.h"
#include "gfxPlatform.h"
#include "mozilla/gfx/2D.h"
#include "nsContentUtils.h"
#include "nsGkAtoms.h"
#include "nsISVGChildFrame.h"
@ -26,6 +28,7 @@
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::gfx;
//----------------------------------------------------------------------
// Helper classes
@ -140,6 +143,23 @@ nsSVGPatternFrame::GetCanvasTM(uint32_t aFor, nsIFrame* aTransformRoot)
// Helper functions
// -------------------------------------------------------------------------
/** Calculate the maximum expansion of a matrix */
static float
MaxExpansion(const Matrix &aMatrix)
{
// maximum expansion derivation from
// http://lists.cairographics.org/archives/cairo/2004-October/001980.html
// and also implemented in cairo_matrix_transformed_circle_major_axis
double a = aMatrix._11;
double b = aMatrix._12;
double c = aMatrix._21;
double d = aMatrix._22;
double f = (a * a + b * b + c * c + d * d) / 2;
double g = (a * a + b * b - c * c - d * d) / 2;
double h = a * c + b * d;
return sqrt(f + sqrt(g * g + h * h));
}
// The SVG specification says that the 'patternContentUnits' attribute "has no effect if
// attribute viewBox is specified". We still need to include a bbox scale
// if the viewBox is specified and _patternUnits_ is set to or defaults to
@ -161,7 +181,7 @@ GetPatternMatrix(uint16_t aPatternUnits,
const gfxMatrix &patternTransform,
const gfxRect &bbox,
const gfxRect &callerBBox,
const gfxMatrix &callerCTM)
const Matrix &callerCTM)
{
// We really want the pattern matrix to handle translations
gfxFloat minx = bbox.X();
@ -172,7 +192,7 @@ GetPatternMatrix(uint16_t aPatternUnits,
miny += callerBBox.Y();
}
float scale = 1.0f / nsSVGUtils::MaxExpansion(callerCTM);
float scale = 1.0f / MaxExpansion(callerCTM);
gfxMatrix patternMatrix = patternTransform;
patternMatrix.Scale(scale, scale);
patternMatrix.Translate(gfxPoint(minx, miny));
@ -186,7 +206,7 @@ GetTargetGeometry(gfxRect *aBBox,
uint16_t aPatternContentUnits,
uint16_t aPatternUnits,
nsIFrame *aTarget,
const gfxMatrix &aContextMatrix,
const Matrix &aContextMatrix,
const gfxRect *aOverrideBounds)
{
*aBBox = aOverrideBounds ? *aOverrideBounds : nsSVGUtils::GetBBox(aTarget);
@ -199,7 +219,7 @@ GetTargetGeometry(gfxRect *aBBox,
// OK, now fix up the bounding box to reflect user coordinates
// We handle device unit scaling in pattern matrix
float scale = nsSVGUtils::MaxExpansion(aContextMatrix);
float scale = MaxExpansion(aContextMatrix);
if (scale <= 0) {
return NS_ERROR_FAILURE;
}
@ -267,14 +287,14 @@ nsSVGPatternFrame::PaintPattern(gfxASurface** surface,
viewBox,
patternContentUnits, patternUnits,
aSource,
aContextMatrix,
ToMatrix(aContextMatrix),
aOverrideBounds)))
return NS_ERROR_FAILURE;
// Construct the CTM that we will provide to our children when we
// render them into the tile.
gfxMatrix ctm = ConstructCTM(viewBox, patternContentUnits, patternUnits,
callerBBox, aContextMatrix, aSource);
callerBBox, ToMatrix(aContextMatrix), aSource);
if (ctm.IsSingular()) {
return NS_ERROR_FAILURE;
}
@ -291,7 +311,7 @@ nsSVGPatternFrame::PaintPattern(gfxASurface** surface,
// Get the bounding box of the pattern. This will be used to determine
// the size of the surface, and will also be used to define the bounding
// box for the pattern tile.
gfxRect bbox = GetPatternRect(patternUnits, callerBBox, aContextMatrix, aSource);
gfxRect bbox = GetPatternRect(patternUnits, callerBBox, ToMatrix(aContextMatrix), aSource);
// Get the pattern transform
gfxMatrix patternTransform = GetPatternTransform();
@ -304,7 +324,7 @@ nsSVGPatternFrame::PaintPattern(gfxASurface** surface,
// Get the transformation matrix that we will hand to the renderer's pattern
// routine.
*patternMatrix = GetPatternMatrix(patternUnits, patternTransform,
bbox, callerBBox, aContextMatrix);
bbox, callerBBox, ToMatrix(aContextMatrix));
if (patternMatrix->IsSingular()) {
return NS_ERROR_FAILURE;
}
@ -574,7 +594,7 @@ nsSVGPatternFrame::GetReferencedPatternIfNotInUse()
gfxRect
nsSVGPatternFrame::GetPatternRect(uint16_t aPatternUnits,
const gfxRect &aTargetBBox,
const gfxMatrix &aTargetCTM,
const Matrix &aTargetCTM,
nsIFrame *aTarget)
{
// We need to initialize our box
@ -593,7 +613,7 @@ nsSVGPatternFrame::GetPatternRect(uint16_t aPatternUnits,
width = nsSVGUtils::ObjectSpace(aTargetBBox, tmpWidth);
height = nsSVGUtils::ObjectSpace(aTargetBBox, tmpHeight);
} else {
float scale = nsSVGUtils::MaxExpansion(aTargetCTM);
float scale = MaxExpansion(aTargetCTM);
x = nsSVGUtils::UserSpace(aTarget, tmpX) * scale;
y = nsSVGUtils::UserSpace(aTarget, tmpY) * scale;
width = nsSVGUtils::UserSpace(aTarget, tmpWidth) * scale;
@ -608,7 +628,7 @@ nsSVGPatternFrame::ConstructCTM(const nsSVGViewBox& aViewBox,
uint16_t aPatternContentUnits,
uint16_t aPatternUnits,
const gfxRect &callerBBox,
const gfxMatrix &callerCTM,
const Matrix &callerCTM,
nsIFrame *aTarget)
{
gfxMatrix tCTM;
@ -622,7 +642,7 @@ nsSVGPatternFrame::ConstructCTM(const nsSVGViewBox& aViewBox,
if (targetContent->IsSVG()) {
ctx = static_cast<nsSVGElement*>(targetContent)->GetCtx();
}
float scale = nsSVGUtils::MaxExpansion(callerCTM);
float scale = MaxExpansion(callerCTM);
tCTM.Scale(scale, scale);
}

View File

@ -8,6 +8,7 @@
#include "mozilla/Attributes.h"
#include "gfxMatrix.h"
#include "mozilla/gfx/2D.h"
#include "nsSVGPaintServerFrame.h"
class gfxASurface;
@ -30,6 +31,8 @@ typedef nsSVGPaintServerFrame nsSVGPatternFrameBase;
*/
class nsSVGPatternFrame : public nsSVGPatternFrameBase
{
typedef mozilla::gfx::Matrix Matrix;
public:
NS_DECL_FRAMEARENA_HELPERS
@ -117,13 +120,13 @@ protected:
nsIFrame* GetPatternFirstChild();
gfxRect GetPatternRect(uint16_t aPatternUnits,
const gfxRect &bbox,
const gfxMatrix &callerCTM,
const Matrix &callerCTM,
nsIFrame *aTarget);
gfxMatrix ConstructCTM(const nsSVGViewBox& aViewBox,
uint16_t aPatternContentUnits,
uint16_t aPatternUnits,
const gfxRect &callerBBox,
const gfxMatrix &callerCTM,
const Matrix &callerCTM,
nsIFrame *aTarget);
private:

View File

@ -1295,22 +1295,6 @@ nsSVGUtils::CanOptimizeOpacity(nsIFrame *aFrame)
return false;
}
float
nsSVGUtils::MaxExpansion(const gfxMatrix &aMatrix)
{
// maximum expansion derivation from
// http://lists.cairographics.org/archives/cairo/2004-October/001980.html
// and also implemented in cairo_matrix_transformed_circle_major_axis
double a = aMatrix.xx;
double b = aMatrix.yx;
double c = aMatrix.xy;
double d = aMatrix.yy;
double f = (a * a + b * b + c * c + d * d) / 2;
double g = (a * a + b * b - c * c - d * d) / 2;
double h = a * c + b * d;
return sqrt(f + sqrt(g * g + h * h));
}
gfxMatrix
nsSVGUtils::AdjustMatrixForUnits(const gfxMatrix &aMatrix,
nsSVGEnum *aUnits,

View File

@ -507,10 +507,6 @@ public:
static bool
CanOptimizeOpacity(nsIFrame *aFrame);
/* Calculate the maximum expansion of a matrix */
static float
MaxExpansion(const gfxMatrix &aMatrix);
/**
* Take the CTM to userspace for an element, and adjust it to a CTM to its
* object bounding box space if aUnits is SVG_UNIT_TYPE_OBJECTBOUNDINGBOX.

View File

@ -1,7 +1,7 @@
The source from this directory was copied from the libogg subversion
repository using the update.sh script. The only changes made were
those applied by update.sh and the addition/upate of Makefile.in files
for the Mozilla build system.
those applied by update.sh and the addition/update of moz.build and
Makefile.in files for the Mozilla build system.
The svn revision number used was r17287.

View File

@ -1,10 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
DIRS += ['ogg']
MODULE = 'ogg'

View File

@ -1,12 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
EXPORTS.ogg += [
'config_types.h',
'ogg.h',
'os_types.h',
]

View File

@ -4,7 +4,24 @@
# 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/.
DIRS += ['include', 'src']
MODULE = 'ogg'
EXPORTS.ogg += [
'include/ogg/config_types.h',
'include/ogg/ogg.h',
'include/ogg/os_types.h',
]
LIBRARY_NAME = 'ogg'
SOURCES += [
'src/ogg_bitwise.c',
'src/ogg_framing.c',
]
MSVC_ENABLE_PGO = True
FORCE_STATIC_LIB = True
if CONFIG['OS_TARGET'] == 'WINNT':
NO_VISIBILITY_FLAGS = True

View File

@ -1,4 +0,0 @@
# 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/.

View File

@ -1,14 +0,0 @@
diff -r f33a75da59bd media/libvorbis/lib/os.h
--- a/media/libvorbis/lib/os.h Sun Dec 07 19:31:40 2008 -0800
+++ b/media/libvorbis/lib/os.h Mon Dec 15 16:26:36 2008 +0800
@@ -25,6 +25,10 @@
#include <ogg/os_types.h>
#include "misc.h"
+
+#ifdef SOLARIS
+#define HAVE_ALLOCA_H
+#endif
#ifndef _V_IFDEFJAIL_H_
# define _V_IFDEFJAIL_H_

View File

@ -1,10 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
DIRS += ['vorbis']
MODULE = 'vorbis'

View File

@ -1,10 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
EXPORTS.vorbis += [
'codec.h',
]

View File

@ -1,8 +0,0 @@
# 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/.
ifeq ($(OS_ARCH),AIX)
DEFINES += -Dalloca=__alloca
endif

View File

@ -1,39 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
MODULE = 'vorbis'
LIBRARY_NAME = 'vorbis'
SOURCES += [
'vorbis_analysis.c',
'vorbis_bitrate.c',
'vorbis_block.c',
'vorbis_codebook.c',
'vorbis_envelope.c',
'vorbis_floor0.c',
'vorbis_floor1.c',
'vorbis_info.c',
'vorbis_lookup.c',
'vorbis_lpc.c',
'vorbis_lsp.c',
'vorbis_mapping0.c',
'vorbis_mdct.c',
'vorbis_psy.c',
'vorbis_registry.c',
'vorbis_res0.c',
'vorbis_sharedbook.c',
'vorbis_smallft.c',
'vorbis_synthesis.c',
'vorbis_window.c',
]
MSVC_ENABLE_PGO = True
FORCE_STATIC_LIB = True
if CONFIG['OS_TARGET'] == 'WINNT':
NO_VISIBILITY_FLAGS = True

View File

@ -4,7 +4,46 @@
# 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/.
DIRS += ['include', 'lib']
MODULE = 'vorbis'
EXPORTS.vorbis += [
'include/vorbis/codec.h',
]
LIBRARY_NAME = 'vorbis'
SOURCES += [
'lib/vorbis_analysis.c',
'lib/vorbis_bitrate.c',
'lib/vorbis_block.c',
'lib/vorbis_codebook.c',
'lib/vorbis_envelope.c',
'lib/vorbis_floor0.c',
'lib/vorbis_floor1.c',
'lib/vorbis_info.c',
'lib/vorbis_lookup.c',
'lib/vorbis_lpc.c',
'lib/vorbis_lsp.c',
'lib/vorbis_mapping0.c',
'lib/vorbis_mdct.c',
'lib/vorbis_psy.c',
'lib/vorbis_registry.c',
'lib/vorbis_res0.c',
'lib/vorbis_sharedbook.c',
'lib/vorbis_smallft.c',
'lib/vorbis_synthesis.c',
'lib/vorbis_window.c',
]
if CONFIG['OS_ARCH'] == 'AIX':
DEFINES['alloca'] = '__alloca'
if CONFIG['OS_ARCH'] == 'SunOS':
DEFINES['HAVE_ALLOCA_H'] = True
MSVC_ENABLE_PGO = True
FORCE_STATIC_LIB = True
if CONFIG['OS_TARGET'] == 'WINNT':
NO_VISIBILITY_FLAGS = True

View File

@ -47,4 +47,4 @@ cp $1/COPYING ./COPYING
cp $1/README ./README
cp $1/AUTHORS ./AUTHORS
patch -p3 < ./alloca.diff
# Add any patches against upstream here.

View File

@ -15,6 +15,7 @@ EXPORTS.mtransport += [
'../runnable_utils.h',
'../runnable_utils_generated.h',
'../sigslot.h',
'../simpletokenbucket.h',
'../transportflow.h',
'../transportlayer.h',
'../transportlayerdtls.h',

View File

@ -13,6 +13,7 @@ mtransport_lcppsrcs = [
'nriceresolver.cpp',
'nriceresolverfake.cpp',
'nrinterfaceprioritizer.cpp',
'simpletokenbucket.cpp',
'transportflow.cpp',
'transportlayer.cpp',
'transportlayerdtls.cpp',

View File

@ -0,0 +1,62 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
/* Original author: bcampen@mozilla.com */
#include "simpletokenbucket.h"
#include <stdint.h>
#include "prinrval.h"
namespace mozilla {
SimpleTokenBucket::SimpleTokenBucket(size_t bucket_size,
size_t tokens_per_second) :
max_tokens_(bucket_size),
num_tokens_(bucket_size),
tokens_per_second_(tokens_per_second),
last_time_tokens_added_(PR_IntervalNow()) {
}
size_t SimpleTokenBucket::getTokens(size_t num_requested_tokens) {
// Only fill if there isn't enough to satisfy the request.
// If we get tokens so seldomly that we are able to roll the timer all
// the way around its range, then we lose that entire range of time
// for token accumulation. Probably not the end of the world.
if (num_requested_tokens > num_tokens_) {
PRIntervalTime now = PR_IntervalNow();
// If we roll over the max, since everything in this calculation is the same
// unsigned type, this will still yield the elapsed time (unless we've
// wrapped more than once).
PRIntervalTime elapsed_ticks = now - last_time_tokens_added_;
uint32_t elapsed_milli_sec = PR_IntervalToMilliseconds(elapsed_ticks);
size_t tokens_to_add = (elapsed_milli_sec * tokens_per_second_)/1000;
// Only update our timestamp if we added some tokens
// TODO:(bcampen@mozilla.com) Should we attempt to "save" leftover time?
if (tokens_to_add) {
num_tokens_ += tokens_to_add;
if (num_tokens_ > max_tokens_) {
num_tokens_ = max_tokens_;
}
last_time_tokens_added_ = now;
}
if (num_requested_tokens > num_tokens_) {
return num_tokens_;
}
}
num_tokens_ -= num_requested_tokens;
return num_requested_tokens;
}
} // namespace mozilla

View File

@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
/* Original author: bcampen@mozilla.com */
/*
* This file defines a dirt-simple token bucket class.
*/
#ifndef simpletokenbucket_h__
#define simpletokenbucket_h__
#include <stdint.h>
#include "prinrval.h"
#include "m_cpp_utils.h"
namespace mozilla {
class SimpleTokenBucket {
public:
/*
* Create a SimpleTokenBucket with a given maximum size and
* token replenishment rate.
* (eg; if you want a maximum rate of 5 per second over a 7 second
* period, call SimpleTokenBucket b(5*7, 5);)
*/
SimpleTokenBucket(size_t bucket_size, size_t tokens_per_second);
/*
* Attempt to acquire a number of tokens. If successful, returns
* |num_tokens|, otherwise returns the number of tokens currently
* in the bucket.
* Note: To get the number of tokens in the bucket, pass something
* like UINT32_MAX.
*/
size_t getTokens(size_t num_tokens);
protected: // Allow testing to touch these.
uint64_t max_tokens_;
uint64_t num_tokens_;
size_t tokens_per_second_;
PRIntervalTime last_time_tokens_added_;
DISALLOW_COPY_ASSIGN(SimpleTokenBucket);
};
} // namespace mozilla
#endif // simpletokenbucket_h__

View File

@ -11,6 +11,7 @@ if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
'ice_unittest.cpp',
'nrappkit_unittest.cpp',
'runnable_utils_unittest.cpp',
'simpletokenbucket_unittest.cpp',
'sockettransportservice_unittest.cpp',
'TestSyncRunnable.cpp',
'transport_unittests.cpp',

View File

@ -0,0 +1,115 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
/* Original author: bcampen@mozilla.com */
#include "simpletokenbucket.h"
#define GTEST_HAS_RTTI 0
#include "gtest/gtest.h"
#include "gtest_utils.h"
using mozilla::SimpleTokenBucket;
class TestSimpleTokenBucket : public SimpleTokenBucket {
public:
TestSimpleTokenBucket(size_t bucketSize, size_t tokensPerSecond) :
SimpleTokenBucket(bucketSize, tokensPerSecond) {
}
void fastForward(int32_t timeMilliSeconds) {
if (timeMilliSeconds >= 0) {
last_time_tokens_added_ -= PR_MillisecondsToInterval(timeMilliSeconds);
} else {
last_time_tokens_added_ += PR_MillisecondsToInterval(-timeMilliSeconds);
}
}
};
TEST(SimpleTokenBucketTest, TestConstruct) {
TestSimpleTokenBucket b(10, 1);
}
TEST(SimpleTokenBucketTest, TestGet) {
TestSimpleTokenBucket b(10, 1);
ASSERT_EQ(5U, b.getTokens(5));
}
TEST(SimpleTokenBucketTest, TestGetAll) {
TestSimpleTokenBucket b(10, 1);
ASSERT_EQ(10U, b.getTokens(10));
}
TEST(SimpleTokenBucketTest, TestGetInsufficient) {
TestSimpleTokenBucket b(10, 1);
ASSERT_EQ(5U, b.getTokens(5));
ASSERT_EQ(5U, b.getTokens(6));
}
TEST(SimpleTokenBucketTest, TestGetBucketCount) {
TestSimpleTokenBucket b(10, 1);
ASSERT_EQ(10U, b.getTokens(UINT32_MAX));
ASSERT_EQ(5U, b.getTokens(5));
ASSERT_EQ(5U, b.getTokens(UINT32_MAX));
}
TEST(SimpleTokenBucketTest, TestTokenRefill) {
TestSimpleTokenBucket b(10, 1);
ASSERT_EQ(5U, b.getTokens(5));
b.fastForward(1000);
ASSERT_EQ(6U, b.getTokens(6));
}
TEST(SimpleTokenBucketTest, TestNoTimeWasted) {
// Makes sure that when the time elapsed is insufficient to add any
// tokens to the bucket, the internal timestamp that is used in this
// calculation is not updated (ie; two subsequent 0.5 second elapsed times
// counts as a full second)
TestSimpleTokenBucket b(10, 1);
ASSERT_EQ(5U, b.getTokens(5));
b.fastForward(500);
ASSERT_EQ(5U, b.getTokens(6));
b.fastForward(500);
ASSERT_EQ(6U, b.getTokens(6));
}
TEST(SimpleTokenBucketTest, TestNegativeTime) {
TestSimpleTokenBucket b(10, 1);
b.fastForward(-1000);
// Make sure we don't end up with an invalid number of tokens, but otherwise
// permit anything.
ASSERT_GT(11U, b.getTokens(100));
}
TEST(SimpleTokenBucketTest, TestEmptyBucket) {
TestSimpleTokenBucket b(10, 1);
ASSERT_EQ(10U, b.getTokens(10));
ASSERT_EQ(0U, b.getTokens(10));
}
TEST(SimpleTokenBucketTest, TestEmptyThenFillBucket) {
TestSimpleTokenBucket b(10, 1);
ASSERT_EQ(10U, b.getTokens(10));
ASSERT_EQ(0U, b.getTokens(1));
b.fastForward(50000);
ASSERT_EQ(10U, b.getTokens(10));
}
TEST(SimpleTokenBucketTest, TestNoOverflow) {
TestSimpleTokenBucket b(10, 1);
ASSERT_EQ(10U, b.getTokens(10));
ASSERT_EQ(0U, b.getTokens(1));
b.fastForward(50000);
ASSERT_EQ(10U, b.getTokens(11));
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
int rv = RUN_ALL_TESTS();
return rv;
}

View File

@ -470,7 +470,7 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
// Always abort updates if the resolution has changed. There's no use
// in drawing at the incorrect resolution.
if (!FloatUtils.fuzzyEquals(resolution, viewportMetrics.zoomFactor)) {
Log.d(LOGTAG, "Aborting draw due to resolution change");
Log.d(LOGTAG, "Aborting draw due to resolution change: " + resolution + " != " + viewportMetrics.zoomFactor);
mProgressiveUpdateData.abort = true;
return mProgressiveUpdateData;
}

View File

@ -2,11 +2,13 @@
package @ANDROID_PACKAGE_NAME@.tests;
import @ANDROID_PACKAGE_NAME@.*;
import com.jayway.android.robotium.solo.Condition;
import com.jayway.android.robotium.solo.Solo;
import android.widget.ListView;
import android.graphics.Rect;
import android.view.View;
import java.util.ArrayList;
import android.view.ViewGroup;
import android.widget.ListView;
import java.util.ArrayList;
import org.json.JSONException;
import org.json.JSONObject;
@ -17,7 +19,8 @@ import org.json.JSONObject;
* and that the reading list is properly populated after adding or removing reader items
*/
public class testReaderMode extends AboutHomeTest {
int height,width;
static final int EVENT_CLEAR_DELAY_MS = 3000;
static final int READER_ICON_MAX_WAIT_MS = 15000;
@Override
protected int getTestType() {
@ -33,26 +36,27 @@ public class testReaderMode extends AboutHomeTest {
Actions.RepeatedEventExpecter paintExpecter;
ListView list;
View child;
View readerIcon;
String textUrl = getAbsoluteUrl(StringHelper.ROBOCOP_TEXT_PAGE_URL);
String devType = mDevice.type;
int childNo;
int eventClearDelay = 3000;
int height;
int width;
contentEventExpecter = mActions.expectGeckoEvent("DOMContentLoaded");
loadAndPaint(textUrl);
contentEventExpecter.blockForEvent();
contentEventExpecter.unregisterListener();
// Add the page to the Reading List using log click on the reader icon
// Add the page to the Reading List using long click on the reader icon
readerIcon = getReaderIcon();
contentReaderAddedExpecter = mActions.expectGeckoEvent("Reader:Added");
mSolo.clickLongOnView(getReaderIcon());
mSolo.clickLongOnView(readerIcon);
String eventData = contentReaderAddedExpecter.blockForEventData();
isAdded(eventData);
contentReaderAddedExpecter.unregisterListener();
// Try to add the page to the Reading List using log click on the reader icon a second time
// Try to add the page to the Reading List using long click on the reader icon a second time
readerIcon = getReaderIcon();
contentReaderAddedExpecter = mActions.expectGeckoEvent("Reader:Added");
mSolo.clickLongOnView(getReaderIcon());
mSolo.clickLongOnView(readerIcon);
eventData = contentReaderAddedExpecter.blockForEventData();
isAdded(eventData);
contentReaderAddedExpecter.unregisterListener();
@ -60,8 +64,9 @@ public class testReaderMode extends AboutHomeTest {
// Waiting for the favicon since is the last element loaded usually
faviconExpecter = mActions.expectGeckoEvent("Reader:FaviconRequest");
contentPageShowExpecter = mActions.expectGeckoEvent("Content:PageShow");
readerIcon = getReaderIcon();
paintExpecter = mActions.expectPaint();
mSolo.clickOnView(getReaderIcon());
mSolo.clickOnView(readerIcon);
// Changing devices orientation to be sure that all devices are in portrait when will access the reader toolbar
mSolo.setActivityOrientation(Solo.PORTRAIT);
@ -69,7 +74,7 @@ public class testReaderMode extends AboutHomeTest {
faviconExpecter.unregisterListener();
contentPageShowExpecter.blockForEvent();
contentPageShowExpecter.unregisterListener();
paintExpecter.blockUntilClear(eventClearDelay);
paintExpecter.blockUntilClear(EVENT_CLEAR_DELAY_MS);
paintExpecter.unregisterListener();
verifyPageTitle("Robocop Text Page");
@ -150,10 +155,27 @@ public class testReaderMode extends AboutHomeTest {
// Get the reader icon method
protected View getReaderIcon() {
View pageActionLayout = mSolo.getView(0x7f070025);
ArrayList<String> pageActionLayoutChilds = new ArrayList();
View actionLayoutItem = pageActionLayout;
ViewGroup actionLayoutEntry = (ViewGroup)actionLayoutItem;
final ViewGroup actionLayoutEntry = (ViewGroup)pageActionLayout;
View icon = actionLayoutEntry.getChildAt(1);
if (icon == null || icon.getVisibility() != View.VISIBLE) {
// wait for the view to be visible, otherwise it may not respond
// to clicks -- see bug 927578
mAsserter.dumpLog("reader icon not visible -- waiting for visibility");
Condition visibilityCondition = new Condition() {
@Override
public boolean isSatisfied() {
View conditionIcon = actionLayoutEntry.getChildAt(1);
if (conditionIcon == null ||
conditionIcon.getVisibility() != View.VISIBLE)
return false;
return true;
}
};
waitForCondition(visibilityCondition, READER_ICON_MAX_WAIT_MS);
icon = actionLayoutEntry.getChildAt(1);
mAsserter.ok(icon != null, "checking reader icon view", "reader icon view not null");
mAsserter.ok(icon.getVisibility() == View.VISIBLE, "checking reader icon visible", "reader icon visible");
}
return icon;
}

View File

@ -2911,7 +2911,7 @@ Tab.prototype = {
// we should never be drawing background tabs at resolutions other than the user-
// visible zoom. for foreground tabs, however, if we are drawing at some other
// resolution, we need to set the resolution as specified.
let cwu = window.top.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
if (BrowserApp.selectedTab == this) {
if (resolution != this._drawZoom) {
this._drawZoom = resolution;
@ -2930,8 +2930,6 @@ Tab.prototype = {
let geckoScrollY = this.browser.contentWindow.scrollY;
aDisplayPort = this._dirtiestHackEverToWorkAroundGeckoRounding(aDisplayPort, geckoScrollX, geckoScrollY);
cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
let displayPort = {
x: (aDisplayPort.left / resolution) - geckoScrollX,
y: (aDisplayPort.top / resolution) - geckoScrollY,
@ -3193,7 +3191,7 @@ Tab.prototype = {
if (aForce || !fuzzyEquals(aZoom, this._zoom)) {
this._zoom = aZoom;
if (BrowserApp.selectedTab == this) {
let cwu = window.top.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
this._drawZoom = aZoom;
cwu.setResolution(aZoom / window.devicePixelRatio, aZoom / window.devicePixelRatio);
}

View File

@ -232,6 +232,7 @@ pref("media.navigator.video.default_fps",30);
pref("media.navigator.video.default_minfps",10);
pref("media.navigator.video.max_fs", 0); // unrestricted
pref("media.navigator.video.max_fr", 0); // unrestricted
pref("media.navigator.load_adapt", false);
pref("media.peerconnection.enabled", true);
pref("media.navigator.permission.disabled", false);
pref("media.peerconnection.default_iceservers", "[{\"url\": \"stun:stun.services.mozilla.com\"}]");

View File

@ -65,6 +65,7 @@ nsGtkIMModule* nsGtkIMModule::sLastFocusedModule = nullptr;
nsGtkIMModule::nsGtkIMModule(nsWindow* aOwnerWindow) :
mOwnerWindow(aOwnerWindow), mLastFocusedWindow(nullptr),
mContext(nullptr),
mSimpleContext(nullptr),
mDummyContext(nullptr),
mCompositionStart(UINT32_MAX), mProcessingKeyEvent(nullptr),
mCompositionState(eCompositionState_NotComposing),
@ -114,6 +115,28 @@ nsGtkIMModule::Init()
G_CALLBACK(nsGtkIMModule::OnEndCompositionCallback),
this);
// Simple context
mSimpleContext = gtk_im_context_simple_new();
gtk_im_context_set_client_window(mSimpleContext, gdkWindow);
g_signal_connect(mSimpleContext, "preedit_changed",
G_CALLBACK(&nsGtkIMModule::OnChangeCompositionCallback),
this);
g_signal_connect(mSimpleContext, "retrieve_surrounding",
G_CALLBACK(&nsGtkIMModule::OnRetrieveSurroundingCallback),
this);
g_signal_connect(mSimpleContext, "delete_surrounding",
G_CALLBACK(&nsGtkIMModule::OnDeleteSurroundingCallback),
this);
g_signal_connect(mSimpleContext, "commit",
G_CALLBACK(&nsGtkIMModule::OnCommitCompositionCallback),
this);
g_signal_connect(mSimpleContext, "preedit_start",
G_CALLBACK(nsGtkIMModule::OnStartCompositionCallback),
this);
g_signal_connect(mSimpleContext, "preedit_end",
G_CALLBACK(nsGtkIMModule::OnEndCompositionCallback),
this);
// Dummy context
mDummyContext = gtk_im_multicontext_new();
gtk_im_context_set_client_window(mDummyContext, gdkWindow);
@ -168,6 +191,12 @@ nsGtkIMModule::OnDestroyWindow(nsWindow* aWindow)
mContext = nullptr;
}
if (mSimpleContext) {
gtk_im_context_set_client_window(mSimpleContext, nullptr);
g_object_unref(mSimpleContext);
mSimpleContext = nullptr;
}
if (mDummyContext) {
// mContext and mDummyContext have the same slaveType and signal_data
// so no need for another workaround_gtk_im_display_closed.
@ -548,7 +577,9 @@ nsGtkIMModule::GetContext()
if (IsEnabled()) {
return mContext;
}
if (mInputContext.mIMEState.mEnabled == IMEState::PASSWORD) {
return mSimpleContext;
}
return mDummyContext;
}
@ -556,7 +587,6 @@ bool
nsGtkIMModule::IsEnabled()
{
return mInputContext.mIMEState.mEnabled == IMEState::ENABLED ||
mInputContext.mIMEState.mEnabled == IMEState::PASSWORD ||
mInputContext.mIMEState.mEnabled == IMEState::PLUGIN;
}