From dce0af009550d77b6e7869d453290528d62230a4 Mon Sep 17 00:00:00 2001 From: Nobuhiko Tanibata Date: Tue, 15 Jan 2013 12:00:09 +0900 Subject: [PATCH] WaylandBaseWindowSystem: Add finishFrame and repaint scheduling - Adds implementation of BaseWindowSystem::finishFrame. - Modify the schedule of a repaint from client commit to timer event: 10ms except drm backend. DRM backend is triggered by page flip not by timer. Signed-off-by: Nobuhiko Tanibata --- .../WindowSystems/WaylandBaseWindowSystem.h | 7 +++ .../src/WindowSystems/WaylandBaseWindowSystem.cpp | 62 ++++++++++++++++++++-- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/WaylandBaseWindowSystem.h b/LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/WaylandBaseWindowSystem.h index db7efb8..6ed7b65 100644 --- a/LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/WaylandBaseWindowSystem.h +++ b/LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/WaylandBaseWindowSystem.h @@ -89,6 +89,8 @@ public: void doScreenShotOfSurface(std::string fileName, const uint id, const uint layer_id); int getWindowWidth() const; int getWindowHeight() const; + virtual void finishFrame(); + virtual void scheduleRepaint(void *data); protected: struct wl_display* m_wlDisplay; @@ -122,6 +124,10 @@ protected: bool m_error; int m_width; int m_height; + bool m_bRepaintNeeded; + bool m_bRepaintScheduled; + bool m_bUseFrameTimer; + struct wl_event_source* m_finishFrameTimer; struct wl_list m_listFrameCallback; struct wl_list m_nativeSurfaceList; @@ -163,6 +169,7 @@ public: static void* eventLoopCallback(void* ptr); static void registryHandleGlobalClient(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version); static void surfaceListenerFrame(void* data, struct wl_callback* callback, uint32_t time); + static int finishFrameHandler(void *data); // wl_surface interface static void surfaceIFDestroy(struct wl_client *client, struct wl_resource *resource); diff --git a/LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/WaylandBaseWindowSystem.cpp b/LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/WaylandBaseWindowSystem.cpp index d6cccaf..2229d0b 100644 --- a/LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/WaylandBaseWindowSystem.cpp +++ b/LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/WaylandBaseWindowSystem.cpp @@ -111,6 +111,16 @@ extern "C" { m_serverInfo = (void*)serverInfo; } + + int WaylandBaseWindowSystem::finishFrameHandler(void *data) + { + BaseWindowSystem* windowSystem = static_cast(data); + if (windowSystem) + { + windowSystem->finishFrame(); + } + return 1; + } } WaylandBaseWindowSystem::WaylandBaseWindowSystem(const char* displayname, int width, int height, Scene* pScene, InputManager* pInputManager) @@ -139,6 +149,10 @@ WaylandBaseWindowSystem::WaylandBaseWindowSystem(const char* displayname, int wi , m_error(false) , m_width(width) , m_height(height) +, m_bRepaintNeeded(false) +, m_bRepaintScheduled(false) +, m_bUseFrameTimer(true) +, m_finishFrameTimer(NULL) , m_listFrameCallback() , m_inputEvent(NULL) , m_connectionList() @@ -388,6 +402,12 @@ void WaylandBaseWindowSystem::RedrawAllLayers(bool clear, bool swap) m_systemState = IDLE_STATE; } + + // update the frame timer + if (true == m_bUseFrameTimer) + { + wl_event_source_timer_update(m_finishFrameTimer, 10); + } } void WaylandBaseWindowSystem::renderHWLayer(Layer *layer) @@ -736,7 +756,7 @@ extern "C" void WaylandBaseWindowSystem::surfaceIFCommit(struct wl_client *clien wl_list_insert_list(windowSystem->m_listFrameCallback.prev, &nativeSurface->pending.frame_callback_list); wl_list_init(&nativeSurface->pending.frame_callback_list); - idleEventRepaint(windowSystem); + windowSystem->scheduleRepaint(windowSystem); LOG_DEBUG("WaylandBaseWindowSystem", "surfaceIFCommit OUT"); } @@ -828,14 +848,43 @@ void WaylandBaseWindowSystem::repaint(int msecs) LOG_DEBUG("WaylandBaseWindowSystem", "repaint OUT"); } +void WaylandBaseWindowSystem::finishFrame() +{ + if (m_bRepaintNeeded) + { + repaint(getTime()); + m_bRepaintNeeded = false; + return; + } + m_bRepaintScheduled = false; +} + void WaylandBaseWindowSystem::idleEventRepaint(void *data) { - WaylandBaseWindowSystem* windowSystem = static_cast( (WaylandBaseWindowSystem*)data); LOG_DEBUG("WaylandBaseWindowSystem", "idleEventRepaint IN"); - windowSystem->repaint(getTime()); + WaylandBaseWindowSystem* windowSystem = static_cast(data); + if (windowSystem) + { + windowSystem->finishFrame(); + } LOG_DEBUG("WaylandBaseWindowSystem", "idleEventRepaint OUT"); } +void WaylandBaseWindowSystem::scheduleRepaint(void *data) +{ + m_bRepaintNeeded = true; + + if (m_bRepaintScheduled) + return; + + struct wl_event_loop *loop = wl_display_get_event_loop(m_wlDisplay); + if (loop) + { + wl_event_loop_add_idle(loop, WaylandBaseWindowSystem::idleEventRepaint, data); + m_bRepaintScheduled = true; + } +} + bool WaylandBaseWindowSystem::initCompositor() { LOG_DEBUG("WaylandBaseWindowSystem", "initCompositor START"); @@ -946,6 +995,12 @@ void* WaylandBaseWindowSystem::eventLoop() } LOG_DEBUG("WaylandBaseWindowSystem", "SUCCESS:init GraphicSystem"); + if (true == m_bUseFrameTimer) + { + struct wl_event_loop *loop = wl_display_get_event_loop(m_wlDisplay); + m_finishFrameTimer = wl_event_loop_add_timer(loop, finishFrameHandler, this); + } + // create input event status = createInputEvent(); if (false == status) @@ -1014,7 +1069,6 @@ void WaylandBaseWindowSystem::signalRedrawEvent() struct wl_callback* callback = wl_surface_frame(m_wlSurfaceClient); wl_callback_add_listener(callback, &g_frameListener, NULL); wl_surface_commit(m_wlSurfaceClient); - wl_display_roundtrip(m_wlDisplayClient); } void WaylandBaseWindowSystem::cleanup() -- 2.7.4