Merge the last PGO-green inbound changeset to m-c.

This commit is contained in:
Ryan VanderMeulen 2012-11-07 20:08:02 -05:00
commit 12c86d585c
273 changed files with 38088 additions and 1548 deletions

View File

@ -18,6 +18,13 @@ XPCOMUtils.defineLazyServiceGetter(Services, "fm",
"@mozilla.org/focus-manager;1",
"nsIFocusManager");
XPCOMUtils.defineLazyGetter(this, "domWindowUtils", function () {
return content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
});
const FOCUS_CHANGE_DELAY = 20;
let HTMLInputElement = Ci.nsIDOMHTMLInputElement;
let HTMLTextAreaElement = Ci.nsIDOMHTMLTextAreaElement;
let HTMLSelectElement = Ci.nsIDOMHTMLSelectElement;
@ -28,7 +35,6 @@ let FormAssistant = {
init: function fa_init() {
addEventListener("focus", this, true, false);
addEventListener("blur", this, true, false);
addEventListener("keypress", this, true, false);
addEventListener("resize", this, true, false);
addMessageListener("Forms:Select:Choice", this);
addMessageListener("Forms:Input:Value", this);
@ -37,6 +43,10 @@ let FormAssistant = {
Services.obs.addObserver(this, "xpcom-shutdown", false);
},
ignoredInputTypes: new Set([
'button', 'file', 'checkbox', 'radio', 'reset', 'submit', 'image'
]),
isKeyboardOpened: false,
selectionStart: 0,
selectionEnd: 0,
@ -80,43 +90,24 @@ let FormAssistant = {
switch (evt.type) {
case "focus":
if (this.isKeyboardOpened)
if (this.isTextInputElement(target) && this.isIMEDisabled())
return;
let ignore = {
button: true,
file: true,
checkbox: true,
radio: true,
reset: true,
submit: true,
image: true
};
if (target instanceof HTMLSelectElement) {
content.setTimeout(function showIMEForSelect() {
sendAsyncMessage("Forms:Input", getJSON(target));
});
this.setFocusedElement(target);
} else if (target instanceof HTMLOptionElement &&
target.parentNode instanceof HTMLSelectElement) {
target = target.parentNode;
content.setTimeout(function showIMEForSelect() {
sendAsyncMessage("Forms:Input", getJSON(target));
});
this.setFocusedElement(target);
} else if ((target instanceof HTMLInputElement && !ignore[target.type]) ||
target instanceof HTMLTextAreaElement) {
this.isKeyboardOpened = this.tryShowIme(target);
this.setFocusedElement(target);
if (target && this.isFocusableElement(target)) {
if (this.blurTimeout) {
this.blurTimeout = content.clearTimeout(this.blurTimeout);
this.handleIMEStateDisabled();
}
this.handleIMEStateEnabled(target);
}
break;
case "blur":
if (this.focusedElement) {
sendAsyncMessage("Forms:Input", { "type": "blur" });
this.setFocusedElement(null);
this.isKeyboardOpened = false;
this.blurTimeout = content.setTimeout(function () {
this.blurTimeout = null;
this.handleIMEStateDisabled();
}.bind(this), FOCUS_CHANGE_DELAY);
}
break;
@ -146,17 +137,6 @@ let FormAssistant = {
this.focusedElement.scrollIntoView(false);
}
break;
case "keypress":
if (evt.keyCode != evt.DOM_VK_ESCAPE || !this.isKeyboardOpened)
return;
sendAsyncMessage("Forms:Input", { "type": "blur" });
this.isKeyboardOpened = false;
evt.preventDefault();
evt.stopPropagation();
break;
}
},
@ -213,21 +193,17 @@ let FormAssistant = {
observe: function fa_observe(subject, topic, data) {
switch (topic) {
case "ime-enabled-state-changed":
let isOpen = this.isKeyboardOpened;
let shouldOpen = parseInt(data);
if (shouldOpen && !isOpen) {
let target = Services.fm.focusedElement;
let target = Services.fm.focusedElement;
if (!target || !this.isTextInputElement(target))
return;
if (!target || !this.tryShowIme(target)) {
this.setFocusedElement(null);
return;
} else {
this.setFocusedElement(target);
}
} else if (!shouldOpen && isOpen) {
sendAsyncMessage("Forms:Input", { "type": "blur" });
if (shouldOpen) {
if (!this.focusedElement && this.isFocusableElement(target))
this.handleIMEStateEnabled(target);
} else if (this._focusedElement == target) {
this.handleIMEStateDisabled();
}
this.isKeyboardOpened = shouldOpen;
break;
case "xpcom-shutdown":
@ -239,11 +215,54 @@ let FormAssistant = {
}
},
tryShowIme: function(element) {
if (!element) {
return;
}
isIMEDisabled: function fa_isIMEDisabled() {
let disabled = false;
try {
disabled = domWindowUtils.IMEStatus == domWindowUtils.IME_STATUS_DISABLED;
} catch (e) {}
return disabled;
},
handleIMEStateEnabled: function fa_handleIMEStateEnabled(target) {
if (this.isKeyboardOpened)
return;
if (target instanceof HTMLOptionElement)
target = target.parentNode;
let kbOpened = this.tryShowIme(target);
if (this.isTextInputElement(target))
this.isKeyboardOpened = kbOpened;
this.setFocusedElement(target);
},
handleIMEStateDisabled: function fa_handleIMEStateDisabled() {
sendAsyncMessage("Forms:Input", { "type": "blur" });
this.isKeyboardOpened = false;
this.setFocusedElement(null);
},
isFocusableElement: function fa_isFocusableElement(element) {
if (element instanceof HTMLSelectElement ||
element instanceof HTMLTextAreaElement)
return true;
if (element instanceof HTMLOptionElement &&
element.parentNode instanceof HTMLSelectElement)
return true;
return (element instanceof HTMLInputElement &&
!this.ignoredInputTypes.has(element.type));
},
isTextInputElement: function fa_isTextInputElement(element) {
return element instanceof HTMLInputElement ||
element instanceof HTMLTextAreaElement;
},
tryShowIme: function(element) {
// FIXME/bug 729623: work around apparent bug in the IME manager
// in gecko.
let readonly = element.getAttribute("readonly");

View File

@ -131,6 +131,11 @@ SettingsListener.observe('language.current', 'en-US', function(value) {
}
});
});
SettingsListener.observe('ril.sms.strict7BitEncoding.enabled', false,
function(value) {
Services.prefs.setBoolPref('dom.sms.strict7BitEncoding', value);
});
})();
//=================== DeviceInfo ====================

View File

@ -17,6 +17,7 @@ Cu.import('resource://gre/modules/accessibility/AccessFu.jsm');
Cu.import('resource://gre/modules/Payment.jsm');
Cu.import("resource://gre/modules/AppsUtils.jsm");
Cu.import('resource://gre/modules/UserAgentOverrides.jsm');
Cu.import('resource://gre/modules/Keyboard.jsm');
#ifdef MOZ_B2G_RIL
Cu.import('resource://gre/modules/NetworkStatsService.jsm');
#endif
@ -518,7 +519,7 @@ Services.obs.addObserver(function onWebappsReady(subject, topic, data) {
Services.obs.addObserver(function onBluetoothVolumeChange(subject, topic, data) {
shell.sendChromeEvent({
type: "volumeset",
type: "bluetooth-volumeset",
value: data
});
}, 'bluetooth-volume-change', false);

101
b2g/components/Keyboard.jsm Normal file
View File

@ -0,0 +1,101 @@
/* 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/. */
'use strict';
this.EXPORTED_SYMBOLS = ['Keyboard'];
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
const kFormsFrameScript = 'chrome://browser/content/forms.js';
Cu.import('resource://gre/modules/Services.jsm');
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
"@mozilla.org/parentprocessmessagemanager;1", "nsIMessageBroadcaster");
let Keyboard = {
_messageManager: null,
_messageNames: [
'SetValue', 'RemoveFocus', 'SetSelectedOption', 'SetSelectedOptions'
],
get messageManager() {
if (this._messageManager && !Cu.isDeadWrapper(this._messageManager))
return this._messageManager;
throw Error('no message manager set');
},
set messageManager(mm) {
this._messageManager = mm;
},
init: function keyboardInit() {
Services.obs.addObserver(this, 'in-process-browser-frame-shown', false);
Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
for (let name of this._messageNames)
ppmm.addMessageListener('Keyboard:' + name, this);
},
observe: function keyboardObserve(subject, topic, data) {
let frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
let mm = frameLoader.messageManager;
mm.addMessageListener('Forms:Input', this);
try {
mm.loadFrameScript(kFormsFrameScript, true);
} catch (e) {
dump('Error loading ' + kFormsFrameScript + ' as frame script: ' + e + '\n');
}
},
receiveMessage: function keyboardReceiveMessage(msg) {
switch (msg.name) {
case 'Forms:Input':
this.handleFormsInput(msg);
break;
case 'Keyboard:SetValue':
this.setValue(msg);
break;
case 'Keyboard:RemoveFocus':
this.removeFocus();
break;
case 'Keyboard:SetSelectedOption':
this.setSelectedOption(msg);
break;
case 'Keyboard:SetSelectedOptions':
this.setSelectedOption(msg);
break;
}
},
handleFormsInput: function keyboardHandleFormsInput(msg) {
this.messageManager = msg.target.QueryInterface(Ci.nsIFrameLoaderOwner)
.frameLoader.messageManager;
ppmm.broadcastAsyncMessage('Keyboard:FocusChange', msg.data);
},
setSelectedOption: function keyboardSetSelectedOption(msg) {
this.messageManager.sendAsyncMessage('Forms:Select:Choice', msg.data);
},
setSelectedOptions: function keyboardSetSelectedOptions(msg) {
this.messageManager.sendAsyncMessage('Forms:Select:Choice', msg.data);
},
setValue: function keyboardSetValue(msg) {
this.messageManager.sendAsyncMessage('Forms:Input:Value', msg.data);
},
removeFocus: function keyboardRemoveFocus() {
this.messageManager.sendAsyncMessage('Forms:Select:Blur', {});
}
};
Keyboard.init();

View File

@ -34,6 +34,7 @@ EXTRA_PP_COMPONENTS = \
$(NULL)
EXTRA_JS_MODULES = \
Keyboard.jsm \
TelURIParser.jsm \
$(NULL)

View File

@ -4,15 +4,16 @@
"use strict";
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const kFormsFrameScript = "chrome://browser/content/forms.js";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/ObjectWrapper.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1", "nsIMessageSender");
// -----------------------------------------------------------------------
// MozKeyboard
// -----------------------------------------------------------------------
@ -36,20 +37,19 @@ MozKeyboard.prototype = {
init: function mozKeyboardInit(win) {
Services.obs.addObserver(this, "inner-window-destroyed", false);
Services.obs.addObserver(this, 'in-process-browser-frame-shown', false);
Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
cpmm.addMessageListener('Keyboard:FocusChange', this);
this._window = win;
this._utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
this.innerWindowID = this._utils.currentInnerWindowID;
this._focusHandler = null;
},
uninit: function mozKeyboardUninit() {
Services.obs.removeObserver(this, "inner-window-destroyed");
this._messageManager = null;
cpmm.removeMessageListener('Keyboard:FocusChange', this);
this._window = null;
this._utils = null;
this._focusHandler = null;
@ -63,25 +63,25 @@ MozKeyboard.prototype = {
},
setSelectedOption: function mozKeyboardSetSelectedOption(index) {
this._messageManager.sendAsyncMessage("Forms:Select:Choice", {
"index": index
cpmm.sendAsyncMessage('Keyboard:SetSelectedOption', {
'index': index
});
},
setValue: function mozKeyboardSetValue(value) {
this._messageManager.sendAsyncMessage("Forms:Input:Value", {
"value": value
cpmm.sendAsyncMessage('Keyboard:SetValue', {
'value': value
});
},
setSelectedOptions: function mozKeyboardSetSelectedOptions(indexes) {
this._messageManager.sendAsyncMessage("Forms:Select:Choice", {
"indexes": indexes || []
cpmm.sendAsyncMessage('Keyboard:SetSelectedOptions', {
'indexes': indexes
});
},
removeFocus: function mozKeyboardRemoveFocus() {
this._messageManager.sendAsyncMessage("Forms:Select:Blur", {});
cpmm.sendAsyncMessage('Keyboard:RemoveFocus', {});
},
set onfocuschange(val) {
@ -92,7 +92,7 @@ MozKeyboard.prototype = {
return this._focusHandler;
},
handleMessage: function mozKeyboardHandleMessage(msg) {
receiveMessage: function mozKeyboardReceiveMessage(msg) {
let handler = this._focusHandler;
if (!handler || !(handler instanceof Ci.nsIDOMEventListener))
return;
@ -107,32 +107,9 @@ MozKeyboard.prototype = {
},
observe: function mozKeyboardObserve(subject, topic, data) {
switch (topic) {
case "inner-window-destroyed": {
let wId = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (wId == this.innerWindowID) {
this.uninit();
}
break;
}
case 'remote-browser-frame-shown':
case 'in-process-browser-frame-shown': {
let frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
let mm = frameLoader.messageManager;
mm.addMessageListener("Forms:Input", (function receiveMessage(msg) {
// Need to save mm here so later the message can be sent back to the
// correct app in the methods called by the value selector.
this._messageManager = mm;
this.handleMessage(msg);
}).bind(this));
try {
mm.loadFrameScript(kFormsFrameScript, true);
} catch (e) {
dump('Error loading ' + kFormsFrameScript + ' as frame script: ' + e + '\n');
}
break;
}
}
let wId = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (wId == this.innerWindowID)
this.uninit();
}
};

View File

@ -46,3 +46,4 @@ MOZ_TIME_MANAGER=1
MOZ_PAY=1
MOZ_TOOLKIT_SEARCH=
MOZ_B2G=1

View File

@ -54,6 +54,7 @@
@BINPATH@/@DLL_PREFIX@xpcom@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@nspr4@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@mozalloc@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@soundtouch@DLL_SUFFIX@
#ifdef XP_MACOSX
@BINPATH@/XUL
#else

View File

@ -54,6 +54,7 @@
@BINPATH@/@DLL_PREFIX@gkmedias@DLL_SUFFIX@
#endif
@BINPATH@/@DLL_PREFIX@mozalloc@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@soundtouch@DLL_SUFFIX@
#ifdef MOZ_SHARED_MOZGLUE
@BINPATH@/@DLL_PREFIX@mozglue@DLL_SUFFIX@
#endif

View File

@ -17,6 +17,7 @@ pymake.pth:build/pymake
optional:setup.py:python/psutil:build_ext:--inplace
optional:psutil.pth:python/psutil
which.pth:python/which
mock.pth:python/mock-1.0.0
mozilla.pth:build
mozilla.pth:config
copy:build/buildconfig.py

View File

@ -981,6 +981,8 @@ plstr.h
plarenas.h
plarena.h
plhash.h
speex/speex_resampler.h
soundtouch/SoundTouch.h
#if MOZ_NATIVE_PNG==1
png.h
#endif
@ -1053,7 +1055,6 @@ vpx/vpx_encoder.h
vpx/vp8cx.h
vpx/vp8dx.h
sydneyaudio/sydney_audio.h
speex/speex_resampler.h
vorbis/codec.h
theora/theoradec.h
tremor/ivorbiscodec.h

View File

@ -402,7 +402,6 @@ dnl ========================================================
dnl Special win32 checks
dnl ========================================================
# With win8, sdk target=602, WINVER=602
MOZ_ARG_ENABLE_BOOL(metro,
[ --enable-metro Enable Windows Metro build targets],
MOZ_METRO=1,
@ -3832,12 +3831,6 @@ dnl are defined in build/autoconf/altoptions.m4.
dnl If the compiler supports these attributes, define them as
dnl convenience macros.
if test "$ac_cv_attribute_always_inline" = yes ; then
AC_DEFINE(NS_ALWAYS_INLINE, [__attribute__((always_inline))])
else
AC_DEFINE(NS_ALWAYS_INLINE,)
fi
if test "$ac_cv_attribute_malloc" = yes ; then
AC_DEFINE(NS_ATTR_MALLOC, [__attribute__((malloc))])
else
@ -4225,6 +4218,7 @@ MOZ_OGG=1
MOZ_RAW=
MOZ_SYDNEYAUDIO=
MOZ_SPEEX_RESAMPLER=1
MOZ_SOUNDTOUCH=1
MOZ_CUBEB=
MOZ_VORBIS=
MOZ_TREMOR=
@ -4414,11 +4408,15 @@ browser)
xulrunner)
AC_DEFINE(MOZ_XULRUNNER)
;;
b2g)
AC_DEFINE(MOZ_B2G)
;;
esac
AC_SUBST(MOZ_BUILD_APP)
AC_SUBST(MOZ_PHOENIX)
AC_SUBST(MOZ_XULRUNNER)
AC_SUBST(MOZ_B2G)
AC_DEFINE_UNQUOTED(MOZ_BUILD_APP,$MOZ_BUILD_APP)
@ -5580,6 +5578,19 @@ if test -n "$MOZ_SPEEX_RESAMPLER"; then
AC_DEFINE(MOZ_SPEEX_RESAMPLER)
fi
if test -n "$MOZ_SOUNDTOUCH"; then
AC_DEFINE(MOZ_SOUNDTOUCH)
fi
if test -z "$GNU_CC" -a "$OS_ARCH" = "WINNT"; then
SOUNDTOUCH_LIBS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)soundtouch.$(LIB_SUFFIX)'
else
SOUNDTOUCH_LIBS='-lsoundtouch'
fi
AC_SUBST(SOUNDTOUCH_CFLAGS)
AC_SUBST(SOUNDTOUCH_LIBS)
AC_SUBST(SOUNDTOUCH_CONFIG)
if test -n "$MOZ_CUBEB"; then
case "$target" in
*-android*|*-linuxandroid*)
@ -8653,6 +8664,7 @@ AC_SUBST(MOZ_APP_EXTRA_LIBS)
AC_SUBST(MOZ_MEDIA)
AC_SUBST(MOZ_SYDNEYAUDIO)
AC_SUBST(MOZ_SPEEX_RESAMPLER)
AC_SUBST(MOZ_SOUNDTOUCH)
AC_SUBST(MOZ_CUBEB)
AC_SUBST(MOZ_WAVE)
AC_SUBST(MOZ_VORBIS)

View File

@ -463,6 +463,8 @@ WINDOW_ONLY_EVENT(devicelight,
NS_DEVICE_LIGHT,
EventNameType_None,
NS_EVENT)
#ifdef MOZ_B2G
WINDOW_ONLY_EVENT(moztimechange,
NS_MOZ_TIME_CHANGE_EVENT,
EventNameType_None,
@ -475,6 +477,7 @@ WINDOW_ONLY_EVENT(moznetworkdownload,
NS_NETWORK_DOWNLOAD_EVENT,
EventNameType_None,
NS_EVENT)
#endif // MOZ_B2G
TOUCH_EVENT(touchstart,
NS_TOUCH_START,

View File

@ -286,6 +286,7 @@ nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener,
EnableDevice(NS_DEVICE_LIGHT);
} else if (aTypeAtom == nsGkAtoms::ondevicemotion) {
EnableDevice(NS_DEVICE_MOTION);
#ifdef MOZ_B2G
} else if (aTypeAtom == nsGkAtoms::onmoztimechange) {
nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
if (window) {
@ -301,6 +302,7 @@ nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener,
if (window) {
window->EnableNetworkEvent(NS_NETWORK_DOWNLOAD_EVENT);
}
#endif // MOZ_B2G
} else if (aTypeAtom == nsGkAtoms::ontouchstart ||
aTypeAtom == nsGkAtoms::ontouchend ||
aTypeAtom == nsGkAtoms::ontouchmove ||
@ -422,9 +424,11 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
uint32_t count = mListeners.Length();
uint32_t typeCount = 0;
bool deviceType = IsDeviceType(aType);
#ifdef MOZ_B2G
bool timeChangeEvent = (aType == NS_MOZ_TIME_CHANGE_EVENT);
bool networkEvent = (aType == NS_NETWORK_UPLOAD_EVENT ||
aType == NS_NETWORK_DOWNLOAD_EVENT);
#endif // MOZ_B2G
for (uint32_t i = 0; i < count; ++i) {
ls = &mListeners.ElementAt(i);
@ -438,7 +442,11 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
mNoListenerForEvent = NS_EVENT_TYPE_NULL;
mNoListenerForEventAtom = nullptr;
if (!deviceType && !timeChangeEvent && !networkEvent) {
if (!deviceType
#ifdef MOZ_B2G
&& !timeChangeEvent && !networkEvent
#endif // MOZ_B2G
) {
return;
}
--typeCount;
@ -448,6 +456,7 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
if (!aAllEvents && deviceType && typeCount == 0) {
DisableDevice(aType);
#ifdef MOZ_B2G
} else if (timeChangeEvent && typeCount == 0) {
nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
if (window) {
@ -458,6 +467,7 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
if (window) {
window->DisableNetworkEvent(aType);
}
#endif // MOZ_B2G
}
}

View File

@ -16,6 +16,7 @@
#include "DelayNode.h"
#include "PannerNode.h"
#include "AudioListener.h"
#include "DynamicsCompressorNode.h"
namespace mozilla {
namespace dom {
@ -115,6 +116,14 @@ AudioContext::CreatePanner()
return pannerNode.forget();
}
already_AddRefed<DynamicsCompressorNode>
AudioContext::CreateDynamicsCompressor()
{
nsRefPtr<DynamicsCompressorNode> compressorNode =
new DynamicsCompressorNode(this);
return compressorNode.forget();
}
AudioListener*
AudioContext::Listener()
{

View File

@ -28,6 +28,7 @@ class AudioBufferSourceNode;
class AudioDestinationNode;
class AudioListener;
class DelayNode;
class DynamicsCompressorNode;
class GainNode;
class PannerNode;
@ -76,6 +77,9 @@ public:
already_AddRefed<PannerNode>
CreatePanner();
already_AddRefed<DynamicsCompressorNode>
CreateDynamicsCompressor();
private:
nsCOMPtr<nsIDOMWindow> mWindow;
nsRefPtr<AudioDestinationNode> mDestination;

View File

@ -0,0 +1,57 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 "DynamicsCompressorNode.h"
#include "mozilla/dom/DynamicsCompressorNodeBinding.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_CLASS(DynamicsCompressorNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DynamicsCompressorNode, AudioNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mThreshold)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mKnee)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRatio)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mReduction)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAttack)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRelease)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DynamicsCompressorNode, AudioNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mThreshold, AudioParam, "threshold value")
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mKnee, AudioParam, "knee value")
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mRatio, AudioParam, "ratio value")
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mReduction, AudioParam, "reduction value")
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mAttack, AudioParam, "attack value")
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mRelease, AudioParam, "release value")
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DynamicsCompressorNode)
NS_INTERFACE_MAP_END_INHERITING(AudioNode)
NS_IMPL_ADDREF_INHERITED(DynamicsCompressorNode, AudioNode)
NS_IMPL_RELEASE_INHERITED(DynamicsCompressorNode, AudioNode)
DynamicsCompressorNode::DynamicsCompressorNode(AudioContext* aContext)
: AudioNode(aContext)
, mThreshold(new AudioParam(aContext, -24.f, -100.f, 0.f))
, mKnee(new AudioParam(aContext, 30.f, 0.f, 40.f))
, mRatio(new AudioParam(aContext, 12.f, 1.f, 20.f))
, mReduction(new AudioParam(aContext, 0.f, -20.f, 0.f))
, mAttack(new AudioParam(aContext, 0.003f, 0.f, 1.f))
, mRelease(new AudioParam(aContext, 0.25f, 0.f, 1.f))
{
}
JSObject*
DynamicsCompressorNode::WrapObject(JSContext* aCx, JSObject* aScope,
bool* aTriedToWrap)
{
return DynamicsCompressorNodeBinding::Wrap(aCx, aScope, this, aTriedToWrap);
}
}
}

View File

@ -0,0 +1,82 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 DynamicsCompressorNode_h_
#define DynamicsCompressorNode_h_
#include "AudioNode.h"
#include "AudioParam.h"
namespace mozilla {
namespace dom {
class AudioContext;
class DynamicsCompressorNode : public AudioNode
{
public:
explicit DynamicsCompressorNode(AudioContext* aContext);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DynamicsCompressorNode, AudioNode)
virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
bool* aTriedToWrap);
virtual uint32_t MaxNumberOfInputs() const MOZ_FINAL MOZ_OVERRIDE
{
return 1;
}
virtual uint32_t MaxNumberOfOutputs() const MOZ_FINAL MOZ_OVERRIDE
{
return 1;
}
AudioParam* Threshold() const
{
return mThreshold;
}
AudioParam* Knee() const
{
return mKnee;
}
AudioParam* Ratio() const
{
return mRatio;
}
AudioParam* Reduction() const
{
return mReduction;
}
AudioParam* Attack() const
{
return mAttack;
}
// Called GetRelease to prevent clashing with the nsISupports::Release name
AudioParam* GetRelease() const
{
return mRelease;
}
private:
nsRefPtr<AudioParam> mThreshold;
nsRefPtr<AudioParam> mKnee;
nsRefPtr<AudioParam> mRatio;
nsRefPtr<AudioParam> mReduction;
nsRefPtr<AudioParam> mAttack;
nsRefPtr<AudioParam> mRelease;
};
}
}
#endif

View File

@ -24,6 +24,7 @@ CPPSRCS := \
AudioParam.cpp \
AudioSourceNode.cpp \
DelayNode.cpp \
DynamicsCompressorNode.cpp \
EnableWebAudioCheck.cpp \
GainNode.cpp \
PannerNode.cpp \
@ -39,6 +40,7 @@ EXPORTS_mozilla/dom := \
AudioParam.h \
AudioSourceNode.h \
DelayNode.h \
DynamicsCompressorNode.h \
GainNode.h \
PannerNode.h \
$(NULL)

View File

@ -17,6 +17,7 @@ MOCHITEST_FILES := \
test_AudioListener.html \
test_badConnect.html \
test_delayNode.html \
test_dynamicsCompressorNode.html \
test_gainNode.html \
test_pannerNode.html \
test_singleSourceDest.html \

View File

@ -0,0 +1,77 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test DynamicsCompressorNode</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
function near(a, b, msg) {
ok(Math.abs(a - b) < 1e-4, msg);
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
SpecialPowers.setBoolPref("media.webaudio.enabled", true);
var context = new mozAudioContext();
var buffer = context.createBuffer(1, 2048, 44100);
for (var i = 0; i < 2048; ++i) {
buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / 44100);
}
var destination = context.destination;
var source = context.createBufferSource();
var compressor = context.createDynamicsCompressor();
source.buffer = buffer;
source.connect(compressor);
compressor.connect(destination);
// Verify default values
with (compressor) {
near(threshold.defaultValue, -24, "Correct default value for threshold");
near(knee.defaultValue, 30, "Correct default value for knee");
near(ratio.defaultValue, 12, "Correct default value for ratio");
near(reduction.defaultValue, 0, "Correct default value for reduction");
near(attack.defaultValue, 0.003, "Correct default value for attack");
near(release.defaultValue, 0.25, "Correct default value for release");
}
// Verify min/max values
with (compressor) {
near(threshold.minValue, -100, "Correct min value for threshold");
near(knee.minValue, 0, "Correct min value for knee");
near(ratio.minValue, 1, "Correct min value for ratio");
near(reduction.minValue, -20, "Correct min value for reduction");
near(attack.minValue, 0, "Correct min value for attack");
near(release.minValue, 0, "Correct min value for release");
near(threshold.maxValue, 0, "Correct max value for threshold");
near(knee.maxValue, 40, "Correct max value for knee");
near(ratio.maxValue, 20, "Correct max value for ratio");
near(reduction.maxValue, 0, "Correct max value for reduction");
near(attack.maxValue, 1, "Correct max value for attack");
near(release.maxValue, 1, "Correct max value for release");
}
source.start(0);
SimpleTest.executeSoon(function() {
source.stop(0);
source.disconnect();
compressor.disconnect();
SpecialPowers.clearUserPref("media.webaudio.enabled");
SimpleTest.finish();
});
});
</script>
</pre>
</body>
</html>

View File

@ -2375,6 +2375,21 @@ nsDOMClassInfo::RegisterExternalClasses()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMUIEvent) \
DOM_CLASSINFO_EVENT_MAP_ENTRIES
#ifdef MOZ_B2G
#define DOM_CLASSINFO_WINDOW_MAP_ENTRIES(_support_indexed_db) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindow) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowB2G) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMJSWindow) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget) \
DOM_CLASSINFO_MAP_ENTRY(nsIInlineEventHandlers) \
DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDOMStorageIndexedDB, \
_support_indexed_db) \
DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDOMWindowPerformance, \
nsGlobalWindow::HasPerformanceSupport()) \
DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsITouchEventReceiver, \
nsDOMTouchEvent::PrefEnabled()) \
DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIWindowCrypto, domCryptoEnabled)
#else // !MOZ_B2G
#define DOM_CLASSINFO_WINDOW_MAP_ENTRIES(_support_indexed_db) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindow) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMJSWindow) \
@ -2387,6 +2402,7 @@ nsDOMClassInfo::RegisterExternalClasses()
DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsITouchEventReceiver, \
nsDOMTouchEvent::PrefEnabled()) \
DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIWindowCrypto, domCryptoEnabled)
#endif // MOZ_B2G
nsresult
nsDOMClassInfo::Init()

View File

@ -533,6 +533,14 @@ private:
NS_IMPL_ISUPPORTS2(nsGlobalWindowObserver, nsIObserver, nsIInterfaceRequestor)
nsTimeout::nsTimeout()
: mCleared(false),
mRunning(false),
mIsInterval(false),
mPublicId(0),
mInterval(0),
mFiringDepth(0),
mNestingLevel(0),
mPopupState(openAllowed)
{
#ifdef DEBUG_jst
{
@ -542,8 +550,6 @@ nsTimeout::nsTimeout()
}
#endif
memset(this, 0, sizeof(*this));
MOZ_COUNT_CTOR(nsTimeout);
}
@ -723,9 +729,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
// Initialize the PRCList (this).
PR_INIT_CLIST(this);
// Initialize timeout storage
PR_INIT_CLIST(&mTimeouts);
if (aOuterWindow) {
// |this| is an inner window, add this inner window to the outer
// window list of inners.
@ -1026,8 +1029,10 @@ nsGlobalWindow::CleanUp(bool aIgnoreModalDialog)
os->RemoveObserver(mObserver, "dom-storage2-changed");
}
#ifdef MOZ_B2G
DisableNetworkEvent(NS_NETWORK_UPLOAD_EVENT);
DisableNetworkEvent(NS_NETWORK_DOWNLOAD_EVENT);
#endif // MOZ_B2G
if (mIdleService) {
mIdleService->RemoveIdleObserver(mObserver, MIN_IDLE_NOTIFICATION_TIME_S);
@ -1226,6 +1231,9 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindow)
// Make sure this matches the cast in nsGlobalWindow::FromWrapper()
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptGlobalObject)
NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)
#ifdef MOZ_B2G
NS_INTERFACE_MAP_ENTRY(nsIDOMWindowB2G)
#endif // MOZ_B2G
NS_INTERFACE_MAP_ENTRY(nsIDOMJSWindow)
if (aIID.Equals(NS_GET_IID(nsIDOMWindowInternal))) {
foundInterface = static_cast<nsIDOMWindowInternal*>(this);
@ -1314,9 +1322,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mListenerManager,
nsEventListenerManager)
for (nsTimeout* timeout = tmp->FirstTimeout();
tmp->IsTimeout(timeout);
timeout = timeout->Next()) {
for (nsTimeout* timeout = tmp->mTimeouts.getFirst();
timeout;
timeout = timeout->getNext()) {
cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(nsTimeout));
}
@ -1421,9 +1429,9 @@ nsGlobalWindow::IsBlackForCC()
void
nsGlobalWindow::UnmarkGrayTimers()
{
for (nsTimeout* timeout = FirstTimeout();
timeout && IsTimeout(timeout);
timeout = timeout->Next()) {
for (nsTimeout* timeout = mTimeouts.getFirst();
timeout;
timeout = timeout->getNext()) {
if (timeout->mScriptHandler) {
JSObject* o = timeout->mScriptHandler->GetScriptObject();
xpc_UnmarkGrayObject(o);
@ -2313,8 +2321,7 @@ nsGlobalWindow::DetachFromDocShell()
// (mJSObject) so that it can be retrieved later (until it is
// finalized by the JS GC).
NS_ASSERTION(PR_CLIST_IS_EMPTY(&mTimeouts),
"Uh, outer window holds timeouts!");
NS_ASSERTION(mTimeouts.isEmpty(), "Uh, outer window holds timeouts!");
// Call FreeInnerObjects on all inner windows, not just the current
// one, since some could be held by WindowStateHolder objects that
@ -9151,6 +9158,7 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
}
#ifdef MOZ_B2G
if (!nsCRT::strcmp(aTopic, NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC) ||
!nsCRT::strcmp(aTopic, NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC)) {
nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nullptr, nullptr);
@ -9167,6 +9175,7 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
bool dummy;
return DispatchEvent(event, &dummy);
}
#endif // MOZ_B2G
NS_WARNING("unrecognized topic in nsGlobalWindow::Observe");
return NS_ERROR_FAILURE;
@ -9899,7 +9908,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
// timeout events fire "early", so we need to test the timer as well
// as the deadline.
last_expired_timeout = nullptr;
for (timeout = FirstTimeout(); IsTimeout(timeout); timeout = timeout->Next()) {
for (timeout = mTimeouts.getFirst(); timeout; timeout = timeout->getNext()) {
if (((timeout == aTimeout) || (timeout->mWhen <= deadline)) &&
(timeout->mFiringDepth == 0)) {
// Mark any timeouts that are on the list to be fired with the
@ -9933,7 +9942,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
// list for any timeouts inserted as a result of running a timeout.
dummy_timeout.mFiringDepth = firingDepth;
dummy_timeout.mWhen = now;
PR_INSERT_AFTER(&dummy_timeout, last_expired_timeout);
last_expired_timeout->setNext(&dummy_timeout);
// Don't let ClearWindowTimeouts throw away our stack-allocated
// dummy timeout.
@ -9947,10 +9956,10 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
Telemetry::AutoCounter<Telemetry::DOM_TIMERS_FIRED_PER_NATIVE_TIMEOUT> timeoutsRan;
for (timeout = FirstTimeout();
for (timeout = mTimeouts.getFirst();
timeout != &dummy_timeout && !IsFrozen();
timeout = nextTimeout) {
nextTimeout = timeout->Next();
nextTimeout = timeout->getNext();
if (timeout->mFiringDepth != firingDepth) {
// We skip the timeout since it's on the list to run at another
@ -10014,9 +10023,9 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
// Running a timeout can cause another timeout to be deleted, so
// we need to reset the pointer to the following timeout.
nextTimeout = timeout->Next();
nextTimeout = timeout->getNext();
PR_REMOVE_LINK(timeout);
timeout->remove();
if (needsReinsertion) {
// Insert interval timeout onto list sorted in deadline order.
@ -10029,7 +10038,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
}
// Take the dummy timeout off the head of the list
PR_REMOVE_LINK(&dummy_timeout);
dummy_timeout.remove();
mTimeoutInsertionPoint = last_insertion_point;
}
@ -10067,9 +10076,7 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID)
uint32_t public_id = (uint32_t)aTimerID;
nsTimeout *timeout;
for (timeout = FirstTimeout();
IsTimeout(timeout);
timeout = timeout->Next()) {
for (timeout = mTimeouts.getFirst(); timeout; timeout = timeout->getNext()) {
if (timeout->mPublicId == public_id) {
if (timeout->mRunning) {
/* We're running from inside the timeout. Mark this
@ -10079,7 +10086,7 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID)
}
else {
/* Delete the timeout from the pending timeout list */
PR_REMOVE_LINK(timeout);
timeout->remove();
if (timeout->mTimer) {
timeout->mTimer->Cancel();
@ -10114,13 +10121,13 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
// start at the timer after mTimeoutInsertionPoint, if there is one.
// Otherwise, start at the beginning of the list.
for (nsTimeout *timeout = mTimeoutInsertionPoint ?
mTimeoutInsertionPoint->Next() : FirstTimeout();
IsTimeout(timeout); ) {
mTimeoutInsertionPoint->getNext() : mTimeouts.getFirst();
timeout; ) {
// It's important that this check be <= so that we guarantee that
// taking NS_MAX with |now| won't make a quantity equal to
// timeout->mWhen below.
if (timeout->mWhen <= now) {
timeout = timeout->Next();
timeout = timeout->getNext();
continue;
}
@ -10157,14 +10164,14 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
// Get the pointer to the next timeout now, before we move the
// current timeout in the list.
nsTimeout* nextTimeout = timeout->Next();
nsTimeout* nextTimeout = timeout->getNext();
// It is safe to remove and re-insert because mWhen is now
// strictly smaller than it used to be, so we know we'll insert
// |timeout| before nextTimeout.
NS_ASSERTION(!IsTimeout(nextTimeout) ||
NS_ASSERTION(!nextTimeout ||
timeout->mWhen < nextTimeout->mWhen, "How did that happen?");
PR_REMOVE_LINK(timeout);
timeout->remove();
// InsertTimeoutIntoList will addref |timeout| and reset
// mFiringDepth. Make sure to undo that after calling it.
uint32_t firingDepth = timeout->mFiringDepth;
@ -10181,7 +10188,7 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
timeout = nextTimeout;
} else {
timeout = timeout->Next();
timeout = timeout->getNext();
}
}
@ -10193,7 +10200,7 @@ nsGlobalWindow::ClearAllTimeouts()
{
nsTimeout *timeout, *nextTimeout;
for (timeout = FirstTimeout(); IsTimeout(timeout); timeout = nextTimeout) {
for (timeout = mTimeouts.getFirst(); timeout; timeout = nextTimeout) {
/* If RunTimeout() is higher up on the stack for this
window, e.g. as a result of document.write from a timeout,
then we need to reset the list insertion point for
@ -10202,7 +10209,7 @@ nsGlobalWindow::ClearAllTimeouts()
if (mRunningTimeout == timeout)
mTimeoutInsertionPoint = nullptr;
nextTimeout = timeout->Next();
nextTimeout = timeout->getNext();
if (timeout->mTimer) {
timeout->mTimer->Cancel();
@ -10222,7 +10229,7 @@ nsGlobalWindow::ClearAllTimeouts()
}
// Clear out our list
PR_INIT_CLIST(&mTimeouts);
mTimeouts.clear();
}
void
@ -10235,19 +10242,23 @@ nsGlobalWindow::InsertTimeoutIntoList(nsTimeout *aTimeout)
// mTimeoutInsertionPoint, though. This optimizes for the common case of
// insertion at the end.
nsTimeout* prevSibling;
for (prevSibling = LastTimeout();
IsTimeout(prevSibling) && prevSibling != mTimeoutInsertionPoint &&
for (prevSibling = mTimeouts.getLast();
prevSibling && prevSibling != mTimeoutInsertionPoint &&
// This condition needs to match the one in SetTimeoutOrInterval that
// determines whether to set mWhen or mTimeRemaining.
((IsFrozen() || mTimeoutsSuspendDepth) ?
prevSibling->mTimeRemaining > aTimeout->mTimeRemaining :
prevSibling->mWhen > aTimeout->mWhen);
prevSibling = prevSibling->Prev()) {
prevSibling = prevSibling->getPrevious()) {
/* Do nothing; just searching */
}
// Now link in aTimeout after prevSibling.
PR_INSERT_AFTER(aTimeout, prevSibling);
if (prevSibling) {
prevSibling->setNext(aTimeout);
} else {
mTimeouts.insertFront(aTimeout);
}
aTimeout->mFiringDepth = 0;
@ -10539,7 +10550,7 @@ nsGlobalWindow::SuspendTimeouts(uint32_t aIncrease,
mozilla::dom::workers::SuspendWorkersForWindow(cx, this);
TimeStamp now = TimeStamp::Now();
for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) {
for (nsTimeout *t = mTimeouts.getFirst(); t; t = t->getNext()) {
// Set mTimeRemaining to be the time remaining for this timer.
if (t->mWhen > now)
t->mTimeRemaining = t->mWhen - now;
@ -10627,7 +10638,7 @@ nsGlobalWindow::ResumeTimeouts(bool aThawChildren)
bool _seenDummyTimeout = false;
#endif
for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) {
for (nsTimeout *t = mTimeouts.getFirst(); t; t = t->getNext()) {
// There's a chance we're being called with RunTimeout on the stack in which
// case we have a dummy timeout in the list that *must not* be resumed. It
// can be identified by a null mWindow.
@ -11220,6 +11231,7 @@ nsGlobalWindow::SetHasAudioAvailableEventListeners()
}
}
#ifdef MOZ_B2G
void
nsGlobalWindow::EnableNetworkEvent(uint32_t aType)
{
@ -11271,6 +11283,7 @@ nsGlobalWindow::DisableNetworkEvent(uint32_t aType)
break;
}
}
#endif // MOZ_B2G
#define EVENT(name_, id_, type_, struct_) \
NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx, \

View File

@ -59,6 +59,7 @@
#include "nsIContent.h"
#include "nsIIDBFactory.h"
#include "nsFrameMessageManager.h"
#include "mozilla/LinkedList.h"
#include "mozilla/TimeStamp.h"
#include "nsIDOMTouchEvent.h"
#include "nsIInlineEventHandlers.h"
@ -70,6 +71,10 @@
// JS includes
#include "jsapi.h"
#ifdef MOZ_B2G
#include "nsIDOMWindowB2G.h"
#endif // MOZ_B2G
#define DEFAULT_HOME_PAGE "www.mozilla.org"
#define PREF_BROWSER_STARTUP_HOMEPAGE "browser.startup.homepage"
@ -134,7 +139,7 @@ NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
* timeout. Holds a strong reference to an nsIScriptTimeoutHandler, which
* abstracts the language specific cruft.
*/
struct nsTimeout : PRCList
struct nsTimeout : mozilla::LinkedListElement<nsTimeout>
{
nsTimeout();
~nsTimeout();
@ -144,16 +149,6 @@ struct nsTimeout : PRCList
nsrefcnt Release();
nsrefcnt AddRef();
nsTimeout* Next() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_NEXT_LINK(this));
}
nsTimeout* Prev() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_PREV_LINK(this));
}
nsresult InitTimer(nsTimerCallbackFunc aFunc, uint64_t delay) {
return mTimer->InitWithFuncCallback(aFunc, this, delay,
nsITimer::TYPE_ONE_SHOT);
@ -273,6 +268,9 @@ class nsGlobalWindow : public nsPIDOMWindow,
public nsITouchEventReceiver,
public nsIInlineEventHandlers,
public nsIWindowCrypto
#ifdef MOZ_B2G
, public nsIDOMWindowB2G
#endif // MOZ_B2G
{
public:
friend class nsDOMMozURLProperty;
@ -322,6 +320,11 @@ public:
// nsIDOMWindow
NS_DECL_NSIDOMWINDOW
#ifdef MOZ_B2G
// nsIDOMWindowB2G
NS_DECL_NSIDOMWINDOWB2G
#endif // MOZ_B2G
// nsIDOMWindowPerformance
NS_DECL_NSIDOMWINDOWPERFORMANCE
@ -546,8 +549,10 @@ public:
virtual void EnableTimeChangeNotifications();
virtual void DisableTimeChangeNotifications();
#ifdef MOZ_B2G
virtual void EnableNetworkEvent(uint32_t aType);
virtual void DisableNetworkEvent(uint32_t aType);
#endif // MOZ_B2G
virtual nsresult SetArguments(nsIArray *aArguments, nsIPrincipal *aOrigin);
@ -872,20 +877,6 @@ protected:
bool IsInModalState();
nsTimeout* FirstTimeout() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_LIST_HEAD(&mTimeouts));
}
nsTimeout* LastTimeout() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_LIST_TAIL(&mTimeouts));
}
bool IsTimeout(PRCList* aList) {
return aList != &mTimeouts;
}
// Convenience functions for the many methods that need to scale
// from device to CSS pixels or vice versa. Note: if a presentation
// context is not available, they will assume a 1:1 ratio.
@ -1053,7 +1044,7 @@ protected:
// non-null. In that case, the dummy timeout pointed to by
// mTimeoutInsertionPoint may have a later mWhen than some of the timeouts
// that come after it.
PRCList mTimeouts;
mozilla::LinkedList<nsTimeout> mTimeouts;
// If mTimeoutInsertionPoint is non-null, insertions should happen after it.
// This is a dummy timeout at the moment; if that ever changes, the logic in
// ResetTimersForNonBackgroundWindow needs to change.

View File

@ -913,6 +913,14 @@ nsLocation::ToString(nsAString& aReturn)
return GetHref(aReturn);
}
NS_IMETHODIMP
nsLocation::ValueOf(nsIDOMLocation** aReturn)
{
nsCOMPtr<nsIDOMLocation> loc(this);
loc.forget(aReturn);
return NS_OK;
}
nsresult
nsLocation::GetSourceBaseURL(JSContext* cx, nsIURI** sourceURL)
{

View File

@ -574,6 +574,7 @@ public:
virtual void EnableTimeChangeNotifications() = 0;
virtual void DisableTimeChangeNotifications() = 0;
#ifdef MOZ_B2G
/**
* Tell the window that it should start to listen to the network event of the
* given aType.
@ -585,6 +586,7 @@ public:
* given aType.
*/
virtual void DisableNetworkEvent(uint32_t aType) = 0;
#endif // MOZ_B2G
/**
* Set a arguments for this window. This will be set on the window

View File

@ -181,6 +181,15 @@ DOMInterfaces = {
}
},
'DynamicsCompressorNode': [
{
'resultNotAddRefed': [ 'threshold', 'knee', 'ratio',
'reduction', 'attack', 'release' ],
'binaryNames': {
'release': 'getRelease'
}
}],
'Event': [
{
'workers': True,

View File

@ -25,7 +25,7 @@
#include <unistd.h> /* usleep() */
#define MOZSETTINGS_CHANGED_ID "mozsettings-changed"
#define AUDIO_VOLUME_MASTER "audio.volume.master"
#define AUDIO_VOLUME_MASTER "audio.volume.bt_sco"
#define HANDSFREE_UUID mozilla::dom::bluetooth::BluetoothServiceUuidStr::Handsfree
#define HEADSET_UUID mozilla::dom::bluetooth::BluetoothServiceUuidStr::Headset

View File

@ -266,6 +266,19 @@ BluetoothManager::Notify(const BluetoothSignal& aData)
}
}
NS_IMETHODIMP
BluetoothManager::IsConnected(uint16_t aProfileId, bool* aConnected)
{
BluetoothService* bs = BluetoothService::Get();
if (!bs) {
NS_WARNING("BluetoothService not available!");
return NS_ERROR_FAILURE;
}
*aConnected = bs->IsConnected(aProfileId);
return NS_OK;
}
NS_IMPL_EVENT_HANDLER(BluetoothManager, enabled)
NS_IMPL_EVENT_HANDLER(BluetoothManager, disabled)
NS_IMPL_EVENT_HANDLER(BluetoothManager, adapteradded)

View File

@ -273,6 +273,9 @@ public:
virtual void
Disconnect(uint16_t aProfileId, BluetoothReplyRunnable* aRunnable) = 0;
virtual bool
IsConnected(uint16_t aProfileId) = 0;
virtual void
SendFile(const nsAString& aDeviceAddress,
BlobParent* aBlobParent,

View File

@ -391,3 +391,10 @@ BluetoothServiceChildProcess::StopInternal()
MOZ_NOT_REACHED("This should never be called!");
return NS_ERROR_FAILURE;
}
bool
BluetoothServiceChildProcess::IsConnected(uint16_t aProfileId)
{
MOZ_NOT_REACHED("This should never be called!");
return false;
}

View File

@ -139,6 +139,9 @@ public:
Disconnect(const uint16_t aProfileId,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual bool
IsConnected(uint16_t aProfileId) MOZ_OVERRIDE;
virtual void
SendFile(const nsAString& aDeviceAddress,
BlobParent* aBlobParent,

View File

@ -2387,6 +2387,23 @@ BluetoothDBusService::Disconnect(const uint16_t aProfileId,
DispatchBluetoothReply(aRunnable, v, replyError);
}
bool
BluetoothDBusService::IsConnected(const uint16_t aProfileId)
{
NS_ASSERTION(NS_IsMainThread(), "Must be called from main thread!");
if (aProfileId == (uint16_t)(BluetoothServiceUuid::Handsfree >> 32)
|| aProfileId == (uint16_t)(BluetoothServiceUuid::Headset >> 32)) {
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
return hfp->GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTED;
} else if (aProfileId == (uint16_t)(BluetoothServiceUuid::ObjectPush >> 32)) {
BluetoothOppManager* opp = BluetoothOppManager::Get();
return opp->GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTED;
}
return false;
}
class ConnectBluetoothSocketRunnable : public nsRunnable
{
public:

View File

@ -139,6 +139,9 @@ public:
const uint16_t aProfileId,
BluetoothReplyRunnable* aRunnable);
virtual bool
IsConnected(uint16_t aProfileId);
virtual void
Disconnect(const uint16_t aProfileId, BluetoothReplyRunnable* aRunnable);

View File

@ -9,13 +9,15 @@
interface nsIDOMDOMRequest;
interface nsIDOMBluetoothAdapter;
[scriptable, builtinclass, uuid(d27ec867-949f-4585-b718-d2352e420ec6)]
[scriptable, builtinclass, uuid(3300693f-ae91-4a3f-b887-bf502c6a97ee)]
interface nsIDOMBluetoothManager : nsIDOMEventTarget
{
readonly attribute bool enabled;
nsIDOMDOMRequest getDefaultAdapter();
bool isConnected(in unsigned short aProfile);
[implicit_jscontext] attribute jsval onenabled;
[implicit_jscontext] attribute jsval ondisabled;
[implicit_jscontext] attribute jsval onadapteradded;

View File

@ -57,6 +57,12 @@ XPIDLSRCS = \
nsIIdleObserver.idl \
$(NULL)
ifdef MOZ_B2G
XPIDLSRCS += \
nsIDOMWindowB2G.idl \
$(NULL)
endif
include $(topsrcdir)/config/rules.mk
XPIDL_FLAGS += \

View File

@ -5,7 +5,7 @@
#include "domstubs.idl"
[scriptable, uuid(a6cf906d-15b3-11d2-932e-00805f8add32)]
[scriptable, uuid(9472bf0f-2d1c-415c-90fd-f4260678b73b)]
interface nsIDOMLocation : nsISupports
{
/**
@ -27,4 +27,5 @@ interface nsIDOMLocation : nsISupports
void assign(in DOMString url);
DOMString toString();
nsIDOMLocation valueOf();
};

View File

@ -32,7 +32,7 @@ interface nsIDOMMozURLProperty : nsISupports
* @see <http://www.whatwg.org/html/#window>
*/
[scriptable, uuid(148ab425-5d38-40fd-9fe0-0eae9fed81df)]
[scriptable, uuid(1534ecd7-e298-420e-9063-e6c2d1243d49)]
interface nsIDOMWindow : nsISupports
{
// the current browsing context
@ -496,13 +496,9 @@ interface nsIDOMWindow : nsISupports
[implicit_jscontext] attribute jsval ondeviceproximity;
[implicit_jscontext] attribute jsval onuserproximity;
[implicit_jscontext] attribute jsval ondevicelight;
[implicit_jscontext] attribute jsval onmoztimechange;
[implicit_jscontext] attribute jsval onmouseenter;
[implicit_jscontext] attribute jsval onmouseleave;
[implicit_jscontext] attribute jsval onmoznetworkupload;
[implicit_jscontext] attribute jsval onmoznetworkdownload;
};
[scriptable, uuid(2146c906-57f7-486c-a1b4-8cdb57ef577f)]

View File

@ -0,0 +1,14 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
[scriptable, uuid(96bde2ae-9b74-4f4d-b674-664a67a35b7e)]
interface nsIDOMWindowB2G : nsISupports
{
[implicit_jscontext] attribute jsval onmoztimechange;
[implicit_jscontext] attribute jsval onmoznetworkupload;
[implicit_jscontext] attribute jsval onmoznetworkdownload;
};

View File

@ -504,6 +504,8 @@ public:
}
LOG(("Selected video device"));
}
found = false;
if (mAudio) {
nsTArray<nsRefPtr<MediaEngineAudioSource> > audioSources;
mBackend->EnumerateAudioDevices(&audioSources);

View File

@ -450,11 +450,11 @@ PeerConnection.prototype = {
// Must determine the type where we still know if entries are undefined.
let type;
if (dict.maxRetransmitTime != undefined) {
type = Ci.IPeerConnection.DATACHANNEL_PARTIAL_RELIABLE_TIMED;
type = Ci.IPeerConnection.kDataChannelPartialReliableTimed;
} else if (dict.maxRetransmitNum != undefined) {
type = Ci.IPeerConnection.DATACHANNEL_PARTIAL_RELIABLE_REXMIT;
type = Ci.IPeerConnection.kDataChannelPartialReliableRexmit;
} else {
type = Ci.IPeerConnection.DATACHANNEL_RELIABLE;
type = Ci.IPeerConnection.kDataChannelReliable;
}
// Synchronous since it doesn't block.

View File

@ -69,6 +69,11 @@ interface IPeerConnection : nsISupports
const long kIceConnected = 3;
const long kIceFailed = 4;
/* for 'type' in DataChannelInit dictionary */
const unsigned short kDataChannelReliable = 0;
const unsigned short kDataChannelPartialReliableRexmit = 1;
const unsigned short kDataChannelPartialReliableTimed = 2;
/* Must be called first. Observer events will be dispatched on the thread provided */
void initialize(in IPeerConnectionObserver observer, in nsIDOMWindow window,
[optional] in nsIThread thread);

View File

@ -389,7 +389,10 @@ NetworkManager.prototype = {
let options = {
cmd: this.active.dhcp ? "runDHCPAndSetDefaultRouteAndDNS" : "setDefaultRouteAndDNS",
ifname: this.active.name,
oldIfname: (oldInterface && oldInterface != this.active) ? oldInterface.name : null
oldIfname: (oldInterface && oldInterface != this.active) ? oldInterface.name : null,
gateway_str: this.active.gateway,
dns1_str: this.active.dns1,
dns2_str: this.active.dns2
};
this.worker.postMessage(options);
this.setNetworkProxy();

View File

@ -123,11 +123,9 @@ function networkInterfaceStatsSuccess(params) {
* Name of the network interface.
*/
function getIFProperties(ifname) {
let gateway_str = libcutils.property_get("net." + ifname + ".gw");
return {
ifname: ifname,
gateway: netHelpers.stringToIP(gateway_str),
gateway_str: gateway_str,
gateway_str: libcutils.property_get("net." + ifname + ".gw"),
dns1_str: libcutils.property_get("net." + ifname + ".dns1"),
dns2_str: libcutils.property_get("net." + ifname + ".dns2"),
};
@ -159,13 +157,15 @@ function setDefaultRouteAndDNS(options) {
libnetutils.ifc_remove_default_route(options.oldIfname);
}
if (!options.gateway || !options.dns1_str) {
options = getIFProperties(options.ifname);
}
let ifprops = getIFProperties(options.ifname);
let gateway_str = options.gateway_str || ifprops.gateway_str;
let dns1_str = options.dns1_str || ifprops.dns1_str;
let dns2_str = options.dns2_str || ifprops.dns2_str;
let gateway = netHelpers.stringToIP(gateway_str);
libnetutils.ifc_set_default_route(options.ifname, options.gateway);
libcutils.property_set("net.dns1", options.dns1_str);
libcutils.property_set("net.dns2", options.dns2_str);
libnetutils.ifc_set_default_route(options.ifname, gateway);
libcutils.property_set("net.dns1", dns1_str);
libcutils.property_set("net.dns2", dns2_str);
// Bump the DNS change property.
let dnschange = libcutils.property_get("net.dnschange", "0");

View File

@ -2894,6 +2894,13 @@ let RIL = {
return numbers.indexOf(number) != -1;
},
/**
* Report STK Service is running.
*/
reportStkServiceIsRunning: function reportStkServiceIsRunning() {
Buf.simpleRequest(REQUEST_REPORT_STK_SERVICE_IS_RUNNING);
},
/**
* Process ICC status.
*/
@ -2961,6 +2968,7 @@ let RIL = {
this.getSignalStrength();
if (newCardState == GECKO_CARDSTATE_READY) {
this.fetchICCRecords();
this.reportStkServiceIsRunning();
}
this.cardState = newCardState;

View File

@ -33,6 +33,9 @@ interface mozAudioContext {
[Creator]
PannerNode createPanner();
[Creator]
DynamicsCompressorNode createDynamicsCompressor();
};
typedef mozAudioContext AudioContext;

View File

@ -0,0 +1,24 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[PrefControlled]
interface DynamicsCompressorNode : AudioNode {
readonly attribute AudioParam threshold; // in Decibels
readonly attribute AudioParam knee; // in Decibels
readonly attribute AudioParam ratio; // unit-less
readonly attribute AudioParam reduction; // in Decibels
readonly attribute AudioParam attack; // in Seconds
readonly attribute AudioParam release; // in Seconds
};

View File

@ -26,6 +26,7 @@ webidl_files = \
DOMTokenList.webidl \
DOMSettableTokenList.webidl \
DOMStringMap.webidl \
DynamicsCompressorNode.webidl \
Function.webidl \
EventHandler.webidl \
EventListener.webidl \

View File

@ -12,6 +12,9 @@
#include "mozilla/Constants.h"
#include "mozilla/Util.h"
#include "2D.h"
#include "Tools.h"
using namespace std;
namespace mozilla {
@ -311,8 +314,8 @@ SpreadVertical(unsigned char* aInput,
}
}
static CheckedInt<int32_t>
RoundUpToMultipleOf4(int32_t aVal)
CheckedInt<int32_t>
AlphaBoxBlur::RoundUpToMultipleOf4(int32_t aVal)
{
CheckedInt<int32_t> val(aVal);
@ -378,10 +381,11 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
if (stride.isValid()) {
mStride = stride.value();
CheckedInt<int32_t> size = CheckedInt<int32_t>(mStride) * mRect.height *
sizeof(unsigned char);
// We need to leave room for an additional 3 bytes for a potential overrun
// in our blurring code.
CheckedInt<int32_t> size = CheckedInt<int32_t>(mStride) * mRect.height + 3;
if (size.isValid()) {
mData = static_cast<unsigned char*>(malloc(size.value()));
mData = new uint8_t[size.value()];
memset(mData, 0, size.value());
}
}
@ -405,7 +409,7 @@ AlphaBoxBlur::AlphaBoxBlur(uint8_t* aData,
AlphaBoxBlur::~AlphaBoxBlur()
{
if (mFreeData) {
free(mData);
delete [] mData;
}
}
@ -455,42 +459,238 @@ AlphaBoxBlur::Blur()
if (mBlurRadius != IntSize(0,0) || mSpreadRadius != IntSize(0,0)) {
int32_t stride = GetStride();
// No need to use CheckedInt here - we have validated it in the constructor.
size_t szB = stride * GetSize().height * sizeof(unsigned char);
unsigned char* tmpData = static_cast<unsigned char*>(malloc(szB));
if (!tmpData)
return; // OOM
memset(tmpData, 0, szB);
IntSize size = GetSize();
if (mSpreadRadius.width > 0 || mSpreadRadius.height > 0) {
// No need to use CheckedInt here - we have validated it in the constructor.
size_t szB = stride * size.height;
unsigned char* tmpData = new uint8_t[szB];
memset(tmpData, 0, szB);
SpreadHorizontal(mData, tmpData, mSpreadRadius.width, GetSize().width, GetSize().height, stride, mSkipRect);
SpreadVertical(tmpData, mData, mSpreadRadius.height, GetSize().width, GetSize().height, stride, mSkipRect);
delete [] tmpData;
}
if (mBlurRadius.width > 0) {
int32_t lobes[3][2];
ComputeLobes(mBlurRadius.width, lobes);
BoxBlurHorizontal(mData, tmpData, lobes[0][0], lobes[0][1], stride, GetSize().height, mSkipRect);
BoxBlurHorizontal(tmpData, mData, lobes[1][0], lobes[1][1], stride, GetSize().height, mSkipRect);
BoxBlurHorizontal(mData, tmpData, lobes[2][0], lobes[2][1], stride, GetSize().height, mSkipRect);
int32_t horizontalLobes[3][2];
ComputeLobes(mBlurRadius.width, horizontalLobes);
int32_t verticalLobes[3][2];
ComputeLobes(mBlurRadius.height, verticalLobes);
// We want to allow for some extra space on the left for alignment reasons.
int32_t maxLeftLobe = RoundUpToMultipleOf4(horizontalLobes[0][0] + 1).value();
IntSize integralImageSize(size.width + maxLeftLobe + horizontalLobes[1][1],
size.height + verticalLobes[0][0] + verticalLobes[1][1] + 1);
#ifdef IS_BIG_ENDIAN
const bool cIsBigEndian = true;
#else
const bool cIsBigEndian = false;
#endif
if (cIsBigEndian || (integralImageSize.width * integralImageSize.height) > (1 << 24)) {
// Fallback to old blurring code when the surface is so large it may
// overflow our integral image!
// No need to use CheckedInt here - we have validated it in the constructor.
size_t szB = stride * size.height;
unsigned char* tmpData = new uint8_t[szB];
memset(tmpData, 0, szB);
if (mBlurRadius.width > 0) {
BoxBlurHorizontal(mData, tmpData, horizontalLobes[0][0], horizontalLobes[0][1], stride, GetSize().height, mSkipRect);
BoxBlurHorizontal(tmpData, mData, horizontalLobes[1][0], horizontalLobes[1][1], stride, GetSize().height, mSkipRect);
BoxBlurHorizontal(mData, tmpData, horizontalLobes[2][0], horizontalLobes[2][1], stride, GetSize().height, mSkipRect);
} else {
uint8_t *tmp = mData;
mData = tmpData;
tmpData = tmp;
}
if (mBlurRadius.height > 0) {
BoxBlurVertical(tmpData, mData, verticalLobes[0][0], verticalLobes[0][1], stride, GetSize().height, mSkipRect);
BoxBlurVertical(mData, tmpData, verticalLobes[1][0], verticalLobes[1][1], stride, GetSize().height, mSkipRect);
BoxBlurVertical(tmpData, mData, verticalLobes[2][0], verticalLobes[2][1], stride, GetSize().height, mSkipRect);
} else {
uint8_t *tmp = mData;
mData = tmpData;
tmpData = tmp;
}
delete [] tmpData;
} else {
memcpy(tmpData, mData, stride * GetSize().height);
}
size_t integralImageStride = GetAlignedStride<16>(integralImageSize.width * 4);
if (mBlurRadius.height > 0) {
int32_t lobes[3][2];
ComputeLobes(mBlurRadius.height, lobes);
BoxBlurVertical(tmpData, mData, lobes[0][0], lobes[0][1], stride, GetSize().height, mSkipRect);
BoxBlurVertical(mData, tmpData, lobes[1][0], lobes[1][1], stride, GetSize().height, mSkipRect);
BoxBlurVertical(tmpData, mData, lobes[2][0], lobes[2][1], stride, GetSize().height, mSkipRect);
} else {
memcpy(mData, tmpData, stride * GetSize().height);
}
// We need to leave room for an additional 12 bytes for a maximum overrun
// of 3 pixels in the blurring code.
AlignedArray<uint32_t> integralImage((integralImageStride / 4) * integralImageSize.height + 12);
free(tmpData);
#ifdef USE_SSE2
if (Factory::HasSSE2()) {
BoxBlur_SSE2(horizontalLobes[0][0], horizontalLobes[0][1], verticalLobes[0][0],
verticalLobes[0][1], integralImage, integralImageStride);
BoxBlur_SSE2(horizontalLobes[1][0], horizontalLobes[1][1], verticalLobes[1][0],
verticalLobes[1][1], integralImage, integralImageStride);
BoxBlur_SSE2(horizontalLobes[2][0], horizontalLobes[2][1], verticalLobes[2][0],
verticalLobes[2][1], integralImage, integralImageStride);
} else
#endif
{
BoxBlur_C(horizontalLobes[0][0], horizontalLobes[0][1], verticalLobes[0][0],
verticalLobes[0][1], integralImage, integralImageStride);
BoxBlur_C(horizontalLobes[1][0], horizontalLobes[1][1], verticalLobes[1][0],
verticalLobes[1][1], integralImage, integralImageStride);
BoxBlur_C(horizontalLobes[2][0], horizontalLobes[2][1], verticalLobes[2][0],
verticalLobes[2][1], integralImage, integralImageStride);
}
}
}
}
MOZ_ALWAYS_INLINE void
GenerateIntegralRow(uint32_t *aDest, const uint8_t *aSource, uint32_t *aPreviousRow,
const uint32_t &aSourceWidth, const uint32_t &aLeftInflation, const uint32_t &aRightInflation)
{
uint32_t currentRowSum = 0;
uint32_t pixel = aSource[0];
for (uint32_t x = 0; x < aLeftInflation; x++) {
currentRowSum += pixel;
*aDest++ = currentRowSum + *aPreviousRow++;
}
for (uint32_t x = aLeftInflation; x < (aSourceWidth + aLeftInflation); x += 4) {
uint32_t alphaValues = *(uint32_t*)(aSource + (x - aLeftInflation));
currentRowSum += alphaValues & 0xff;
*aDest++ = *aPreviousRow++ + currentRowSum;
alphaValues >>= 8;
currentRowSum += alphaValues & 0xff;
*aDest++ = *aPreviousRow++ + currentRowSum;
alphaValues >>= 8;
currentRowSum += alphaValues & 0xff;
*aDest++ = *aPreviousRow++ + currentRowSum;
alphaValues >>= 8;
currentRowSum += alphaValues & 0xff;
*aDest++ = *aPreviousRow++ + currentRowSum;
}
pixel = aSource[aSourceWidth - 1];
for (uint32_t x = (aSourceWidth + aLeftInflation); x < (aSourceWidth + aLeftInflation + aRightInflation); x++) {
currentRowSum += pixel;
*aDest++ = currentRowSum + *aPreviousRow++;
}
}
MOZ_ALWAYS_INLINE void
GenerateIntegralImage_C(int32_t aLeftInflation, int32_t aRightInflation,
int32_t aTopInflation, int32_t aBottomInflation,
uint32_t *aIntegralImage, size_t aIntegralImageStride,
uint8_t *aSource, int32_t aSourceStride, const IntSize &aSize)
{
uint32_t stride32bit = aIntegralImageStride / 4;
IntSize integralImageSize(aSize.width + aLeftInflation + aRightInflation,
aSize.height + aTopInflation + aBottomInflation);
memset(aIntegralImage, 0, aIntegralImageStride);
GenerateIntegralRow(aIntegralImage, aSource, aIntegralImage,
aSize.width, aLeftInflation, aRightInflation);
for (int y = 1; y < aTopInflation + 1; y++) {
uint32_t *intRow = aIntegralImage + (y * stride32bit);
uint32_t *intPrevRow = aIntegralImage + (y - 1) * stride32bit;
uint32_t *intFirstRow = aIntegralImage;
GenerateIntegralRow(aIntegralImage + (y * stride32bit), aSource, aIntegralImage + (y - 1) * stride32bit,
aSize.width, aLeftInflation, aRightInflation);
}
for (int y = aTopInflation + 1; y < (aSize.height + aTopInflation); y++) {
GenerateIntegralRow(aIntegralImage + (y * stride32bit), aSource + aSourceStride * (y - aTopInflation),
aIntegralImage + (y - 1) * stride32bit, aSize.width, aLeftInflation, aRightInflation);
}
if (aBottomInflation) {
for (int y = (aSize.height + aTopInflation); y < integralImageSize.height; y++) {
GenerateIntegralRow(aIntegralImage + (y * stride32bit), aSource + ((aSize.height - 1) * aSourceStride),
aIntegralImage + (y - 1) * stride32bit,
aSize.width, aLeftInflation, aRightInflation);
}
}
}
/**
* Attempt to do an in-place box blur using an integral image.
*/
void
AlphaBoxBlur::BoxBlur_C(int32_t aLeftLobe,
int32_t aRightLobe,
int32_t aTopLobe,
int32_t aBottomLobe,
uint32_t *aIntegralImage,
size_t aIntegralImageStride)
{
IntSize size = GetSize();
MOZ_ASSERT(size.width > 0);
// Our 'left' or 'top' lobe will include the current pixel. i.e. when
// looking at an integral image the value of a pixel at 'x,y' is calculated
// using the value of the integral image values above/below that.
aLeftLobe++;
aTopLobe++;
int32_t boxSize = (aLeftLobe + aRightLobe) * (aTopLobe + aBottomLobe);
MOZ_ASSERT(boxSize > 0);
if (boxSize == 1) {
return;
}
uint32_t stride32bit = aIntegralImageStride / 4;
int32_t leftInflation = RoundUpToMultipleOf4(aLeftLobe).value();
GenerateIntegralImage_C(leftInflation, aRightLobe, aTopLobe, aBottomLobe,
aIntegralImage, aIntegralImageStride, mData,
mStride, size);
uint32_t reciprocal = uint32_t((uint64_t(1) << 32) / boxSize);
uint32_t *innerIntegral = aIntegralImage + (aTopLobe * stride32bit) + leftInflation;
// Storing these locally makes this about 30% faster! Presumably the compiler
// can't be sure we're not altering the member variables in this loop.
IntRect skipRect = mSkipRect;
uint8_t *data = mData;
int32_t stride = mStride;
for (int32_t y = 0; y < size.height; y++) {
bool inSkipRectY = y > skipRect.y && y < skipRect.YMost();
uint32_t *topLeftBase = innerIntegral + ((y - aTopLobe) * stride32bit - aLeftLobe);
uint32_t *topRightBase = innerIntegral + ((y - aTopLobe) * stride32bit + aRightLobe);
uint32_t *bottomRightBase = innerIntegral + ((y + aBottomLobe) * stride32bit + aRightLobe);
uint32_t *bottomLeftBase = innerIntegral + ((y + aBottomLobe) * stride32bit - aLeftLobe);
for (int32_t x = 0; x < size.width; x++) {
if (inSkipRectY && x > skipRect.x && x < skipRect.XMost()) {
x = skipRect.XMost() - 1;
// Trigger early jump on coming loop iterations, this will be reset
// next line anyway.
inSkipRectY = false;
continue;
}
int32_t topLeft = topLeftBase[x];
int32_t topRight = topRightBase[x];
int32_t bottomRight = bottomRightBase[x];
int32_t bottomLeft = bottomLeftBase[x];
uint32_t value = bottomRight - topRight - bottomLeft;
value += topLeft;
data[stride * y + x] = (uint64_t(reciprocal) * value) >> 32;
}
}
}
/**

View File

@ -7,6 +7,7 @@
#include "mozilla/gfx/Rect.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/CheckedInt.h"
namespace mozilla {
namespace gfx {
@ -114,6 +115,13 @@ public:
private:
void BoxBlur_C(int32_t aLeftLobe, int32_t aRightLobe, int32_t aTopLobe,
int32_t aBottomLobe, uint32_t *aIntegralImage, size_t aIntegralImageStride);
void BoxBlur_SSE2(int32_t aLeftLobe, int32_t aRightLobe, int32_t aTopLobe,
int32_t aBottomLobe, uint32_t *aIntegralImage, size_t aIntegralImageStride);
static CheckedInt<int32_t> RoundUpToMultipleOf4(int32_t aVal);
/**
* A rect indicating the area where blurring is unnecessary, and the blur
* algorithm should skip over it.

250
gfx/2d/BlurSSE2.cpp Normal file
View File

@ -0,0 +1,250 @@
/* 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 "Blur.h"
#include "SSEHelpers.h"
#include <string.h>
namespace mozilla {
namespace gfx {
MOZ_ALWAYS_INLINE
uint32_t DivideAndPack(__m128i aValues, __m128i aDivisor, __m128i aMask)
{
__m128i multiplied = _mm_srli_epi64(_mm_mul_epu32(aValues, aDivisor), 32); // 00p300p1
multiplied = _mm_or_si128(multiplied, _mm_and_si128(_mm_mul_epu32(_mm_srli_epi64(aValues, 32), aDivisor),
aMask)); // p4p3p2p1
__m128i final = _mm_packus_epi16(_mm_packs_epi32(multiplied, _mm_setzero_si128()), _mm_setzero_si128());
return _mm_cvtsi128_si32(final);
}
MOZ_ALWAYS_INLINE
void LoadIntegralRowFromRow(uint32_t *aDest, const uint8_t *aSource,
int32_t aSourceWidth, int32_t aLeftInflation,
int32_t aRightInflation)
{
int32_t currentRowSum = 0;
for (int x = 0; x < aLeftInflation; x++) {
currentRowSum += aSource[0];
aDest[x] = currentRowSum;
}
for (int x = aLeftInflation; x < (aSourceWidth + aLeftInflation); x++) {
currentRowSum += aSource[(x - aLeftInflation)];
aDest[x] = currentRowSum;
}
for (int x = (aSourceWidth + aLeftInflation); x < (aSourceWidth + aLeftInflation + aRightInflation); x++) {
currentRowSum += aSource[aSourceWidth - 1];
aDest[x] = currentRowSum;
}
}
// This function calculates an integral of four pixels stored in the 4
// 32-bit integers on aPixels. i.e. for { 30, 50, 80, 100 } this returns
// { 30, 80, 160, 260 }. This seems to be the fastest way to do this after
// much testing.
MOZ_ALWAYS_INLINE
__m128i AccumulatePixelSums(__m128i aPixels)
{
__m128i sumPixels = aPixels;
__m128i currentPixels = _mm_slli_si128(aPixels, 4);
sumPixels = _mm_add_epi32(sumPixels, currentPixels);
currentPixels = _mm_unpacklo_epi64(_mm_setzero_si128(), sumPixels);
return _mm_add_epi32(sumPixels, currentPixels);
}
MOZ_ALWAYS_INLINE void
GenerateIntegralImage_SSE2(int32_t aLeftInflation, int32_t aRightInflation,
int32_t aTopInflation, int32_t aBottomInflation,
uint32_t *aIntegralImage, size_t aIntegralImageStride,
uint8_t *aSource, int32_t aSourceStride, const IntSize &aSize)
{
MOZ_ASSERT(!(aLeftInflation & 3));
uint32_t stride32bit = aIntegralImageStride / 4;
IntSize integralImageSize(aSize.width + aLeftInflation + aRightInflation,
aSize.height + aTopInflation + aBottomInflation);
LoadIntegralRowFromRow(aIntegralImage, aSource, aSize.width, aLeftInflation, aRightInflation);
for (int y = 1; y < aTopInflation + 1; y++) {
uint32_t *intRow = aIntegralImage + (y * stride32bit);
uint32_t *intPrevRow = aIntegralImage + (y - 1) * stride32bit;
uint32_t *intFirstRow = aIntegralImage;
for (int x = 0; x < integralImageSize.width; x += 4) {
__m128i firstRow = _mm_load_si128((__m128i*)(intFirstRow + x));
__m128i previousRow = _mm_load_si128((__m128i*)(intPrevRow + x));
_mm_store_si128((__m128i*)(intRow + x), _mm_add_epi32(firstRow, previousRow));
}
}
for (int y = aTopInflation + 1; y < (aSize.height + aTopInflation); y++) {
__m128i currentRowSum = _mm_setzero_si128();
uint32_t *intRow = aIntegralImage + (y * stride32bit);
uint32_t *intPrevRow = aIntegralImage + (y - 1) * stride32bit;
uint8_t *sourceRow = aSource + aSourceStride * (y - aTopInflation);
uint32_t pixel = sourceRow[0];
for (int x = 0; x < aLeftInflation; x += 4) {
__m128i sumPixels = AccumulatePixelSums(_mm_shuffle_epi32(_mm_set1_epi32(pixel), _MM_SHUFFLE(0, 0, 0, 0)));
sumPixels = _mm_add_epi32(sumPixels, currentRowSum);
currentRowSum = _mm_shuffle_epi32(sumPixels, _MM_SHUFFLE(3, 3, 3, 3));
_mm_store_si128((__m128i*)(intRow + x), _mm_add_epi32(sumPixels, _mm_load_si128((__m128i*)(intPrevRow + x))));
}
for (int x = aLeftInflation; x < (aSize.width + aLeftInflation); x += 4) {
uint32_t pixels = *(uint32_t*)(sourceRow + (x - aLeftInflation));
// It's important to shuffle here. When we exit this loop currentRowSum
// has to be set to sumPixels, so that the following loop can get the
// correct pixel for the currentRowSum. The highest order pixel in
// currentRowSum could've originated from accumulation in the stride.
currentRowSum = _mm_shuffle_epi32(currentRowSum, _MM_SHUFFLE(3, 3, 3, 3));
__m128i sumPixels = AccumulatePixelSums(_mm_unpacklo_epi16(_mm_unpacklo_epi8( _mm_set1_epi32(pixels), _mm_setzero_si128()), _mm_setzero_si128()));
sumPixels = _mm_add_epi32(sumPixels, currentRowSum);
currentRowSum = sumPixels;
_mm_store_si128((__m128i*)(intRow + x), _mm_add_epi32(sumPixels, _mm_load_si128((__m128i*)(intPrevRow + x))));
}
pixel = sourceRow[aSize.width - 1];
int x = (aSize.width + aLeftInflation);
if ((aSize.width & 3)) {
// Deal with unaligned portion. Get the correct pixel from currentRowSum,
// see explanation above.
uint32_t intCurrentRowSum = ((uint32_t*)&currentRowSum)[(aSize.width % 4) - 1];
for (; x < integralImageSize.width; x++) {
// We could be unaligned here!
if (!(x & 3)) {
// aligned!
currentRowSum = _mm_set1_epi32(intCurrentRowSum);
break;
}
intCurrentRowSum += pixel;
intRow[x] = intPrevRow[x] + intCurrentRowSum;
}
} else {
currentRowSum = _mm_shuffle_epi32(currentRowSum, _MM_SHUFFLE(3, 3, 3, 3));
}
for (; x < integralImageSize.width; x += 4) {
__m128i sumPixels = AccumulatePixelSums(_mm_set1_epi32(pixel));
sumPixels = _mm_add_epi32(sumPixels, currentRowSum);
currentRowSum = _mm_shuffle_epi32(sumPixels, _MM_SHUFFLE(3, 3, 3, 3));
_mm_store_si128((__m128i*)(intRow + x), _mm_add_epi32(sumPixels, _mm_load_si128((__m128i*)(intPrevRow + x))));
}
}
if (aBottomInflation) {
// Store the last valid row of our source image in the last row of
// our integral image. This will be overwritten with the correct values
// in the upcoming loop.
LoadIntegralRowFromRow(aIntegralImage + (integralImageSize.height - 1) * stride32bit,
aSource + (aSize.height - 1) * aSourceStride, aSize.width, aLeftInflation, aRightInflation);
for (int y = aSize.height + aTopInflation; y < integralImageSize.height; y++) {
__m128i *intRow = (__m128i*)(aIntegralImage + (y * stride32bit));
__m128i *intPrevRow = (__m128i*)(aIntegralImage + (y - 1) * stride32bit);
__m128i *intLastRow = (__m128i*)(aIntegralImage + (integralImageSize.height - 1) * stride32bit);
for (int x = 0; x < integralImageSize.width; x += 4) {
_mm_store_si128(intRow + (x / 4),
_mm_add_epi32(_mm_load_si128(intLastRow + (x / 4)),
_mm_load_si128(intPrevRow + (x / 4))));
}
}
}
}
/**
* Attempt to do an in-place box blur using an integral image.
*/
void
AlphaBoxBlur::BoxBlur_SSE2(int32_t aLeftLobe,
int32_t aRightLobe,
int32_t aTopLobe,
int32_t aBottomLobe,
uint32_t *aIntegralImage,
size_t aIntegralImageStride)
{
IntSize size = GetSize();
MOZ_ASSERT(size.height > 0);
// Our 'left' or 'top' lobe will include the current pixel. i.e. when
// looking at an integral image the value of a pixel at 'x,y' is calculated
// using the value of the integral image values above/below that.
aLeftLobe++;
aTopLobe++;
int32_t boxSize = (aLeftLobe + aRightLobe) * (aTopLobe + aBottomLobe);
MOZ_ASSERT(boxSize > 0);
if (boxSize == 1) {
return;
}
uint32_t reciprocal = uint32_t((uint64_t(1) << 32) / boxSize);
uint32_t stride32bit = aIntegralImageStride / 4;
int32_t leftInflation = RoundUpToMultipleOf4(aLeftLobe).value();
GenerateIntegralImage_SSE2(leftInflation, aRightLobe, aTopLobe, aBottomLobe,
aIntegralImage, aIntegralImageStride, mData,
mStride, size);
__m128i divisor = _mm_set1_epi32(reciprocal);
__m128i mask = _mm_setr_epi32(0x0, 0xffffffff, 0x0, 0xffffffff);
// This points to the start of the rectangle within the IntegralImage that overlaps
// the surface being blurred.
uint32_t *innerIntegral = aIntegralImage + (aTopLobe * stride32bit) + leftInflation;
IntRect skipRect = mSkipRect;
int32_t stride = mStride;
uint8_t *data = mData;
for (int32_t y = 0; y < size.height; y++) {
bool inSkipRectY = y > skipRect.y && y < skipRect.YMost();
uint32_t *topLeftBase = innerIntegral + ((y - aTopLobe) * ptrdiff_t(stride32bit) - aLeftLobe);
uint32_t *topRightBase = innerIntegral + ((y - aTopLobe) * ptrdiff_t(stride32bit) + aRightLobe);
uint32_t *bottomRightBase = innerIntegral + ((y + aBottomLobe) * ptrdiff_t(stride32bit) + aRightLobe);
uint32_t *bottomLeftBase = innerIntegral + ((y + aBottomLobe) * ptrdiff_t(stride32bit) - aLeftLobe);
for (int32_t x = 0; x < size.width; x += 4) {
if (inSkipRectY && x > skipRect.x && x < skipRect.XMost()) {
x = skipRect.XMost() - 4;
// Trigger early jump on coming loop iterations, this will be reset
// next line anyway.
inSkipRectY = false;
continue;
}
__m128i topLeft = loadUnaligned128((__m128i*)(topLeftBase + x));
__m128i topRight = loadUnaligned128((__m128i*)(topRightBase + x));
__m128i bottomRight = loadUnaligned128((__m128i*)(bottomRightBase + x));
__m128i bottomLeft = loadUnaligned128((__m128i*)(bottomLeftBase + x));
__m128i values = _mm_add_epi32(_mm_sub_epi32(_mm_sub_epi32(bottomRight, topRight), bottomLeft), topLeft);
*(uint32_t*)(data + stride * y + x) = DivideAndPack(values, divisor, mask);
}
}
}
}
}

View File

@ -6,8 +6,7 @@
#include "ImageScaling.h"
#include "mozilla/Attributes.h"
#include <xmmintrin.h>
#include <emmintrin.h>
#include "SSEHelpers.h"
/* The functions below use the following system for averaging 4 pixels:
*
@ -108,17 +107,6 @@ MOZ_ALWAYS_INLINE __m128i avg_sse2_8x1_4x1(__m128i a, __m128i b)
return _mm_not_si128(_mm_avg_epu8(_mm_not_si128(a), _mm_not_si128(b)));
}
/* Before Nehalem _mm_loadu_si128 could be very slow, this trick is a little
* faster. Once enough people are on architectures where _mm_loadu_si128 is
* fast we can migrate to it.
*/
MOZ_ALWAYS_INLINE __m128i loadUnaligned128(const __m128i *aSource)
{
// Yes! We use uninitialized memory here, we'll overwrite it though!
__m128 res = _mm_loadl_pi(_mm_set1_ps(0), (const __m64*)aSource);
return _mm_castps_si128(_mm_loadh_pi(res, ((const __m64*)(aSource)) + 1));
}
MOZ_ALWAYS_INLINE uint32_t Avg2x2(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
{
uint32_t sum = a ^ b ^ c;

View File

@ -116,7 +116,10 @@ endif
ifneq (,$(INTEL_ARCHITECTURE))
# VC2005 doesn't support _mm_castsi128_ps, so SSE2 is turned off
ifneq (1400,$(_MSC_VER))
CPPSRCS += ImageScalingSSE2.cpp
CPPSRCS += \
ImageScalingSSE2.cpp \
BlurSSE2.cpp \
$(NULL)
DEFINES += -DUSE_SSE2
endif
endif
@ -161,10 +164,12 @@ DEFINES := $(filter-out -DUNICODE -D_UNICODE,$(DEFINES))
ifneq (,$(INTEL_ARCHITECTURE))
ifdef GNU_CC
ImageScalingSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
BlurSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
endif
ifdef SOLARIS_SUNPRO_CXX
ImageScalingSSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
BlurSSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
endif
endif

17
gfx/2d/SSEHelpers.h Normal file
View File

@ -0,0 +1,17 @@
/* 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 <xmmintrin.h>
#include <emmintrin.h>
/* Before Nehalem _mm_loadu_si128 could be very slow, this trick is a little
* faster. Once enough people are on architectures where _mm_loadu_si128 is
* fast we can migrate to it.
*/
MOZ_ALWAYS_INLINE __m128i loadUnaligned128(const __m128i *aSource)
{
// Yes! We use uninitialized memory here, we'll overwrite it though!
__m128 res = _mm_loadl_pi(_mm_set1_ps(0), (const __m64*)aSource);
return _mm_castps_si128(_mm_loadh_pi(res, ((const __m64*)(aSource)) + 1));
}

View File

@ -81,6 +81,64 @@ BytesPerPixel(SurfaceFormat aFormat)
}
}
template<typename T, int alignment = 16>
struct AlignedArray
{
AlignedArray()
: mStorage(nullptr)
, mPtr(nullptr)
{
}
MOZ_ALWAYS_INLINE AlignedArray(size_t aSize)
: mStorage(nullptr)
{
Realloc(aSize);
}
MOZ_ALWAYS_INLINE ~AlignedArray()
{
delete [] mStorage;
}
void Dealloc()
{
delete [] mStorage;
mStorage = mPtr = nullptr;
}
MOZ_ALWAYS_INLINE void Realloc(size_t aSize)
{
delete [] mStorage;
mStorage = new T[aSize + (alignment - 1)];
if (uintptr_t(mStorage) % alignment) {
// Our storage does not start at a <alignment>-byte boundary. Make sure mData does!
mPtr = (uint32_t*)(uintptr_t(mStorage) +
(alignment - (uintptr_t(mStorage) % alignment)));
} else {
mPtr = mStorage;
}
}
MOZ_ALWAYS_INLINE operator T*()
{
return mPtr;
}
T *mStorage;
T *mPtr;
};
template<int alignment>
int32_t GetAlignedStride(int32_t aStride)
{
if (aStride % alignment) {
return aStride + (alignment - (aStride % alignment));
}
return aStride;
}
}
}

View File

@ -172,6 +172,10 @@ EXPORTS_mozilla/layers += ShadowLayerUtilsD3D10.h
DEFINES += -DMOZ_ENABLE_D3D10_LAYER
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
CPPSRCS += ShadowLayerUtilsMac.cpp
endif
# NB: Gralloc is available on other platforms that use the android GL
# libraries, but only Gonk is able to use it reliably because Gecko
# has full system permissions there.

View File

@ -16,6 +16,10 @@
# include "mozilla/layers/ShadowLayerUtilsD3D10.h"
#endif
#if defined(XP_MACOSX)
#define MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
#endif
#if defined(MOZ_X11)
# include "mozilla/layers/ShadowLayerUtilsX11.h"
#else

View File

@ -0,0 +1,94 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* 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 "mozilla/layers/PLayers.h"
#include "mozilla/layers/ShadowLayers.h"
#include "gfxPlatform.h"
#include "gfxSharedQuartzSurface.h"
using namespace mozilla::gl;
namespace mozilla {
namespace layers {
bool
ShadowLayerForwarder::PlatformAllocBuffer(const gfxIntSize& aSize,
gfxASurface::gfxContentType aContent,
uint32_t aCaps,
SurfaceDescriptor* aBuffer)
{
return false;
}
/*static*/ already_AddRefed<gfxASurface>
ShadowLayerForwarder::PlatformOpenDescriptor(OpenMode aMode,
const SurfaceDescriptor& aSurface)
{
if (SurfaceDescriptor::TShmem != aSurface.type()) {
return nullptr;
}
return gfxSharedQuartzSurface::Open(aSurface.get_Shmem());
}
/*static*/ bool
ShadowLayerForwarder::PlatformCloseDescriptor(const SurfaceDescriptor& aDescriptor)
{
return false;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceContentType(
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
gfxContentType* aContent,
gfxASurface** aSurface)
{
return false;
}
/*static*/ bool
ShadowLayerForwarder::PlatformGetDescriptorSurfaceSize(
const SurfaceDescriptor& aDescriptor, OpenMode aMode,
gfxIntSize* aSize,
gfxASurface** aSurface)
{
return false;
}
bool
ShadowLayerForwarder::PlatformDestroySharedSurface(SurfaceDescriptor* aSurface)
{
return false;
}
/*static*/ void
ShadowLayerForwarder::PlatformSyncBeforeUpdate()
{
}
/*static*/ void
ShadowLayerManager::PlatformSyncBeforeReplyUpdate()
{
}
bool
ShadowLayerManager::PlatformDestroySharedSurface(SurfaceDescriptor*)
{
return false;
}
/*static*/ already_AddRefed<TextureImage>
ShadowLayerManager::OpenDescriptorForDirectTexturing(GLContext*,
const SurfaceDescriptor&,
GLenum)
{
return nullptr;
}
} // namespace layers
} // namespace mozilla

View File

@ -49,7 +49,9 @@ EXPORTS = \
gfxUtils.h \
gfxUserFontSet.h \
nsSurfaceTexture.h \
gfxBaseSharedMemorySurface.h \
gfxSharedImageSurface.h \
gfxSharedQuartzSurface.h \
gfxReusableSurfaceWrapper.h \
gfxSVGGlyphs.h \
$(NULL)
@ -179,7 +181,7 @@ CPPSRCS = \
gfxUtils.cpp \
gfxScriptItemizer.cpp \
gfxHarfBuzzShaper.cpp \
gfxSharedImageSurface.cpp \
gfxBaseSharedMemorySurface.cpp \
gfxReusableSurfaceWrapper.cpp \
nsSurfaceTexture.cpp \
gfxSVGGlyphs.cpp \

View File

@ -0,0 +1,10 @@
// vim:set ts=4 sts=4 sw=4 et cin:
/* -*- Mode: C++; tab-width: 20; 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/. */
#include "gfxSharedImageSurface.h"
const cairo_user_data_key_t SHM_KEY = {0};

View File

@ -0,0 +1,172 @@
// vim:set ts=4 sts=4 sw=4 et cin:
/* -*- Mode: C++; tab-width: 20; 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 GFX_SHARED_MEMORYSURFACE_H
#define GFX_SHARED_MEMORYSURFACE_H
#include "mozilla/ipc/Shmem.h"
#include "mozilla/ipc/SharedMemory.h"
#include "gfxASurface.h"
#include "gfxImageSurface.h"
#include "cairo.h"
struct SharedImageInfo {
int32_t width;
int32_t height;
int32_t format;
};
inline SharedImageInfo*
GetShmInfoPtr(const mozilla::ipc::Shmem& aShmem)
{
return reinterpret_cast<SharedImageInfo*>
(aShmem.get<char>() + aShmem.Size<char>() - sizeof(SharedImageInfo));
}
extern const cairo_user_data_key_t SHM_KEY;
template <typename Base, typename Sub>
class THEBES_API gfxBaseSharedMemorySurface : public Base {
typedef mozilla::ipc::SharedMemory SharedMemory;
typedef mozilla::ipc::Shmem Shmem;
public:
virtual ~gfxBaseSharedMemorySurface()
{
MOZ_COUNT_DTOR(gfxBaseSharedMemorySurface);
}
/**
* Return a new gfxSharedImageSurface around a shmem segment newly
* allocated by this function. |aAllocator| is the object used to
* allocate the new shmem segment. Null is returned if creating
* the surface failed.
*
* NB: the *caller* is responsible for freeing the Shmem allocated
* by this function.
*/
template<class ShmemAllocator>
static already_AddRefed<Sub>
Create(ShmemAllocator* aAllocator,
const gfxIntSize& aSize,
gfxASurface::gfxImageFormat aFormat,
SharedMemory::SharedMemoryType aShmType = SharedMemory::TYPE_BASIC)
{
return Create<ShmemAllocator, false>(aAllocator, aSize, aFormat, aShmType);
}
/**
* Return a new gfxSharedImageSurface that wraps a shmem segment
* already created by the Create() above. Bad things will happen
* if an attempt is made to wrap any other shmem segment. Null is
* returned if creating the surface failed.
*/
static already_AddRefed<Sub>
Open(const Shmem& aShmem)
{
SharedImageInfo* shmInfo = GetShmInfoPtr(aShmem);
gfxIntSize size(shmInfo->width, shmInfo->height);
if (!gfxASurface::CheckSurfaceSize(size))
return nullptr;
gfxASurface::gfxImageFormat format = (gfxASurface::gfxImageFormat)shmInfo->format;
long stride = gfxImageSurface::ComputeStride(size, format);
nsRefPtr<Sub> s =
new Sub(size,
stride,
format,
aShmem);
// We didn't create this Shmem and so don't free it on errors
return (s->CairoStatus() != 0) ? nullptr : s.forget();
}
template<class ShmemAllocator>
static already_AddRefed<Sub>
CreateUnsafe(ShmemAllocator* aAllocator,
const gfxIntSize& aSize,
gfxASurface::gfxImageFormat aFormat,
SharedMemory::SharedMemoryType aShmType = SharedMemory::TYPE_BASIC)
{
return Create<ShmemAllocator, true>(aAllocator, aSize, aFormat, aShmType);
}
Shmem& GetShmem() { return mShmem; }
static bool IsSharedImage(gfxASurface *aSurface)
{
return (aSurface
&& aSurface->GetType() == gfxASurface::SurfaceTypeImage
&& aSurface->GetData(&SHM_KEY));
}
protected:
gfxBaseSharedMemorySurface(const gfxIntSize& aSize, long aStride,
gfxASurface::gfxImageFormat aFormat,
const Shmem& aShmem)
: Base(aShmem.get<unsigned char>(), aSize, aStride, aFormat)
{
MOZ_COUNT_CTOR(gfxBaseSharedMemorySurface);
mShmem = aShmem;
this->SetData(&SHM_KEY, this, nullptr);
}
private:
void WriteShmemInfo()
{
SharedImageInfo* shmInfo = GetShmInfoPtr(mShmem);
shmInfo->width = this->mSize.width;
shmInfo->height = this->mSize.height;
shmInfo->format = this->mFormat;
}
static size_t GetAlignedSize(const gfxIntSize& aSize, long aStride)
{
#define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
return MOZ_ALIGN_WORD(sizeof(SharedImageInfo) + aSize.height * aStride);
}
template<class ShmemAllocator, bool Unsafe>
static already_AddRefed<Sub>
Create(ShmemAllocator* aAllocator,
const gfxIntSize& aSize,
gfxASurface::gfxImageFormat aFormat,
SharedMemory::SharedMemoryType aShmType)
{
if (!gfxASurface::CheckSurfaceSize(aSize))
return nullptr;
Shmem shmem;
long stride = gfxImageSurface::ComputeStride(aSize, aFormat);
size_t size = GetAlignedSize(aSize, stride);
if (!Unsafe) {
if (!aAllocator->AllocShmem(size, aShmType, &shmem))
return nullptr;
} else {
if (!aAllocator->AllocUnsafeShmem(size, aShmType, &shmem))
return nullptr;
}
nsRefPtr<Sub> s =
new Sub(aSize, stride, aFormat, shmem);
if (s->CairoStatus() != 0) {
aAllocator->DeallocShmem(shmem);
return nullptr;
}
s->WriteShmemInfo();
return s.forget();
}
Shmem mShmem;
// Calling these is very bad, disallow it
gfxBaseSharedMemorySurface(const gfxBaseSharedMemorySurface&);
gfxBaseSharedMemorySurface& operator=(const gfxBaseSharedMemorySurface&);
};
#endif /* GFX_SHARED_MEMORYSURFACE_H */

View File

@ -92,6 +92,7 @@ public:
virtual void MovePixels(const nsIntRect& aSourceRect,
const nsIntPoint& aDestTopLeft) MOZ_OVERRIDE;
static long ComputeStride(const gfxIntSize&, gfxImageFormat);
protected:
gfxImageSurface();
void InitWithData(unsigned char *aData, const gfxIntSize& aSize,
@ -99,7 +100,6 @@ protected:
void InitFromSurface(cairo_surface_t *csurf);
long ComputeStride() const { return ComputeStride(mSize, mFormat); }
static long ComputeStride(const gfxIntSize&, gfxImageFormat);
void MakeInvalid();

View File

@ -1,95 +0,0 @@
// vim:set ts=4 sts=4 sw=4 et cin:
/* -*- Mode: C++; tab-width: 20; 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/. */
#include "base/basictypes.h"
#include "gfxSharedImageSurface.h"
#include "cairo.h"
#define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
using namespace mozilla::ipc;
static const cairo_user_data_key_t SHM_KEY = {0};
struct SharedImageInfo {
int32_t width;
int32_t height;
int32_t format;
};
static SharedImageInfo*
GetShmInfoPtr(const Shmem& aShmem)
{
return reinterpret_cast<SharedImageInfo*>
(aShmem.get<char>() + aShmem.Size<char>() - sizeof(SharedImageInfo));
}
gfxSharedImageSurface::~gfxSharedImageSurface()
{
MOZ_COUNT_DTOR(gfxSharedImageSurface);
}
/*static*/ bool
gfxSharedImageSurface::IsSharedImage(gfxASurface* aSurface)
{
return (aSurface
&& aSurface->GetType() == gfxASurface::SurfaceTypeImage
&& aSurface->GetData(&SHM_KEY));
}
gfxSharedImageSurface::gfxSharedImageSurface(const gfxIntSize& aSize,
gfxImageFormat aFormat,
const Shmem& aShmem)
{
MOZ_COUNT_CTOR(gfxSharedImageSurface);
mSize = aSize;
mFormat = aFormat;
mStride = ComputeStride(aSize, aFormat);
mShmem = aShmem;
mData = aShmem.get<unsigned char>();
cairo_surface_t *surface =
cairo_image_surface_create_for_data(mData,
(cairo_format_t)mFormat,
mSize.width,
mSize.height,
mStride);
if (surface) {
cairo_surface_set_user_data(surface, &SHM_KEY, this, NULL);
}
Init(surface);
}
void
gfxSharedImageSurface::WriteShmemInfo()
{
SharedImageInfo* shmInfo = GetShmInfoPtr(mShmem);
shmInfo->width = mSize.width;
shmInfo->height = mSize.height;
shmInfo->format = mFormat;
}
/*static*/ size_t
gfxSharedImageSurface::GetAlignedSize(const gfxIntSize& aSize, long aStride)
{
return MOZ_ALIGN_WORD(sizeof(SharedImageInfo) + aSize.height * aStride);
}
/*static*/ already_AddRefed<gfxSharedImageSurface>
gfxSharedImageSurface::Open(const Shmem& aShmem)
{
SharedImageInfo* shmInfo = GetShmInfoPtr(aShmem);
gfxIntSize size(shmInfo->width, shmInfo->height);
if (!CheckSurfaceSize(size))
return nullptr;
nsRefPtr<gfxSharedImageSurface> s =
new gfxSharedImageSurface(size,
(gfxImageFormat)shmInfo->format,
aShmem);
// We didn't create this Shmem and so don't free it on errors
return (s->CairoStatus() != 0) ? nullptr : s.forget();
}

View File

@ -7,104 +7,18 @@
#ifndef GFX_SHARED_IMAGESURFACE_H
#define GFX_SHARED_IMAGESURFACE_H
#include "mozilla/ipc/Shmem.h"
#include "mozilla/ipc/SharedMemory.h"
#include "gfxASurface.h"
#include "gfxImageSurface.h"
class THEBES_API gfxSharedImageSurface : public gfxImageSurface {
typedef mozilla::ipc::SharedMemory SharedMemory;
typedef mozilla::ipc::Shmem Shmem;
public:
virtual ~gfxSharedImageSurface();
/**
* Return a new gfxSharedImageSurface around a shmem segment newly
* allocated by this function. |aAllocator| is the object used to
* allocate the new shmem segment. Null is returned if creating
* the surface failed.
*
* NB: the *caller* is responsible for freeing the Shmem allocated
* by this function.
*/
template<class ShmemAllocator>
static already_AddRefed<gfxSharedImageSurface>
Create(ShmemAllocator* aAllocator,
const gfxIntSize& aSize,
gfxImageFormat aFormat,
SharedMemory::SharedMemoryType aShmType = SharedMemory::TYPE_BASIC)
{
return Create<ShmemAllocator, false>(aAllocator, aSize, aFormat, aShmType);
}
/**
* Return a new gfxSharedImageSurface that wraps a shmem segment
* already created by the Create() above. Bad things will happen
* if an attempt is made to wrap any other shmem segment. Null is
* returned if creating the surface failed.
*/
static already_AddRefed<gfxSharedImageSurface>
Open(const Shmem& aShmem);
template<class ShmemAllocator>
static already_AddRefed<gfxSharedImageSurface>
CreateUnsafe(ShmemAllocator* aAllocator,
const gfxIntSize& aSize,
gfxImageFormat aFormat,
SharedMemory::SharedMemoryType aShmType = SharedMemory::TYPE_BASIC)
{
return Create<ShmemAllocator, true>(aAllocator, aSize, aFormat, aShmType);
}
Shmem& GetShmem() { return mShmem; }
static bool IsSharedImage(gfxASurface *aSurface);
#include "gfxBaseSharedMemorySurface.h"
class gfxSharedImageSurface : public gfxBaseSharedMemorySurface<gfxImageSurface, gfxSharedImageSurface>
{
typedef gfxBaseSharedMemorySurface<gfxImageSurface, gfxSharedImageSurface> Super;
friend class gfxBaseSharedMemorySurface<gfxImageSurface, gfxSharedImageSurface>;
private:
gfxSharedImageSurface(const gfxIntSize&, gfxImageFormat, const Shmem&);
void WriteShmemInfo();
static size_t GetAlignedSize(const gfxIntSize&, long aStride);
template<class ShmemAllocator, bool Unsafe>
static already_AddRefed<gfxSharedImageSurface>
Create(ShmemAllocator* aAllocator,
const gfxIntSize& aSize,
gfxImageFormat aFormat,
SharedMemory::SharedMemoryType aShmType)
{
if (!CheckSurfaceSize(aSize))
return nullptr;
Shmem shmem;
long stride = ComputeStride(aSize, aFormat);
size_t size = GetAlignedSize(aSize, stride);
if (!Unsafe) {
if (!aAllocator->AllocShmem(size, aShmType, &shmem))
return nullptr;
} else {
if (!aAllocator->AllocUnsafeShmem(size, aShmType, &shmem))
return nullptr;
}
nsRefPtr<gfxSharedImageSurface> s =
new gfxSharedImageSurface(aSize, aFormat, shmem);
if (s->CairoStatus() != 0) {
aAllocator->DeallocShmem(shmem);
return nullptr;
}
s->WriteShmemInfo();
return s.forget();
}
Shmem mShmem;
// Calling these is very bad, disallow it
gfxSharedImageSurface(const gfxSharedImageSurface&);
gfxSharedImageSurface& operator=(const gfxSharedImageSurface&);
gfxSharedImageSurface(const gfxIntSize& aSize, long aStride,
gfxASurface::gfxImageFormat aFormat,
const mozilla::ipc::Shmem& aShmem)
: Super(aSize, aStride, aFormat, aShmem)
{}
};
#endif /* GFX_SHARED_IMAGESURFACE_H */

View File

@ -0,0 +1,25 @@
// vim:set ts=4 sts=4 sw=4 et cin:
/* -*- Mode: C++; tab-width: 20; 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 GFX_SHARED_QUARTZSURFACE_H
#define GFX_SHARED_QUARTZSURFACE_H
#include "gfxBaseSharedMemorySurface.h"
#include "gfxQuartzSurface.h"
class gfxSharedQuartzSurface : public gfxBaseSharedMemorySurface<gfxQuartzSurface, gfxSharedQuartzSurface>
{
typedef gfxBaseSharedMemorySurface<gfxQuartzSurface, gfxSharedQuartzSurface> Super;
friend class gfxBaseSharedMemorySurface<gfxQuartzSurface, gfxSharedQuartzSurface>;
private:
gfxSharedQuartzSurface(const gfxIntSize& aSize, long aStride,
gfxASurface::gfxImageFormat aFormat,
const mozilla::ipc::Shmem& aShmem)
: Super(aSize, aStride, aFormat, aShmem)
{}
};
#endif /* GFX_SHARED_QUARTZSURFACE_H */

View File

@ -403,7 +403,6 @@ RasterImage::~RasterImage()
num_discardable_containers,
total_source_bytes,
discardable_source_bytes));
DiscardTracker::Remove(&mDiscardTrackerNode);
}
if (mDecoder) {
@ -421,6 +420,8 @@ RasterImage::~RasterImage()
// Total statistics
num_containers--;
total_source_bytes -= mSourceData.Length();
DiscardTracker::Remove(&mDiscardTrackerNode);
}
void

View File

@ -501,8 +501,7 @@ nsresult nsExtensibleStringBundle::GetSimpleEnumeration(nsISimpleEnumerator ** a
#define MAX_CACHED_BUNDLES 16
struct bundleCacheEntry_t {
PRCList list;
struct bundleCacheEntry_t : public LinkedListElement<bundleCacheEntry_t> {
nsCStringKey *mHashKey;
// do not use a nsCOMPtr - this is a struct not a class!
nsIStringBundle* mBundle;
@ -516,7 +515,6 @@ nsStringBundleService::nsStringBundleService() :
printf("\n++ nsStringBundleService::nsStringBundleService ++\n");
#endif
PR_INIT_CLIST(&mBundleCache);
PL_InitArenaPool(&mCacheEntryPool, "srEntries",
sizeof(bundleCacheEntry_t)*MAX_CACHED_BUNDLES,
sizeof(bundleCacheEntry_t));
@ -582,16 +580,10 @@ nsStringBundleService::flushBundleCache()
// release all bundles in the cache
mBundleMap.Reset();
PRCList *current = PR_LIST_HEAD(&mBundleCache);
while (current != &mBundleCache) {
bundleCacheEntry_t *cacheEntry = (bundleCacheEntry_t*)current;
while (!mBundleCache.isEmpty()) {
bundleCacheEntry_t *cacheEntry = mBundleCache.popFirst();
recycleEntry(cacheEntry);
PRCList *oldItem = current;
current = PR_NEXT_LINK(current);
// will be freed in PL_FreeArenaPool
PR_REMOVE_LINK(oldItem);
}
PL_FreeArenaPool(&mCacheEntryPool);
}
@ -616,7 +608,7 @@ nsStringBundleService::getStringBundle(const char *aURLSpec,
// cache hit!
// remove it from the list, it will later be reinserted
// at the head of the list
PR_REMOVE_LINK((PRCList*)cacheEntry);
cacheEntry->remove();
} else {
@ -633,8 +625,7 @@ nsStringBundleService::getStringBundle(const char *aURLSpec,
// at this point the cacheEntry should exist in the hashtable,
// but is not in the LRU cache.
// put the cache entry at the front of the list
PR_INSERT_LINK((PRCList *)cacheEntry, &mBundleCache);
mBundleCache.insertFront(cacheEntry);
// finally, return the value
*aResult = cacheEntry->mBundle;
@ -654,12 +645,12 @@ nsStringBundleService::insertIntoCache(nsIStringBundle* aBundle,
void *cacheEntryArena;
PL_ARENA_ALLOCATE(cacheEntryArena, &mCacheEntryPool, sizeof(bundleCacheEntry_t));
cacheEntry = (bundleCacheEntry_t*)cacheEntryArena;
cacheEntry = new (cacheEntryArena) bundleCacheEntry_t();
} else {
// cache is full
// take the last entry in the list, and recycle it.
cacheEntry = (bundleCacheEntry_t*)PR_LIST_TAIL(&mBundleCache);
cacheEntry = mBundleCache.getLast();
// remove it from the hash table and linked list
NS_ASSERTION(mBundleMap.Exists(cacheEntry->mHashKey),
@ -670,7 +661,7 @@ nsStringBundleService::insertIntoCache(nsIStringBundle* aBundle,
aHashKey->GetString()).get());
#endif
mBundleMap.Remove(cacheEntry->mHashKey);
PR_REMOVE_LINK((PRCList*)cacheEntry);
cacheEntry->remove();
// free up excess memory
recycleEntry(cacheEntry);

View File

@ -6,7 +6,6 @@
#ifndef nsStringBundleService_h__
#define nsStringBundleService_h__
#include "prclist.h"
#include "plarena.h"
#include "nsCOMPtr.h"
@ -18,6 +17,8 @@
#include "nsIErrorService.h"
#include "nsIStringBundleOverride.h"
#include "mozilla/LinkedList.h"
struct bundleCacheEntry_t;
class nsStringBundleService : public nsIStringBundleService,
@ -48,7 +49,7 @@ private:
static void recycleEntry(bundleCacheEntry_t*);
nsHashtable mBundleMap;
PRCList mBundleCache;
mozilla::LinkedList<bundleCacheEntry_t> mBundleCache;
PLArenaPool mCacheEntryPool;
nsCOMPtr<nsIErrorService> mErrorService;

View File

@ -981,6 +981,8 @@ plstr.h
plarenas.h
plarena.h
plhash.h
speex/speex_resampler.h
soundtouch/SoundTouch.h
#if MOZ_NATIVE_PNG==1
png.h
#endif
@ -1053,7 +1055,6 @@ vpx/vpx_encoder.h
vpx/vp8cx.h
vpx/vp8dx.h
sydneyaudio/sydney_audio.h
speex/speex_resampler.h
vorbis/codec.h
theora/theoradec.h
tremor/ivorbiscodec.h

View File

@ -346,7 +346,6 @@ MOZ_TOOL_VARIABLES
dnl Special win32 checks
dnl ========================================================
# With win8, sdk target=602, WINVER=602
MOZ_ARG_ENABLE_BOOL(metro,
[ --enable-metro Enable Windows Metro build targets],
MOZ_METRO=1,
@ -355,8 +354,7 @@ if test -n "$MOZ_METRO"; then
AC_DEFINE(MOZ_METRO)
# Target the Windows 8 Kit
WINSDK_TARGETVER=602
# Allow a higher api set
WINVER=602
WINVER=502
else
# Target the Windows 7 SDK by default
WINSDK_TARGETVER=601
@ -3136,12 +3134,6 @@ dnl are defined in build/autoconf/altoptions.m4.
dnl If the compiler supports these attributes, define them as
dnl convenience macros.
if test "$ac_cv_attribute_always_inline" = yes ; then
AC_DEFINE(NS_ALWAYS_INLINE, [__attribute__((always_inline))])
else
AC_DEFINE(NS_ALWAYS_INLINE,)
fi
if test "$ac_cv_attribute_malloc" = yes ; then
AC_DEFINE(NS_ATTR_MALLOC, [__attribute__((malloc))])
else

View File

@ -712,7 +712,7 @@ Load(JSContext *cx, unsigned argc, jsval *vp)
return false;
errno = 0;
CompileOptions opts(cx);
opts.setCompileAndGo(true).setNoScriptRval(true);
opts.setUTF8(true).setCompileAndGo(true).setNoScriptRval(true);
if ((compileOnly && !Compile(cx, thisobj, opts, filename.ptr())) ||
!Evaluate(cx, thisobj, opts, filename.ptr(), NULL))
{

View File

@ -4864,6 +4864,12 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c
{
static const char* allowed[] = { "isSuccessCode", "lookupMethod", nullptr };
*_retval = xpc_CheckAccessList(methodName, allowed);
if (*_retval &&
methodName[0] == 'l' &&
!AccessCheck::callerIsXBL(nsContentUtils::GetCurrentJSContext()))
{
Telemetry::Accumulate(Telemetry::COMPONENTS_LOOKUPMETHOD_ACCESSED_BY_CONTENT, true);
}
return NS_OK;
}
@ -4873,6 +4879,12 @@ nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName
{
static const char* allowed[] = { "interfaces", "interfacesByID", "results", nullptr};
*_retval = xpc_CheckAccessList(propertyName, allowed);
if (*_retval &&
propertyName[0] == 'i' &&
!AccessCheck::callerIsXBL(nsContentUtils::GetCurrentJSContext()))
{
Telemetry::Accumulate(Telemetry::COMPONENTS_INTERFACES_ACCESSED_BY_CONTENT, true);
}
return NS_OK;
}

View File

@ -48,7 +48,6 @@ const char* XPCJSRuntime::mStrings[] = {
"constructor", // IDX_CONSTRUCTOR
"toString", // IDX_TO_STRING
"toSource", // IDX_TO_SOURCE
"valueOf", // IDX_VALUE_OF
"lastResult", // IDX_LAST_RESULT
"returnCode", // IDX_RETURN_CODE
"value", // IDX_VALUE

View File

@ -768,7 +768,6 @@ public:
IDX_CONSTRUCTOR = 0 ,
IDX_TO_STRING ,
IDX_TO_SOURCE ,
IDX_VALUE_OF ,
IDX_LAST_RESULT ,
IDX_RETURN_CODE ,
IDX_VALUE ,

View File

@ -13,7 +13,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=781476
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=781476">Mozilla Bug 781476</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe onload="go();" id="ifr" src="file_bug781476.html"></iframe>
</div>
<pre id="test">
<script type="application/javascript">
@ -32,5 +31,6 @@ function go() {
</script>
</pre>
<iframe onload="go();" id="ifr" src="file_bug781476.html"></iframe>
</body>
</html>

View File

@ -14,7 +14,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=801576
<p id="display"></p>
<div id="content" style="display: none">
</div>
<iframe id="ifr" onload="go();" src="file_empty.html"></iframe>
<pre id="test">
<script type="application/javascript">
@ -93,5 +92,6 @@ function go() {
</script>
</pre>
<iframe id="ifr" onload="go();" src="file_empty.html"></iframe>
</body>
</html>

View File

@ -731,13 +731,6 @@ XPCWrappedNativeXrayTraits::preserveWrapper(JSObject *target)
ci->PreserveWrapper(wn->Native());
}
static JSBool
IdentityValueOf(JSContext *cx, unsigned argc, jsval *vp)
{
JS_SET_RVAL(cx, vp, JS_THIS(cx, vp));
return true;
}
bool
XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext *cx, JSObject *wrapper,
JSObject *holder, jsid id, bool set,
@ -768,23 +761,6 @@ XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext *cx, JSObject *wrapp
return true;
}
// Explicitly make valueOf an identity operation so that it plays better
// with the rest of the Xray infrastructure.
if (id == rt->GetStringID(XPCJSRuntime::IDX_VALUE_OF) &&
Is<nsIDOMLocation>(wrapper))
{
JSFunction *fun = JS_NewFunctionById(cx, &IdentityValueOf, 0, 0, NULL, id);
if (!fun)
return false;
desc->obj = wrapper;
desc->attrs = 0;
desc->getter = NULL;
desc->setter = NULL;
desc->shortid = 0;
desc->value = ObjectValue(*JS_GetFunctionObject(fun));
return true;
}
desc->obj = NULL;
// This will do verification and the method lookup for us.

View File

@ -116,6 +116,7 @@
#include "nsIDOMSVGFilters.h"
#include "DOMSVGTests.h"
#include "nsSVGEffects.h"
#include "nsSVGTextPathFrame.h"
#include "nsSVGUtils.h"
#include "nsRefreshDriver.h"
@ -4407,6 +4408,9 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay* aDisplay,
FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructTable) },
{ NS_STYLE_DISPLAY_INLINE_TABLE,
FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructTable) },
// NOTE: In the unlikely event that we add another table-part here that has
// a desired-parent-type (& hence triggers table fixup), we'll need to also
// update the flexbox chunk in nsStyleContext::ApplyStyleFixups().
{ NS_STYLE_DISPLAY_TABLE_CAPTION,
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_ALLOW_BLOCK_STYLES |
FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_SKIP_ABSPOS_PUSH |
@ -7797,6 +7801,12 @@ DoApplyRenderingChangeToTree(nsIFrame* aFrame,
aFrame->InvalidateFrameSubtree();
}
}
if (aChange & nsChangeHint_UpdateTextPath) {
NS_ABORT_IF_FALSE(aFrame->GetType() == nsGkAtoms::svgTextPathFrame,
"textPath frame expected");
// Invalidate and reflow the entire nsSVGTextFrame:
static_cast<nsSVGTextPathFrame*>(aFrame)->NotifyGlyphMetricsChange();
}
if (aChange & nsChangeHint_UpdateOpacityLayer) {
// FIXME/bug 796697: we can get away with empty transactions for
// opacity updates in many cases.

View File

@ -43,13 +43,12 @@ enum nsChangeHint {
nsChangeHint_UpdateCursor = 0x40,
/**
* SVG filter/mask/clip effects need to be recomputed because the URI
* in the filter/mask/clip-path property has changed. This wipes
* out cached nsSVGPropertyBase and subclasses which hold a reference to
* the element referenced by the URI, and a mutation observer for
* the DOM subtree rooted at that element. Also, for filters they store a
* bounding-box for the filter result so that if the filter changes we can
* invalidate the old covered area.
* Used when the computed value (a URI) of one or more of an element's
* filter/mask/clip/etc CSS properties changes, causing the element's frame
* to start/stop referencing (or reference different) SVG resource elements.
* (_Not_ used to handle changes to referenced resource elements.) Using this
* hint results in nsSVGEffects::UpdateEffects being called on the element's
* frame.
*/
nsChangeHint_UpdateEffects = 0x80,
@ -111,7 +110,13 @@ enum nsChangeHint {
* changes, and it's inherited by a child, that might require a reflow
* due to the border-width change on the child.
*/
nsChangeHint_BorderStyleNoneChange = 0x8000
nsChangeHint_BorderStyleNoneChange = 0x8000,
/**
* SVG textPath needs to be recomputed because the path has changed.
* This means that the glyph positions of the text need to be recomputed.
*/
nsChangeHint_UpdateTextPath = 0x10000
// IMPORTANT NOTE: When adding new hints, consider whether you need to
// add them to NS_HintsNotHandledForDescendantsIn() below.

View File

@ -810,6 +810,9 @@ void*
nsDisplayListBuilder::Allocate(size_t aSize) {
void *tmp;
PL_ARENA_ALLOCATE(tmp, &mPool, aSize);
if (!tmp) {
NS_RUNTIMEABORT("out of memory");
}
return tmp;
}
@ -3752,8 +3755,7 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const nsIFrame* aFrame,
if (nsLayoutUtils::Are3DTransformsEnabled() && perspectiveCoord > 0.0) {
gfx3DMatrix perspective;
perspective._34 =
-1.0 / NSAppUnitsToFloatPixels(parentDisp->mChildPerspective.GetCoordValue(),
aAppUnitsPerPixel);
-1.0 / NSAppUnitsToFloatPixels(perspectiveCoord, aAppUnitsPerPixel);
/* At the point when perspective is applied, we have been translated to the transform origin.
* The translation to the perspective origin is the difference between these values.
*/

View File

@ -176,6 +176,7 @@ using namespace mozilla;
#ifdef PR_LOGGING
#ifdef NS_PRINTING
static PRLogModuleInfo *
GetPrintingLog()
{
@ -185,6 +186,7 @@ GetPrintingLog()
return sLog;
}
#define PR_PL(_p1) PR_LOG(GetPrintingLog(), PR_LOG_DEBUG, _p1);
#endif // NS_PRINTING
#define PRT_YESNO(_p) ((_p)?"YES":"NO")
#else
@ -4198,7 +4200,32 @@ DocumentViewerImpl::IncrementDestroyRefCount()
//------------------------------------------------------------
static void ResetFocusState(nsIDocShell* aDocShell);
#if defined(NS_PRINTING) && defined(NS_PRINT_PREVIEW)
//------------------------------------------------------------
// Reset ESM focus for all descendent doc shells.
static void
ResetFocusState(nsIDocShell* aDocShell)
{
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (!fm)
return;
nsCOMPtr<nsISimpleEnumerator> docShellEnumerator;
aDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeContent,
nsIDocShell::ENUMERATE_FORWARDS,
getter_AddRefs(docShellEnumerator));
nsCOMPtr<nsISupports> currentContainer;
bool hasMoreDocShells;
while (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMoreDocShells))
&& hasMoreDocShells) {
docShellEnumerator->GetNext(getter_AddRefs(currentContainer));
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(currentContainer);
if (win)
fm->ClearFocus(win);
}
}
#endif // NS_PRINTING && NS_PRINT_PREVIEW
void
DocumentViewerImpl::ReturnToGalleyPresentation()
@ -4226,31 +4253,6 @@ DocumentViewerImpl::ReturnToGalleyPresentation()
#endif // NS_PRINTING && NS_PRINT_PREVIEW
}
//------------------------------------------------------------
// Reset ESM focus for all descendent doc shells.
static void
ResetFocusState(nsIDocShell* aDocShell)
{
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (!fm)
return;
nsCOMPtr<nsISimpleEnumerator> docShellEnumerator;
aDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeContent,
nsIDocShell::ENUMERATE_FORWARDS,
getter_AddRefs(docShellEnumerator));
nsCOMPtr<nsISupports> currentContainer;
bool hasMoreDocShells;
while (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMoreDocShells))
&& hasMoreDocShells) {
docShellEnumerator->GetNext(getter_AddRefs(currentContainer));
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(currentContainer);
if (win)
fm->ClearFocus(win);
}
}
//------------------------------------------------------------
// This called ONLY when printing has completed and the DV
// is being notified that it should get rid of the PrintEngine.

View File

@ -340,6 +340,9 @@ struct nsPresArena::State {
// Allocate a new chunk from the arena
list->mEntriesEverAllocated++;
PL_ARENA_ALLOCATE(result, &mPool, aSize);
if (!result) {
NS_RUNTIMEABORT("out of memory");
}
return result;
}

View File

@ -3659,9 +3659,6 @@ nsresult
PresShell::PostReflowCallback(nsIReflowCallback* aCallback)
{
void* result = AllocateMisc(sizeof(nsCallbackEventRequest));
if (MOZ_UNLIKELY(!result)) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsCallbackEventRequest* request = (nsCallbackEventRequest*)result;
request->callback = aCallback;

View File

@ -260,9 +260,7 @@ nsIFrame*
NS_NewBlockFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, uint32_t aFlags)
{
nsBlockFrame* it = new (aPresShell) nsBlockFrame(aContext);
if (it) {
it->SetFlags(aFlags);
}
it->SetFlags(aFlags);
return it;
}

View File

@ -160,10 +160,7 @@ nsIFrame*
NS_NewColumnSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, uint32_t aStateFlags)
{
nsColumnSetFrame* it = new (aPresShell) nsColumnSetFrame(aContext);
if (it) {
it->AddStateBits(aStateFlags | NS_BLOCK_MARGIN_ROOT);
}
it->AddStateBits(aStateFlags | NS_BLOCK_MARGIN_ROOT);
return it;
}

View File

@ -423,8 +423,6 @@ nsHTMLFramesetFrame::Init(nsIContent* aContent,
// XXX the blank frame is using the content of its parent - at some point it
// should just have null content, if we support that
nsHTMLFramesetBlankFrame* blankFrame = new (shell) nsHTMLFramesetBlankFrame(pseudoStyleContext);
if (!blankFrame)
return NS_ERROR_OUT_OF_MEMORY;
result = blankFrame->Init(mContent, this, nullptr);
if (NS_FAILED(result)) {

View File

@ -71,9 +71,7 @@ NS_NewLineBox(nsIPresShell* aPresShell, nsLineBox* aFromLine,
nsIFrame* aFrame, int32_t aCount)
{
nsLineBox* newLine = new (aPresShell) nsLineBox(aFrame, aCount, false);
if (newLine) {
newLine->NoteFramesMovedFrom(aFromLine);
}
newLine->NoteFramesMovedFrom(aFromLine);
return newLine;
}

View File

@ -18,12 +18,6 @@
font: 14px sans-serif;
}
i {
/* XXXdholbert HACK - REMOVEME after bug 783415 lands (which will
make this display:block conversion happen automatically). */
display: block;
}
.big {
height: 100px;
font: 24px sans-serif;

View File

@ -21,12 +21,6 @@
font: 14px sans-serif;
}
input, label {
/* XXXdholbert HACK - REMOVEME after bug 783415 lands (which will
make this display:block conversion happen automatically). */
display: block;
}
.big {
height: 100px;
font: 24px sans-serif;

View File

@ -24,19 +24,19 @@
<!-- These cases have a floated span as a grandchild of the flex container.
The span should float within its flex item. -->
<div class="flexbox">
aaa<span><span style="float: left">lll</span></span>bbb
<span>aaa<span style="float: left">lll</span>bbb</span>
</div>
<div class="flexbox">
aaa<span><span style="float: right">rrr</span></span>bbb
<span>aaa<span style="float: right">rrr</span>bbb</span>
</div>
<!-- These cases have a floated div as a grandchild of the flex container.
The div should float within its flex item. -->
<div class="flexbox">
aaa<span><div style="float: left">lll</div></span>bbb
<span>aaa<div style="float: left">lll</div>bbb</span>
</div>
<div class="flexbox">
aaa<span><div style="float: right">rrr</div></span>bbb
<span>aaa<div style="float: right">rrr</div>bbb</span>
</div>
</body>
</html>

View File

@ -17,6 +17,6 @@
</style>
</head>
<body>
<div id="block"><u>abc def ghi</u> jkl <i>mno pqr stu</i></div>
<div id="block">abc def ghi jkl mno pqr stu</div>
</body>
</html>

View File

@ -4,7 +4,7 @@
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!--
This test has a few inline elements in a flex container, for comparison
This test has a run of text in a flex container, for comparison
against the "b" & "c" variants of this test (which use dynamic tweaks).
-->
<html xmlns="http://www.w3.org/1999/xhtml">
@ -19,6 +19,6 @@
</style>
</head>
<body>
<div id="flexbox"><u>abc def ghi</u> jkl <i>mno pqr stu</i></div>
<div id="flexbox">abc def ghi jkl mno pqr stu</div>
</body>
</html>

View File

@ -14,8 +14,7 @@
<link rel="stylesheet" type="text/css" href="ahem.css" />
<script>
function tweak() {
var newInlineContent = document.createElement("u");
newInlineContent.innerHTML = "abc def ghi";
var newInlineContent = document.createTextNode("abc def ghi");
var flexbox = document.getElementById("flexbox");
flexbox.insertBefore(newInlineContent, flexbox.firstChild);
@ -34,6 +33,6 @@
</style>
</head>
<body>
<div id="flexbox"> jkl <i>mno pqr stu</i></div>
<div id="flexbox"> jkl mno pqr stu</div>
</body>
</html>

View File

@ -14,8 +14,7 @@
<link rel="stylesheet" type="text/css" href="ahem.css" />
<script>
function tweak() {
var newInlineContent = document.createElement("i");
newInlineContent.innerHTML = "mno pqr stu";
var newInlineContent = document.createTextNode("mno pqr stu");
var flexbox = document.getElementById("flexbox");
flexbox.insertBefore(newInlineContent, null);
@ -34,6 +33,6 @@
</style>
</head>
<body>
<div id="flexbox"><u>abc def ghi</u> jkl </div>
<div id="flexbox">abc def ghi jkl </div>
</body>
</html>

View File

@ -12,7 +12,7 @@
<head>
<script>
function tweak() {
var removeMe = document.getElementById("removeMe");
var removeMe = document.getElementsByClassName("flexbox")[0].lastChild;
removeMe.parentNode.removeChild(removeMe);
document.documentElement.removeAttribute("class");
}
@ -30,7 +30,7 @@
</head>
<body>
<div class="flexbox">text<div>div</div>
<span id="removeMe">REMOVE</span>
REMOVE ME
</div>
</body>
</html>

View File

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!--
This reference case is like its testcase, but with an explicit div
in the place where we expect an anonymous flex item to be generated
in the testcase.
-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
div.flexbox {
width: 200px;
height: 100px;
display: flex;
justify-content: space-around;
border: 1px dotted black;
}
div.a {
width: 30px;
height: 50px;
background: lightgreen;
}
div.b {
width: 40px;
height: 50px;
background: blue;
}
</style>
</head>
<body>
<div class="flexbox">
<div><span>abc<div class="a"/>def</span></div>
<div class="b"/>
</div>
</body>
</html>

View File

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!--
This test has a block inside an inline inside a flexbox. This is like one
of the examples in the flexbox spec, and the desired behavior is that
the entire inline (including the block inside of it) gets wrapped in an
anonymous flex item.
-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
div.flexbox {
width: 200px;
height: 100px;
display: flex;
justify-content: space-around;
border: 1px dotted black;
}
div.a {
width: 30px;
height: 50px;
background: lightgreen;
}
div.b {
width: 40px;
height: 50px;
background: blue;
}
</style>
</head>
<body>
<div class="flexbox">
<span>abc<div class="a"/>def</span>
<div class="b"/>
</div>
</body>
</html>

View File

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!--
This reference case is like its testcase, but with all of the <span>
wrappers removed, since (if we're doing things right) they shouldn't
affect our rendering.
-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" href="ahem.css" />
<style>
div.flexbox {
border: 1px dashed blue;
display: flex;
}
</style>
</head>
<body>
<div class="flexbox">abc def</div>
<div class="flexbox">abc def</div>
<div class="flexbox">abc def</div>
<div class="flexbox">abc def</div>
<div class="flexbox">abc def</div>
<div class="flexbox">abc def</div>
<div class="flexbox">abc def</div>
<div class="flexbox">abc def</div>
</body>
</html>

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!--
This test verifies that we don't drop whitespace between consecutive
inline boxes inside of an anonymous flex item. In other words, it
verifies that "<span>abc</span> <span>def</span>" renders like "abc def",
and more variants on that theme.
-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" href="ahem.css" />
<style>
div.flexbox {
border: 1px dashed blue;
display: flex;
}
</style>
</head>
<body>
<div class="flexbox">abc def</div>
<div class="flexbox">abc <span>def</span></div>
<div class="flexbox"><span>abc</span> def</div>
<div class="flexbox"><span>abc</span> <span>def</span></div>
<!-- ...and now with whitespace just inside the <span> elements, for extra
fun. (Shouldn't be visible.) -->
<div class="flexbox">abc def</div>
<div class="flexbox">abc <span> def </span></div>
<div class="flexbox"><span> abc </span> def</div>
<div class="flexbox"><span> abc </span> <span> def </span></div>
</body>
</html>

View File

@ -17,6 +17,7 @@
outline: 1px dashed black;
margin: 0;
vertical-align: top;
display: block;
}
</style>
</head>

Some files were not shown because too many files have changed in this diff Show More