author | JerryShih <hshih@mozilla.com> |
Wed, 14 Jan 2015 00:37:00 +0100 | |
changeset 223935 | b9cd3847b0afc227c4071d11a9a2cc8688b9bde8 |
parent 223934 | 61c681281c3047a9f7acf1aba6d9270a4dc1d48a |
child 223936 | 11e3a259b15d83f4b2ac390b33f71fc156cccccf |
push id | 54084 |
push user | cbook@mozilla.com |
push date | Thu, 15 Jan 2015 10:47:30 +0000 |
treeherder | mozilla-inbound@828b434f69f7 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bent |
bugs | 1121331 |
milestone | 38.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/ipc/glue/BackgroundChildImpl.cpp +++ b/ipc/glue/BackgroundChildImpl.cpp @@ -6,16 +6,17 @@ #include "ActorsChild.h" // IndexedDB #include "FileDescriptorSetChild.h" #include "mozilla/Assertions.h" #include "mozilla/dom/PBlobChild.h" #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h" #include "mozilla/dom/ipc/BlobChild.h" #include "mozilla/ipc/PBackgroundTestChild.h" +#include "mozilla/layout/VsyncChild.h" #include "nsID.h" #include "nsTraceRefcnt.h" namespace { class TestChild MOZ_FINAL : public mozilla::ipc::PBackgroundTestChild { friend class mozilla::ipc::BackgroundChildImpl; @@ -180,16 +181,31 @@ BackgroundChildImpl::DeallocPFileDescrip PFileDescriptorSetChild* aActor) { MOZ_ASSERT(aActor); delete static_cast<FileDescriptorSetChild*>(aActor); return true; } +BackgroundChildImpl::PVsyncChild* +BackgroundChildImpl::AllocPVsyncChild() +{ + return new mozilla::layout::VsyncChild(); +} + +bool +BackgroundChildImpl::DeallocPVsyncChild(PVsyncChild* aActor) +{ + MOZ_ASSERT(aActor); + + delete static_cast<mozilla::layout::VsyncChild*>(aActor); + return true; +} + } // namespace ipc } // namespace mozilla bool TestChild::Recv__delete__(const nsCString& aTestArg) { MOZ_RELEASE_ASSERT(aTestArg == mTestArg, "BackgroundTest message was corrupted!");
--- a/ipc/glue/BackgroundChildImpl.h +++ b/ipc/glue/BackgroundChildImpl.h @@ -65,16 +65,22 @@ protected: DeallocPBlobChild(PBlobChild* aActor) MOZ_OVERRIDE; virtual PFileDescriptorSetChild* AllocPFileDescriptorSetChild(const FileDescriptor& aFileDescriptor) MOZ_OVERRIDE; virtual bool DeallocPFileDescriptorSetChild(PFileDescriptorSetChild* aActor) MOZ_OVERRIDE; + + virtual PVsyncChild* + AllocPVsyncChild() MOZ_OVERRIDE; + + virtual bool + DeallocPVsyncChild(PVsyncChild* aActor) MOZ_OVERRIDE; }; class BackgroundChildImpl::ThreadLocal MOZ_FINAL { friend class nsAutoPtr<ThreadLocal>; public: nsAutoPtr<mozilla::dom::indexedDB::ThreadLocal> mIndexedDBThreadLocal;
--- a/ipc/glue/BackgroundParentImpl.cpp +++ b/ipc/glue/BackgroundParentImpl.cpp @@ -6,16 +6,18 @@ #include "FileDescriptorSetParent.h" #include "mozilla/Assertions.h" #include "mozilla/dom/PBlobParent.h" #include "mozilla/dom/indexedDB/ActorsParent.h" #include "mozilla/dom/ipc/BlobParent.h" #include "mozilla/ipc/BackgroundParent.h" #include "mozilla/ipc/PBackgroundTestParent.h" +#include "mozilla/layout/VsyncParent.h" +#include "nsRefPtr.h" #include "nsThreadUtils.h" #include "nsTraceRefcnt.h" #include "nsXULAppAPI.h" #ifdef DISABLE_ASSERTS_FOR_FUZZING #define ASSERT_UNLESS_FUZZING(...) do { } while (0) #else #define ASSERT_UNLESS_FUZZING(...) MOZ_ASSERT(false) @@ -202,16 +204,42 @@ BackgroundParentImpl::DeallocPFileDescri AssertIsInMainProcess(); AssertIsOnBackgroundThread(); MOZ_ASSERT(aActor); delete static_cast<FileDescriptorSetParent*>(aActor); return true; } +BackgroundParentImpl::PVsyncParent* +BackgroundParentImpl::AllocPVsyncParent() +{ + AssertIsInMainProcess(); + AssertIsOnBackgroundThread(); + + nsRefPtr<mozilla::layout::VsyncParent> actor = + mozilla::layout::VsyncParent::Create(); + // There still has one ref-count after return, and it will be released in + // DeallocPVsyncParent(). + return actor.forget().take(); +} + +bool +BackgroundParentImpl::DeallocPVsyncParent(PVsyncParent* aActor) +{ + AssertIsInMainProcess(); + AssertIsOnBackgroundThread(); + MOZ_ASSERT(aActor); + + // This actor already has one ref-count. Please check AllocPVsyncParent(). + nsRefPtr<mozilla::layout::VsyncParent> actor = + dont_AddRef(static_cast<mozilla::layout::VsyncParent*>(aActor)); + return true; +} + } // namespace ipc } // namespace mozilla void TestParent::ActorDestroy(ActorDestroyReason aWhy) { AssertIsInMainProcess(); AssertIsOnBackgroundThread();
--- a/ipc/glue/BackgroundParentImpl.h +++ b/ipc/glue/BackgroundParentImpl.h @@ -4,16 +4,21 @@ #ifndef mozilla_ipc_backgroundparentimpl_h__ #define mozilla_ipc_backgroundparentimpl_h__ #include "mozilla/Attributes.h" #include "mozilla/ipc/PBackgroundParent.h" namespace mozilla { + +namespace layout { +class VsyncParent; +} + namespace ipc { // Instances of this class should never be created directly. This class is meant // to be inherited in BackgroundImpl. class BackgroundParentImpl : public PBackgroundParent { protected: BackgroundParentImpl(); @@ -53,14 +58,20 @@ protected: virtual PFileDescriptorSetParent* AllocPFileDescriptorSetParent(const FileDescriptor& aFileDescriptor) MOZ_OVERRIDE; virtual bool DeallocPFileDescriptorSetParent(PFileDescriptorSetParent* aActor) MOZ_OVERRIDE; + + virtual PVsyncParent* + AllocPVsyncParent() MOZ_OVERRIDE; + + virtual bool + DeallocPVsyncParent(PVsyncParent* aActor) MOZ_OVERRIDE; }; } // namespace ipc } // namespace mozilla #endif // mozilla_ipc_backgroundparentimpl_h__
--- a/ipc/glue/PBackground.ipdl +++ b/ipc/glue/PBackground.ipdl @@ -1,36 +1,40 @@ /* 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 protocol PBackgroundIDBFactory; include protocol PBackgroundTest; include protocol PBlob; include protocol PFileDescriptorSet; +include protocol PVsync; include DOMTypes; include PBackgroundIDBSharedTypes; namespace mozilla { namespace ipc { sync protocol PBackground { manages PBackgroundIDBFactory; manages PBackgroundTest; manages PBlob; manages PFileDescriptorSet; + manages PVsync; parent: // Only called at startup during mochitests to check the basic infrastructure. PBackgroundTest(nsCString testArg); PBackgroundIDBFactory(LoggingInfo loggingInfo); + PVsync(); + both: PBlob(BlobConstructorParams params); PFileDescriptorSet(FileDescriptor fd); }; } // namespace ipc } // namespace mozilla
new file mode 100644 --- /dev/null +++ b/layout/ipc/PVsync.ipdl @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +include protocol PBackground; + +using class mozilla::TimeStamp from "mozilla/TimeStamp.h"; + +namespace mozilla { +namespace layout { + +/* + * The PVsync is a sub-protocol in PBackground and it is used to notify + * the vsync event from chrome to content process. It also provides the + * interfaces for content to observe/unobserve vsync event notifications. + */ +async protocol PVsync +{ + manager PBackground; + +child: + // Send vsync event from chrome to content process. + async Notify(TimeStamp aVsyncTimestamp); + +parent: + // Content process use these messages to acquire the vsync event. + async Observe(); + async Unobserve(); + + // This message is never sent. Each PVsync actor will stay alive as long as + // its PBackground manager. + async __delete__(); +}; + +} // namespace layout +} // namespace mozilla +
new file mode 100644 --- /dev/null +++ b/layout/ipc/VsyncChild.cpp @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "VsyncChild.h" + +#include "mozilla/VsyncDispatcher.h" +#include "nsThreadUtils.h" + +namespace mozilla { +namespace layout { + +VsyncChild::VsyncChild() + : mObservingVsync(false) +{ + MOZ_ASSERT(NS_IsMainThread()); +} + +VsyncChild::~VsyncChild() +{ + MOZ_ASSERT(NS_IsMainThread()); +} + +bool +VsyncChild::SendObserve() +{ + MOZ_ASSERT(NS_IsMainThread()); + if (!mObservingVsync) { + PVsyncChild::SendObserve(); + mObservingVsync = true; + } + return true; +} + +bool +VsyncChild::SendUnobserve() +{ + MOZ_ASSERT(NS_IsMainThread()); + if (mObservingVsync) { + PVsyncChild::SendUnobserve(); + mObservingVsync = false; + } + return true; +} + +void +VsyncChild::ActorDestroy(ActorDestroyReason aActorDestroyReason) +{ + MOZ_ASSERT(NS_IsMainThread()); + mObserver = nullptr; +} + +bool +VsyncChild::RecvNotify(const TimeStamp& aVsyncTimestamp) +{ + MOZ_ASSERT(NS_IsMainThread()); + if (mObservingVsync && mObserver) { + mObserver->NotifyVsync(aVsyncTimestamp); + } + return true; +} + +void +VsyncChild::SetVsyncObserver(VsyncObserver* aVsyncObserver) +{ + MOZ_ASSERT(NS_IsMainThread()); + mObserver = aVsyncObserver; +} + +} // namespace layout +} // namespace mozilla
new file mode 100644 --- /dev/null +++ b/layout/ipc/VsyncChild.h @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_layout_ipc_VsyncChild_h +#define mozilla_layout_ipc_VsyncChild_h + +#include "mozilla/layout/PVsyncChild.h" +#include "nsRefPtr.h" + +namespace mozilla { + +class VsyncObserver; + +namespace ipc { +class BackgroundChildImpl; +} + +namespace layout { + +// The PVsyncChild actor receives a vsync event from the main process and +// delivers it to the child process. Currently this is restricted to the main +// thread only. The actor will stay alive until the process dies or its +// PVsyncParent actor dies. +class VsyncChild MOZ_FINAL : public PVsyncChild +{ + friend class mozilla::ipc::BackgroundChildImpl; + +public: + // Hide the SendObserve/SendUnobserve in PVsyncChild. We add an flag + // mObservingVsync to handle the race problem of unobserving vsync event. + bool SendObserve(); + bool SendUnobserve(); + + // Bind a VsyncObserver into VsyncChild after ipc channel connected. + void SetVsyncObserver(VsyncObserver* aVsyncObserver); + +private: + VsyncChild(); + virtual ~VsyncChild(); + + virtual bool RecvNotify(const TimeStamp& aVsyncTimestamp) MOZ_OVERRIDE; + virtual void ActorDestroy(ActorDestroyReason aActorDestroyReason) MOZ_OVERRIDE; + + bool mObservingVsync; + + // The content side vsync observer. + nsRefPtr<VsyncObserver> mObserver; +}; + +} // namespace layout +} // namespatce mozilla + +#endif // mozilla_layout_ipc_VsyncChild_h
new file mode 100644 --- /dev/null +++ b/layout/ipc/VsyncParent.cpp @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "VsyncParent.h" + +#include "BackgroundParent.h" +#include "BackgroundParentImpl.h" +#include "gfxPlatform.h" +#include "mozilla/unused.h" +#include "nsIThread.h" +#include "nsThreadUtils.h" +#include "VsyncSource.h" + +namespace mozilla { + +using namespace ipc; + +namespace layout { + +/*static*/ already_AddRefed<VsyncParent> +VsyncParent::Create() +{ + AssertIsOnBackgroundThread(); + nsRefPtr<gfx::VsyncSource> vsyncSource = gfxPlatform::GetPlatform()->GetHardwareVsync(); + nsRefPtr<VsyncParent> vsyncParent = new VsyncParent(); + vsyncParent->mVsyncDispatcher = vsyncSource->GetRefreshTimerVsyncDispatcher(); + return vsyncParent.forget(); +} + +VsyncParent::VsyncParent() + : mObservingVsync(false) + , mDestroyed(false) + , mBackgroundThread(NS_GetCurrentThread()) +{ + MOZ_ASSERT(mBackgroundThread); + AssertIsOnBackgroundThread(); +} + +VsyncParent::~VsyncParent() +{ + // Since we use NS_INLINE_DECL_THREADSAFE_REFCOUNTING, we can't make sure + // VsyncParent is always released on the background thread. +} + +bool +VsyncParent::NotifyVsync(TimeStamp aTimeStamp) +{ + // Called on hardware vsync thread. We should post to current ipc thread. + MOZ_ASSERT(!IsOnBackgroundThread()); + nsRefPtr<nsIRunnable> vsyncEvent = + NS_NewRunnableMethodWithArg<TimeStamp>(this, + &VsyncParent::DispatchVsyncEvent, + aTimeStamp); + MOZ_ALWAYS_TRUE(NS_SUCCEEDED(mBackgroundThread->Dispatch(vsyncEvent, NS_DISPATCH_NORMAL))); + return true; +} + +void +VsyncParent::DispatchVsyncEvent(TimeStamp aTimeStamp) +{ + AssertIsOnBackgroundThread(); + + // If we call NotifyVsync() when we handle ActorDestroy() message, we might + // still call DispatchVsyncEvent(). + // Similarly, we might also receive RecvUnobserveVsync() when call + // NotifyVsync(). We use mObservingVsync and mDestroyed flags to skip this + // notification. + if (mObservingVsync && !mDestroyed) { + unused << SendNotify(aTimeStamp); + } +} + +bool +VsyncParent::RecvObserve() +{ + AssertIsOnBackgroundThread(); + if (!mObservingVsync) { + mVsyncDispatcher->AddChildRefreshTimer(this); + mObservingVsync = true; + return true; + } + return false; +} + +bool +VsyncParent::RecvUnobserve() +{ + AssertIsOnBackgroundThread(); + if (mObservingVsync) { + mVsyncDispatcher->RemoveChildRefreshTimer(this); + mObservingVsync = false; + return true; + } + return false; +} + +void +VsyncParent::ActorDestroy(ActorDestroyReason aReason) +{ + MOZ_ASSERT(!mDestroyed); + AssertIsOnBackgroundThread(); + if (mObservingVsync) { + mVsyncDispatcher->RemoveChildRefreshTimer(this); + } + mVsyncDispatcher = nullptr; + mDestroyed = true; +} + +} // namespace layout +} // namespace mozilla
new file mode 100644 --- /dev/null +++ b/layout/ipc/VsyncParent.h @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_layout_ipc_VsyncParent_h +#define mozilla_layout_ipc_VsyncParent_h + +#include "mozilla/layout/PVsyncParent.h" +#include "mozilla/VsyncDispatcher.h" +#include "nsCOMPtr.h" +#include "nsRefPtr.h" + +class nsIThread; + +namespace mozilla { + +namespace ipc { +class BackgroundParentImpl; +} + +namespace layout { + +// Use PBackground thread in the main process to send vsync notifications to +// content process. This actor will be released when its parent protocol calls +// DeallocPVsyncParent(). +class VsyncParent MOZ_FINAL : public PVsyncParent, + public VsyncObserver +{ + friend class mozilla::ipc::BackgroundParentImpl; + +private: + static already_AddRefed<VsyncParent> Create(); + + VsyncParent(); + virtual ~VsyncParent(); + + virtual bool NotifyVsync(TimeStamp aTimeStamp) MOZ_OVERRIDE; + + virtual bool RecvObserve() MOZ_OVERRIDE; + virtual bool RecvUnobserve() MOZ_OVERRIDE; + virtual void ActorDestroy(ActorDestroyReason aActorDestroyReason) MOZ_OVERRIDE; + + void DispatchVsyncEvent(TimeStamp aTimeStamp); + + bool mObservingVsync; + bool mDestroyed; + nsCOMPtr<nsIThread> mBackgroundThread; + nsRefPtr<RefreshTimerVsyncDispatcher> mVsyncDispatcher; +}; + +} //layout +} //mozilla + +#endif //mozilla_layout_ipc_VsyncParent_h
--- a/layout/ipc/moz.build +++ b/layout/ipc/moz.build @@ -3,25 +3,33 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. EXPORTS.mozilla.layout += [ 'RenderFrameChild.h', 'RenderFrameParent.h', 'RenderFrameUtils.h', + 'VsyncChild.h', + 'VsyncParent.h', ] UNIFIED_SOURCES += [ 'RenderFrameChild.cpp', 'RenderFrameParent.cpp', ] +SOURCES += [ + 'VsyncChild.cpp', + 'VsyncParent.cpp', +] + IPDL_SOURCES = [ 'PRenderFrame.ipdl', + 'PVsync.ipdl', ] FAIL_ON_WARNINGS = True include('/ipc/chromium/chromium-config.mozbuild') FINAL_LIBRARY = 'xul'