diff --git a/browser/base/content/test/general/browser_bug839103.js b/browser/base/content/test/general/browser_bug839103.js index 5f6455b162c6..396329cb62f0 100644 --- a/browser/base/content/test/general/browser_bug839103.js +++ b/browser/base/content/test/general/browser_bug839103.js @@ -1,4 +1,4 @@ -const gTestRoot = getRootDirectory(gTestPath); +const gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); const gStyleSheet = "bug839103.css"; var gTab = null; diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 065d999f5090..66e1c0568651 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -4242,7 +4242,7 @@ nsDocument::AddStyleSheetToStyleSets(nsIStyleSheet* aSheet) event->SetTarget(this); \ nsRefPtr asyncDispatcher = \ new AsyncEventDispatcher(this, event); \ - asyncDispatcher->mDispatchChromeOnly = true; \ + asyncDispatcher->mOnlyChromeDispatch = true; \ asyncDispatcher->PostDOMEvent(); \ } while (0); diff --git a/dom/events/AsyncEventDispatcher.cpp b/dom/events/AsyncEventDispatcher.cpp index d957f164282b..8e110a453998 100644 --- a/dom/events/AsyncEventDispatcher.cpp +++ b/dom/events/AsyncEventDispatcher.cpp @@ -23,7 +23,7 @@ using namespace dom; AsyncEventDispatcher::AsyncEventDispatcher(EventTarget* aTarget, WidgetEvent& aEvent) : mTarget(aTarget) - , mDispatchChromeOnly(false) + , mOnlyChromeDispatch(false) { MOZ_ASSERT(mTarget); EventDispatcher::CreateEvent(aTarget, nullptr, &aEvent, EmptyString(), @@ -36,44 +36,19 @@ AsyncEventDispatcher::AsyncEventDispatcher(EventTarget* aTarget, NS_IMETHODIMP AsyncEventDispatcher::Run() { - if (mEvent) { - if (mDispatchChromeOnly) { - MOZ_ASSERT(mEvent->InternalDOMEvent()->IsTrusted()); - - nsCOMPtr node = do_QueryInterface(mTarget); - MOZ_ASSERT(node, "ChromeOnly dispatch supported with Node targets only!"); - nsPIDOMWindow* window = node->OwnerDoc()->GetWindow(); - if (!window) { - return NS_ERROR_INVALID_ARG; - } - - nsCOMPtr target = window->GetParentTarget(); - if (!target) { - return NS_ERROR_INVALID_ARG; - } - EventDispatcher::DispatchDOMEvent(target, nullptr, mEvent, - nullptr, nullptr); - } else { - bool defaultActionEnabled; // This is not used because the caller is async - mTarget->DispatchEvent(mEvent, &defaultActionEnabled); - } - } else { - if (mDispatchChromeOnly) { - nsCOMPtr node = do_QueryInterface(mTarget); - MOZ_ASSERT(node, "ChromeOnly dispatch supported with Node targets only!"); - nsContentUtils::DispatchChromeEvent(node->OwnerDoc(), node, mEventType, - mBubbles, false); - } else { - nsCOMPtr event; - NS_NewDOMEvent(getter_AddRefs(event), mTarget, nullptr, nullptr); - nsresult rv = event->InitEvent(mEventType, mBubbles, false); - NS_ENSURE_SUCCESS(rv, rv); - event->SetTrusted(true); - bool dummy; - mTarget->DispatchEvent(event, &dummy); - } + nsCOMPtr event = mEvent; + if (!event) { + NS_NewDOMEvent(getter_AddRefs(event), mTarget, nullptr, nullptr); + nsresult rv = event->InitEvent(mEventType, mBubbles, false); + NS_ENSURE_SUCCESS(rv, rv); + event->SetTrusted(true); } - + if (mOnlyChromeDispatch) { + MOZ_ASSERT(event->InternalDOMEvent()->IsTrusted()); + event->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true; + } + bool dummy; + mTarget->DispatchEvent(event, &dummy); return NS_OK; } diff --git a/dom/events/AsyncEventDispatcher.h b/dom/events/AsyncEventDispatcher.h index 7314a079c79c..af7c202aeecf 100644 --- a/dom/events/AsyncEventDispatcher.h +++ b/dom/events/AsyncEventDispatcher.h @@ -28,12 +28,18 @@ namespace mozilla { class AsyncEventDispatcher : public nsRunnable { public: + /** + * If aOnlyChromeDispatch is true, the event is dispatched to only + * chrome node. In that case, if aTarget is already a chrome node, + * the event is dispatched to it, otherwise the dispatch path starts + * at the first chrome ancestor of that target. + */ AsyncEventDispatcher(nsINode* aTarget, const nsAString& aEventType, - bool aBubbles, bool aDispatchChromeOnly) + bool aBubbles, bool aOnlyChromeDispatch) : mTarget(aTarget) , mEventType(aEventType) , mBubbles(aBubbles) - , mDispatchChromeOnly(aDispatchChromeOnly) + , mOnlyChromeDispatch(aOnlyChromeDispatch) { } @@ -42,14 +48,14 @@ public: : mTarget(aTarget) , mEventType(aEventType) , mBubbles(aBubbles) - , mDispatchChromeOnly(false) + , mOnlyChromeDispatch(false) { } AsyncEventDispatcher(dom::EventTarget* aTarget, nsIDOMEvent* aEvent) : mTarget(aTarget) , mEvent(aEvent) - , mDispatchChromeOnly(false) + , mOnlyChromeDispatch(false) { } @@ -63,7 +69,7 @@ public: nsCOMPtr mEvent; nsString mEventType; bool mBubbles; - bool mDispatchChromeOnly; + bool mOnlyChromeDispatch; }; class LoadBlockingAsyncEventDispatcher final : public AsyncEventDispatcher diff --git a/dom/events/Event.cpp b/dom/events/Event.cpp index dbaac0dddbde..870785855d73 100644 --- a/dom/events/Event.cpp +++ b/dom/events/Event.cpp @@ -481,6 +481,13 @@ Event::StopImmediatePropagation() return NS_OK; } +NS_IMETHODIMP +Event::StopCrossProcessForwarding() +{ + mEvent->mFlags.mNoCrossProcessBoundaryForwarding = true; + return NS_OK; +} + NS_IMETHODIMP Event::GetIsTrusted(bool* aIsTrusted) { diff --git a/dom/events/Event.h b/dom/events/Event.h index 2cee1b019670..d864edd835d9 100644 --- a/dom/events/Event.h +++ b/dom/events/Event.h @@ -309,6 +309,7 @@ private: NS_IMETHOD GetCancelable(bool* aCancelable) override { return _to GetCancelable(aCancelable); } \ NS_IMETHOD GetTimeStamp(DOMTimeStamp* aTimeStamp) override { return _to GetTimeStamp(aTimeStamp); } \ NS_IMETHOD StopPropagation(void) override { return _to StopPropagation(); } \ + NS_IMETHOD StopCrossProcessForwarding(void) override { return _to StopCrossProcessForwarding(); } \ NS_IMETHOD PreventDefault(void) override { return _to PreventDefault(); } \ NS_IMETHOD InitEvent(const nsAString& eventTypeArg, bool canBubbleArg, bool cancelableArg) override { return _to InitEvent(eventTypeArg, canBubbleArg, cancelableArg); } \ NS_IMETHOD GetDefaultPrevented(bool* aDefaultPrevented) override { return _to GetDefaultPrevented(aDefaultPrevented); } \ diff --git a/dom/interfaces/events/nsIDOMEvent.idl b/dom/interfaces/events/nsIDOMEvent.idl index 5792b315e25c..cb3f253b7985 100644 --- a/dom/interfaces/events/nsIDOMEvent.idl +++ b/dom/interfaces/events/nsIDOMEvent.idl @@ -40,7 +40,7 @@ class EventTarget; * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html */ -[builtinclass, uuid(02d54f52-a1f5-4ad2-b560-36f14012935e)] +[builtinclass, uuid(63857daf-c084-4ea6-a8b9-6812e3176991)] interface nsIDOMEvent : nsISupports { // PhaseType @@ -213,6 +213,7 @@ interface nsIDOMEvent : nsISupports [notxpcom] boolean Deserialize(in ConstIPCMessagePtr aMsg, out voidPtr aIter); [noscript,notxpcom] void SetOwner(in EventTargetPtr aOwner); [notxpcom] DOMEventPtr InternalDOMEvent(); + [noscript] void stopCrossProcessForwarding(); }; %{C++ diff --git a/dom/manifest/ManifestProcessor.jsm b/dom/manifest/ManifestProcessor.jsm index 67cbf9724e50..f1ae86ac902d 100644 --- a/dom/manifest/ManifestProcessor.jsm +++ b/dom/manifest/ManifestProcessor.jsm @@ -21,7 +21,7 @@ */ /*exported EXPORTED_SYMBOLS */ /*JSLint options in comment below: */ -/*globals Components, XPCOMUtils*/ +/*globals Components, XPCOMUtils, Intl*/ 'use strict'; this.EXPORTED_SYMBOLS = ['ManifestProcessor']; // jshint ignore:line const imports = {}; @@ -100,6 +100,7 @@ ManifestProcessor.prototype = { const extractor = new ManifestValueExtractor(console); const imgObjProcessor = new ImgObjProcessor(console, extractor); const processedManifest = { + 'lang': processLangMember(rawManifest), 'start_url': processStartURLMember(rawManifest, manifestURL, docURL), 'display': processDisplayMember(rawManifest), 'orientation': processOrientationMember(rawManifest), @@ -246,7 +247,26 @@ ManifestProcessor.prototype = { }; return extractor.extractColorValue(spec); } + + function processLangMember(aManifest) { + const spec = { + objectName: 'manifest', + object: aManifest, + property: 'lang', + expectedType: 'string', + trim: true + }; + let tag = extractor.extractValue(spec); + // TODO: Check if tag is structurally valid. + // Cannot do this because we don't support Intl API on Android. + // https://bugzilla.mozilla.org/show_bug.cgi?id=864843 + // https://github.com/tc39/ecma402/issues/5 + // TODO: perform canonicalization on the tag. + // Can't do this today because there is no direct means to + // access canonicalization algorithms through Intl API. + // https://github.com/tc39/ecma402/issues/5 + return tag; + } } }; - this.ManifestProcessor = ManifestProcessor; // jshint ignore:line diff --git a/dom/manifest/test/mochitest.ini b/dom/manifest/test/mochitest.ini index f1141943fce1..086896de07d3 100644 --- a/dom/manifest/test/mochitest.ini +++ b/dom/manifest/test/mochitest.ini @@ -3,7 +3,6 @@ support-files = common.js resource.sjs manifestLoader.html - [test_ImageObjectProcessor_background_color.html] [test_ImageObjectProcessor_density.html] [test_ImageObjectProcessor_sizes.html] @@ -12,8 +11,9 @@ support-files = [test_ManifestProcessor_display.html] [test_ManifestProcessor_icons.html] [test_ManifestProcessor_JSON.html] +[test_ManifestProcessor_lang.html] [test_ManifestProcessor_name_and_short_name.html] [test_ManifestProcessor_orientation.html] -[test_ManifestProcessor_start_url.html] [test_ManifestProcessor_scope.html] [test_ManifestProcessor_splash_screens.html] +[test_ManifestProcessor_start_url.html] diff --git a/dom/manifest/test/test_ManifestProcessor_lang.html b/dom/manifest/test/test_ManifestProcessor_lang.html new file mode 100644 index 000000000000..f5e994175d7c --- /dev/null +++ b/dom/manifest/test/test_ManifestProcessor_lang.html @@ -0,0 +1,112 @@ + + + +Test for Bug 1143879 - Implement lang member of Web manifest + + + + diff --git a/dom/media/DecodedStream.cpp b/dom/media/DecodedStream.cpp index 891361345f93..72be03706679 100644 --- a/dom/media/DecodedStream.cpp +++ b/dom/media/DecodedStream.cpp @@ -159,11 +159,6 @@ private: nsRefPtr mStream; }; -OutputStreamData::OutputStreamData() -{ - // -} - OutputStreamData::~OutputStreamData() { mListener->Forget(); @@ -195,6 +190,33 @@ DecodedStream::DestroyData() { MOZ_ASSERT(NS_IsMainThread()); GetReentrantMonitor().AssertCurrentThreadIn(); + + // Avoid the redundant blocking to output stream. + if (!mData) { + return; + } + + // All streams are having their SourceMediaStream disconnected, so they + // need to be explicitly blocked again. + auto& outputStreams = OutputStreams(); + for (int32_t i = outputStreams.Length() - 1; i >= 0; --i) { + OutputStreamData& os = outputStreams[i]; + // Explicitly remove all existing ports. + // This is not strictly necessary but it's good form. + MOZ_ASSERT(os.mPort, "Double-delete of the ports!"); + os.mPort->Destroy(); + os.mPort = nullptr; + // During cycle collection, nsDOMMediaStream can be destroyed and send + // its Destroy message before this decoder is destroyed. So we have to + // be careful not to send any messages after the Destroy(). + if (os.mStream->IsDestroyed()) { + // Probably the DOM MediaStream was GCed. Clean up. + outputStreams.RemoveElementAt(i); + } else { + os.mStream->ChangeExplicitBlockerCount(1); + } + } + mData = nullptr; } @@ -204,7 +226,18 @@ DecodedStream::RecreateData(int64_t aInitialTime, SourceMediaStream* aStream) MOZ_ASSERT(NS_IsMainThread()); GetReentrantMonitor().AssertCurrentThreadIn(); MOZ_ASSERT(!mData); + mData.reset(new DecodedStreamData(aInitialTime, aStream)); + + // Note that the delay between removing ports in DestroyDecodedStream + // and adding new ones won't cause a glitch since all graph operations + // between main-thread stable states take effect atomically. + auto& outputStreams = OutputStreams(); + for (int32_t i = outputStreams.Length() - 1; i >= 0; --i) { + OutputStreamData& os = outputStreams[i]; + MOZ_ASSERT(!os.mStream->IsDestroyed(), "Should've been removed in DestroyData()"); + Connect(&os); + } } nsTArray& @@ -220,4 +253,35 @@ DecodedStream::GetReentrantMonitor() return mMonitor; } +void +DecodedStream::Connect(OutputStreamData* aStream) +{ + MOZ_ASSERT(NS_IsMainThread()); + GetReentrantMonitor().AssertCurrentThreadIn(); + NS_ASSERTION(!aStream->mPort, "Already connected?"); + + // The output stream must stay in sync with the decoded stream, so if + // either stream is blocked, we block the other. + aStream->mPort = aStream->mStream->AllocateInputPort(mData->mStream, + MediaInputPort::FLAG_BLOCK_INPUT | MediaInputPort::FLAG_BLOCK_OUTPUT); + // Unblock the output stream now. While it's connected to DecodedStream, + // DecodedStream is responsible for controlling blocking. + aStream->mStream->ChangeExplicitBlockerCount(-1); +} + +void +DecodedStream::Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded) +{ + MOZ_ASSERT(NS_IsMainThread()); + GetReentrantMonitor().AssertCurrentThreadIn(); + + OutputStreamData* os = OutputStreams().AppendElement(); + os->Init(this, aStream); + Connect(os); + if (aFinishWhenEnded) { + // Ensure that aStream finishes the moment mDecodedStream does. + aStream->SetAutofinish(true); + } +} + } // namespace mozilla diff --git a/dom/media/DecodedStream.h b/dom/media/DecodedStream.h index f6ce4503ba85..f26bc3dd8060 100644 --- a/dom/media/DecodedStream.h +++ b/dom/media/DecodedStream.h @@ -19,7 +19,6 @@ class SourceMediaStream; class ProcessedMediaStream; class DecodedStream; class DecodedStreamGraphListener; -class OutputStreamData; class OutputStreamListener; class ReentrantMonitor; @@ -82,11 +81,6 @@ public: class OutputStreamData { public: - // Compiler-generated default constructor needs the complete definition - // of OutputStreamListener when constructing OutputStreamData. Provide our - // own default constructor for forward declaration of OutputStreamListener - // to work. - OutputStreamData(); ~OutputStreamData(); void Init(DecodedStream* aDecodedStream, ProcessedMediaStream* aStream); nsRefPtr mStream; @@ -103,8 +97,11 @@ public: void RecreateData(int64_t aInitialTime, SourceMediaStream* aStream); nsTArray& OutputStreams(); ReentrantMonitor& GetReentrantMonitor(); + void Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded); private: + void Connect(OutputStreamData* aStream); + UniquePtr mData; // Data about MediaStreams that are being fed by the decoder. nsTArray mOutputStreams; diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp index 3d05d8ab5281..5835b1fb9ad1 100644 --- a/dom/media/MediaDecoder.cpp +++ b/dom/media/MediaDecoder.cpp @@ -289,19 +289,6 @@ void MediaDecoder::SetVolume(double aVolume) mVolume = aVolume; } -void MediaDecoder::ConnectDecodedStreamToOutputStream(OutputStreamData* aStream) -{ - NS_ASSERTION(!aStream->mPort, "Already connected?"); - - // The output stream must stay in sync with the decoded stream, so if - // either stream is blocked, we block the other. - aStream->mPort = aStream->mStream->AllocateInputPort(GetDecodedStream()->mStream, - MediaInputPort::FLAG_BLOCK_INPUT | MediaInputPort::FLAG_BLOCK_OUTPUT); - // Unblock the output stream now. While it's connected to mDecodedStream, - // mDecodedStream is responsible for controlling blocking. - aStream->mStream->ChangeExplicitBlockerCount(-1); -} - void MediaDecoder::UpdateDecodedStream() { MOZ_ASSERT(NS_IsMainThread()); @@ -316,40 +303,6 @@ void MediaDecoder::UpdateDecodedStream() } } -void MediaDecoder::DestroyDecodedStream() -{ - MOZ_ASSERT(NS_IsMainThread()); - GetReentrantMonitor().AssertCurrentThreadIn(); - - // Avoid the redundant blocking to output stream. - if (!GetDecodedStream()) { - return; - } - - // All streams are having their SourceMediaStream disconnected, so they - // need to be explicitly blocked again. - auto& outputStreams = OutputStreams(); - for (int32_t i = outputStreams.Length() - 1; i >= 0; --i) { - OutputStreamData& os = outputStreams[i]; - // Explicitly remove all existing ports. - // This is not strictly necessary but it's good form. - MOZ_ASSERT(os.mPort, "Double-delete of the ports!"); - os.mPort->Destroy(); - os.mPort = nullptr; - // During cycle collection, nsDOMMediaStream can be destroyed and send - // its Destroy message before this decoder is destroyed. So we have to - // be careful not to send any messages after the Destroy(). - if (os.mStream->IsDestroyed()) { - // Probably the DOM MediaStream was GCed. Clean up. - outputStreams.RemoveElementAt(i); - } else { - os.mStream->ChangeExplicitBlockerCount(1); - } - } - - mDecodedStream.DestroyData(); -} - void MediaDecoder::UpdateStreamBlockingForStateMachinePlaying() { GetReentrantMonitor().AssertCurrentThreadIn(); @@ -382,20 +335,10 @@ void MediaDecoder::RecreateDecodedStream(int64_t aStartTimeUSecs, if (!aGraph) { aGraph = GetDecodedStream()->mStream->Graph(); } - DestroyDecodedStream(); + mDecodedStream.DestroyData(); mDecodedStream.RecreateData(aStartTimeUSecs, aGraph->CreateSourceStream(nullptr)); - // Note that the delay between removing ports in DestroyDecodedStream - // and adding new ones won't cause a glitch since all graph operations - // between main-thread stable states take effect atomically. - auto& outputStreams = OutputStreams(); - for (int32_t i = outputStreams.Length() - 1; i >= 0; --i) { - OutputStreamData& os = outputStreams[i]; - MOZ_ASSERT(!os.mStream->IsDestroyed(), - "Should've been removed in DestroyDecodedStream()"); - ConnectDecodedStreamToOutputStream(&os); - } UpdateStreamBlockingForStateMachinePlaying(); GetDecodedStream()->mHaveBlockedForPlayState = mPlayState != PLAY_STATE_PLAYING; @@ -418,13 +361,7 @@ void MediaDecoder::AddOutputStream(ProcessedMediaStream* aStream, if (!GetDecodedStream()) { RecreateDecodedStream(mLogicalPosition, aStream->Graph()); } - OutputStreamData* os = OutputStreams().AppendElement(); - os->Init(&mDecodedStream, aStream); - ConnectDecodedStreamToOutputStream(os); - if (aFinishWhenEnded) { - // Ensure that aStream finishes the moment mDecodedStream does. - aStream->SetAutofinish(true); - } + mDecodedStream.Connect(aStream, aFinishWhenEnded); } // This can be called before Load(), in which case our mDecoderStateMachine @@ -575,7 +512,7 @@ MediaDecoder::~MediaDecoder() // Don't destroy the decoded stream until destructor in order to keep the // invariant that the decoded stream is always available in capture mode. ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); - DestroyDecodedStream(); + mDecodedStream.DestroyData(); } MediaMemoryTracker::RemoveMediaDecoder(this); UnpinForSeek(); diff --git a/dom/media/MediaDecoder.h b/dom/media/MediaDecoder.h index 3e44343256d7..36537523e51b 100644 --- a/dom/media/MediaDecoder.h +++ b/dom/media/MediaDecoder.h @@ -395,18 +395,8 @@ public: // replaying after the input as ended. In the latter case, the new source is // not connected to streams created by captureStreamUntilEnded. - /** - * Connects mDecodedStream->mStream to aStream->mStream. - */ - void ConnectDecodedStreamToOutputStream(OutputStreamData* aStream); - void UpdateDecodedStream(); - /** - * Disconnects mDecodedStream->mStream from all outputs and clears - * mDecodedStream. - */ - void DestroyDecodedStream(); /** * Recreates mDecodedStream. Call this to create mDecodedStream at first, * and when seeking, to ensure a new stream is set up with fresh buffers. @@ -421,12 +411,6 @@ public: */ void UpdateStreamBlockingForStateMachinePlaying(); - nsTArray& OutputStreams() - { - GetReentrantMonitor().AssertCurrentThreadIn(); - return mDecodedStream.OutputStreams(); - } - DecodedStreamData* GetDecodedStream() { GetReentrantMonitor().AssertCurrentThreadIn(); diff --git a/dom/media/omx/MediaOmxCommonDecoder.cpp b/dom/media/omx/MediaOmxCommonDecoder.cpp index 7e1b21d098a9..b39211c2bfc5 100644 --- a/dom/media/omx/MediaOmxCommonDecoder.cpp +++ b/dom/media/omx/MediaOmxCommonDecoder.cpp @@ -47,7 +47,7 @@ bool MediaOmxCommonDecoder::CheckDecoderCanOffloadAudio() { return (mCanOffloadAudio && !mFallbackToStateMachine && - !OutputStreams().Length() && mPlaybackRate == 1.0); + !GetDecodedStream() && mPlaybackRate == 1.0); } void diff --git a/gfx/layers/IMFYCbCrImage.cpp b/gfx/layers/IMFYCbCrImage.cpp index 80deb251f0f0..61c4f59b5da7 100644 --- a/gfx/layers/IMFYCbCrImage.cpp +++ b/gfx/layers/IMFYCbCrImage.cpp @@ -208,9 +208,9 @@ IMFYCbCrImage::GetD3D9TextureClient(CompositableClient* aClient) TextureClient* IMFYCbCrImage::GetTextureClient(CompositableClient* aClient) { - ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11MediaDevice(); + ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ImageBridgeDevice(); if (!device || - aClient->GetForwarder()->GetCompositorBackendType() != LayersBackend::LAYERS_D3D11) { + aClient->GetForwarder()->GetCompositorBackendType() != LayersBackend::LAYERS_D3D11) { IDirect3DDevice9* d3d9device = gfxWindowsPlatform::GetPlatform()->GetD3D9Device(); if (d3d9device && aClient->GetForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_D3D9) { diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 34240d3d5f69..d70ef5d40b2b 100644 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -411,7 +411,6 @@ NS_IMPL_ISUPPORTS(D3D9SharedTextureReporter, nsIMemoryReporter) gfxWindowsPlatform::gfxWindowsPlatform() : mD3D11DeviceInitialized(false) , mIsWARP(false) - , mCanInitMediaDevice(false) , mHasDeviceReset(false) { mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE; @@ -1600,55 +1599,15 @@ gfxWindowsPlatform::GetD3D11ContentDevice() } ID3D11Device* -gfxWindowsPlatform::GetD3D11MediaDevice() +gfxWindowsPlatform::GetD3D11ImageBridgeDevice() { - if (mD3D11MediaDevice) { - return mD3D11MediaDevice; + if (mD3D11DeviceInitialized) { + return mD3D11ImageBridgeDevice; } - if (!mCanInitMediaDevice) { - return nullptr; - } + InitD3D11Devices(); - mCanInitMediaDevice = false; - - nsModuleHandle d3d11Module(LoadLibrarySystem32(L"d3d11.dll")); - decltype(D3D11CreateDevice)* d3d11CreateDevice = (decltype(D3D11CreateDevice)*) - GetProcAddress(d3d11Module, "D3D11CreateDevice"); - MOZ_ASSERT(d3d11CreateDevice); - - nsTArray featureLevels; - if (IsWin8OrLater()) { - featureLevels.AppendElement(D3D_FEATURE_LEVEL_11_1); - } - featureLevels.AppendElement(D3D_FEATURE_LEVEL_11_0); - featureLevels.AppendElement(D3D_FEATURE_LEVEL_10_1); - featureLevels.AppendElement(D3D_FEATURE_LEVEL_10_0); - featureLevels.AppendElement(D3D_FEATURE_LEVEL_9_3); - - RefPtr adapter = GetDXGIAdapter(); - MOZ_ASSERT(adapter); - - HRESULT hr = E_INVALIDARG; - - MOZ_SEH_TRY{ - hr = d3d11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, - D3D11_CREATE_DEVICE_BGRA_SUPPORT, - featureLevels.Elements(), featureLevels.Length(), - D3D11_SDK_VERSION, byRef(mD3D11MediaDevice), nullptr, nullptr); - } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - mD3D11MediaDevice = nullptr; - } - - d3d11Module.disown(); - - if (FAILED(hr)) { - return nullptr; - } - - mD3D11MediaDevice->SetExceptionMode(0); - - return mD3D11MediaDevice; + return mD3D11ImageBridgeDevice; } @@ -1776,19 +1735,11 @@ bool DoesD3D11DeviceWork(ID3D11Device *device) // See bug 1083071. On some drivers, Direct3D 11 CreateShaderResourceView fails // with E_OUTOFMEMORY. -bool DoesD3D11TextureSharingWork(ID3D11Device *device) +bool DoesD3D11TextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT format, UINT bindflags) { - static bool checked = false; - static bool result = false; - - if (checked) - return result; - checked = true; - if (gfxPrefs::Direct2DForceEnabled() || gfxPrefs::LayersAccelerationForceEnabled()) { - result = true; return true; } @@ -1813,13 +1764,13 @@ bool DoesD3D11TextureSharingWork(ID3D11Device *device) desc.Height = 32; desc.MipLevels = 1; desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.Format = format; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; desc.CPUAccessFlags = 0; desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; - desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; + desc.BindFlags = bindflags; if (FAILED(device->CreateTexture2D(&desc, NULL, byRef(texture)))) { return false; } @@ -1860,10 +1811,22 @@ bool DoesD3D11TextureSharingWork(ID3D11Device *device) return false; } - result = true; return true; } +bool DoesD3D11TextureSharingWork(ID3D11Device *device) +{ + static bool checked; + static bool result; + + if (checked) + return result; + checked = true; + + result = DoesD3D11TextureSharingWorkInternal(device, DXGI_FORMAT_B8G8R8A8_UNORM, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE); + return result; +} + void gfxWindowsPlatform::InitD3D11Devices() { @@ -2035,7 +1998,27 @@ gfxWindowsPlatform::InitD3D11Devices() } if (!useWARP) { - mCanInitMediaDevice = true; + hr = E_INVALIDARG; + + MOZ_SEH_TRY{ + hr = d3d11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, + D3D11_CREATE_DEVICE_BGRA_SUPPORT, + featureLevels.Elements(), featureLevels.Length(), + D3D11_SDK_VERSION, byRef(mD3D11ImageBridgeDevice), nullptr, nullptr); + } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + mD3D11ImageBridgeDevice = nullptr; + } + + if (FAILED(hr)) { + d3d11Module.disown(); + return; + } + + mD3D11ImageBridgeDevice->SetExceptionMode(0); + + if (!DoesD3D11TextureSharingWorkInternal(mD3D11ImageBridgeDevice, DXGI_FORMAT_A8_UNORM, D3D11_BIND_SHADER_RESOURCE)) { + mD3D11ImageBridgeDevice = nullptr; + } } // We leak these everywhere and we need them our entire runtime anyway, let's diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h index 19db05028dab..1e99cd902e01 100644 --- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -244,7 +244,8 @@ public: #endif ID3D11Device *GetD3D11Device(); ID3D11Device *GetD3D11ContentDevice(); - ID3D11Device *GetD3D11MediaDevice(); + // Device to be used on the ImageBridge thread + ID3D11Device *GetD3D11ImageBridgeDevice(); // Create a D3D11 device to be used for DXVA decoding. mozilla::TemporaryRef CreateD3D11DecoderDevice(); @@ -294,11 +295,10 @@ private: nsRefPtr mDeviceManager; mozilla::RefPtr mD3D11Device; mozilla::RefPtr mD3D11ContentDevice; - mozilla::RefPtr mD3D11MediaDevice; + mozilla::RefPtr mD3D11ImageBridgeDevice; bool mD3D11DeviceInitialized; mozilla::RefPtr mD3D11ReadbackManager; bool mIsWARP; - bool mCanInitMediaDevice; bool mHasDeviceReset; DeviceResetReason mDeviceResetReason; diff --git a/layout/xul/nsXULPopupManager.cpp b/layout/xul/nsXULPopupManager.cpp index cbada39f859b..eb2e5081f2cd 100644 --- a/layout/xul/nsXULPopupManager.cpp +++ b/layout/xul/nsXULPopupManager.cpp @@ -2178,6 +2178,7 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode( if (keyCode == nsIDOMKeyEvent::DOM_VK_ESCAPE) { HidePopup(aTopVisibleMenuItem->Content(), false, false, false, true); aKeyEvent->StopPropagation(); + aKeyEvent->StopCrossProcessForwarding(); aKeyEvent->PreventDefault(); } return true; @@ -2249,6 +2250,7 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode( if (consume) { aKeyEvent->StopPropagation(); + aKeyEvent->StopCrossProcessForwarding(); aKeyEvent->PreventDefault(); } return true; @@ -2449,6 +2451,7 @@ nsXULPopupManager::KeyUp(nsIDOMKeyEvent* aKeyEvent) } aKeyEvent->StopPropagation(); + aKeyEvent->StopCrossProcessForwarding(); aKeyEvent->PreventDefault(); return NS_OK; // I am consuming event @@ -2507,6 +2510,7 @@ nsXULPopupManager::KeyDown(nsIDOMKeyEvent* aKeyEvent) // Since a menu was open, stop propagation of the event to keep other event // listeners from becoming confused. aKeyEvent->StopPropagation(); + aKeyEvent->StopCrossProcessForwarding(); return NS_OK; } @@ -2528,6 +2532,7 @@ nsXULPopupManager::KeyPress(nsIDOMKeyEvent* aKeyEvent) HandleShortcutNavigation(keyEvent, nullptr); if (consume) { aKeyEvent->StopPropagation(); + aKeyEvent->StopCrossProcessForwarding(); aKeyEvent->PreventDefault(); }