- Revision
- 108104
- Author
- [email protected]
- Date
- 2012-02-17 12:00:11 -0800 (Fri, 17 Feb 2012)
Log Message
[GTK] [AC] Events can starve accelerated compositing updates
https://bugs.webkit.org/show_bug.cgi?id=78826
Reviewed by Gustavo Noronha Silva.
Instead of using a WebCore timer, which can be starved by GdkEvents,
use a raw GLib timer with GDK_PRIORITY_EVENTS to drive AC updates.
This prevents dragging from blocking rendering.
* WebCoreSupport/AcceleratedCompositingContext.h:
(AcceleratedCompositingContext): Store a GLib source tag instead of a WebCore timer.
* WebCoreSupport/AcceleratedCompositingContextClutter.cpp:
(WebKit::AcceleratedCompositingContext::AcceleratedCompositingContext):
(WebKit::AcceleratedCompositingContext::AcceleratedCompositingContext):
Remove the timer upon destruction.
(WebKit::syncLayersTimeoutCallback): Added this callback for the GLib timer.
(WebKit::AcceleratedCompositingContext::markForSync): Use a GLib timer.
(WebKit::AcceleratedCompositingContext::syncLayersTimeout): Ditto.
* WebCoreSupport/AcceleratedCompositingContextGL.cpp:
(WebKit::AcceleratedCompositingContext::AcceleratedCompositingContext):
(WebKit::AcceleratedCompositingContext::~AcceleratedCompositingContext):
Remove the timer upon destruction.
(WebKit::syncLayersTimeoutCallback): Added this callback for the GLib timer.
(WebKit::AcceleratedCompositingContext::markForSync): Use a GLib timer.
(WebKit::AcceleratedCompositingContext::syncLayersTimeout): Ditto.
Modified Paths
Diff
Modified: trunk/Source/WebKit/gtk/ChangeLog (108103 => 108104)
--- trunk/Source/WebKit/gtk/ChangeLog 2012-02-17 19:58:56 UTC (rev 108103)
+++ trunk/Source/WebKit/gtk/ChangeLog 2012-02-17 20:00:11 UTC (rev 108104)
@@ -1,3 +1,31 @@
+2012-02-16 Martin Robinson <[email protected]>
+
+ [GTK] [AC] Events can starve accelerated compositing updates
+ https://bugs.webkit.org/show_bug.cgi?id=78826
+
+ Reviewed by Gustavo Noronha Silva.
+
+ Instead of using a WebCore timer, which can be starved by GdkEvents,
+ use a raw GLib timer with GDK_PRIORITY_EVENTS to drive AC updates.
+ This prevents dragging from blocking rendering.
+
+ * WebCoreSupport/AcceleratedCompositingContext.h:
+ (AcceleratedCompositingContext): Store a GLib source tag instead of a WebCore timer.
+ * WebCoreSupport/AcceleratedCompositingContextClutter.cpp:
+ (WebKit::AcceleratedCompositingContext::AcceleratedCompositingContext):
+ (WebKit::AcceleratedCompositingContext::AcceleratedCompositingContext):
+ Remove the timer upon destruction.
+ (WebKit::syncLayersTimeoutCallback): Added this callback for the GLib timer.
+ (WebKit::AcceleratedCompositingContext::markForSync): Use a GLib timer.
+ (WebKit::AcceleratedCompositingContext::syncLayersTimeout): Ditto.
+ * WebCoreSupport/AcceleratedCompositingContextGL.cpp:
+ (WebKit::AcceleratedCompositingContext::AcceleratedCompositingContext):
+ (WebKit::AcceleratedCompositingContext::~AcceleratedCompositingContext):
+ Remove the timer upon destruction.
+ (WebKit::syncLayersTimeoutCallback): Added this callback for the GLib timer.
+ (WebKit::AcceleratedCompositingContext::markForSync): Use a GLib timer.
+ (WebKit::AcceleratedCompositingContext::syncLayersTimeout): Ditto.
+
2012-02-16 Adam Barth <[email protected]>
Attempt to fix the GTK build.
Modified: trunk/Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContext.h (108103 => 108104)
--- trunk/Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContext.h 2012-02-17 19:58:56 UTC (rev 108103)
+++ trunk/Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContext.h 2012-02-17 20:00:11 UTC (rev 108104)
@@ -48,7 +48,7 @@
void attachRootGraphicsLayer(WebCore::GraphicsLayer*);
void scheduleRootLayerRepaint(const WebCore::IntRect&);
void markForSync();
- void syncLayersTimeout(WebCore::Timer<AcceleratedCompositingContext>*);
+ void syncLayersTimeout();
void syncLayersNow();
void resizeRootLayer(const WebCore::IntSize&);
bool renderLayersToWindow(const WebCore::IntRect& clipRect);
@@ -64,7 +64,7 @@
private:
WebKitWebView* m_webView;
OwnPtr<WebCore::GraphicsLayer> m_rootGraphicsLayer;
- WebCore::Timer<AcceleratedCompositingContext> m_syncTimer;
+ unsigned int m_syncTimerCallbackId;
#if USE(CLUTTER)
GtkWidget* m_rootLayerEmbedder;
Modified: trunk/Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContextClutter.cpp (108103 => 108104)
--- trunk/Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContextClutter.cpp 2012-02-17 19:58:56 UTC (rev 108103)
+++ trunk/Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContextClutter.cpp 2012-02-17 20:00:11 UTC (rev 108104)
@@ -36,13 +36,15 @@
AcceleratedCompositingContext::AcceleratedCompositingContext(WebKitWebView* webView)
: m_webView(webView)
, m_rootGraphicsLayer(0)
- , m_syncTimer(this, &AcceleratedCompositingContext::syncLayersTimeout)
+ , m_syncTimerCallbackId(0)
, m_rootLayerEmbedder(0)
{
}
AcceleratedCompositingContext::~AcceleratedCompositingContext()
{
+ if (m_syncTimerCallbackId)
+ g_source_remove(m_syncTimerCallbackId);
}
bool AcceleratedCompositingContext::enabled()
@@ -109,14 +111,23 @@
gtk_widget_size_allocate(GTK_WIDGET(m_webView->priv->rootLayerEmbedder), &allocation);
}
+static gboolean syncLayersTimeoutCallback(AcceleratedCompositingContext* context)
+{
+ context->syncLayersTimeout();
+ return FALSE;
+}
+
void AcceleratedCompositingContext::markForSync()
{
- if (m_syncTimer.isActive())
+ if (m_syncTimerCallbackId)
return;
- m_syncTimer.startOneShot(0);
+
+ // We use a GLib timer because otherwise GTK+ event handling during
+ // dragging can starve WebCore timers, which have a lower priority.
+ m_syncTimerCallbackId = g_timeout_add_full(GDK_PRIORITY_EVENTS, 0, reinterpret_cast<GSourceFunc>(syncLayersTimeoutCallback), this, 0);
}
-void AcceleratedCompositingContext::syncLayersTimeout(Timer<AcceleratedCompositingContext>*)
+void AcceleratedCompositingContext::syncLayersTimeout()
{
core(m_webView)->mainFrame()->view()->syncCompositingStateIncludingSubframes();
}
Modified: trunk/Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContextGL.cpp (108103 => 108104)
--- trunk/Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContextGL.cpp 2012-02-17 19:58:56 UTC (rev 108103)
+++ trunk/Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContextGL.cpp 2012-02-17 20:00:11 UTC (rev 108104)
@@ -41,7 +41,7 @@
AcceleratedCompositingContext::AcceleratedCompositingContext(WebKitWebView* webView)
: m_webView(webView)
- , m_syncTimer(this, &AcceleratedCompositingContext::syncLayersTimeout)
+ , m_syncTimerCallbackId(0)
, m_initialized(false)
, m_rootTextureMapperLayer(0)
{
@@ -49,7 +49,8 @@
AcceleratedCompositingContext::~AcceleratedCompositingContext()
{
-
+ if (m_syncTimerCallbackId)
+ g_source_remove(m_syncTimerCallbackId);
}
void AcceleratedCompositingContext::initializeIfNecessary()
@@ -150,11 +151,20 @@
m_rootGraphicsLayer->setNeedsDisplay();
}
+static gboolean syncLayersTimeoutCallback(AcceleratedCompositingContext* context)
+{
+ context->syncLayersTimeout();
+ return FALSE;
+}
+
void AcceleratedCompositingContext::markForSync()
{
- if (m_syncTimer.isActive())
+ if (m_syncTimerCallbackId)
return;
- m_syncTimer.startOneShot(0);
+
+ // We use a GLib timer because otherwise GTK+ event handling during
+ // dragging can starve WebCore timers, which have a lower priority.
+ m_syncTimerCallbackId = g_timeout_add_full(GDK_PRIORITY_EVENTS, 0, reinterpret_cast<GSourceFunc>(syncLayersTimeoutCallback), this, 0);
}
void AcceleratedCompositingContext::syncLayersNow()
@@ -165,8 +175,9 @@
core(m_webView)->mainFrame()->view()->syncCompositingStateIncludingSubframes();
}
-void AcceleratedCompositingContext::syncLayersTimeout(Timer<AcceleratedCompositingContext>*)
+void AcceleratedCompositingContext::syncLayersTimeout()
{
+ m_syncTimerCallbackId = 0;
syncLayersNow();
if (!m_rootGraphicsLayer)
return;
@@ -174,7 +185,7 @@
renderLayersToWindow(IntRect());
if (toTextureMapperLayer(m_rootGraphicsLayer.get())->descendantsOrSelfHaveRunningAnimations())
- m_syncTimer.startOneShot(1.0 / 60.0);
+ m_syncTimerCallbackId = g_timeout_add_full(GDK_PRIORITY_EVENTS, 1000.0 / 60.0, reinterpret_cast<GSourceFunc>(syncLayersTimeoutCallback), this, 0);
}
void AcceleratedCompositingContext::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time)