mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge the last PGO-green inbound changeset to m-c.
This commit is contained in:
commit
12c86d585c
@ -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");
|
||||
|
@ -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 ====================
|
||||
|
@ -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
101
b2g/components/Keyboard.jsm
Normal 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();
|
@ -34,6 +34,7 @@ EXTRA_PP_COMPONENTS = \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_JS_MODULES = \
|
||||
Keyboard.jsm \
|
||||
TelURIParser.jsm \
|
||||
$(NULL)
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -46,3 +46,4 @@ MOZ_TIME_MANAGER=1
|
||||
|
||||
MOZ_PAY=1
|
||||
MOZ_TOOLKIT_SEARCH=
|
||||
MOZ_B2G=1
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
26
configure.in
26
configure.in
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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;
|
||||
|
57
content/media/webaudio/DynamicsCompressorNode.cpp
Normal file
57
content/media/webaudio/DynamicsCompressorNode.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
82
content/media/webaudio/DynamicsCompressorNode.h
Normal file
82
content/media/webaudio/DynamicsCompressorNode.h
Normal 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
|
||||
|
@ -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)
|
||||
|
@ -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 \
|
||||
|
77
content/media/webaudio/test/test_dynamicsCompressorNode.html
Normal file
77
content/media/webaudio/test/test_dynamicsCompressorNode.html
Normal 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>
|
@ -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()
|
||||
|
@ -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, \
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -181,6 +181,15 @@ DOMInterfaces = {
|
||||
}
|
||||
},
|
||||
|
||||
'DynamicsCompressorNode': [
|
||||
{
|
||||
'resultNotAddRefed': [ 'threshold', 'knee', 'ratio',
|
||||
'reduction', 'attack', 'release' ],
|
||||
'binaryNames': {
|
||||
'release': 'getRelease'
|
||||
}
|
||||
}],
|
||||
|
||||
'Event': [
|
||||
{
|
||||
'workers': True,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -57,6 +57,12 @@ XPIDLSRCS = \
|
||||
nsIIdleObserver.idl \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_B2G
|
||||
XPIDLSRCS += \
|
||||
nsIDOMWindowB2G.idl \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
XPIDL_FLAGS += \
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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)]
|
||||
|
14
dom/interfaces/base/nsIDOMWindowB2G.idl
Normal file
14
dom/interfaces/base/nsIDOMWindowB2G.idl
Normal 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;
|
||||
};
|
@ -504,6 +504,8 @@ public:
|
||||
}
|
||||
LOG(("Selected video device"));
|
||||
}
|
||||
|
||||
found = false;
|
||||
if (mAudio) {
|
||||
nsTArray<nsRefPtr<MediaEngineAudioSource> > audioSources;
|
||||
mBackend->EnumerateAudioDevices(&audioSources);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -33,6 +33,9 @@ interface mozAudioContext {
|
||||
[Creator]
|
||||
PannerNode createPanner();
|
||||
|
||||
[Creator]
|
||||
DynamicsCompressorNode createDynamicsCompressor();
|
||||
|
||||
};
|
||||
|
||||
typedef mozAudioContext AudioContext;
|
||||
|
24
dom/webidl/DynamicsCompressorNode.webidl
Normal file
24
dom/webidl/DynamicsCompressorNode.webidl
Normal 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
|
||||
|
||||
};
|
||||
|
@ -26,6 +26,7 @@ webidl_files = \
|
||||
DOMTokenList.webidl \
|
||||
DOMSettableTokenList.webidl \
|
||||
DOMStringMap.webidl \
|
||||
DynamicsCompressorNode.webidl \
|
||||
Function.webidl \
|
||||
EventHandler.webidl \
|
||||
EventListener.webidl \
|
||||
|
262
gfx/2d/Blur.cpp
262
gfx/2d/Blur.cpp
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
250
gfx/2d/BlurSSE2.cpp
Normal 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*)¤tRowSum)[(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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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
17
gfx/2d/SSEHelpers.h
Normal 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));
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
94
gfx/layers/ipc/ShadowLayerUtilsMac.cpp
Normal file
94
gfx/layers/ipc/ShadowLayerUtilsMac.cpp
Normal 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
|
@ -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 \
|
||||
|
10
gfx/thebes/gfxBaseSharedMemorySurface.cpp
Normal file
10
gfx/thebes/gfxBaseSharedMemorySurface.cpp
Normal 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};
|
||||
|
172
gfx/thebes/gfxBaseSharedMemorySurface.h
Normal file
172
gfx/thebes/gfxBaseSharedMemorySurface.h
Normal 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 */
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
}
|
@ -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 */
|
||||
|
25
gfx/thebes/gfxSharedQuartzSurface.h
Normal file
25
gfx/thebes/gfxSharedQuartzSurface.h
Normal 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 */
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 ,
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
@ -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>
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user