summaryrefslogtreecommitdiffstats
path: root/src/compositor/wayland_wrapper/qwlsurface.cpp
diff options
context:
space:
mode:
authorGiulio Camuffo <giulio.camuffo@jollamobile.com>2014-01-24 12:10:17 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-05 14:27:37 +0100
commita237778666666ab77c4e8e6b501cf0fbe7c9223e (patch)
treef5a435d3ccc8e49b4cbc696d0341a6ac831d3c1d /src/compositor/wayland_wrapper/qwlsurface.cpp
parentc7d146428d0de9a19abe834a7bd0ae54c5b30327 (diff)
Improve the frame callbacks handling
Improve the way wl_surface's frame callbacks are handled. The sooner they are sent the better is for the clients, as they have more time to render the next frame, but reducing the time for the compositor to render its frame. The best compromise is probably to send them out after the compositor has issued its GL calls but before calling eglSwapBuffers(), and before the GPU actually draws anything. Rename the function to send the callbacks to only reflect its purpose, leaving the compositors free to choose when they want to send them. Change-Id: Ifcdfcad9e54b4d07d5c087898123ac724395a194 Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
Diffstat (limited to 'src/compositor/wayland_wrapper/qwlsurface.cpp')
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface.cpp62
1 files changed, 49 insertions, 13 deletions
diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp
index 00a69d289..b7f45c675 100644
--- a/src/compositor/wayland_wrapper/qwlsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlsurface.cpp
@@ -73,6 +73,39 @@ namespace QtWayland {
static bool QT_WAYLAND_PRINT_BUFFERING_WARNINGS = qEnvironmentVariableIsSet("QT_WAYLAND_PRINT_BUFFERING_WARNINGS");
+class FrameCallback {
+public:
+ FrameCallback(Surface *surf, wl_resource *res)
+ : surface(surf)
+ , resource(res)
+ {
+ wl_resource_set_implementation(res, 0, this, destroyCallback);
+ }
+ ~FrameCallback()
+ {
+ }
+ void destroy()
+ {
+ if (resource)
+ wl_resource_destroy(resource);
+ else
+ delete this;
+ }
+ void send(uint time)
+ {
+ wl_callback_send_done(resource, time);
+ wl_resource_destroy(resource);
+ }
+ static void destroyCallback(wl_resource *res)
+ {
+ FrameCallback *_this = static_cast<FrameCallback *>(wl_resource_get_user_data(res));
+ _this->surface->removeFrameCallback(_this);
+ delete _this;
+ }
+ Surface *surface;
+ wl_resource *resource;
+};
+
Surface::Surface(struct wl_client *client, uint32_t id, Compositor *compositor)
: QtWaylandServer::wl_surface(client, id)
, m_compositor(compositor)
@@ -87,7 +120,6 @@ Surface::Surface(struct wl_client *client, uint32_t id, Compositor *compositor)
, m_transientInactive(false)
, m_isCursorSurface(false)
{
- wl_list_init(&m_frame_callback_list);
}
Surface::~Surface()
@@ -97,6 +129,11 @@ Surface::~Surface()
for (int i = 0; i < m_bufferPool.size(); i++)
delete m_bufferPool[i];
+
+ foreach (FrameCallback *c, m_pendingFrameCallbacks)
+ c->destroy();
+ foreach (FrameCallback *c, m_frameCallbacks)
+ c->destroy();
}
void Surface::releaseSurfaces()
@@ -146,9 +183,8 @@ bool Surface::isYInverted() const
bool Surface::visible() const
{
-
SurfaceBuffer *surfacebuffer = currentSurfaceBuffer();
- return surfacebuffer->waylandBufferHandle();
+ return surfacebuffer ? surfacebuffer->waylandBufferHandle() : 0;
}
QPointF Surface::pos() const
@@ -222,17 +258,15 @@ GLuint Surface::textureId() const
void Surface::sendFrameCallback()
{
uint time = m_compositor->currentTimeMsecs();
- struct wl_resource *frame_callback, *next;
- wl_list_for_each_safe(frame_callback, next, &m_frame_callback_list, link) {
- wl_callback_send_done(frame_callback, time);
- wl_resource_destroy(frame_callback);
- }
- wl_list_init(&m_frame_callback_list);
+ foreach (FrameCallback *callback, m_frameCallbacks)
+ callback->send(time);
+ m_frameCallbacks.clear();
}
-void Surface::frameFinished()
+void Surface::removeFrameCallback(FrameCallback *callback)
{
- m_compositor->frameFinished(this);
+ m_pendingFrameCallbacks.removeOne(callback);
+ m_frameCallbacks.removeOne(callback);
}
QWaylandSurface * Surface::waylandSurface() const
@@ -344,7 +378,6 @@ void Surface::setBackBuffer(SurfaceBuffer *buffer)
emit m_waylandSurface->unmapped();
}
- m_compositor->markSurfaceAsDirty(this);
emit m_waylandSurface->damaged(m_backBuffer->damageRect());
} else {
InputDevice *inputDevice = m_compositor->defaultInputDevice();
@@ -438,7 +471,7 @@ void Surface::surface_damage(Resource *, int32_t x, int32_t y, int32_t width, in
void Surface::surface_frame(Resource *resource, uint32_t callback)
{
struct wl_resource *frame_callback = wl_client_add_object(resource->client(), &wl_callback_interface, 0, callback, this);
- wl_list_insert(&m_frame_callback_list, &frame_callback->link);
+ m_pendingFrameCallbacks << new FrameCallback(this, frame_callback);
}
void Surface::surface_set_opaque_region(Resource *, struct wl_resource *region)
@@ -474,6 +507,9 @@ void Surface::surface_commit(Resource *)
setBackBuffer(surfaceBuffer);
m_bufferQueue.takeFirst();
}
+
+ m_frameCallbacks << m_pendingFrameCallbacks;
+ m_pendingFrameCallbacks.clear();
}
void Surface::setClassName(const QString &className)