diff options
author | rachytski <siarhei.rachytski@gmail.com> | 2011-09-22 19:58:39 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 01:24:16 +0300 |
commit | a032f7e6b612e2f1ad0d774067fbb973091897ad (patch) | |
tree | 0112898798f6189c27a71c97df3d45323a181d26 /platform | |
parent | 11c675cd56f1ac7ddef3414bd000575fe2fd9cd9 (diff) |
introduced VideoTimer, refactored rendering loop to use Timers, as on iOS.
Diffstat (limited to 'platform')
-rw-r--r-- | platform/apple_video_timer.mm | 67 | ||||
-rw-r--r-- | platform/ios_video_timer.mm | 89 | ||||
-rw-r--r-- | platform/platform.pro | 13 | ||||
-rw-r--r-- | platform/video_timer.cpp | 4 | ||||
-rw-r--r-- | platform/video_timer.hpp | 26 |
5 files changed, 197 insertions, 2 deletions
diff --git a/platform/apple_video_timer.mm b/platform/apple_video_timer.mm new file mode 100644 index 0000000000..6092d33901 --- /dev/null +++ b/platform/apple_video_timer.mm @@ -0,0 +1,67 @@ +#include "video_timer.hpp" + +#include "../std/target_os.hpp" + +#include <CoreVideo/CVDisplayLink.h> + +class AppleVideoTimer : public VideoTimer +{ + + CVDisplayLinkRef m_displayLink; + +public: + + AppleVideoTimer(VideoTimer::TFrameFn frameFn) + : VideoTimer(frameFn), m_displayLink(0) + {} + + ~AppleVideoTimer() + { + stop(); + } + + void start() + { + if (m_displayLink == 0) + { + CVDisplayLinkCreateWithActiveCGDisplays(&m_displayLink); + CVDisplayLinkSetOutputCallback(m_displayLink, &displayLinkCallback, (void*)this); + CVDisplayLinkStart(m_displayLink); + } + } + + static CVReturn displayLinkCallback( + CVDisplayLinkRef displayLink, + const CVTimeStamp *inNow, + const CVTimeStamp *inOutputTime, + CVOptionFlags flagsIn, + CVOptionFlags *flagsOut, + void *displayLinkContext + ) + { + AppleVideoTimer * t = reinterpret_cast<AppleVideoTimer*>(displayLinkContext); + t->perform(); + + return kCVReturnSuccess; + } + + void stop() + { + if (m_displayLink) + { + CVDisplayLinkStop(m_displayLink); + CVDisplayLinkRelease(m_displayLink); + m_displayLink = 0; + } + } + + void perform() + { + m_frameFn(); + } +}; + +VideoTimer * CreateAppleVideoTimer(VideoTimer::TFrameFn frameFn) +{ + return new AppleVideoTimer(frameFn); +} diff --git a/platform/ios_video_timer.mm b/platform/ios_video_timer.mm new file mode 100644 index 0000000000..4a80809ac5 --- /dev/null +++ b/platform/ios_video_timer.mm @@ -0,0 +1,89 @@ +#include "video_timer.hpp" + +#include "../std/target_os.hpp" + +#import <QuartzCore/CADisplayLink.h> +#import <Foundation/NSRunLoop.h> + +class IOSVideoTimer; + +@interface VideoTimerWrapper : NSObject { +@private + IOSVideoTimer * m_timer; +} +- (id)initWithTimer:(IOSVideoTimer *) timer; +- (void)perform; +@end + +class IOSVideoTimer : public VideoTimer +{ + + VideoTimerWrapper * m_objCppWrapper; + CADisplayLink * m_displayLink; + +public: + + IOSVideoTimer(VideoTimer::TFrameFn frameFn) : VideoTimer(frameFn), m_objCppWrapper(0), m_displayLink(0) + {} + + ~IOSVideoTimer() + { + stop(); + } + + void start() + { + if (m_displayLink == 0) + { + m_objCppWrapper = [[VideoTimerWrapper alloc] initWithTimer:this]; + m_displayLink = [CADisplayLink displayLinkWithTarget:m_objCppWrapper selector:@selector(perform)]; + m_displayLink.frameInterval = 1; + [m_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; + } + } + + void stop() + { + if (m_displayLink) + { + [m_displayLink invalidate]; + [m_objCppWrapper release]; + m_displayLink = 0; + } + } + + void perform() + { + m_frameFn(); + } +}; + +@implementation VideoTimerWrapper + +- (id)initWithTimer:(IOSVideoTimer*) timer +{ + self = [super init]; + if (self) { + m_timer = timer; + } + return self; +} + +- (void)dealloc +{ + [super dealloc]; +} + +- (void)perform +{ + m_timer->perform(); +} + +@end + +VideoTimer * CreateIOSVideoTimer(VideoTimer::TFrameFn frameFn) +{ + return new IOSVideoTimer(frameFn); +} + + diff --git a/platform/platform.pro b/platform/platform.pro index 2889e7ab9f..bcf2fcf510 100644 --- a/platform/platform.pro +++ b/platform/platform.pro @@ -35,8 +35,15 @@ macx|iphone* { } macx:!iphone* { - OBJECTIVE_SOURCES += wifi_info_mac.mm - LIBS += -framework CoreWLAN + OBJECTIVE_SOURCES += wifi_info_mac.mm \ + apple_video_timer.mm + + LIBS += -framework CoreWLAN -framework QuartzCore +} + +iphone* { + OBJECTIVE_SOURCES += ios_video_timer.mm + LIBS += -framework QuartzCore } win32 { @@ -52,9 +59,11 @@ HEADERS += \ concurrent_runner.hpp \ preferred_languages.hpp \ settings.hpp \ + video_timer.hpp SOURCES += \ location_manager.cpp \ preferred_languages.cpp \ settings.cpp \ platform.cpp \ + video_timer.cpp diff --git a/platform/video_timer.cpp b/platform/video_timer.cpp new file mode 100644 index 0000000000..288534d04a --- /dev/null +++ b/platform/video_timer.cpp @@ -0,0 +1,4 @@ +#include "video_timer.hpp" + +VideoTimer::VideoTimer(TFrameFn fn) : m_frameFn(fn) +{} diff --git a/platform/video_timer.hpp b/platform/video_timer.hpp new file mode 100644 index 0000000000..a93bfee31a --- /dev/null +++ b/platform/video_timer.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "../std/function.hpp" + +/// Timer, synchronized to Vertical Sync +class VideoTimer +{ +public: + + typedef function<void()> TFrameFn; + +protected: + + TFrameFn m_frameFn; + +public: + + VideoTimer(TFrameFn fn); + + virtual void start() = 0; + virtual void stop() = 0; +}; + +extern "C" VideoTimer * CreateIOSVideoTimer(VideoTimer::TFrameFn frameFn); +extern "C" VideoTimer * CreateAppleVideoTimer(VideoTimer::TFrameFn frameFn); +extern "C" VideoTimer * CreateWin32VideoTimer(VideoTimer::TFrameFn frameFn); |