Merge inbound to central, a=merge

This commit is contained in:
Wes Kocher 2015-07-06 17:07:18 -07:00
commit ee29b75368
82 changed files with 951 additions and 848 deletions

View File

@ -457,10 +457,12 @@ DocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
if (IPCAccessibilityActive()) {
DocAccessibleChild* ipcDoc = new DocAccessibleChild(docAcc);
docAcc->SetIPCDoc(ipcDoc);
nsCOMPtr<nsITabChild> tabChild =
do_GetInterface(aDocument->GetDocShell());
static_cast<TabChild*>(tabChild.get())->
SendPDocAccessibleConstructor(ipcDoc, nullptr, 0);
nsIDocShell* docShell = aDocument->GetDocShell();
if (docShell) {
nsCOMPtr<nsITabChild> tabChild = do_GetInterface(docShell);
static_cast<TabChild*>(tabChild.get())->
SendPDocAccessibleConstructor(ipcDoc, nullptr, 0);
}
}
} else {
parentDocAcc->BindChildDocument(docAcc);

View File

@ -928,6 +928,8 @@ pref("general.useragent.device_id", "");
// Make <audio> and <video> talk to the AudioChannelService.
pref("media.useAudioChannelService", true);
// Add Mozilla AudioChannel APIs.
pref("media.useAudioChannelAPI", true);
pref("b2g.version", @MOZ_B2G_VERSION@);
pref("b2g.osName", @MOZ_B2G_OS_NAME@);

View File

@ -555,6 +555,8 @@ let settingsToObserve = {
},
'dom.mozApps.use_reviewer_certs': false,
'dom.mozApps.signed_apps_installable_from': 'https://marketplace.firefox.com',
'dom.serviceWorkers.interception.enabled': true,
'dom.serviceWorkers.testing.enabled': false,
'gfx.layerscope.enabled': false,
'layers.draw-borders': false,
'layers.draw-tile-borders': false,
@ -562,12 +564,12 @@ let settingsToObserve = {
'layers.enable-tiles': true,
'layers.effect.invert': false,
'layers.effect.grayscale': false,
'layers.effect.contrast': "0.0",
'layers.effect.contrast': '0.0',
'mms.debugging.enabled': false,
'network.debugging.enabled': false,
'privacy.donottrackheader.enabled': false,
'ril.debugging.enabled': false,
'ril.radio.disabled': false,
'mms.debugging.enabled': false,
'ril.mms.requestReadReport.enabled': {
prefName: 'dom.mms.requestReadReport',
defaultValue: true

View File

@ -52,6 +52,7 @@ var tests = [
// Preferences
function() {
SpecialPowers.pushPrefEnv({"set": [["dom.ipc.browser_frames.oop_by_default", true],
["media.useAudioChannelAPI", true],
["media.useAudioChannelService", true],
["media.defaultAudioChannel", "telephony"],
["dom.mozBrowserFramesEnabled", true],

View File

@ -13,7 +13,6 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/Likely.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/SegmentedVector.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/dom/FragmentOrElement.h"
@ -1227,12 +1226,24 @@ FragmentOrElement::FireNodeInserted(nsIDocument* aDoc,
//----------------------------------------------------------------------
class ContentUnbinder
{
static const size_t kSegmentSize = sizeof(void*) * 512;
typedef SegmentedVector<nsCOMPtr<nsIContent>, kSegmentSize, InfallibleAllocPolicy> ContentArray;
// nsISupports implementation
static void UnbindSubtree(nsIContent* aNode)
#define SUBTREE_UNBINDINGS_PER_RUNNABLE 500
class ContentUnbinder : public nsRunnable
{
public:
ContentUnbinder()
{
mLast = this;
}
~ContentUnbinder()
{
Run();
}
void UnbindSubtree(nsIContent* aNode)
{
if (aNode->NodeType() != nsIDOMNode::ELEMENT_NODE &&
aNode->NodeType() != nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
@ -1258,56 +1269,73 @@ class ContentUnbinder
}
}
// These two methods are based on DeferredFinalizerImpl.
static void*
AppendContentUnbinderPointer(void* aData, void* aObject)
NS_IMETHOD Run()
{
ContentArray* contentArray = static_cast<ContentArray*>(aData);
if (!contentArray) {
contentArray = new ContentArray();
}
contentArray->InfallibleAppend(dont_AddRef(static_cast<nsIContent*>(aObject)));
return contentArray;
}
static bool
DeferredFinalize(uint32_t aSliceBudget, void* aData)
{
MOZ_ASSERT(aSliceBudget > 0, "nonsensical/useless call with aSliceBudget == 0");
nsAutoScriptBlocker scriptBlocker;
ContentArray* contentArray = static_cast<ContentArray*>(aData);
size_t numToRemove = contentArray->Length();
if (aSliceBudget < numToRemove) {
numToRemove = aSliceBudget;
uint32_t len = mSubtreeRoots.Length();
if (len) {
for (uint32_t i = 0; i < len; ++i) {
UnbindSubtree(mSubtreeRoots[i]);
}
mSubtreeRoots.Clear();
}
for (size_t i = 0; i < numToRemove; ++i) {
nsCOMPtr<nsIContent> element = contentArray->GetLast().forget();
contentArray->PopLast();
UnbindSubtree(element);
}
nsCycleCollector_dispatchDeferredDeletion();
if (contentArray->Length() == 0) {
delete contentArray;
return true;
if (this == sContentUnbinder) {
sContentUnbinder = nullptr;
if (mNext) {
nsRefPtr<ContentUnbinder> next;
next.swap(mNext);
sContentUnbinder = next;
next->mLast = mLast;
mLast = nullptr;
NS_DispatchToMainThread(next);
}
}
return false;
return NS_OK;
}
public:
static void
Append(nsIContent* aSubtreeRoot)
static void UnbindAll()
{
nsCOMPtr<nsIContent> root = aSubtreeRoot;
mozilla::DeferredFinalize(AppendContentUnbinderPointer, DeferredFinalize, root.forget().take());
nsRefPtr<ContentUnbinder> ub = sContentUnbinder;
sContentUnbinder = nullptr;
while (ub) {
ub->Run();
ub = ub->mNext;
}
}
static void Append(nsIContent* aSubtreeRoot)
{
if (!sContentUnbinder) {
sContentUnbinder = new ContentUnbinder();
nsCOMPtr<nsIRunnable> e = sContentUnbinder;
NS_DispatchToMainThread(e);
}
if (sContentUnbinder->mLast->mSubtreeRoots.Length() >=
SUBTREE_UNBINDINGS_PER_RUNNABLE) {
sContentUnbinder->mLast->mNext = new ContentUnbinder();
sContentUnbinder->mLast = sContentUnbinder->mLast->mNext;
}
sContentUnbinder->mLast->mSubtreeRoots.AppendElement(aSubtreeRoot);
}
private:
nsAutoTArray<nsCOMPtr<nsIContent>,
SUBTREE_UNBINDINGS_PER_RUNNABLE> mSubtreeRoots;
nsRefPtr<ContentUnbinder> mNext;
ContentUnbinder* mLast;
static ContentUnbinder* sContentUnbinder;
};
ContentUnbinder* ContentUnbinder::sContentUnbinder = nullptr;
void
FragmentOrElement::ClearContentUnbinder()
{
ContentUnbinder::UnbindAll();
}
NS_IMPL_CYCLE_COLLECTION_CLASS(FragmentOrElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)

View File

@ -65,7 +65,7 @@ public:
private:
~nsNodeWeakReference();
nsINode* mNode;
nsINode* MOZ_NON_OWNING_REF mNode;
};
/**
@ -215,6 +215,7 @@ public:
mRefCnt.RemovePurple();
}
static void ClearContentUnbinder();
static bool CanSkip(nsINode* aNode, bool aRemovingAllowed);
static bool CanSkipInCC(nsINode* aNode);
static bool CanSkipThis(nsINode* aNode);

View File

@ -318,6 +318,8 @@ nsCCUncollectableMarker::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData)
{
if (!strcmp(aTopic, "xpcom-shutdown")) {
Element::ClearContentUnbinder();
nsCOMPtr<nsIObserverService> obs =
mozilla::services::GetObserverService();
if (!obs)
@ -342,6 +344,9 @@ nsCCUncollectableMarker::Observe(nsISupports* aSubject, const char* aTopic,
!strcmp(aTopic, "cycle-collector-forget-skippable");
bool prepareForCC = !strcmp(aTopic, "cycle-collector-begin");
if (prepareForCC) {
Element::ClearContentUnbinder();
}
// Increase generation to effectively unmark all current objects
if (!++sGeneration) {

View File

@ -62,7 +62,7 @@ struct CharacterDataChangeInfo
* mChangeStart + mReplaceLength.
*/
struct Details {
struct MOZ_STACK_CLASS Details {
enum {
eMerge, // two text nodes are merged as a result of normalize()
eSplit // a text node is split as a result of splitText()
@ -71,7 +71,7 @@ struct CharacterDataChangeInfo
* For eMerge it's the text node that will be removed, for eSplit it's the
* new text node.
*/
nsIContent* mNextSibling;
nsIContent* MOZ_NON_OWNING_REF mNextSibling;
};
/**

View File

@ -778,7 +778,10 @@ protected:
// These members are only used on outer windows.
nsCOMPtr<mozilla::dom::Element> mFrameElement;
nsIDocShell *mDocShell; // Weak Reference
// This reference is used by the subclass nsGlobalWindow, and cleared in it's
// DetachFromDocShell() method. This method is called by nsDocShell::Destroy(),
// which is called before the nsDocShell is destroyed.
nsIDocShell* MOZ_NON_OWNING_REF mDocShell; // Weak Reference
// mPerformance is only used on inner windows.
nsRefPtr<nsPerformance> mPerformance;

View File

@ -46,15 +46,6 @@ namespace mozilla {
namespace dom {
template<typename DataType> class MozMap;
struct SelfRef
{
SelfRef() : ptr(nullptr) {}
explicit SelfRef(nsISupports *p) : ptr(p) {}
~SelfRef() { NS_IF_RELEASE(ptr); }
nsISupports* ptr;
};
nsresult
UnwrapArgImpl(JS::Handle<JSObject*> src, const nsIID& iid, void** ppArg);

View File

@ -455,6 +455,9 @@ void
EventStateManager::OnStartToObserveContent(
IMEContentObserver* aIMEContentObserver)
{
if (mIMEContentObserver == aIMEContentObserver) {
return;
}
ReleaseCurrentIMEContentObserver();
mIMEContentObserver = aIMEContentObserver;
}

View File

@ -1076,6 +1076,11 @@ static bool UseAudioChannelService()
return Preferences::GetBool("media.useAudioChannelService");
}
static bool UseAudioChannelAPI()
{
return Preferences::GetBool("media.useAudioChannelAPI");
}
void HTMLMediaElement::UpdatePreloadAction()
{
PreloadAction nextAction = PRELOAD_UNDEFINED;
@ -4445,11 +4450,15 @@ nsresult HTMLMediaElement::UpdateChannelMuteState(AudioChannelState aCanPlay)
// We have to mute this channel.
if (aCanPlay == AUDIO_CHANNEL_STATE_MUTED && !(mMuted & MUTED_BY_AUDIO_CHANNEL)) {
SetMutedInternal(mMuted | MUTED_BY_AUDIO_CHANNEL);
DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptbegin"));
if (UseAudioChannelAPI()) {
DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptbegin"));
}
} else if (aCanPlay != AUDIO_CHANNEL_STATE_MUTED &&
(mMuted & MUTED_BY_AUDIO_CHANNEL)) {
SetMutedInternal(mMuted & ~MUTED_BY_AUDIO_CHANNEL);
DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptend"));
if (UseAudioChannelAPI()) {
DispatchAsyncEvent(NS_LITERAL_STRING("mozinterruptend"));
}
}
SuspendOrResumeElement(mMuted & MUTED_BY_AUDIO_CHANNEL, false);

View File

@ -263,7 +263,7 @@ this.Keyboard = {
break;
case 'Keyboard:Register':
this._keyboardMM = mm;
if (kbID !== null) {
if (kbID) {
// keyboard identifies itself, use its kbID
// this msg would be async, so no need to return
this._keyboardID = kbID;

View File

@ -19,12 +19,34 @@ XPCOMUtils.defineLazyServiceGetter(this, "tm",
"@mozilla.org/thread-manager;1", "nsIThreadManager");
/*
* A WeakMap to map input method iframe window to its active status and kbID.
* A WeakMap to map input method iframe window to
* it's active status, kbID, and ipcHelper.
*/
let WindowMap = {
// WeakMap of <window, object> pairs.
_map: null,
/*
* Set the object associated to the window and return it.
*/
_getObjForWin: function(win) {
if (!this._map) {
this._map = new WeakMap();
}
if (this._map.has(win)) {
return this._map.get(win);
} else {
let obj = {
active: false,
kbID: undefined,
ipcHelper: null
};
this._map.set(win, obj);
return obj;
}
},
/*
* Check if the given window is active.
*/
@ -33,12 +55,7 @@ let WindowMap = {
return false;
}
let obj = this._map.get(win);
if (obj && 'active' in obj) {
return obj.active;
}else{
return false;
}
return this._getObjForWin(win).active;
},
/*
@ -48,45 +65,59 @@ let WindowMap = {
if (!win) {
return;
}
if (!this._map) {
this._map = new WeakMap();
}
if (!this._map.has(win)) {
this._map.set(win, {});
}
this._map.get(win).active = isActive;
let obj = this._getObjForWin(win);
obj.active = isActive;
},
/*
* Get the keyboard ID (assigned by Keyboard.ksm) of the given window.
* Get the keyboard ID (assigned by Keyboard.jsm) of the given window.
*/
getKbID: function(win) {
if (!this._map || !win) {
return null;
return undefined;
}
let obj = this._map.get(win);
if (obj && 'kbID' in obj) {
return obj.kbID;
}else{
return null;
}
let obj = this._getObjForWin(win);
return obj.kbID;
},
/*
* Set the keyboard ID (assigned by Keyboard.ksm) of the given window.
* Set the keyboard ID (assigned by Keyboard.jsm) of the given window.
*/
setKbID: function(win, kbID) {
if (!win) {
return;
}
if (!this._map) {
this._map = new WeakMap();
let obj = this._getObjForWin(win);
obj.kbID = kbID;
},
/*
* Get InputContextDOMRequestIpcHelper instance attached to this window.
*/
getInputContextIpcHelper: function(win) {
if (!win) {
return;
}
if (!this._map.has(win)) {
this._map.set(win, {});
let obj = this._getObjForWin(win);
if (!obj.ipcHelper) {
obj.ipcHelper = new InputContextDOMRequestIpcHelper(win);
}
this._map.get(win).kbID = kbID;
return obj.ipcHelper;
},
/*
* Unset InputContextDOMRequestIpcHelper instance.
*/
unsetInputContextIpcHelper: function(win) {
if (!win) {
return;
}
let obj = this._getObjForWin(win);
if (!obj.ipcHelper) {
return;
}
obj.ipcHelper = null;
}
};
@ -332,9 +363,9 @@ MozInputMethod.prototype = {
// Note: if we need to get it from Keyboard.jsm,
// we have to use a synchronous message
var kbID = WindowMap.getKbID(this._window);
if (kbID !== null) {
if (kbID) {
cpmmSendAsyncMessageWithKbID(this, 'Keyboard:Register', {});
}else{
} else {
let res = cpmm.sendSyncMessage('Keyboard:Register', {});
WindowMap.setKbID(this._window, res[0]);
}
@ -415,6 +446,61 @@ MozInputMethod.prototype = {
}
};
/**
* ==============================================
* InputContextDOMRequestIpcHelper
* ==============================================
*/
function InputContextDOMRequestIpcHelper(win) {
this.initDOMRequestHelper(win,
["Keyboard:GetText:Result:OK",
"Keyboard:GetText:Result:Error",
"Keyboard:SetSelectionRange:Result:OK",
"Keyboard:ReplaceSurroundingText:Result:OK",
"Keyboard:SendKey:Result:OK",
"Keyboard:SendKey:Result:Error",
"Keyboard:SetComposition:Result:OK",
"Keyboard:EndComposition:Result:OK",
"Keyboard:SequenceError"]);
}
InputContextDOMRequestIpcHelper.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
_inputContext: null,
attachInputContext: function(inputCtx) {
if (this._inputContext) {
throw new Error("InputContextDOMRequestIpcHelper: detach the context first.");
}
this._inputContext = inputCtx;
},
// Unset ourselves when the window is destroyed.
uninit: function() {
WindowMap.unsetInputContextIpcHelper(this._window);
},
detachInputContext: function() {
// All requests that are still pending need to be invalidated
// because the context is no longer valid.
this.forEachPromiseResolver(k => {
this.takePromiseResolver(k).reject("InputContext got destroyed");
});
this._inputContext = null;
},
receiveMessage: function(msg) {
if (!this._inputContext) {
dump('InputContextDOMRequestIpcHelper received message without context attached.\n');
return;
}
this._inputContext.receiveMessage(msg);
}
};
/**
* ==============================================
* InputContext
@ -438,11 +524,10 @@ function MozInputContext(ctx) {
}
MozInputContext.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
_window: null,
_context: null,
_contextId: -1,
_ipcHelper: null,
classID: Components.ID("{1e38633d-d08b-4867-9944-afa5c648adb6}"),
@ -453,30 +538,12 @@ MozInputContext.prototype = {
init: function ic_init(win) {
this._window = win;
this._utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
this.initDOMRequestHelper(win,
["Keyboard:GetText:Result:OK",
"Keyboard:GetText:Result:Error",
"Keyboard:SetSelectionRange:Result:OK",
"Keyboard:ReplaceSurroundingText:Result:OK",
"Keyboard:SendKey:Result:OK",
"Keyboard:SendKey:Result:Error",
"Keyboard:SetComposition:Result:OK",
"Keyboard:EndComposition:Result:OK",
"Keyboard:SequenceError"]);
this._ipcHelper = WindowMap.getInputContextIpcHelper(win);
this._ipcHelper.attachInputContext(this);
},
destroy: function ic_destroy() {
let self = this;
// All requests that are still pending need to be invalidated
// because the context is no longer valid.
this.forEachPromiseResolver(function(k) {
self.takePromiseResolver(k).reject("InputContext got destroyed");
});
this.destroyDOMRequestHelper();
// A consuming application might still hold a cached version of
// this object. After destroying all methods will throw because we
// cannot create new promises anymore, but we still hold
@ -487,6 +554,9 @@ MozInputContext.prototype = {
}
}
this._ipcHelper.detachInputContext();
this._ipcHelper = null;
this._window = null;
},
@ -497,9 +567,10 @@ MozInputContext.prototype = {
}
let json = msg.json;
let resolver = this.takePromiseResolver(json.requestId);
let resolver = this._ipcHelper.takePromiseResolver(json.requestId);
if (!resolver) {
dump('InputContext received invalid requestId.\n');
return;
}
@ -715,10 +786,10 @@ MozInputContext.prototype = {
_sendPromise: function(callback) {
let self = this;
return this.createPromise(function(resolve, reject) {
let resolverId = self.getPromiseResolverId({ resolve: resolve, reject: reject });
return this._ipcHelper.createPromise(function(resolve, reject) {
let resolverId = self._ipcHelper.getPromiseResolverId({ resolve: resolve, reject: reject });
if (!WindowMap.isActive(self._window)) {
self.removePromiseResolver(resolverId);
self._ipcHelper.removePromiseResolver(resolverId);
reject('Input method is not active.');
return;
}

View File

@ -671,7 +671,8 @@ let FormAssistant = {
target = target.parentNode;
this.setFocusedElement(target);
this.isHandlingFocus = this.sendInputState(target);
this.sendInputState(target);
this.isHandlingFocus = true;
},
unhandleFocus: function fa_unhandleFocus() {
@ -690,7 +691,8 @@ let FormAssistant = {
return true;
return (element instanceof HTMLInputElement &&
!this.ignoredInputTypes.has(element.type));
!this.ignoredInputTypes.has(element.type) &&
!element.readOnly);
},
getTopLevelEditable: function fa_getTopLevelEditable(element) {
@ -705,15 +707,7 @@ let FormAssistant = {
},
sendInputState: function(element) {
// FIXME/bug 729623: work around apparent bug in the IME manager
// in gecko.
let readonly = element.getAttribute("readonly");
if (readonly) {
return false;
}
sendAsyncMessage("Forms:Input", getJSON(element, this._focusCounter));
return true;
},
getSelectionInfo: function fa_getSelectionInfo() {

View File

@ -20,6 +20,7 @@ support-files =
[test_bug1043828.html]
[test_bug1059163.html]
[test_bug1066515.html]
[test_bug1175399.html]
[test_sendkey_cancel.html]
[test_sync_edit.html]
[test_two_inputs.html]

View File

@ -32,7 +32,7 @@ function kbFrameScript() {
}, function(e){
sendAsyncMessage('test:InputMethod:getText:Reject');
});
}else{
} else {
dump("Could not get inputcontext") ;
}
}
@ -103,7 +103,7 @@ function runTest() {
mmKeyboardB.loadFrameScript('data:,(' + kbFrameScript.toString() + ')();', false);
mmKeyboardB.addMessageListener('test:InputMethod:getText:Resolve', function() {
ok(true, 'getText() was resolved');
info('getText() was resolved');
inputmethod_cleanup();
});
@ -124,6 +124,7 @@ function runTest() {
// STEP 2: Set keyboard A active
function step2() {
info('step2');
let req = keyboardA.setInputMethodActive(true);
req.onsuccess = function(){
@ -140,6 +141,7 @@ function runTest() {
// STEP 3: Set keyboard B active
function step3() {
info('step3');
let req = keyboardB.setInputMethodActive(true);
req.onsuccess = function(){
@ -156,6 +158,7 @@ function runTest() {
// STEP 4: Set keyboard A inactive
function step4() {
info('step4');
let req = keyboardA.setInputMethodActive(false);
req.onsuccess = function(){
@ -172,6 +175,7 @@ function runTest() {
// STEP 5: getText
function step5() {
info('step5');
mmKeyboardB.sendAsyncMessage('test:InputMethod:getText:Do');
}

View File

@ -0,0 +1,62 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1175399
-->
<head>
<title>Test focus when page unloads</title>
<script type="application/javascript;version=1.7" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript;version=1.7" src="inputmethod_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1175399">Mozilla Bug 1175399</a>
<p id="display"></p>
<pre id="test">
<script class="testbody" type="application/javascript;version=1.7">
inputmethod_setup(function() {
runTest();
});
let appFrameScript = function appFrameScript() {
let input = content.document.body.firstElementChild;
input.focus();
content.setTimeout(function() {
sendAsyncMessage('test:step');
});
};
function runTest() {
let im = navigator.mozInputMethod;
// Set current page as an input method.
SpecialPowers.wrap(im).setActive(true);
let iframe = document.createElement('iframe');
iframe.src = 'data:text/html,<html><body><input value="First" readonly></body></html>';
iframe.setAttribute('mozbrowser', true);
document.body.appendChild(iframe);
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
im.oninputcontextchange = function() {
is(false, 'should not receive inputcontextchange event');
};
iframe.addEventListener('mozbrowserloadend', function() {
mm.addMessageListener('test:step', function() {
let inputcontext = navigator.mozInputMethod.inputcontext;
is(inputcontext, null, 'inputcontext is null');
inputmethod_cleanup();
});
mm.loadFrameScript('data:,(' + encodeURIComponent(appFrameScript.toString()) + ')();', false);
});
}
</script>
</pre>
</body>
</html>

View File

@ -161,17 +161,6 @@ EnsureMinCDMVersion(mozIGeckoMediaPluginService* aGMPService,
return MediaKeySystemStatus::Cdm_not_installed;
}
if (aMinCdmVersion == NO_CDM_VERSION) {
return MediaKeySystemStatus::Available;
}
nsresult rv;
int32_t version = versionStr.ToInteger(&rv);
if (NS_FAILED(rv) || version < 0 || aMinCdmVersion > version) {
aOutMessage = NS_LITERAL_CSTRING("Installed CDM version insufficient");
return MediaKeySystemStatus::Cdm_insufficient_version;
}
#ifdef XP_WIN
if (aKeySystem.EqualsLiteral("com.adobe.access") ||
aKeySystem.EqualsLiteral("com.adobe.primetime")) {
@ -197,6 +186,14 @@ EnsureMinCDMVersion(mozIGeckoMediaPluginService* aGMPService,
}
#endif
nsresult rv;
int32_t version = versionStr.ToInteger(&rv);
if (aMinCdmVersion != NO_CDM_VERSION &&
(NS_FAILED(rv) || version < 0 || aMinCdmVersion > version)) {
aOutMessage = NS_LITERAL_CSTRING("Installed CDM version insufficient");
return MediaKeySystemStatus::Cdm_insufficient_version;
}
return MediaKeySystemStatus::Available;
}

View File

@ -183,7 +183,7 @@ GMPParent::LoadProcess()
mState = GMPStateLoaded;
// Hold a self ref while the child process is alive. This ensures that
// during shutdown the GMPParent stays we stay alive long enough to
// during shutdown the GMPParent stays alive long enough to
// terminate the child process.
MOZ_ASSERT(!mHoldingSelfRef);
mHoldingSelfRef = true;
@ -212,6 +212,7 @@ AbortWaitingForGMPAsyncShutdown(nsITimer* aTimer, void* aClosure)
nsresult
GMPParent::EnsureAsyncShutdownTimeoutSet()
{
MOZ_ASSERT(mAsyncShutdownRequired);
if (mAsyncShutdownTimeout) {
return NS_OK;
}
@ -235,9 +236,11 @@ GMPParent::EnsureAsyncShutdownTimeoutSet()
if (service) {
timeout = service->AsyncShutdownTimeoutMs();
}
return mAsyncShutdownTimeout->InitWithFuncCallback(
rv = mAsyncShutdownTimeout->InitWithFuncCallback(
&AbortWaitingForGMPAsyncShutdown, this, timeout,
nsITimer::TYPE_ONE_SHOT);
unused << NS_WARN_IF(NS_FAILED(rv));
return rv;
}
bool
@ -286,17 +289,25 @@ GMPParent::CloseIfUnused()
NS_LITERAL_CSTRING("Sent BeginAsyncShutdown"));
#endif
mAsyncShutdownInProgress = true;
if (!SendBeginAsyncShutdown() ||
NS_FAILED(EnsureAsyncShutdownTimeoutSet())) {
if (!SendBeginAsyncShutdown()) {
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AnnotateCrashReport(
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
NS_LITERAL_CSTRING("Could not send BeginAsyncShutdown - Aborting"));
NS_LITERAL_CSTRING("Could not send BeginAsyncShutdown - Aborting async shutdown"));
#endif
AbortAsyncShutdown();
} else if (NS_FAILED(EnsureAsyncShutdownTimeoutSet())) {
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AnnotateCrashReport(
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
NS_LITERAL_CSTRING("Could not start timer after sending BeginAsyncShutdown - Aborting async shutdown"));
#endif
AbortAsyncShutdown();
}
}
} else {
// No async-shutdown, kill async-shutdown timer started in CloseActive().
AbortAsyncShutdown();
// Any async shutdown must be complete. Shutdown GMPStorage.
for (size_t i = mStorage.Length(); i > 0; i--) {
mStorage[i - 1]->Shutdown();
@ -346,7 +357,38 @@ GMPParent::CloseActive(bool aDieWhenUnloaded)
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
nsPrintfCString("Sent CloseActive, content children to close: %u", mGMPContentChildCount));
#endif
unused << SendCloseActive();
if (!SendCloseActive()) {
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AnnotateCrashReport(
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
NS_LITERAL_CSTRING("Could not send CloseActive - Aborting async shutdown"));
#endif
AbortAsyncShutdown();
} else if (IsUsed()) {
// We're expecting RecvPGMPContentChildDestroyed's -> Start async-shutdown timer now if needed.
if (mAsyncShutdownRequired && NS_FAILED(EnsureAsyncShutdownTimeoutSet())) {
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AnnotateCrashReport(
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
NS_LITERAL_CSTRING("Could not start timer after sending CloseActive - Aborting async shutdown"));
#endif
AbortAsyncShutdown();
}
} else {
// We're not expecting any RecvPGMPContentChildDestroyed
// -> Call CloseIfUnused() now, to run async shutdown if necessary.
// Note that CloseIfUnused() may have already been called from a prior
// RecvPGMPContentChildDestroyed(), however depending on the state at
// that time, it might not have proceeded with shutdown; And calling it
// again after shutdown is fine because after the first one we'll be in
// GMPStateNotLoaded.
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AnnotateCrashReport(
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
NS_LITERAL_CSTRING("Content children already destroyed"));
#endif
CloseIfUnused();
}
}
}

View File

@ -35,6 +35,7 @@
#include "PeriodicWave.h"
#include "ConvolverNode.h"
#include "OscillatorNode.h"
#include "blink/PeriodicWave.h"
#include "nsNetUtil.h"
#include "AudioStream.h"
#include "mozilla/dom/Promise.h"
@ -1050,5 +1051,48 @@ AudioContext::ExtraCurrentTime() const
return mDestination->ExtraCurrentTime();
}
BasicWaveFormCache*
AudioContext::GetBasicWaveFormCache()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mBasicWaveFormCache) {
mBasicWaveFormCache = new BasicWaveFormCache(SampleRate());
}
return mBasicWaveFormCache;
}
BasicWaveFormCache::BasicWaveFormCache(uint32_t aSampleRate)
: mSampleRate(aSampleRate)
{
MOZ_ASSERT(NS_IsMainThread());
}
BasicWaveFormCache::~BasicWaveFormCache()
{ }
WebCore::PeriodicWave*
BasicWaveFormCache::GetBasicWaveForm(OscillatorType aType)
{
MOZ_ASSERT(!NS_IsMainThread());
if (aType == OscillatorType::Sawtooth) {
if (!mSawtooth) {
mSawtooth = WebCore::PeriodicWave::createSawtooth(mSampleRate);
}
return mSawtooth;
} else if (aType == OscillatorType::Square) {
if (!mSquare) {
mSquare = WebCore::PeriodicWave::createSquare(mSampleRate);
}
return mSquare;
} else if (aType == OscillatorType::Triangle) {
if (!mTriangle) {
mTriangle = WebCore::PeriodicWave::createTriangle(mSampleRate);
}
return mTriangle;
} else {
MOZ_ASSERT(false, "Not reached");
return nullptr;
}
}
}
}

View File

@ -27,6 +27,10 @@
#undef CurrentTime
#endif
namespace WebCore {
class PeriodicWave;
};
class nsPIDOMWindow;
namespace mozilla {
@ -65,6 +69,25 @@ class StereoPannerNode;
class WaveShaperNode;
class PeriodicWave;
class Promise;
enum class OscillatorType : uint32_t;
// This is addrefed by the OscillatorNodeEngine on the main thread
// and then used from the MSG thread.
// It can be released either from the graph thread or the main thread.
class BasicWaveFormCache
{
public:
explicit BasicWaveFormCache(uint32_t aSampleRate);
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BasicWaveFormCache)
WebCore::PeriodicWave* GetBasicWaveForm(OscillatorType aType);
private:
~BasicWaveFormCache();
nsRefPtr<WebCore::PeriodicWave> mSawtooth;
nsRefPtr<WebCore::PeriodicWave> mSquare;
nsRefPtr<WebCore::PeriodicWave> mTriangle;
uint32_t mSampleRate;
};
/* This runnable allows the MSG to notify the main thread when audio is actually
* flowing */
@ -294,6 +317,8 @@ public:
void OnStateChanged(void* aPromise, AudioContextState aNewState);
BasicWaveFormCache* GetBasicWaveFormCache();
IMPL_EVENT_HANDLER(mozinterruptbegin)
IMPL_EVENT_HANDLER(mozinterruptend)
@ -339,6 +364,8 @@ private:
// Hashsets containing all the PannerNodes, to compute the doppler shift.
// These are weak pointers.
nsTHashtable<nsPtrHashKey<PannerNode> > mPannerNodes;
// Cache to avoid recomputing basic waveforms all the time.
nsRefPtr<BasicWaveFormCache> mBasicWaveFormCache;
// Number of channels passed in the OfflineAudioContext ctor.
uint32_t mNumberOfChannels;
// Number of nodes that currently exist for this AudioContext

View File

@ -293,6 +293,11 @@ static bool UseAudioChannelService()
return Preferences::GetBool("media.useAudioChannelService");
}
static bool UseAudioChannelAPI()
{
return Preferences::GetBool("media.useAudioChannelAPI");
}
class EventProxyHandler final : public nsIDOMEventListener
{
public:
@ -543,9 +548,11 @@ AudioDestinationNode::CanPlayChanged(int32_t aCanPlay)
mAudioChannelAgentPlaying = playing;
SetCanPlay(playing);
Context()->DispatchTrustedEvent(
playing ? NS_LITERAL_STRING("mozinterruptend")
: NS_LITERAL_STRING("mozinterruptbegin"));
if (UseAudioChannelAPI()) {
Context()->DispatchTrustedEvent(
playing ? NS_LITERAL_STRING("mozinterruptend")
: NS_LITERAL_STRING("mozinterruptbegin"));
}
return NS_OK;
}

View File

@ -40,6 +40,8 @@ public:
, mRecomputeParameters(true)
, mCustomLength(0)
{
MOZ_ASSERT(NS_IsMainThread());
mBasicWaveFormCache = aDestination->Context()->GetBasicWaveFormCache();
}
void SetSourceStream(AudioNodeStream* aSource)
@ -104,13 +106,9 @@ public:
mPhase = 0.0;
break;
case OscillatorType::Square:
mPeriodicWave = WebCore::PeriodicWave::createSquare(mSource->SampleRate());
break;
case OscillatorType::Triangle:
mPeriodicWave = WebCore::PeriodicWave::createTriangle(mSource->SampleRate());
break;
case OscillatorType::Sawtooth:
mPeriodicWave = WebCore::PeriodicWave::createSawtooth(mSource->SampleRate());
mPeriodicWave = mBasicWaveFormCache->GetBasicWaveForm(mType);
break;
case OscillatorType::Custom:
break;
@ -371,8 +369,9 @@ public:
float mPhaseIncrement;
bool mRecomputeParameters;
nsRefPtr<ThreadSharedFloatArrayBufferList> mCustom;
nsRefPtr<BasicWaveFormCache> mBasicWaveFormCache;
uint32_t mCustomLength;
nsAutoPtr<WebCore::PeriodicWave> mPeriodicWave;
nsRefPtr<WebCore::PeriodicWave> mPeriodicWave;
};
OscillatorNode::OscillatorNode(AudioContext* aContext)

View File

@ -12,7 +12,6 @@
#include "mozilla/Attributes.h"
#include "AudioContext.h"
#include "AudioNodeEngine.h"
#include "nsAutoPtr.h"
namespace mozilla {

View File

@ -40,48 +40,58 @@ using mozilla::dom::OscillatorType;
namespace WebCore {
PeriodicWave* PeriodicWave::create(float sampleRate,
const float* real,
const float* imag,
size_t numberOfComponents)
already_AddRefed<PeriodicWave>
PeriodicWave::create(float sampleRate,
const float* real,
const float* imag,
size_t numberOfComponents)
{
bool isGood = real && imag && numberOfComponents > 0 &&
numberOfComponents <= PeriodicWaveSize;
MOZ_ASSERT(isGood);
if (isGood) {
PeriodicWave* periodicWave = new PeriodicWave(sampleRate);
nsRefPtr<PeriodicWave> periodicWave =
new PeriodicWave(sampleRate);
periodicWave->createBandLimitedTables(real, imag, numberOfComponents);
return periodicWave;
return periodicWave.forget();
}
return 0;
return nullptr;
}
PeriodicWave* PeriodicWave::createSine(float sampleRate)
already_AddRefed<PeriodicWave>
PeriodicWave::createSine(float sampleRate)
{
PeriodicWave* periodicWave = new PeriodicWave(sampleRate);
periodicWave->generateBasicWaveform(OscillatorType::Sine);
return periodicWave;
nsRefPtr<PeriodicWave> periodicWave =
new PeriodicWave(sampleRate);
periodicWave->generateBasicWaveform(OscillatorType::Sine);
return periodicWave.forget();
}
PeriodicWave* PeriodicWave::createSquare(float sampleRate)
already_AddRefed<PeriodicWave>
PeriodicWave::createSquare(float sampleRate)
{
PeriodicWave* periodicWave = new PeriodicWave(sampleRate);
periodicWave->generateBasicWaveform(OscillatorType::Square);
return periodicWave;
nsRefPtr<PeriodicWave> periodicWave =
new PeriodicWave(sampleRate);
periodicWave->generateBasicWaveform(OscillatorType::Square);
return periodicWave.forget();
}
PeriodicWave* PeriodicWave::createSawtooth(float sampleRate)
already_AddRefed<PeriodicWave>
PeriodicWave::createSawtooth(float sampleRate)
{
PeriodicWave* periodicWave = new PeriodicWave(sampleRate);
periodicWave->generateBasicWaveform(OscillatorType::Sawtooth);
return periodicWave;
nsRefPtr<PeriodicWave> periodicWave =
new PeriodicWave(sampleRate);
periodicWave->generateBasicWaveform(OscillatorType::Sawtooth);
return periodicWave.forget();
}
PeriodicWave* PeriodicWave::createTriangle(float sampleRate)
already_AddRefed<PeriodicWave>
PeriodicWave::createTriangle(float sampleRate)
{
PeriodicWave* periodicWave = new PeriodicWave(sampleRate);
periodicWave->generateBasicWaveform(OscillatorType::Triangle);
return periodicWave;
nsRefPtr<PeriodicWave> periodicWave =
new PeriodicWave(sampleRate);
periodicWave->generateBasicWaveform(OscillatorType::Triangle);
return periodicWave.forget();
}
PeriodicWave::PeriodicWave(float sampleRate)

View File

@ -42,17 +42,19 @@ typedef nsTArray<float> AudioFloatArray;
class PeriodicWave {
public:
static PeriodicWave* createSine(float sampleRate);
static PeriodicWave* createSquare(float sampleRate);
static PeriodicWave* createSawtooth(float sampleRate);
static PeriodicWave* createTriangle(float sampleRate);
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebCore::PeriodicWave);
static already_AddRefed<PeriodicWave> createSine(float sampleRate);
static already_AddRefed<PeriodicWave> createSquare(float sampleRate);
static already_AddRefed<PeriodicWave> createSawtooth(float sampleRate);
static already_AddRefed<PeriodicWave> createTriangle(float sampleRate);
// Creates an arbitrary periodic wave given the frequency components
// (Fourier coefficients).
static PeriodicWave* create(float sampleRate,
const float* real,
const float* imag,
size_t numberOfComponents);
static already_AddRefed<PeriodicWave> create(float sampleRate,
const float* real,
const float* imag,
size_t numberOfComponents);
// Returns pointers to the lower and higher wave data for the pitch range
// containing the given fundamental frequency. These two tables are in
@ -75,6 +77,7 @@ public:
private:
explicit PeriodicWave(float sampleRate);
~PeriodicWave() {}
void generateBasicWaveform(mozilla::dom::OscillatorType);

View File

@ -35,6 +35,7 @@ function test() {
"dom/media/webaudio/test/browser_mozAudioChannel.html";
SpecialPowers.pushPrefEnv({"set": [["media.defaultAudioChannel", "content" ],
["media.useAudioChannelAPI", true ],
["media.useAudioChannelService", true ]]},
function() {
let tab1 = gBrowser.addTab(testURL);

View File

@ -35,6 +35,7 @@ function test() {
"dom/media/webaudio/test/browser_mozAudioChannel_muted.html";
SpecialPowers.pushPrefEnv({"set": [["media.defaultAudioChannel", "content" ],
["media.useAudioChannelAPI", true ],
["media.useAudioChannelService", true ]]},
function() {
let tab1 = gBrowser.addTab(testURL);

View File

@ -141,7 +141,8 @@ function runTest() {
test();
}
SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelService", true ]]}, runTest);
SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelAPI", true ],
["media.useAudioChannelService", true ]]}, runTest);
SimpleTest.waitForExplicitFinish();
SimpleTest.requestLongerTimeout(5);

View File

@ -2853,8 +2853,7 @@ PluginInstanceChild::CreateOptSurface(void)
#endif
#ifdef XP_WIN
if (mSurfaceType == gfxSurfaceType::Win32 ||
mSurfaceType == gfxSurfaceType::D2D) {
if (mSurfaceType == gfxSurfaceType::Win32) {
bool willHaveTransparentPixels = mIsTransparent && !mBackground;
SharedDIBSurface* s = new SharedDIBSurface();

View File

@ -50,8 +50,9 @@ class Promise;
#if defined(DOM_PROMISE_DEPRECATED_REPORTING)
class PromiseReportRejectFeature : public workers::WorkerFeature
{
// The Promise that owns this feature.
Promise* mPromise;
// PromiseReportRejectFeature is held by an nsAutoPtr on the Promise which
// means that this object will be destroyed before the Promise is destroyed.
Promise* MOZ_NON_OWNING_REF mPromise;
public:
explicit PromiseReportRejectFeature(Promise* aPromise)

View File

@ -95,16 +95,16 @@ interface AudioContext : EventTarget {
// Mozilla extensions
partial interface AudioContext {
// Read AudioChannel.webidl for more information about this attribute.
[Pref="media.useAudioChannelService"]
[Pref="media.useAudioChannelAPI"]
readonly attribute AudioChannel mozAudioChannelType;
// These 2 events are dispatched when the AudioContext object is muted by
// the AudioChannelService. It's call 'interrupt' because when this event is
// dispatched on a HTMLMediaElement, the audio stream is paused.
[Pref="media.useAudioChannelService"]
[Pref="media.useAudioChannelAPI"]
attribute EventHandler onmozinterruptbegin;
[Pref="media.useAudioChannelService"]
[Pref="media.useAudioChannelAPI"]
attribute EventHandler onmozinterruptend;
// This method is for test only.

View File

@ -3544,12 +3544,38 @@ WorkerPrivateParent<Derived>::DispatchMessageEventToMessagePort(
AssertIsOnMainThread();
JSAutoStructuredCloneBuffer buffer(Move(aBuffer));
const JSStructuredCloneCallbacks* callbacks =
WorkerStructuredCloneCallbacks(true);
class MOZ_STACK_CLASS AutoCloneBufferCleaner final
{
public:
AutoCloneBufferCleaner(JSAutoStructuredCloneBuffer& aBuffer,
const JSStructuredCloneCallbacks* aCallbacks,
WorkerStructuredCloneClosure& aClosure)
: mBuffer(aBuffer)
, mCallbacks(aCallbacks)
, mClosure(aClosure)
{}
~AutoCloneBufferCleaner()
{
mBuffer.clear(mCallbacks, &mClosure);
}
private:
JSAutoStructuredCloneBuffer& mBuffer;
const JSStructuredCloneCallbacks* mCallbacks;
WorkerStructuredCloneClosure& mClosure;
};
WorkerStructuredCloneClosure closure;
closure.mClonedObjects.SwapElements(aClosure.mClonedObjects);
MOZ_ASSERT(aClosure.mMessagePorts.IsEmpty());
closure.mMessagePortIdentifiers.SwapElements(aClosure.mMessagePortIdentifiers);
AutoCloneBufferCleaner bufferCleaner(buffer, callbacks, closure);
SharedWorker* sharedWorker;
if (!mSharedWorkers.Get(aMessagePortSerial, &sharedWorker)) {
// SharedWorker has already been unregistered?
@ -3577,8 +3603,6 @@ WorkerPrivateParent<Derived>::DispatchMessageEventToMessagePort(
return false;
}
buffer.clear();
nsRefPtr<MessageEvent> event = new MessageEvent(port, nullptr, nullptr);
nsresult rv =
event->InitMessageEvent(NS_LITERAL_STRING("message"), false, false, data,

View File

@ -659,9 +659,6 @@ DrawTargetCairo::GetType() const
case CAIRO_SURFACE_TYPE_RECORDING:
case CAIRO_SURFACE_TYPE_DRM:
case CAIRO_SURFACE_TYPE_SUBSURFACE:
#ifdef CAIRO_HAS_D2D_SURFACE
case CAIRO_SURFACE_TYPE_D2D:
#endif
case CAIRO_SURFACE_TYPE_TEE: // included to silence warning about unhandled enum value
return DrawTargetType::SOFTWARE_RASTER;
default:

View File

@ -50,7 +50,12 @@ DrawTargetD2D1::~DrawTargetD2D1()
// mSnapshot will be cleared now.
}
mDC->EndDraw();
if (mDC) {
// The only way mDC can be null is if Init failed, but it can happen and the
// destructor is the only place where we need to check for it since the
// DrawTarget will destroyed right after Init fails.
mDC->EndDraw();
}
// Targets depending on us can break that dependency, since we're obviously not going to
// be modified in the future.

View File

@ -32,7 +32,6 @@
#endif
#ifdef XP_WIN
#include "gfxD2DSurface.h"
#include "gfxWindowsPlatform.h"
#include <d3d10_1.h>
#include "D3D9SurfaceImage.h"

View File

@ -45,7 +45,9 @@ window.onload = function() {
// The B2G emulator is hella slow, and needs more than 300ms to run the
// main-thread code that deals with layerizing subframes and running
// touch listeners. In my local runs this needs to be at least 1000.
["apz.content_response_timeout", "5000"]
// On try this sometimes needs to be as long as 8 seconds (bug 1176798)
// so we make it 15 seconds just to be extra safe.
["apz.content_response_timeout", "15000"]
]
}, testDone);
};

View File

@ -74,7 +74,7 @@ ContentClient::CreateContentClient(CompositableForwarder* aForwarder)
#ifdef XP_WIN
if (backend == LayersBackend::LAYERS_D3D11) {
useDoubleBuffering = !!gfxWindowsPlatform::GetPlatform()->GetD2DDevice();
useDoubleBuffering = !!gfxWindowsPlatform::GetPlatform()->GetD3D10Device();
} else
#endif
#ifdef MOZ_WIDGET_GTK

View File

@ -344,7 +344,7 @@ TextureClient::CreateForDrawing(ISurfaceAllocator* aAllocator,
if (parentBackend == LayersBackend::LAYERS_D3D11 &&
(aMoz2DBackend == gfx::BackendType::DIRECT2D ||
aMoz2DBackend == gfx::BackendType::DIRECT2D1_1) &&
gfxWindowsPlatform::GetPlatform()->GetD2DDevice() &&
gfxWindowsPlatform::GetPlatform()->GetD3D10Device() &&
aSize.width <= maxTextureSize &&
aSize.height <= maxTextureSize) {
texture = new TextureClientD3D11(aAllocator, aFormat, aTextureFlags);
@ -355,7 +355,7 @@ TextureClient::CreateForDrawing(ISurfaceAllocator* aAllocator,
aSize.width <= maxTextureSize &&
aSize.height <= maxTextureSize) {
if (gfxWindowsPlatform::GetPlatform()->GetD3D9Device()) {
texture = new CairoTextureClientD3D9(aAllocator, aFormat, aTextureFlags);
texture = new TextureClientD3D9(aAllocator, aFormat, aTextureFlags);
}
}

View File

@ -502,7 +502,7 @@ protected:
* deserialized.
* Calling ToSurfaceDescriptor again after it has already returned true,
* or never constructing a TextureHost with aDescriptor may result in a memory
* leak (see CairoTextureClientD3D9 for example).
* leak (see TextureClientD3D9 for example).
*/
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) = 0;

View File

@ -9,7 +9,6 @@
#include "Effects.h"
#include "mozilla/layers/YCbCrImageDataSerializer.h"
#include "gfxWindowsPlatform.h"
#include "gfxD2DSurface.h"
#include "gfx2DGlue.h"
#include "gfxPrefs.h"
#include "ReadbackManagerD3D11.h"

View File

@ -161,7 +161,7 @@ CompositingRenderTargetD3D9::GetSize() const
}
/**
* Helper method for DataToTexture and SurfaceToTexture.
* Helper method for DataToTexture.
* The last three params are out params.
* Returns the created texture, or null if we fail.
*/
@ -203,7 +203,7 @@ TextureSourceD3D9::InitTextures(DeviceManagerD3D9* aDeviceManager,
}
/**
* Helper method for DataToTexture and SurfaceToTexture.
* Helper method for DataToTexture.
*/
static void
FinishTextures(DeviceManagerD3D9* aDeviceManager,
@ -274,47 +274,6 @@ TextureSourceD3D9::TextureToTexture(DeviceManagerD3D9* aDeviceManager,
return texture.forget();
}
already_AddRefed<IDirect3DTexture9>
TextureSourceD3D9::SurfaceToTexture(DeviceManagerD3D9* aDeviceManager,
gfxWindowsSurface* aSurface,
const IntSize& aSize,
_D3DFORMAT aFormat)
{
RefPtr<IDirect3DSurface9> surface;
D3DLOCKED_RECT lockedRect;
RefPtr<IDirect3DTexture9> texture = InitTextures(aDeviceManager, aSize, aFormat,
surface, lockedRect);
if (!texture) {
return nullptr;
}
{
RefPtr<DrawTarget> dt =
Factory::CreateDrawTargetForData(BackendType::CAIRO,
reinterpret_cast<unsigned char*>(lockedRect.pBits),
aSize, lockedRect.Pitch,
gfxPlatform::GetPlatform()->Optimal2DFormatForContent(aSurface->GetContentType()));
if (dt) {
NativeSurface nativeSurf;
nativeSurf.mSize = aSize;
nativeSurf.mType = NativeSurfaceType::CAIRO_SURFACE;
// We don't know that this is actually the right format, but it's the best
// we can get for the content type. In practice this probably always works.
nativeSurf.mFormat = dt->GetFormat();
nativeSurf.mSurface = aSurface->CairoSurface();
RefPtr<SourceSurface> surf = dt->CreateSourceSurfaceFromNativeSurface(nativeSurf);
dt->CopySurface(surf, IntRect(IntPoint(), aSize), IntPoint());
}
}
FinishTextures(aDeviceManager, texture, surface);
return texture.forget();
}
DataTextureSourceD3D9::DataTextureSourceD3D9(gfx::SurfaceFormat aFormat,
CompositorD3D9* aCompositor,
TextureFlags aFlags,
@ -440,81 +399,6 @@ DataTextureSourceD3D9::Update(gfx::DataSourceSurface* aSurface,
return true;
}
bool
DataTextureSourceD3D9::Update(gfxWindowsSurface* aSurface)
{
MOZ_ASSERT(aSurface);
if (!mCompositor || !mCompositor->device()) {
NS_WARNING("No D3D device to update the texture.");
return false;
}
mSize = aSurface->GetSize();
uint32_t bpp = 0;
_D3DFORMAT format = D3DFMT_A8R8G8B8;
mFormat = ImageFormatToSurfaceFormat(
gfxPlatform::GetPlatform()->OptimalFormatForContent(aSurface->GetContentType()));
switch (mFormat) {
case SurfaceFormat::B8G8R8X8:
format = D3DFMT_X8R8G8B8;
bpp = 4;
break;
case SurfaceFormat::B8G8R8A8:
format = D3DFMT_A8R8G8B8;
bpp = 4;
break;
case SurfaceFormat::A8:
format = D3DFMT_A8;
bpp = 1;
break;
default:
NS_WARNING("Bad image format");
return false;
}
int32_t maxSize = mCompositor->GetMaxTextureSize();
DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
if ((mSize.width <= maxSize && mSize.height <= maxSize) ||
(mFlags & TextureFlags::DISALLOW_BIGIMAGE)) {
mTexture = SurfaceToTexture(deviceManager, aSurface, mSize, format);
if (!mTexture) {
NS_WARNING("Could not upload texture");
Reset();
return false;
}
mIsTiled = false;
} else {
mIsTiled = true;
uint32_t tileCount = GetRequiredTilesD3D9(mSize.width, maxSize) *
GetRequiredTilesD3D9(mSize.height, maxSize);
mTileTextures.resize(tileCount);
mTexture = nullptr;
nsRefPtr<gfxImageSurface> imgSurface = aSurface->GetAsImageSurface();
for (uint32_t i = 0; i < tileCount; i++) {
IntRect tileRect = GetTileRect(i);
unsigned char* data = imgSurface->Data() +
tileRect.y * imgSurface->Stride() +
tileRect.x * bpp;
mTileTextures[i] = DataToTexture(deviceManager,
data,
imgSurface->Stride(),
IntSize(tileRect.width, tileRect.height),
format,
bpp);
if (!mTileTextures[i]) {
NS_WARNING("Could not upload texture");
Reset();
return false;
}
}
}
return true;
}
void
DataTextureSourceD3D9::SetCompositor(Compositor* aCompositor)
{
@ -558,9 +442,9 @@ DataTextureSourceD3D9::GetTileRect()
return GetTileRect(mCurrentTile);
}
CairoTextureClientD3D9::CairoTextureClientD3D9(ISurfaceAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
TextureFlags aFlags)
TextureClientD3D9::TextureClientD3D9(ISurfaceAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
TextureFlags aFlags)
: TextureClient(aAllocator, aFlags)
, mFormat(aFormat)
, mIsLocked(false)
@ -568,19 +452,19 @@ CairoTextureClientD3D9::CairoTextureClientD3D9(ISurfaceAllocator* aAllocator,
, mNeedsClearWhite(false)
, mLockRect(false)
{
MOZ_COUNT_CTOR(CairoTextureClientD3D9);
MOZ_COUNT_CTOR(TextureClientD3D9);
}
CairoTextureClientD3D9::~CairoTextureClientD3D9()
TextureClientD3D9::~TextureClientD3D9()
{
MOZ_COUNT_DTOR(CairoTextureClientD3D9);
MOZ_COUNT_DTOR(TextureClientD3D9);
}
already_AddRefed<TextureClient>
CairoTextureClientD3D9::CreateSimilar(TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const
TextureClientD3D9::CreateSimilar(TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const
{
RefPtr<TextureClient> tex = new CairoTextureClientD3D9(mAllocator, mFormat,
mFlags | aFlags);
RefPtr<TextureClient> tex = new TextureClientD3D9(mAllocator, mFormat,
mFlags | aFlags);
if (!tex->AllocateForSurface(mSize, aAllocFlags)) {
return nullptr;
@ -590,7 +474,7 @@ CairoTextureClientD3D9::CreateSimilar(TextureFlags aFlags, TextureAllocationFlag
}
bool
CairoTextureClientD3D9::Lock(OpenMode aMode)
TextureClientD3D9::Lock(OpenMode aMode)
{
MOZ_ASSERT(!mIsLocked);
if (!IsValid() || !IsAllocated()) {
@ -647,7 +531,7 @@ CairoTextureClientD3D9::Lock(OpenMode aMode)
}
void
CairoTextureClientD3D9::Unlock()
TextureClientD3D9::Unlock()
{
MOZ_ASSERT(mIsLocked, "Unlocked called while the texture is not locked!");
if (!mIsLocked) {
@ -664,14 +548,11 @@ CairoTextureClientD3D9::Unlock()
mLockRect = false;
}
if (mSurface) {
mSurface = nullptr;
}
mIsLocked = false;
}
bool
CairoTextureClientD3D9::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
TextureClientD3D9::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
{
MOZ_ASSERT(IsValid());
if (!IsAllocated()) {
@ -684,7 +565,7 @@ CairoTextureClientD3D9::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
}
gfx::DrawTarget*
CairoTextureClientD3D9::BorrowDrawTarget()
TextureClientD3D9::BorrowDrawTarget()
{
MOZ_ASSERT(mIsLocked && mD3D9Surface);
if (!mIsLocked || !mD3D9Surface) {
@ -697,12 +578,13 @@ CairoTextureClientD3D9::BorrowDrawTarget()
}
if (ContentForFormat(mFormat) == gfxContentType::COLOR) {
mSurface = new gfxWindowsSurface(mD3D9Surface);
if (!mSurface || mSurface->CairoStatus()) {
nsRefPtr<gfxASurface> surface = new gfxWindowsSurface(mD3D9Surface);
if (!surface || surface->CairoStatus()) {
NS_WARNING("Could not create surface for d3d9 surface");
mSurface = nullptr;
return nullptr;
}
mDrawTarget =
gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surface, mSize);
} else {
// gfxWindowsSurface don't support transparency so we can't use the d3d9
// windows surface optimization.
@ -713,19 +595,17 @@ CairoTextureClientD3D9::BorrowDrawTarget()
gfxCriticalError() << "Failed to lock rect borrowing the target in D3D9 " << hexa(hr);
return nullptr;
}
mSurface = new gfxImageSurface((uint8_t*)rect.pBits, mSize,
rect.Pitch, SurfaceFormatToImageFormat(mFormat));
mDrawTarget =
gfxPlatform::GetPlatform()->CreateDrawTargetForData((uint8_t*)rect.pBits, mSize,
rect.Pitch, mFormat);
mLockRect = true;
}
mDrawTarget =
gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mSurface, mSize);
return mDrawTarget;
}
bool
CairoTextureClientD3D9::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
TextureClientD3D9::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
{
MOZ_ASSERT(!IsAllocated());
mSize = aSize;
@ -827,7 +707,7 @@ TextureHostD3D9::TextureHostD3D9(TextureFlags aFlags,
{
mTexture = reinterpret_cast<IDirect3DTexture9*>(aDescriptor.texture());
MOZ_ASSERT(mTexture);
mTexture->Release(); // see AddRef in CairoTextureClientD3D9::ToSurfaceDescriptor
mTexture->Release(); // see AddRef in TextureClientD3D9::ToSurfaceDescriptor
MOZ_ASSERT(mTexture);
D3DSURFACE_DESC desc;
HRESULT hr = mTexture->GetLevelDesc(0, &desc);

View File

@ -76,12 +76,6 @@ protected:
const gfx::IntSize& aSize,
_D3DFORMAT aFormat);
already_AddRefed<IDirect3DTexture9> SurfaceToTexture(
DeviceManagerD3D9* aDeviceManager,
gfxWindowsSurface* aSurface,
const gfx::IntSize& aSize,
_D3DFORMAT aFormat);
gfx::IntSize mSize;
// Linked list of all objects holding d3d9 textures.
@ -162,10 +156,6 @@ public:
*/
bool UpdateFromTexture(IDirect3DTexture9* aTexture, const nsIntRegion* aRegion);
// To use with DIBTextureHostD3D9
bool Update(gfxWindowsSurface* aSurface);
protected:
gfx::IntRect GetTileRect(uint32_t aTileIndex) const;
@ -181,16 +171,16 @@ protected:
};
/**
* Can only be drawn into through Cairo and need a D3D9 context on the client side.
* Needs a D3D9 context on the client side.
* The corresponding TextureHost is TextureHostD3D9.
*/
class CairoTextureClientD3D9 : public TextureClient
class TextureClientD3D9 : public TextureClient
{
public:
CairoTextureClientD3D9(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
TextureClientD3D9(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
TextureFlags aFlags);
virtual ~CairoTextureClientD3D9();
virtual ~TextureClientD3D9();
// TextureClient
@ -225,7 +215,6 @@ private:
RefPtr<IDirect3DTexture9> mTexture;
nsRefPtr<IDirect3DSurface9> mD3D9Surface;
RefPtr<gfx::DrawTarget> mDrawTarget;
nsRefPtr<gfxASurface> mSurface;
gfx::IntSize mSize;
gfx::SurfaceFormat mFormat;
bool mIsLocked;

View File

@ -27,9 +27,6 @@
#ifdef CAIRO_HAS_WIN32_SURFACE
#include "gfxWindowsSurface.h"
#endif
#ifdef CAIRO_HAS_D2D_SURFACE
#include "gfxD2DSurface.h"
#endif
#ifdef MOZ_X11
#include "gfxXlibSurface.h"
@ -179,11 +176,6 @@ gfxASurface::Wrap (cairo_surface_t *csurf, const IntSize& aSize)
result = new gfxWindowsSurface(csurf);
}
#endif
#ifdef CAIRO_HAS_D2D_SURFACE
else if (stype == CAIRO_SURFACE_TYPE_D2D) {
result = new gfxD2DSurface(csurf);
}
#endif
#ifdef MOZ_X11
else if (stype == CAIRO_SURFACE_TYPE_XLIB) {
result = new gfxXlibSurface(csurf);
@ -568,15 +560,10 @@ static const SurfaceMemoryReporterAttrs sSurfaceMemoryReporterAttrs[] = {
{"gfx-surface-xml", nullptr},
{"gfx-surface-skia", nullptr},
{"gfx-surface-subsurface", nullptr},
{"gfx-surface-d2d", nullptr},
};
PR_STATIC_ASSERT(MOZ_ARRAY_LENGTH(sSurfaceMemoryReporterAttrs) ==
size_t(gfxSurfaceType::Max));
#ifdef CAIRO_HAS_D2D_SURFACE
PR_STATIC_ASSERT(uint32_t(CAIRO_SURFACE_TYPE_D2D) ==
uint32_t(gfxSurfaceType::D2D));
#endif
PR_STATIC_ASSERT(uint32_t(CAIRO_SURFACE_TYPE_SKIA) ==
uint32_t(gfxSurfaceType::Skia));

View File

@ -434,6 +434,11 @@ CreateBoxShadow(DrawTarget& aDT, SourceSurface* aBlurMask, const gfxRGBA& aShado
gfxPlatform* platform = gfxPlatform::GetPlatform();
RefPtr<DrawTarget> boxShadowDT =
platform->CreateOffscreenContentDrawTarget(blurredSize, SurfaceFormat::B8G8R8A8);
if (!boxShadowDT) {
return nullptr;
}
MOZ_ASSERT(boxShadowDT->GetType() == aDT.GetType());
ColorPattern shadowColor(ToDeviceColor(aShadowColor));
@ -475,6 +480,10 @@ GetBlur(DrawTarget& aDT,
}
RefPtr<SourceSurface> boxShadow = CreateBoxShadow(aDT, blurMask, aShadowColor);
if (!boxShadow) {
return nullptr;
}
CacheBlur(aDT, minSize, aBlurRadius, aCornerRadii, aShadowColor, aExtendDestBy, boxShadow);
return boxShadow;
}

View File

@ -1,101 +0,0 @@
/* -*- 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 "gfxD2DSurface.h"
#include "cairo.h"
#include "cairo-win32.h"
#include "gfxWindowsPlatform.h"
gfxD2DSurface::gfxD2DSurface(HWND aWnd, gfxContentType aContent)
{
Init(cairo_d2d_surface_create_for_hwnd(
gfxWindowsPlatform::GetPlatform()->GetD2DDevice(),
aWnd,
(cairo_content_t)(int)aContent));
}
gfxD2DSurface::gfxD2DSurface(HANDLE handle, gfxContentType aContent)
{
Init(cairo_d2d_surface_create_for_handle(
gfxWindowsPlatform::GetPlatform()->GetD2DDevice(),
handle,
(cairo_content_t)(int)aContent));
}
gfxD2DSurface::gfxD2DSurface(ID3D10Texture2D *texture, gfxContentType aContent)
{
Init(cairo_d2d_surface_create_for_texture(
gfxWindowsPlatform::GetPlatform()->GetD2DDevice(),
texture,
(cairo_content_t)(int)aContent));
}
gfxD2DSurface::gfxD2DSurface(cairo_surface_t *csurf)
{
Init(csurf, true);
}
gfxD2DSurface::gfxD2DSurface(const mozilla::gfx::IntSize& size,
gfxImageFormat imageFormat)
{
Init(cairo_d2d_surface_create(
gfxWindowsPlatform::GetPlatform()->GetD2DDevice(),
(cairo_format_t)(int)imageFormat,
size.width, size.height));
}
gfxD2DSurface::~gfxD2DSurface()
{
}
void
gfxD2DSurface::Present()
{
cairo_d2d_present_backbuffer(CairoSurface());
}
void
gfxD2DSurface::Scroll(const nsIntPoint &aDelta, const mozilla::gfx::IntRect &aClip)
{
cairo_rectangle_t rect;
rect.x = aClip.x;
rect.y = aClip.y;
rect.width = aClip.width;
rect.height = aClip.height;
cairo_d2d_scroll(CairoSurface(), aDelta.x, aDelta.y, &rect);
}
ID3D10Texture2D*
gfxD2DSurface::GetTexture()
{
return cairo_d2d_surface_get_texture(CairoSurface());
}
HDC
gfxD2DSurface::GetDC(bool aRetainContents)
{
return cairo_d2d_get_dc(CairoSurface(), aRetainContents);
}
void
gfxD2DSurface::ReleaseDC(const mozilla::gfx::IntRect *aUpdatedRect)
{
if (!aUpdatedRect) {
return cairo_d2d_release_dc(CairoSurface(), nullptr);
}
cairo_rectangle_int_t rect;
rect.x = aUpdatedRect->x;
rect.y = aUpdatedRect->y;
rect.width = aUpdatedRect->width;
rect.height = aUpdatedRect->height;
cairo_d2d_release_dc(CairoSurface(), &rect);
}
const mozilla::gfx::IntSize gfxD2DSurface::GetSize() const
{
return mozilla::gfx::IntSize(cairo_d2d_surface_get_width(mSurface),
cairo_d2d_surface_get_height(mSurface));
}

View File

@ -1,44 +0,0 @@
/* -*- 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_D2DSURFACE_H
#define GFX_D2DSURFACE_H
#include "gfxASurface.h"
#include "nsPoint.h"
#include <windows.h>
struct ID3D10Texture2D;
class gfxD2DSurface : public gfxASurface {
public:
gfxD2DSurface(HWND wnd,
gfxContentType aContent);
gfxD2DSurface(const mozilla::gfx::IntSize& size,
gfxImageFormat imageFormat = gfxImageFormat::RGB24);
gfxD2DSurface(HANDLE handle, gfxContentType aContent);
gfxD2DSurface(ID3D10Texture2D *texture, gfxContentType aContent);
gfxD2DSurface(cairo_surface_t *csurf);
virtual ~gfxD2DSurface();
void Present();
void Scroll(const nsIntPoint &aDelta, const mozilla::gfx::IntRect &aClip);
virtual const mozilla::gfx::IntSize GetSize() const;
ID3D10Texture2D *GetTexture();
HDC GetDC(bool aRetainContents);
void ReleaseDC(const mozilla::gfx::IntRect *aUpdatedRect);
};
#endif /* GFX_D2DSURFACE_H */

View File

@ -31,7 +31,6 @@
#if defined(XP_WIN)
#include "gfxWindowsPlatform.h"
#include "gfxD2DSurface.h"
#elif defined(XP_MACOSX)
#include "gfxPlatformMac.h"
#include "gfxQuartzSurface.h"
@ -912,21 +911,6 @@ gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurfa
RefPtr<SourceSurface> srcBuffer;
#ifdef XP_WIN
if (aSurface->GetType() == gfxSurfaceType::D2D &&
format != SurfaceFormat::A8) {
NativeSurface surf;
surf.mFormat = format;
surf.mType = NativeSurfaceType::D3D10_TEXTURE;
surf.mSurface = static_cast<gfxD2DSurface*>(aSurface)->GetTexture();
surf.mSize = aSurface->GetSize();
mozilla::gfx::DrawTarget *dt = static_cast<mozilla::gfx::DrawTarget*>(aSurface->GetData(&kDrawTarget));
if (dt) {
dt->Flush();
}
srcBuffer = aTarget->CreateSourceSurfaceFromNativeSurface(surf);
}
#endif
// Currently no other DrawTarget types implement CreateSourceSurfaceFromNativeSurface
if (!srcBuffer) {

View File

@ -82,7 +82,6 @@ enum class gfxSurfaceType {
XML,
Skia,
Subsurface,
D2D,
Max
};

View File

@ -55,8 +55,6 @@
#include <string>
#ifdef CAIRO_HAS_D2D_SURFACE
#include "gfxD2DSurface.h"
#include <d3d10_1.h>
#include "mozilla/gfx/2D.h"
@ -116,38 +114,6 @@ static const char *kFeatureLevelPref =
static const int kSupportedFeatureLevels[] =
{ D3D10_FEATURE_LEVEL_10_1, D3D10_FEATURE_LEVEL_10_0 };
class GfxD2DSurfaceReporter final : public nsIMemoryReporter
{
~GfxD2DSurfaceReporter() {}
public:
NS_DECL_ISUPPORTS
NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData, bool aAnonymize)
{
nsresult rv;
int64_t amount = cairo_d2d_get_image_surface_cache_usage();
rv = MOZ_COLLECT_REPORT(
"gfx-d2d-surface-cache", KIND_OTHER, UNITS_BYTES, amount,
"Memory used by the Direct2D internal surface cache.");
NS_ENSURE_SUCCESS(rv, rv);
cairo_device_t *device =
gfxWindowsPlatform::GetPlatform()->GetD2DDevice();
amount = device ? cairo_d2d_get_surface_vram_usage(device) : 0;
rv = MOZ_COLLECT_REPORT(
"gfx-d2d-surface-vram", KIND_OTHER, UNITS_BYTES, amount,
"Video memory used by D2D surfaces.");
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
};
NS_IMPL_ISUPPORTS(GfxD2DSurfaceReporter, nsIMemoryReporter)
#endif
class GfxD2DVramReporter final : public nsIMemoryReporter
@ -421,10 +387,6 @@ gfxWindowsPlatform::gfxWindowsPlatform()
*/
CoInitialize(nullptr);
#ifdef CAIRO_HAS_D2D_SURFACE
RegisterStrongMemoryReporter(new GfxD2DSurfaceReporter());
mD2DDevice = nullptr;
#endif
RegisterStrongMemoryReporter(new GfxD2DVramReporter());
if (gfxPrefs::Direct2DUse1_1()) {
@ -443,18 +405,11 @@ gfxWindowsPlatform::gfxWindowsPlatform()
gfxWindowsPlatform::~gfxWindowsPlatform()
{
mDeviceManager = nullptr;
mD3D10Device = nullptr;
mD3D11Device = nullptr;
mD3D11ContentDevice = nullptr;
mD3D11ImageBridgeDevice = nullptr;
// not calling FT_Done_FreeType because cairo may still hold references to
// these FT_Faces. See bug 458169.
#ifdef CAIRO_HAS_D2D_SURFACE
if (mD2DDevice) {
cairo_release_device(mD2DDevice);
}
#endif
mozilla::gfx::Factory::D2DCleanup();
mAdapter = nullptr;
@ -548,12 +503,12 @@ gfxWindowsPlatform::UpdateRenderMode()
mDoesD3D11TextureSharingWork) {
VerifyD2DDevice(d2dForceEnabled);
if (mD2DDevice && GetD3D11Device()) {
if (mD3D10Device && GetD3D11Device()) {
mRenderMode = RENDER_DIRECT2D;
mUseDirectWrite = true;
}
} else {
mD2DDevice = nullptr;
mD3D10Device = nullptr;
}
#endif
@ -631,7 +586,7 @@ gfxWindowsPlatform::CreateDevice(nsRefPtr<IDXGIAdapter1> &adapter1,
if (!createD3DDevice)
return E_FAIL;
nsRefPtr<ID3D10Device1> device;
ID3D10Device1* device = nullptr;
HRESULT hr =
createD3DDevice(adapter1, D3D10_DRIVER_TYPE_HARDWARE, nullptr,
#ifdef DEBUG
@ -641,14 +596,17 @@ gfxWindowsPlatform::CreateDevice(nsRefPtr<IDXGIAdapter1> &adapter1,
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
static_cast<D3D10_FEATURE_LEVEL1>(kSupportedFeatureLevels[featureLevelIndex]),
D3D10_1_SDK_VERSION, getter_AddRefs(device));
D3D10_1_SDK_VERSION, &device);
// If we fail here, the DirectX version or video card probably
// changed. We previously could use 10.1 but now we can't
// anymore. Revert back to doing a 10.0 check first before
// the 10.1 check.
if (device) {
mD2DDevice = cairo_d2d_create_device_from_d3d10device(device);
mD3D10Device = device;
// Leak the module while the D3D 10 device is being used.
d3d10module.disown();
// Setup a pref for future launch optimizaitons when in main process.
if (XRE_IsParentProcess()) {
@ -669,13 +627,11 @@ gfxWindowsPlatform::VerifyD2DDevice(bool aAttemptForce)
return;
}
if (mD2DDevice) {
ID3D10Device1 *device = cairo_d2d_device_get_device(mD2DDevice);
if (SUCCEEDED(device->GetDeviceRemovedReason())) {
if (mD3D10Device) {
if (SUCCEEDED(mD3D10Device->GetDeviceRemovedReason())) {
return;
}
mD2DDevice = nullptr;
mD3D10Device = nullptr;
// Surface cache needs to be invalidated since it may contain vector
// images rendered with our old, broken D2D device.
@ -684,8 +640,6 @@ gfxWindowsPlatform::VerifyD2DDevice(bool aAttemptForce)
mozilla::ScopedGfxFeatureReporter reporter("D2D", aAttemptForce);
nsRefPtr<ID3D10Device1> device;
int supportedFeatureLevelsCount = ArrayLength(kSupportedFeatureLevels);
nsRefPtr<IDXGIAdapter1> adapter1 = GetDXGIAdapter();
@ -724,13 +678,9 @@ gfxWindowsPlatform::VerifyD2DDevice(bool aAttemptForce)
}
}
if (!mD2DDevice && aAttemptForce) {
mD2DDevice = cairo_d2d_create_device();
}
if (mD2DDevice) {
if (mD3D10Device) {
reporter.SetSuccessful();
mozilla::gfx::Factory::SetDirect3D10Device(cairo_d2d_device_get_device(mD2DDevice));
mozilla::gfx::Factory::SetDirect3D10Device(mD3D10Device);
}
ScopedGfxFeatureReporter reporter1_1("D2D1.1");
@ -779,17 +729,11 @@ gfxWindowsPlatform::CreateOffscreenSurface(const IntSize& size,
nsRefPtr<gfxASurface> surf = nullptr;
#ifdef CAIRO_HAS_WIN32_SURFACE
if (mRenderMode == RENDER_GDI)
if (mRenderMode == RENDER_GDI || mRenderMode == RENDER_DIRECT2D)
surf = new gfxWindowsSurface(size,
OptimalFormatForContent(contentType));
#endif
#ifdef CAIRO_HAS_D2D_SURFACE
if (mRenderMode == RENDER_DIRECT2D)
surf = new gfxD2DSurface(size,
OptimalFormatForContent(contentType));
#endif
if (!surf || surf->CairoStatus()) {
surf = new gfxImageSurface(size,
OptimalFormatForContent(contentType));

View File

@ -240,10 +240,7 @@ public:
void OnDeviceManagerDestroy(mozilla::layers::DeviceManagerD3D9* aDeviceManager);
mozilla::layers::DeviceManagerD3D9* GetD3D9DeviceManager();
IDirect3DDevice9* GetD3D9Device();
#ifdef CAIRO_HAS_D2D_SURFACE
cairo_device_t *GetD2DDevice() { return mD2DDevice; }
ID3D10Device1 *GetD3D10Device() { return mD2DDevice ? cairo_d2d_device_get_device(mD2DDevice) : nullptr; }
#endif
ID3D10Device1 *GetD3D10Device() { return mD3D10Device; }
ID3D11Device *GetD3D11Device();
ID3D11Device *GetD3D11ContentDevice();
// Device to be used on the ImageBridge thread
@ -290,12 +287,10 @@ private:
nsRefPtr<IDWriteTextAnalyzer> mDWriteAnalyzer;
nsRefPtr<IDWriteRenderingParams> mRenderingParams[TEXT_RENDERING_COUNT];
DWRITE_MEASURING_MODE mMeasuringMode;
#endif
#ifdef CAIRO_HAS_D2D_SURFACE
cairo_device_t *mD2DDevice;
#endif
mozilla::RefPtr<IDXGIAdapter1> mAdapter;
nsRefPtr<mozilla::layers::DeviceManagerD3D9> mDeviceManager;
mozilla::RefPtr<ID3D10Device1> mD3D10Device;
mozilla::RefPtr<ID3D11Device> mD3D11Device;
mozilla::RefPtr<ID3D11Device> mD3D11ContentDevice;
mozilla::RefPtr<ID3D11Device> mD3D11ImageBridgeDevice;

View File

@ -162,7 +162,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
EXPORTS += [
'gfxD2DSurface.h',
'gfxDWriteFonts.h',
'gfxGDIFont.h',
'gfxGDIFontList.h',
@ -185,7 +184,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
'gfxDWriteFontList.cpp',
]
SOURCES += [
'gfxD2DSurface.cpp',
'gfxDWriteCommon.cpp',
'gfxDWriteFonts.cpp',
]

View File

@ -192,7 +192,7 @@ class JS_PUBLIC_API(JSAutoStructuredCloneBuffer) {
uint64_t* data() const { return data_; }
size_t nbytes() const { return nbytes_; }
void clear();
void clear(const JSStructuredCloneCallbacks* optionalCallbacks=nullptr, void* closure=nullptr);
// Copy some memory. It will be automatically freed by the destructor.
bool copy(const uint64_t* data, size_t nbytes, uint32_t version=JS_STRUCTURED_CLONE_VERSION);

View File

@ -10311,8 +10311,10 @@ IonBuilder::getPropTryConstant(bool* emitted, MDefinition* obj, PropertyName* na
}
JSObject* singleton = testSingletonPropertyTypes(obj, name);
if (!singleton)
if (!singleton) {
trackOptimizationOutcome(TrackedOutcome::NotSingleton);
return true;
}
// Property access is a known constant -- safe to emit.
obj->setImplicitlyUsedUnchecked();

View File

@ -59,7 +59,7 @@ MacroAssembler::PushWithPatch(ImmPtr imm)
}
// ===============================================================
// Call functions.
// Simple call functions.
void
MacroAssembler::call(const CallSiteDesc& desc, const Register reg)

View File

@ -350,9 +350,17 @@ class MacroAssembler : public MacroAssemblerSpecific
public:
// ===============================================================
// Call functions.
// Simple call functions.
using MacroAssemblerSpecific::call; // legacy
void call(Register reg) PER_ARCH;
void call(const Address& addr) PER_ARCH ONLY_X86_X64;
void call(Label* label) PER_ARCH;
void call(ImmWord imm) PER_ARCH;
// Call a target native function, which is neither traceable nor movable.
void call(ImmPtr imm) PER_ARCH;
void call(AsmJSImmPtr imm) PER_ARCH;
// Call a target JitCode, which must be traceable, and may be movable.
void call(JitCode* c) PER_ARCH;
inline void call(const CallSiteDesc& desc, const Register reg);
inline void call(const CallSiteDesc& desc, Label* label);

View File

@ -1638,9 +1638,6 @@ class Assembler : public AssemblerShared
return actualOffset(offset);
}
void call(Label* label);
void call(void* target);
void as_bkpt();
public:

View File

@ -4122,7 +4122,7 @@ MacroAssemblerARMCompat::callWithABI(AsmJSImmPtr imm, MoveOp::Type result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust, /* callFromAsmJS = */ true);
call(imm);
asMasm().call(imm);
callWithABIPost(stackAdjust, result);
}
@ -4135,7 +4135,7 @@ MacroAssemblerARMCompat::callWithABI(const Address& fun, MoveOp::Type result)
ma_ldr(fun, r12);
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(r12);
asMasm().call(r12);
callWithABIPost(stackAdjust, result);
}
@ -4146,7 +4146,7 @@ MacroAssemblerARMCompat::callWithABI(Register fun, MoveOp::Type result)
ma_mov(fun, r12);
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(r12);
asMasm().call(r12);
callWithABIPost(stackAdjust, result);
}
@ -5090,6 +5090,14 @@ MacroAssemblerARMCompat::profilerExitFrame()
branch(GetJitContext()->runtime->jitRuntime()->getProfilerExitFrameTail());
}
void
MacroAssemblerARMCompat::callAndPushReturnAddress(Label* label)
{
AutoForbidPools afp(this, 2);
ma_push(pc);
asMasm().call(label);
}
MacroAssembler&
MacroAssemblerARMCompat::asMasm()
{
@ -5240,3 +5248,55 @@ MacroAssembler::reserveStack(uint32_t amount)
ma_sub(Imm32(amount), sp);
adjustFrame(amount);
}
// ===============================================================
// Simple call functions.
void
MacroAssembler::call(Register reg)
{
as_blx(reg);
}
void
MacroAssembler::call(Label* label)
{
// For now, assume that it'll be nearby?
as_bl(label, Always);
}
void
MacroAssembler::call(ImmWord imm)
{
call(ImmPtr((void*)imm.value));
}
void
MacroAssembler::call(ImmPtr imm)
{
BufferOffset bo = m_buffer.nextOffset();
addPendingJump(bo, imm, Relocation::HARDCODED);
ma_call(imm);
}
void
MacroAssembler::call(AsmJSImmPtr imm)
{
movePtr(imm, CallReg);
call(CallReg);
}
void
MacroAssembler::call(JitCode* c)
{
BufferOffset bo = m_buffer.nextOffset();
addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
RelocStyle rs;
if (HasMOVWT())
rs = L_MOVWT;
else
rs = L_LDR;
ma_movPatchable(ImmPtr(c->raw()), ScratchRegister, Always, rs);
ma_callJitHalfPush(ScratchRegister);
}

View File

@ -538,7 +538,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
{ }
public:
using MacroAssemblerARM::call;
// Jumps + other functions that should be called from non-arm specific
// code. Basically, an x86 front end on top of the ARM code.
@ -567,42 +566,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
MOZ_CRASH("NYI-IC");
}
void call(const Register reg) {
as_blx(reg);
}
void call(Label* label) {
// For now, assume that it'll be nearby?
as_bl(label, Always);
}
void call(ImmWord imm) {
call(ImmPtr((void*)imm.value));
}
void call(ImmPtr imm) {
BufferOffset bo = m_buffer.nextOffset();
addPendingJump(bo, imm, Relocation::HARDCODED);
ma_call(imm);
}
void call(AsmJSImmPtr imm) {
movePtr(imm, CallReg);
call(CallReg);
}
void call(JitCode* c) {
BufferOffset bo = m_buffer.nextOffset();
addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
RelocStyle rs;
if (HasMOVWT())
rs = L_MOVWT;
else
rs = L_LDR;
ma_movPatchable(ImmPtr(c->raw()), ScratchRegister, Always, rs);
ma_callJitHalfPush(ScratchRegister);
}
void callAndPushReturnAddress(Label* label) {
AutoForbidPools afp(this, 2);
ma_push(pc);
call(label);
}
void callAndPushReturnAddress(Label* label);
void branch(JitCode* c) {
BufferOffset bo = m_buffer.nextOffset();

View File

@ -55,12 +55,29 @@ MacroAssemblerCompat::buildFakeExitFrame(Register scratch, uint32_t* offset)
*offset = pseudoReturnOffset;
}
void
MacroAssemblerCompat::callWithExitFrame(Label* target)
{
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
Push(Imm32(descriptor)); // descriptor
asMasm().call(target);
}
void
MacroAssemblerCompat::callWithExitFrame(JitCode* target)
{
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
asMasm().Push(Imm32(descriptor));
call(target);
asMasm().call(target);
}
void
MacroAssemblerCompat::callWithExitFrame(JitCode* target, Register dynStack)
{
add32(Imm32(framePushed()), dynStack);
makeFrameDescriptor(dynStack, JitFrame_IonJS);
Push(dynStack); // descriptor
asMasm().call(target);
}
void
@ -441,7 +458,7 @@ MacroAssemblerCompat::callWithABI(void* fun, MoveOp::Type result)
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(ImmPtr(fun));
asMasm().call(ImmPtr(fun));
callWithABIPost(stackAdjust, result);
}
@ -452,7 +469,7 @@ MacroAssemblerCompat::callWithABI(Register fun, MoveOp::Type result)
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(ip0);
asMasm().call(ip0);
callWithABIPost(stackAdjust, result);
}
@ -461,7 +478,7 @@ MacroAssemblerCompat::callWithABI(AsmJSImmPtr imm, MoveOp::Type result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(imm);
asMasm().call(imm);
callWithABIPost(stackAdjust, result);
}
@ -472,7 +489,7 @@ MacroAssemblerCompat::callWithABI(Address fun, MoveOp::Type result)
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(ip0);
asMasm().call(ip0);
callWithABIPost(stackAdjust, result);
}
@ -684,5 +701,57 @@ MacroAssembler::Pop(const ValueOperand& val)
adjustFrame(-1 * int64_t(sizeof(int64_t)));
}
// ===============================================================
// Simple call functions.
void
MacroAssembler::call(Register reg)
{
syncStackPtr();
Blr(ARMRegister(reg, 64));
}
void
MacroAssembler::call(Label* label)
{
syncStackPtr();
Bl(label);
}
void
MacroAssembler::call(ImmWord imm)
{
call(ImmPtr((void*)imm.value));
}
void
MacroAssembler::call(ImmPtr imm)
{
syncStackPtr();
movePtr(imm, ip0);
Blr(vixl::ip0);
}
void
MacroAssembler::call(AsmJSImmPtr imm)
{
vixl::UseScratchRegisterScope temps(this);
const Register scratch = temps.AcquireX().asUnsized();
syncStackPtr();
movePtr(imm, scratch);
call(scratch);
}
void
MacroAssembler::call(JitCode* c)
{
vixl::UseScratchRegisterScope temps(this);
const ARMRegister scratch64 = temps.AcquireX();
syncStackPtr();
BufferOffset off = immPool64(scratch64, uint64_t(c->raw()));
addPendingJump(off, ImmPtr(c->raw()), Relocation::JITCODE);
blr(scratch64);
}
} // namespace jit
} // namespace js

View File

@ -2706,14 +2706,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
orPtr(Imm32(type), frameSizeReg);
}
void callWithExitFrame(JitCode* target, Register dynStack) {
add32(Imm32(framePushed()), dynStack);
makeFrameDescriptor(dynStack, JitFrame_IonJS);
Push(dynStack); // descriptor
call(target);
}
// FIXME: See CodeGeneratorX64 calls to noteAsmJSGlobalAccess.
void patchAsmJSGlobalAccess(CodeOffsetLabel patchAt, uint8_t* code,
uint8_t* globalData, unsigned globalDataOffset)
@ -2737,14 +2729,9 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
// non-function. Returns offset to be passed to markSafepointAt().
void buildFakeExitFrame(Register scratch, uint32_t* offset);
void callWithExitFrame(Label* target) {
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
Push(Imm32(descriptor)); // descriptor
call(target);
}
void callWithExitFrame(Label* target);
void callWithExitFrame(JitCode* target);
void callWithExitFrame(JitCode* target, Register dynStack);
void callJit(Register callee) {
// AArch64 cannot read from the PC, so pushing must be handled callee-side.
@ -2756,53 +2743,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
MOZ_CRASH("appendCallSite");
}
void call(const CallSiteDesc& desc, Label* label) {
syncStackPtr();
call(label);
append(desc, currentOffset(), framePushed_);
}
void call(const CallSiteDesc& desc, Register reg) {
syncStackPtr();
call(reg);
append(desc, currentOffset(), framePushed_);
}
void call(const CallSiteDesc& desc, AsmJSImmPtr imm) {
syncStackPtr();
call(imm);
append(desc, currentOffset(), framePushed_);
}
void call(AsmJSImmPtr imm) {
vixl::UseScratchRegisterScope temps(this);
const Register scratch = temps.AcquireX().asUnsized();
syncStackPtr();
movePtr(imm, scratch);
call(scratch);
}
void call(Register target) {
syncStackPtr();
Blr(ARMRegister(target, 64));
}
// Call a target JitCode, which must be traceable, and may be movable.
void call(JitCode* target) {
vixl::UseScratchRegisterScope temps(this);
const ARMRegister scratch64 = temps.AcquireX();
syncStackPtr();
BufferOffset off = immPool64(scratch64, uint64_t(target->raw()));
addPendingJump(off, ImmPtr(target->raw()), Relocation::JITCODE);
blr(scratch64);
}
// Call a target native function, which is neither traceable nor movable.
void call(ImmPtr target) {
syncStackPtr();
movePtr(target, ip0);
Blr(vixl::ip0);
}
void call(Label* target) {
syncStackPtr();
Bl(target);
}
void callExit(AsmJSImmPtr imm, uint32_t stackArgBytes) {
MOZ_CRASH("callExit");
}

View File

@ -3445,7 +3445,7 @@ MacroAssemblerMIPSCompat::callWithABI(AsmJSImmPtr imm, MoveOp::Type result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust, /* callFromAsmJS = */ true);
call(imm);
asMasm().call(imm);
callWithABIPost(stackAdjust, result);
}
@ -3458,7 +3458,7 @@ MacroAssemblerMIPSCompat::callWithABI(const Address& fun, MoveOp::Type result)
ma_lw(t9, Address(fun.base, fun.offset));
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(t9);
asMasm().call(t9);
callWithABIPost(stackAdjust, result);
}
@ -3470,7 +3470,7 @@ MacroAssemblerMIPSCompat::callWithABI(Register fun, MoveOp::Type result)
ma_move(t9, fun);
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(t9);
asMasm().call(t9);
callWithABIPost(stackAdjust, result);
}
@ -3776,3 +3776,49 @@ MacroAssembler::reserveStack(uint32_t amount)
ma_subu(StackPointer, StackPointer, Imm32(amount));
adjustFrame(amount);
}
// ===============================================================
// Simple call functions.
void
MacroAssembler::call(Register reg)
{
as_jalr(reg);
as_nop();
}
void
MacroAssembler::call(Label* label)
{
ma_bal(label);
}
void
MacroAssembler::call(AsmJSImmPtr target)
{
movePtr(target, CallReg);
call(CallReg);
}
void
MacroAssembler::call(ImmWord target)
{
call(ImmPtr((void*)target.value));
}
void
MacroAssembler::call(ImmPtr target)
{
BufferOffset bo = m_buffer.nextOffset();
addPendingJump(bo, target, Relocation::HARDCODED);
ma_call(target);
}
void
MacroAssembler::call(JitCode* c)
{
BufferOffset bo = m_buffer.nextOffset();
addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
ma_liPatchable(ScratchRegister, Imm32((uint32_t)c->raw()));
ma_callJitHalfPush(ScratchRegister);
}

View File

@ -405,34 +405,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
MOZ_CRASH("NYI-IC");
}
void call(const Register reg) {
as_jalr(reg);
as_nop();
}
void call(Label* label) {
ma_bal(label);
}
void call(ImmWord imm) {
call(ImmPtr((void*)imm.value));
}
void call(ImmPtr imm) {
BufferOffset bo = m_buffer.nextOffset();
addPendingJump(bo, imm, Relocation::HARDCODED);
ma_call(imm);
}
void call(AsmJSImmPtr imm) {
movePtr(imm, CallReg);
call(CallReg);
}
void call(JitCode* c) {
BufferOffset bo = m_buffer.nextOffset();
addPendingJump(bo, ImmPtr(c->raw()), Relocation::JITCODE);
ma_liPatchable(ScratchRegister, Imm32((uint32_t)c->raw()));
ma_callJitHalfPush(ScratchRegister);
}
void callAndPushReturnAddress(Label* label) {
ma_callJitHalfPush(label);
}

View File

@ -323,7 +323,7 @@ MacroAssemblerX64::callWithABI(void* fun, MoveOp::Type result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(ImmPtr(fun));
asMasm().call(ImmPtr(fun));
callWithABIPost(stackAdjust, result);
}
@ -332,7 +332,7 @@ MacroAssemblerX64::callWithABI(AsmJSImmPtr imm, MoveOp::Type result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(imm);
asMasm().call(imm);
callWithABIPost(stackAdjust, result);
}
@ -361,7 +361,7 @@ MacroAssemblerX64::callWithABI(Address fun, MoveOp::Type result)
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(Operand(fun));
asMasm().call(fun);
callWithABIPost(stackAdjust, result);
}
@ -379,7 +379,7 @@ MacroAssemblerX64::callWithABI(Register fun, MoveOp::Type result)
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(Operand(fun));
asMasm().call(fun);
callWithABIPost(stackAdjust, result);
}
@ -513,7 +513,7 @@ MacroAssemblerX64::callWithExitFrame(JitCode* target, Register dynStack)
addPtr(Imm32(asMasm().framePushed()), dynStack);
makeFrameDescriptor(dynStack, JitFrame_IonJS);
asMasm().Push(dynStack);
call(target);
asMasm().call(target);
}
void

View File

@ -89,7 +89,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
MoveResolver moveResolver_;
public:
using MacroAssemblerX86Shared::call;
using MacroAssemblerX86Shared::callWithExitFrame;
using MacroAssemblerX86Shared::branch32;
using MacroAssemblerX86Shared::branchTest32;
@ -108,13 +107,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
/////////////////////////////////////////////////////////////////
// X64 helpers.
/////////////////////////////////////////////////////////////////
void call(ImmWord target) {
mov(target, rax);
call(rax);
}
void call(ImmPtr target) {
call(ImmWord(uintptr_t(target.value)));
}
void writeDataRelocation(const Value& val) {
if (val.isMarkable()) {
gc::Cell* cell = reinterpret_cast<gc::Cell*>(val.toGCThing());

View File

@ -42,7 +42,7 @@ EmitCallIC(CodeOffsetLabel* patchOffset, MacroAssembler& masm)
ICStubReg);
// Call the stubcode.
masm.call(Operand(ICStubReg, ICStub::offsetOfStubCode()));
masm.call(Address(ICStubReg, ICStub::offsetOfStubCode()));
}
inline void
@ -230,7 +230,7 @@ EmitCallTypeUpdateIC(MacroAssembler& masm, JitCode* code, uint32_t objectOffset)
ICStubReg);
// Call the stubcode.
masm.call(Operand(ICStubReg, ICStub::offsetOfStubCode()));
masm.call(Address(ICStubReg, ICStub::offsetOfStubCode()));
// Restore the old stub reg.
masm.pop(ICStubReg);

View File

@ -165,6 +165,24 @@ MacroAssemblerX86Shared::branchNegativeZeroFloat32(FloatRegister reg,
j(Overflow, label);
}
void
MacroAssemblerX86Shared::callJit(Register callee)
{
call(callee);
}
void
MacroAssemblerX86Shared::callJitFromAsmJS(Register callee)
{
call(callee);
}
void
MacroAssemblerX86Shared::callAndPushReturnAddress(Label* label)
{
call(label);
}
MacroAssembler&
MacroAssemblerX86Shared::asMasm()
{
@ -350,3 +368,50 @@ MacroAssembler::Pop(const ValueOperand& val)
popValue(val);
framePushed_ -= sizeof(Value);
}
// ===============================================================
// Simple call functions.
void
MacroAssembler::call(Register reg)
{
Assembler::call(reg);
}
void
MacroAssembler::call(Label* label)
{
Assembler::call(label);
}
void
MacroAssembler::call(const Address& addr)
{
Assembler::call(Operand(addr.base, addr.offset));
}
void
MacroAssembler::call(AsmJSImmPtr target)
{
mov(target, eax);
Assembler::call(eax);
}
void
MacroAssembler::call(ImmWord target)
{
mov(target, eax);
Assembler::call(eax);
}
void
MacroAssembler::call(ImmPtr target)
{
call(ImmWord(uintptr_t(target.value)));
}
void
MacroAssembler::call(JitCode* target)
{
Assembler::call(target);
}

View File

@ -1433,19 +1433,9 @@ class MacroAssemblerX86Shared : public Assembler
void callWithExitFrame(Label* target);
void callWithExitFrame(JitCode* target);
void callJit(Register callee) {
call(callee);
}
void callJitFromAsmJS(Register callee) {
call(callee);
}
void call(AsmJSImmPtr target) {
mov(target, eax);
call(eax);
}
void callAndPushReturnAddress(Label* label) {
call(label);
}
void callJit(Register callee);
void callJitFromAsmJS(Register callee);
void callAndPushReturnAddress(Label* label);
void checkStackAlignment() {
// Exists for ARM compatibility.

View File

@ -328,7 +328,7 @@ MacroAssemblerX86::callWithABI(void* fun, MoveOp::Type result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(ImmPtr(fun));
asMasm().call(ImmPtr(fun));
callWithABIPost(stackAdjust, result);
}
@ -337,7 +337,7 @@ MacroAssemblerX86::callWithABI(AsmJSImmPtr fun, MoveOp::Type result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(fun);
asMasm().call(fun);
callWithABIPost(stackAdjust, result);
}
@ -346,7 +346,7 @@ MacroAssemblerX86::callWithABI(const Address& fun, MoveOp::Type result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(Operand(fun));
asMasm().call(fun);
callWithABIPost(stackAdjust, result);
}
@ -355,7 +355,7 @@ MacroAssemblerX86::callWithABI(Register fun, MoveOp::Type result)
{
uint32_t stackAdjust;
callWithABIPre(&stackAdjust);
call(Operand(fun));
asMasm().call(fun);
callWithABIPost(stackAdjust, result);
}
@ -506,7 +506,7 @@ MacroAssemblerX86::callWithExitFrame(JitCode* target, Register dynStack)
addPtr(ImmWord(asMasm().framePushed()), dynStack);
makeFrameDescriptor(dynStack, JitFrame_IonJS);
asMasm().Push(dynStack);
call(target);
asMasm().call(target);
}
void

View File

@ -43,7 +43,7 @@ EmitCallIC(CodeOffsetLabel* patchOffset, MacroAssembler& masm)
// Load stubcode pointer from BaselineStubEntry into ICTailCallReg
// ICTailCallReg will always be unused in the contexts where ICs are called.
masm.call(Operand(ICStubReg, ICStub::offsetOfStubCode()));
masm.call(Address(ICStubReg, ICStub::offsetOfStubCode()));
}
inline void
@ -236,7 +236,7 @@ EmitCallTypeUpdateIC(MacroAssembler& masm, JitCode* code, uint32_t objectOffset)
ICStubReg);
// Call the stubcode.
masm.call(Operand(ICStubReg, ICStub::offsetOfStubCode()));
masm.call(Address(ICStubReg, ICStub::offsetOfStubCode()));
// Restore the old stub reg.
masm.pop(ICStubReg);

View File

@ -274,7 +274,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type)
Call passed-in code, get return value and fill in the
passed in return value pointer
***************************************************************/
masm.call(Operand(ebp, ARG_JITCODE));
masm.call(Address(ebp, ARG_JITCODE));
if (type == EnterJitBaseline) {
// Baseline OSR will return here.

View File

@ -7,6 +7,7 @@
#include "vm/SharedTypedArrayObject.h"
#include "mozilla/Alignment.h"
#include "mozilla/Attributes.h"
#include "mozilla/PodOperations.h"
#include <string.h>
@ -97,7 +98,7 @@ class SharedTypedArrayObjectTemplate : public SharedTypedArrayObject
typedef SharedTypedArrayObjectTemplate<NativeType> ThisTypedArrayObject;
typedef SharedArrayBufferObject BufferType;
static Scalar::Type ArrayTypeID() { return TypeIDOfType<NativeType>(); }
static MOZ_CONSTEXPR Scalar::Type ArrayTypeID() { return TypeIDOfType<NativeType>::id; }
static bool ArrayTypeIsUnsigned() { return TypeIsUnsigned<NativeType>(); }
static bool ArrayTypeIsFloatingPoint() { return TypeIsFloatingPoint<NativeType>(); }

View File

@ -1984,17 +1984,23 @@ JSAutoStructuredCloneBuffer::operator=(JSAutoStructuredCloneBuffer&& other)
}
void
JSAutoStructuredCloneBuffer::clear()
JSAutoStructuredCloneBuffer::clear(const JSStructuredCloneCallbacks* optionalCallbacks,
void* optionalClosure)
{
if (data_) {
if (ownTransferables_ == OwnsTransferablesIfAny)
DiscardTransferables(data_, nbytes_, callbacks_, closure_);
ownTransferables_ = NoTransferables;
js_free(data_);
data_ = nullptr;
nbytes_ = 0;
version_ = 0;
}
if (!data_)
return;
const JSStructuredCloneCallbacks* callbacks =
optionalCallbacks ? optionalCallbacks : callbacks_;
void* closure = optionalClosure ? optionalClosure : closure_;
if (ownTransferables_ == OwnsTransferablesIfAny)
DiscardTransferables(data_, nbytes_, callbacks, closure);
ownTransferables_ = NoTransferables;
js_free(data_);
data_ = nullptr;
nbytes_ = 0;
version_ = 0;
}
bool

View File

@ -56,16 +56,16 @@ ValueIsLength(const Value& v, uint32_t* len)
return false;
}
template<typename NativeType> static inline Scalar::Type TypeIDOfType();
template<> inline Scalar::Type TypeIDOfType<int8_t>() { return Scalar::Int8; }
template<> inline Scalar::Type TypeIDOfType<uint8_t>() { return Scalar::Uint8; }
template<> inline Scalar::Type TypeIDOfType<int16_t>() { return Scalar::Int16; }
template<> inline Scalar::Type TypeIDOfType<uint16_t>() { return Scalar::Uint16; }
template<> inline Scalar::Type TypeIDOfType<int32_t>() { return Scalar::Int32; }
template<> inline Scalar::Type TypeIDOfType<uint32_t>() { return Scalar::Uint32; }
template<> inline Scalar::Type TypeIDOfType<float>() { return Scalar::Float32; }
template<> inline Scalar::Type TypeIDOfType<double>() { return Scalar::Float64; }
template<> inline Scalar::Type TypeIDOfType<uint8_clamped>() { return Scalar::Uint8Clamped; }
template<typename NativeType> struct TypeIDOfType;
template<> struct TypeIDOfType<int8_t> { static const Scalar::Type id = Scalar::Int8; };
template<> struct TypeIDOfType<uint8_t> { static const Scalar::Type id = Scalar::Uint8; };
template<> struct TypeIDOfType<int16_t> { static const Scalar::Type id = Scalar::Int16; };
template<> struct TypeIDOfType<uint16_t> { static const Scalar::Type id = Scalar::Uint16; };
template<> struct TypeIDOfType<int32_t> { static const Scalar::Type id = Scalar::Int32; };
template<> struct TypeIDOfType<uint32_t> { static const Scalar::Type id = Scalar::Uint32; };
template<> struct TypeIDOfType<float> { static const Scalar::Type id = Scalar::Float32; };
template<> struct TypeIDOfType<double> { static const Scalar::Type id = Scalar::Float64; };
template<> struct TypeIDOfType<uint8_clamped> { static const Scalar::Type id = Scalar::Uint8Clamped; };
inline bool
IsAnyTypedArray(JSObject* obj)

View File

@ -68,15 +68,6 @@ TypedArrayLayout TypedArrayObject::layout_(false, // shared
&TypedArrayObject::classes[0],
&TypedArrayObject::classes[Scalar::MaxTypedArrayViewType]);
TypedArrayLayout::TypedArrayLayout(bool isShared, bool isNeuterable, const Class* firstClass,
const Class* maxClass)
: isShared_(isShared)
, isNeuterable_(isNeuterable)
, firstClass_(firstClass)
, maxClass_(maxClass)
{
}
/* static */ int
TypedArrayLayout::lengthOffset()
{
@ -206,7 +197,7 @@ class TypedArrayObjectTemplate : public TypedArrayObject
public:
typedef NativeType ElementType;
static Scalar::Type ArrayTypeID() { return TypeIDOfType<NativeType>(); }
static MOZ_CONSTEXPR Scalar::Type ArrayTypeID() { return TypeIDOfType<NativeType>::id; }
static bool ArrayTypeIsUnsigned() { return TypeIsUnsigned<NativeType>(); }
static bool ArrayTypeIsFloatingPoint() { return TypeIsFloatingPoint<NativeType>(); }

View File

@ -7,6 +7,8 @@
#ifndef vm_TypedArrayObject_h
#define vm_TypedArrayObject_h
#include "mozilla/Attributes.h"
#include "jsobj.h"
#include "gc/Barrier.h"
@ -43,7 +45,13 @@ class TypedArrayLayout
const Class* maxClass_;
public:
TypedArrayLayout(bool isShared, bool isNeuterable, const Class* firstClass, const Class* maxClass);
MOZ_CONSTEXPR TypedArrayLayout(bool isShared, bool isNeuterable,
const Class* firstClass, const Class* maxClass)
: isShared_(isShared)
, isNeuterable_(isNeuterable)
, firstClass_(firstClass)
, maxClass_(maxClass)
{}
// Underlying (Shared)ArrayBufferObject.
static const size_t BUFFER_SLOT = 0;

View File

@ -1785,3 +1785,6 @@ FontFaceSet::UserFontSet::CreateUserFontEntry(
aFeatureSettings, aLanguageOverride, aUnicodeRanges);
return entry.forget();
}
#undef LOG_ENABLED
#undef LOG

View File

@ -126,6 +126,7 @@ UNIFIED_SOURCES += [
'Declaration.cpp',
'ErrorReporter.cpp',
'FontFace.cpp',
'FontFaceSet.cpp',
'FontFaceSetIterator.cpp',
'ImageLoader.cpp',
'IncrementalClearCOMRuleArray.cpp',
@ -172,10 +173,8 @@ UNIFIED_SOURCES += [
'SVGAttrAnimationRuleProcessor.cpp',
]
# FontFaceSet.cpp needs to be built separately because it redefines LOG.
# nsCSSRuleProcessor.cpp needs to be built separately because it uses plarena.h.
SOURCES += [
'FontFaceSet.cpp',
'nsCSSRuleProcessor.cpp',
]

View File

@ -35,6 +35,7 @@ let WebappRT = {
// Set a future policy version to avoid the telemetry prompt.
pref("toolkit.telemetry.prompted", 999),
pref("toolkit.telemetry.notifiedOptOut", 999),
pref("media.useAudioChannelAPI", true),
pref("media.useAudioChannelService", true),
pref("dom.mozTCPSocket.enabled", true),

View File

@ -182,7 +182,9 @@ nsWindow::nsWindow() :
mIMEMaskEventsCount(1), // Mask IME events since there's no focus yet
mIMERanges(new TextRangeArray()),
mIMEUpdatingContext(false),
mIMESelectionChanged(false)
mIMESelectionChanged(false),
mAwaitingFullScreen(false),
mIsFullScreen(false)
{
}
@ -494,6 +496,12 @@ nsWindow::Resize(double aX,
if (aRepaint && FindTopLevel() == nsWindow::TopWindow())
RedrawAll();
nsIWidgetListener* listener = GetWidgetListener();
if (mAwaitingFullScreen && listener) {
listener->FullscreenChanged(mIsFullScreen);
mAwaitingFullScreen = false;
}
return NS_OK;
}
@ -630,7 +638,7 @@ nsWindow::GetScreenBounds(nsIntRect &aRect)
aRect.y = p.y;
aRect.width = mBounds.width;
aRect.height = mBounds.height;
return NS_OK;
}
@ -672,6 +680,8 @@ nsWindow::DispatchEvent(WidgetGUIEvent* aEvent)
NS_IMETHODIMP
nsWindow::MakeFullScreen(bool aFullScreen, nsIScreen*)
{
mIsFullScreen = aFullScreen;
mAwaitingFullScreen = true;
GeckoAppShell::SetFullScreen(aFullScreen);
return NS_OK;
}
@ -2110,7 +2120,7 @@ nsWindow::SetInputContext(const InputContext& aContext,
// Ensure that opening the virtual keyboard is allowed for this specific
// InputContext depending on the content.ime.strict.policy pref
if (aContext.mIMEState.mEnabled != IMEState::DISABLED &&
if (aContext.mIMEState.mEnabled != IMEState::DISABLED &&
aContext.mIMEState.mEnabled != IMEState::PLUGIN &&
Preferences::GetBool("content.ime.strict_policy", false) &&
!aAction.ContentGotFocusByTrustedCause() &&

View File

@ -231,6 +231,9 @@ protected:
nsAutoTArray<IMEChange, 4> mIMETextChanges;
bool mIMESelectionChanged;
bool mAwaitingFullScreen;
bool mIsFullScreen;
InputContext mInputContext;
virtual nsresult NotifyIMEInternal(