author | Mason Chang <mchang@mozilla.com> |
Fri, 13 Feb 2015 17:17:24 +0800 | |
changeset 229111 | 9b1c4da648cabaefc13638f720408dee3d3ea33a |
parent 229110 | c4061f7c942252920028d6f73f54902a242b5256 |
child 229112 | 6b41f4a594473ffcabf7d7885d166a7d9648fae6 |
push id | 28282 |
push user | cbook@mozilla.com |
push date | Mon, 16 Feb 2015 15:06:35 +0000 |
treeherder | mozilla-central@09f4968d5f42 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | kats |
bugs | 1127151 |
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
|
gfx/thebes/gfxWindowsPlatform.cpp | file | annotate | diff | comparison | revisions | |
gfx/thebes/gfxWindowsPlatform.h | file | annotate | diff | comparison | revisions |
--- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -71,16 +71,18 @@ #include "SurfaceCache.h" #include "gfxPrefs.h" #if defined(MOZ_CRASHREPORTER) #include "nsExceptionHandler.h" #endif +#include "VsyncSource.h" + using namespace mozilla; using namespace mozilla::gfx; using namespace mozilla::layers; using namespace mozilla::widget; using namespace mozilla::image; DCFromDrawTarget::DCFromDrawTarget(DrawTarget& aDrawTarget) { @@ -1906,8 +1908,115 @@ gfxWindowsPlatform::InitD3D11Devices() Factory::SetDirect3D11Device(mD3D11ContentDevice); } // We leak these everywhere and we need them our entire runtime anyway, let's // leak it here as well. d3d11Module.disown(); } +class D3DVsyncSource MOZ_FINAL : public VsyncSource +{ +public: + + class D3DVsyncDisplay MOZ_FINAL : public VsyncSource::Display + { + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(D3DVsyncDisplay) + public: + D3DVsyncDisplay() + : mVsyncEnabledLock("D3DVsyncEnabledLock") + , mVsyncEnabled(false) + { + mVsyncThread = new base::Thread("WindowsVsyncThread"); + } + + virtual ~D3DVsyncDisplay() + { + MOZ_ASSERT(NS_IsMainThread()); + DisableVsync(); + delete mVsyncThread; + } + + virtual void EnableVsync() MOZ_OVERRIDE + { + MOZ_ASSERT(NS_IsMainThread()); + { // scope lock + MonitorAutoLock lock(mVsyncEnabledLock); + if (mVsyncEnabled) { + return; + } + mVsyncEnabled = true; + } + + MOZ_RELEASE_ASSERT(mVsyncThread->Start(), "Could not start Windows vsync thread"); + CancelableTask* vsyncStart = NewRunnableMethod(this, + &D3DVsyncDisplay::VBlankLoop); + mVsyncThread->message_loop()->PostTask(FROM_HERE, vsyncStart); + } + + virtual void DisableVsync() MOZ_OVERRIDE + { + MOZ_ASSERT(NS_IsMainThread()); + { // scope lock + MonitorAutoLock lock(mVsyncEnabledLock); + if (!mVsyncEnabled) { + return; + } + mVsyncEnabled = false; + } + + mVsyncThread->Stop(); + } + + virtual bool IsVsyncEnabled() MOZ_OVERRIDE + { + MOZ_ASSERT(NS_IsMainThread()); + MonitorAutoLock lock(mVsyncEnabledLock); + return mVsyncEnabled; + } + + private: + bool IsInVsyncThread() + { + return mVsyncThread->thread_id() == PlatformThread::CurrentId(); + } + + Monitor mVsyncEnabledLock; + base::Thread* mVsyncThread; + bool mVsyncEnabled; + }; // end d3dvsyncdisplay + + D3DVsyncSource() + { + mPrimaryDisplay = new D3DVsyncDisplay(); + } + + virtual Display& GetGlobalDisplay() MOZ_OVERRIDE + { + return *mPrimaryDisplay; + } + +private: + virtual ~D3DVsyncSource() + { + } + nsRefPtr<D3DVsyncDisplay> mPrimaryDisplay; +}; // end D3DVsyncSource + +already_AddRefed<mozilla::gfx::VsyncSource> +gfxWindowsPlatform::CreateHardwareVsyncSource() +{ + MOZ_RELEASE_ASSERT(NS_IsMainThread()); + if (!WinUtils::dwmIsCompositionEnabledPtr) { + NS_WARNING("Dwm composition not available, falling back to software vsync\n"); + return gfxPlatform::CreateHardwareVsyncSource(); + } + + BOOL dwmEnabled = false; + WinUtils::dwmIsCompositionEnabledPtr(&dwmEnabled); + if (!dwmEnabled) { + NS_WARNING("DWM not enabled, falling back to software vsync\n"); + return gfxPlatform::CreateHardwareVsyncSource(); + } + + nsRefPtr<VsyncSource> d3dVsyncSource = new D3DVsyncSource(); + return d3dVsyncSource.forget(); +}
--- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -248,16 +248,17 @@ public: ID3D11Device *GetD3D11ContentDevice(); mozilla::layers::ReadbackManagerD3D11* GetReadbackManager(); static bool IsOptimus(); bool IsWARP() { return mIsWARP; } + virtual already_AddRefed<mozilla::gfx::VsyncSource> CreateHardwareVsyncSource() MOZ_OVERRIDE; static mozilla::Atomic<size_t> sD3D11MemoryUsed; static mozilla::Atomic<size_t> sD3D9MemoryUsed; static mozilla::Atomic<size_t> sD3D9SurfaceImageUsed; static mozilla::Atomic<size_t> sD3D9SharedTextureUsed; protected: RenderMode mRenderMode;