mirror of https://github.com/kivy/kivy.git
clock: implement rfps (real frame displayed on screen)
base: display and flip only when needed (might be have some bugs.)
This commit is contained in:
parent
dd91a1f940
commit
e838e13e96
|
@ -6,7 +6,8 @@ from kivy.lang import Builder
|
|||
|
||||
class KvApp(App):
|
||||
def _print_fps(self, *largs):
|
||||
print 'FPS:', Clock.get_fps()
|
||||
print 'FPS: %2.4f (real draw: %d)' % (
|
||||
Clock.get_fps(), Clock.get_rfps())
|
||||
def build(self):
|
||||
Clock.schedule_interval(self._print_fps, 1)
|
||||
return Builder.load_file(self.options['filename'])
|
||||
|
|
|
@ -12,6 +12,7 @@ from kivy.logger import Logger
|
|||
from kivy.exceptions import ExceptionManager
|
||||
from kivy.clock import Clock
|
||||
from kivy.input import TouchFactory, kivy_postproc_modules
|
||||
from kivy.graphics import GraphicContext
|
||||
|
||||
# private vars
|
||||
EventLoop = None
|
||||
|
@ -211,7 +212,9 @@ class EventLoopBase(object):
|
|||
self.dispatch_input()
|
||||
|
||||
window = self.window
|
||||
if window:
|
||||
need_redraw = GraphicContext.instance().need_redraw
|
||||
if window and need_redraw:
|
||||
Clock.tick_draw()
|
||||
window.dispatch('on_draw')
|
||||
window.dispatch('on_flip')
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ cdef class GraphicContext:
|
|||
cdef readonly int need_flush
|
||||
cdef Shader _default_shader
|
||||
cdef object _default_texture
|
||||
cdef int need_redraw
|
||||
cdef int _need_redraw
|
||||
|
||||
cpdef post_update(self)
|
||||
cpdef finish_frame(self)
|
||||
|
|
|
@ -45,18 +45,22 @@ cdef class GraphicContext:
|
|||
self.journal = set()
|
||||
self.need_flush = 0
|
||||
self._default_shader = None
|
||||
self._need_redraw = 1
|
||||
|
||||
def __init__(self):
|
||||
# create initial state
|
||||
self.reset()
|
||||
self.save()
|
||||
self.need_redraw = 1
|
||||
|
||||
property need_redraw:
|
||||
def __get__(self):
|
||||
return self._need_redraw
|
||||
|
||||
cpdef post_update(self):
|
||||
self.need_redraw = 1
|
||||
self._need_redraw = 1
|
||||
|
||||
cpdef finish_frame(self):
|
||||
self.need_redraw = 0
|
||||
self._need_redraw = 0
|
||||
err = glGetError()
|
||||
if err:
|
||||
Logger.warning('GContext: GL Error while drawing frame: %d' % err)
|
||||
|
|
|
@ -17,8 +17,9 @@ If the callback return False, the schedule will be removed.
|
|||
|
||||
__all__ = ('Clock', )
|
||||
|
||||
import time
|
||||
from time import time, sleep
|
||||
from kivy.weakmethod import WeakMethod
|
||||
from kivy.config import Config
|
||||
|
||||
class _Event(object):
|
||||
|
||||
|
@ -63,16 +64,19 @@ class _Event(object):
|
|||
|
||||
class ClockBase(object):
|
||||
'''A clock object, that support events'''
|
||||
__slots__ = ('_dt', '_last_fps_tick', '_last_tick', '_fps',
|
||||
'_fps_counter', '_events')
|
||||
__slots__ = ('_dt', '_last_fps_tick', '_last_tick', '_fps', '_rfps',
|
||||
'_fps_counter', '_rfps_counter', '_events', '_max_fps')
|
||||
|
||||
def __init__(self):
|
||||
self._dt = 0.0001
|
||||
self._last_tick = time.time()
|
||||
self._last_tick = time()
|
||||
self._fps = 0
|
||||
self._rfps = 0
|
||||
self._fps_counter = 0
|
||||
self._rfps_counter = 0
|
||||
self._last_fps_tick = None
|
||||
self._events = []
|
||||
self._max_fps = float(Config.getint('graphics', 'fps'))
|
||||
|
||||
@property
|
||||
def frametime(self):
|
||||
|
@ -83,8 +87,16 @@ class ClockBase(object):
|
|||
def tick(self):
|
||||
'''Advance clock to the next step. Must be called every frame.
|
||||
The default clock have the tick() function called by Kivy'''
|
||||
|
||||
# do we need to sleep ?
|
||||
if self._max_fps > 0:
|
||||
fps = self._max_fps
|
||||
s = 1 / fps - (time() - self._last_tick)
|
||||
if s > 0:
|
||||
sleep(s)
|
||||
|
||||
# tick the current time
|
||||
current = time.time()
|
||||
current = time()
|
||||
self._dt = current - self._last_tick
|
||||
self._fps_counter += 1
|
||||
self._last_tick = current
|
||||
|
@ -93,19 +105,37 @@ class ClockBase(object):
|
|||
if self._last_fps_tick == None:
|
||||
self._last_fps_tick = current
|
||||
elif current - self._last_fps_tick > 1:
|
||||
self._fps = self._fps_counter / float(current - self._last_fps_tick)
|
||||
d = float(current - self._last_fps_tick)
|
||||
self._fps = self._fps_counter / d
|
||||
self._rfps = self._rfps_counter
|
||||
self._last_fps_tick = current
|
||||
self._fps_counter = 0
|
||||
self._rfps_counter = 0
|
||||
|
||||
# process event
|
||||
self._process_events()
|
||||
|
||||
return self._dt
|
||||
|
||||
def tick_draw(self):
|
||||
'''Tick the drawing counter
|
||||
'''
|
||||
self._rfps_counter += 1
|
||||
|
||||
def get_fps(self):
|
||||
'''Get the current FPS calculated by the clock'''
|
||||
'''Get the current FPS calculated by the clock
|
||||
'''
|
||||
return self._fps
|
||||
|
||||
def get_rfps(self):
|
||||
'''Get the current "real" FPS calculated by the clock.
|
||||
This counter reflect the real frame displayed on the screen.
|
||||
|
||||
In contrary to get_fps(), this function return a counter of the number
|
||||
of frame, not a average of frame per seconds
|
||||
'''
|
||||
return self._rfps
|
||||
|
||||
def get_time(self):
|
||||
'''Get the last tick made by the clock'''
|
||||
return self._last_tick
|
||||
|
|
|
@ -7,7 +7,6 @@ __all__ = ('WindowPygame', )
|
|||
from . import WindowBase
|
||||
|
||||
import os
|
||||
from time import sleep, time
|
||||
from kivy.config import Config
|
||||
from kivy.clock import Clock
|
||||
from kivy.exceptions import ExceptionManager
|
||||
|
@ -138,17 +137,6 @@ class WindowPygame(WindowBase):
|
|||
pygame.display.flip()
|
||||
super(WindowPygame, self).flip()
|
||||
|
||||
# do software vsync if asked
|
||||
# FIXME: vsync is surely not 60 for everyone
|
||||
# this is not a real vsync. this must be done by driver...
|
||||
# but pygame can't do vsync on X11, and some people
|
||||
# use hack to make it work under darwin...
|
||||
fps = self._fps
|
||||
if fps > 0:
|
||||
s = 1 / fps - (time() - Clock.get_time())
|
||||
if s > 0:
|
||||
sleep(s)
|
||||
|
||||
def toggle_fullscreen(self):
|
||||
if self.flags & pygame.FULLSCREEN:
|
||||
self.flags &= ~pygame.FULLSCREEN
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
source: 'data/images/button.png'
|
||||
Label:
|
||||
text: root.text
|
||||
font_size: 18
|
||||
font_size: 12
|
||||
canvas:
|
||||
Color:
|
||||
rgb: (1, 1, 1)
|
||||
|
|
Loading…
Reference in New Issue