Bug 1144638. Retry getting an active display link. r=mstange

This commit is contained in:
Mason Chang 2015-03-18 16:17:26 -07:00
Родитель 42505bae58
Коммит 0500dc0b4b
1 изменённых файлов: 30 добавлений и 9 удалений

Просмотреть файл

@ -450,13 +450,26 @@ public:
OSXDisplay()
: mDisplayLink(nullptr)
{
MOZ_ASSERT(NS_IsMainThread());
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
}
~OSXDisplay()
{
MOZ_ASSERT(NS_IsMainThread());
mTimer->Cancel();
mTimer = nullptr;
DisableVsync();
}
static void RetryEnableVsync(nsITimer* aTimer, void* aOsxDisplay)
{
MOZ_ASSERT(NS_IsMainThread());
OSXDisplay* osxDisplay = static_cast<OSXDisplay*>(aOsxDisplay);
MOZ_ASSERT(osxDisplay);
osxDisplay->EnableVsync();
}
virtual void EnableVsync() MOZ_OVERRIDE
{
MOZ_ASSERT(NS_IsMainThread());
@ -469,18 +482,25 @@ public:
// 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 with all active displays. Falling back to main display\n");
NS_WARNING("Could not create a display link with all active displays. Retrying\n");
CVDisplayLinkRelease(mDisplayLink);
mDisplayLink = nullptr;
// bug 1142708 - When coming back from sleep, there may be no active displays ready yet,
// even if listening for the kIOMessageSystemHasPoweredOn event from OS X sleep notifications.
// bug 1142708 - When coming back from sleep,
// or when changing displays, active displays may not be ready yet,
// even if listening for the kIOMessageSystemHasPoweredOn event
// from OS X sleep notifications.
// Active displays are those that are drawable.
// In these cases, default back to the main display to try to get a vsync event.
// The alternative would be to keep polling the CGActiveDisplayList for the displays to be ready.
if (CVDisplayLinkCreateWithCGDisplay(CGMainDisplayID(), &mDisplayLink) != kCVReturnSuccess) {
MOZ_CRASH("Could not create a CVDisplayLink with either active displays or the main display");
}
NS_WARNING("Using the CVDisplayLink from the main display\n");
// bug 1144638 - When changing display configurations and getting
// notifications from CGDisplayReconfigurationCallBack, the
// callback gets called twice for each active display
// so it's difficult to know when all displays are active.
// Instead, try again soon. The delay is arbitrary. 100ms chosen
// because on a late 2013 15" retina, it takes about that
// long to come back up from sleep.
uint32_t delay = 100;
mTimer->InitWithFuncCallback(RetryEnableVsync, this, delay, nsITimer::TYPE_ONE_SHOT);
return;
}
if (CVDisplayLinkSetOutputCallback(mDisplayLink, &VsyncCallback, this) != kCVReturnSuccess) {
@ -528,6 +548,7 @@ public:
private:
// Manages the display link render thread
CVDisplayLinkRef mDisplayLink;
nsRefPtr<nsITimer> mTimer;
}; // OSXDisplay
private: