Bug 1101974. Part 4 - Refactor VsyncSource on OS X. r=mstange

This commit is contained in:
Mason Chang 2014-12-18 08:30:06 -08:00
parent 4ee4e02351
commit 528489e520
2 changed files with 78 additions and 54 deletions

View File

@ -26,6 +26,8 @@
#include <CoreVideo/CoreVideo.h>
#include "nsCocoaFeatures.h"
#include "mozilla/layers/CompositorParent.h"
#include "VsyncSource.h"
using namespace mozilla;
using namespace mozilla::gfx;
@ -38,7 +40,7 @@ typedef uint32_t AutoActivationSetting;
// bug 567552 - disable auto-activation of fonts
static void
static void
DisableFontActivation()
{
// get the main bundle identifier
@ -429,81 +431,98 @@ static CVReturn VsyncCallback(CVDisplayLinkRef aDisplayLink,
CVOptionFlags* aFlagsOut,
void* aDisplayLinkContext)
{
mozilla::VsyncSource* vsyncSource = (mozilla::VsyncSource*) aDisplayLinkContext;
if (vsyncSource->IsVsyncEnabled()) {
// Now refers to "Now" as in when this callback is called or when the current frame
// is displayed. aOutputTime is when the next frame should be displayed.
// Now is VERY VERY noisy, aOutputTime is in the future though.
int64_t timestamp = aOutputTime->hostTime;
mozilla::TimeStamp vsyncTime = mozilla::TimeStamp::FromSystemTime(timestamp);
mozilla::VsyncDispatcher::GetInstance()->NotifyVsync(vsyncTime);
return kCVReturnSuccess;
} else {
return kCVReturnDisplayLinkNotRunning;
}
VsyncSource::Display* display = (VsyncSource::Display*) aDisplayLinkContext;
int64_t timestamp = aOutputTime->hostTime;
mozilla::TimeStamp vsyncTime = mozilla::TimeStamp::FromSystemTime(timestamp);
display->NotifyVsync(vsyncTime);
return kCVReturnSuccess;
}
class OSXVsyncSource MOZ_FINAL : public mozilla::VsyncSource
class OSXVsyncSource MOZ_FINAL : public VsyncSource
{
public:
OSXVsyncSource()
{
EnableVsync();
}
virtual void EnableVsync() MOZ_OVERRIDE
virtual Display& GetGlobalDisplay() MOZ_OVERRIDE
{
// Create a display link capable of being used with all active displays
// TODO: See if we need to create an active DisplayLink for each monitor in multi-monitor
// situations. According to the docs, it is compatible with all displays running on the computer
// But if we have different monitors at different display rates, we may hit issues.
if (CVDisplayLinkCreateWithActiveCGDisplays(&mDisplayLink) != kCVReturnSuccess) {
NS_WARNING("Could not create a display link, returning");
return;
}
// Set the renderer output callback function
if (CVDisplayLinkSetOutputCallback(mDisplayLink, &VsyncCallback, this) != kCVReturnSuccess) {
NS_WARNING("Could not set displaylink output callback");
return;
}
// Activate the display link
if (CVDisplayLinkStart(mDisplayLink) != kCVReturnSuccess) {
NS_WARNING("Could not activate the display link");
mDisplayLink = nullptr;
}
return mGlobalDisplay;
}
virtual void DisableVsync() MOZ_OVERRIDE
protected:
class OSXDisplay MOZ_FINAL : public VsyncSource::Display
{
// Release the display link
if (mDisplayLink) {
CVDisplayLinkRelease(mDisplayLink);
mDisplayLink = nullptr;
public:
OSXDisplay()
{
EnableVsync();
}
}
virtual bool IsVsyncEnabled() MOZ_OVERRIDE
{
return mDisplayLink != nullptr;
}
~OSXDisplay()
{
DisableVsync();
}
virtual void EnableVsync() MOZ_OVERRIDE
{
MOZ_ASSERT(NS_IsMainThread());
// Create a display link capable of being used with all active displays
// TODO: See if we need to create an active DisplayLink for each monitor in multi-monitor
// situations. According to the docs, it is compatible with all displays running on the computer
// But if we have different monitors at different display rates, we may hit issues.
if (CVDisplayLinkCreateWithActiveCGDisplays(&mDisplayLink) != kCVReturnSuccess) {
NS_WARNING("Could not create a display link, returning");
return;
}
if (CVDisplayLinkSetOutputCallback(mDisplayLink, &VsyncCallback, this) != kCVReturnSuccess) {
NS_WARNING("Could not set displaylink output callback");
return;
}
if (CVDisplayLinkStart(mDisplayLink) != kCVReturnSuccess) {
NS_WARNING("Could not activate the display link");
mDisplayLink = nullptr;
}
}
virtual void DisableVsync() MOZ_OVERRIDE
{
MOZ_ASSERT(NS_IsMainThread());
// Release the display link
if (mDisplayLink) {
CVDisplayLinkRelease(mDisplayLink);
mDisplayLink = nullptr;
}
}
virtual bool IsVsyncEnabled() MOZ_OVERRIDE
{
MOZ_ASSERT(NS_IsMainThread());
return mDisplayLink != nullptr;
}
private:
// Manages the display link render thread
CVDisplayLinkRef mDisplayLink;
}; // OSXDisplay
private:
virtual ~OSXVsyncSource()
{
DisableVsync();
}
// Manages the display link render thread
CVDisplayLinkRef mDisplayLink;
OSXDisplay mGlobalDisplay;
}; // OSXVsyncSource
void
gfxPlatformMac::InitHardwareVsync()
already_AddRefed<mozilla::gfx::VsyncSource>
gfxPlatformMac::CreateHardwareVsyncSource()
{
nsRefPtr<VsyncSource> osxVsyncSource = new OSXVsyncSource();
mozilla::VsyncDispatcher::GetInstance()->SetVsyncSource(osxVsyncSource);
return osxVsyncSource.forget();
}
void

View File

@ -9,7 +9,12 @@
#include "nsTArrayForwardDeclare.h"
#include "gfxPlatform.h"
namespace mozilla { namespace gfx { class DrawTarget; }}
namespace mozilla {
namespace gfx {
class DrawTarget;
class VsyncSource;
} // gfx
} // mozilla
class gfxPlatformMac : public gfxPlatform {
public:
@ -67,7 +72,7 @@ public:
virtual bool UseTiling() MOZ_OVERRIDE;
virtual bool UseProgressivePaint() MOZ_OVERRIDE;
virtual void InitHardwareVsync() MOZ_OVERRIDE;
virtual already_AddRefed<mozilla::gfx::VsyncSource> CreateHardwareVsyncSource() MOZ_OVERRIDE;
// lower threshold on font anti-aliasing
uint32_t GetAntiAliasingThreshold() { return mFontAntiAliasingThreshold; }