Triggering MotionEvents causes FPS drops(?)

Viewed 63

I'm working on a project that has a simple OpenGL scene (two primitive triangles forming a quad, then shaded with a GLSL shader). Despite the simplicity of the project, I still need to relay uniform values to the GPU at runtime and some of those values are updated by the kivy MotionEvents 'on_touch_down', 'on_touch_move' and 'on_touch_up'. When the events are fired, I'm experiencing significant FPS drops (both on PC and Android). What might be the cause of this declination in performance, in such a simple situation and how can I work around it?

Here is the code:

from kivy.config import Config
Config.set('modules', 'monitor', '')

from kivy.app import App
from kivy.core.window import Window
from kivy.clock import mainthread
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scatterlayout import ScatterLayout
from kivy.vector import Vector
from kivy.clock import Clock
from kivy.graphics.instructions import RenderContext, Callback
from kivy.graphics import Mesh

class MainWidget(Widget):

    def __init__(self, **kwargs):
        super(MainWidget, self).__init__()
        self.cardinalVector = Vector((0, 1))
        self.canvas = RenderContext(use_parent_projection=True)
        self.canvas.shader.source = 'Shaders/fan.glsl'
        self.iTouch = (0, 0)
        Clock.schedule_interval(self.updateShaderUniforms, 1/60)

        self.canvas["iTouch"] = (0, 0)

        self.vfmt = (
            (b'vPosition', 2, 'float'),
            (b'vCardinalUv', 2, 'float')
        )

        self.nextDraw()

    def on_touch_down(self, touch):
        v = Vector(touch.x, touch.y) - Vector(*self.center)
        self.iTouch = (v.x, v.y)
        return True

    def on_touch_move(self, touch):
        v = Vector(touch.x, touch.y) - Vector(*self.center)
        self.iTouch = (v.x, v.y)
        return True

    def on_touch_up(self, touch):
        self.iTouch = (0, 0)
        return True

    @mainthread
    def updateShaderUniforms(self, delta):
        self.canvas["iResolution"] = (float(self.size[0]), float(self.size[1]))
        self.canvas["iTouch"] = (self.iTouch[0]/self.size[0], self.iTouch[1]/self.size[1])

    @mainthread
    def nextDraw(self):
        with self.canvas:
            self.mesh = self.build_mesh()
        self.bind(pos=self.syncValues, size=self.syncValues)

    def build_mesh(self):
        vertices = [
            self.pos[0], self.pos[1], 0, 0,
            self.pos[0]+self.size[0], self.pos[1], 0, 1,
            self.pos[0]+self.size[0], self.size[1]+self.pos[1], 1, 1,
            self.pos[0], self.size[1]+self.pos[1], 1, 0
        ]
        indices = [0, 1, 2, 3]
        return Mesh(vertices=vertices, indices=indices, mode='triangle_fan', fmt=self.vfmt)

    def syncValues(self, *args):
        self.mesh.vertices = [
            self.pos[0], self.pos[1], 0, 0,
            self.pos[0]+self.size[0], self.pos[1], 0, 1,
            self.pos[0]+self.size[0], self.size[1]+self.pos[1], 1, 1,
            self.pos[0], self.size[1]+self.pos[1], 1, 0
        ]



class GLTestApplication(App):

    def build(self):
        self.root = BoxLayout(orientation="vertical")

        self.root.add_widget(MainWidget())

        return self.root

if __name__ == '__main__':
    GLTestApplication().run()
0 Answers
Related