Modified: trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp (203717 => 203718)
--- trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp 2016-07-26 11:08:28 UTC (rev 203717)
+++ trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp 2016-07-26 13:26:35 UTC (rev 203718)
@@ -28,22 +28,97 @@
#if USE(COORDINATED_GRAPHICS_THREADED)
-#include <wtf/CurrentTime.h>
+#include <wtf/HashMap.h>
#include <wtf/MainThread.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/WorkQueue.h>
namespace WebKit {
+class WorkQueuePool {
+ WTF_MAKE_NONCOPYABLE(WorkQueuePool);
+ friend class NeverDestroyed<WorkQueuePool>;
+public:
+ static WorkQueuePool& singleton()
+ {
+ ASSERT(isMainThread());
+ static NeverDestroyed<WorkQueuePool> workQueuePool;
+ return workQueuePool;
+ }
+
+ void dispatch(void* context, Function<void ()>&& function)
+ {
+ ASSERT(isMainThread());
+ getOrCreateWorkQueueForContext(context).dispatch(WTFMove(function));
+ }
+
+ RunLoop& runLoop(void* context)
+ {
+ return getOrCreateWorkQueueForContext(context).runLoop();
+ }
+
+ void invalidate(void* context)
+ {
+ auto workQueue = m_workQueueMap.take(context);
+ RELEASE_ASSERT(workQueue);
+ if (m_workQueueMap.isEmpty()) {
+ m_sharedWorkQueue = nullptr;
+ m_threadCount = 0;
+ } else if (workQueue->hasOneRef())
+ m_threadCount--;
+ }
+
+private:
+ WorkQueuePool()
+ {
+#if PLATFORM(GTK)
+ m_threadCountLimit = 1;
+#else
+ m_threadCountLimit = std::numeric_limits<unsigned>::max();
+#endif
+ }
+
+ WorkQueue& getOrCreateWorkQueueForContext(void* context)
+ {
+ auto addResult = m_workQueueMap.add(context, nullptr);
+ if (addResult.isNewEntry) {
+ // FIXME: This is OK for now, and it works for a single-thread limit. But for configurations where more (but not unlimited)
+ // threads could be used, one option would be to use a HashSet here and disperse the contexts across the available threads.
+ if (m_threadCount >= m_threadCountLimit) {
+ RELEASE_ASSERT(m_sharedWorkQueue);
+ addResult.iterator->value = m_sharedWorkQueue;
+ } else {
+ addResult.iterator->value = WorkQueue::create("org.webkit.ThreadedCompositorWorkQueue");
+ if (!m_threadCount)
+ m_sharedWorkQueue = addResult.iterator->value;
+ m_threadCount++;
+ }
+ }
+
+ return *addResult.iterator->value;
+ }
+
+ HashMap<void*, RefPtr<WorkQueue>> m_workQueueMap;
+ RefPtr<WorkQueue> m_sharedWorkQueue;
+ unsigned m_threadCount { 0 };
+ unsigned m_threadCountLimit;
+};
+
CompositingRunLoop::CompositingRunLoop(std::function<void ()>&& updateFunction)
- : m_runLoop(RunLoop::current())
- , m_updateTimer(m_runLoop, this, &CompositingRunLoop::updateTimerFired)
+ : m_updateTimer(WorkQueuePool::singleton().runLoop(this), this, &CompositingRunLoop::updateTimerFired)
, m_updateFunction(WTFMove(updateFunction))
{
}
+CompositingRunLoop::~CompositingRunLoop()
+{
+ WorkQueuePool::singleton().invalidate(this);
+}
+
void CompositingRunLoop::performTask(Function<void ()>&& function)
{
ASSERT(isMainThread());
- m_runLoop.dispatch(WTFMove(function));
+ WorkQueuePool::singleton().dispatch(this, WTFMove(function));
}
void CompositingRunLoop::performTaskSync(Function<void ()>&& function)
@@ -50,9 +125,9 @@
{
ASSERT(isMainThread());
LockHolder locker(m_dispatchSyncConditionMutex);
- m_runLoop.dispatch([this, function = WTFMove(function)] {
+ WorkQueuePool::singleton().dispatch(this, [this, function = WTFMove(function)] {
+ function();
LockHolder locker(m_dispatchSyncConditionMutex);
- function();
m_dispatchSyncCondition.notifyOne();
});
m_dispatchSyncCondition.wait(m_dispatchSyncConditionMutex);
@@ -82,17 +157,6 @@
m_lastUpdateTime = monotonicallyIncreasingTime();
}
-void CompositingRunLoop::run()
-{
- m_runLoop.run();
-}
-
-void CompositingRunLoop::stop()
-{
- m_updateTimer.stop();
- m_runLoop.stop();
-}
-
} // namespace WebKit
#endif // USE(COORDINATED_GRAPHICS_THREADED)
Modified: trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h (203717 => 203718)
--- trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h 2016-07-26 11:08:28 UTC (rev 203717)
+++ trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h 2016-07-26 13:26:35 UTC (rev 203718)
@@ -28,8 +28,9 @@
#if USE(COORDINATED_GRAPHICS_THREADED)
-#include <functional>
-#include <wtf/FastMalloc.h>
+#include <wtf/Condition.h>
+#include <wtf/Function.h>
+#include <wtf/NeverDestroyed.h>
#include <wtf/Noncopyable.h>
#include <wtf/RunLoop.h>
@@ -37,7 +38,6 @@
class CompositingRunLoop {
WTF_MAKE_NONCOPYABLE(CompositingRunLoop);
- WTF_MAKE_FAST_ALLOCATED;
public:
enum UpdateTiming {
Immediate,
@@ -45,6 +45,7 @@
};
CompositingRunLoop(std::function<void ()>&&);
+ ~CompositingRunLoop();
void performTask(Function<void ()>&&);
void performTaskSync(Function<void ()>&&);
@@ -52,13 +53,9 @@
void startUpdateTimer(UpdateTiming = Immediate);
void stopUpdateTimer();
- void run();
- void stop();
-
private:
void updateTimerFired();
- RunLoop& m_runLoop;
RunLoop::Timer<CompositingRunLoop> m_updateTimer;
std::function<void ()> m_updateFunction;
Lock m_dispatchSyncConditionMutex;
Modified: trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp (203717 => 203718)
--- trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp 2016-07-26 11:08:28 UTC (rev 203717)
+++ trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp 2016-07-26 13:26:35 UTC (rev 203718)
@@ -30,8 +30,6 @@
#include "CompositingRunLoop.h"
#include <WebCore/TransformationMatrix.h>
-#include <wtf/RunLoop.h>
-#include <wtf/StdLibExtras.h>
#if USE(OPENGL_ES_2)
#include <GLES2/gl2.h>
@@ -50,8 +48,12 @@
ThreadedCompositor::ThreadedCompositor(Client* client)
: m_client(client)
+ , m_compositingRunLoop([this] { renderLayerTree(); })
{
- createCompositingThread();
+ m_compositingRunLoop.performTaskSync([this, protectedThis = makeRef(*this)] {
+ m_scene = adoptRef(new CoordinatedGraphicsScene(this));
+ m_viewportController = std::make_unique<SimpleViewportController>(this);
+ });
}
ThreadedCompositor::~ThreadedCompositor()
@@ -61,14 +63,20 @@
void ThreadedCompositor::invalidate()
{
- terminateCompositingThread();
+ m_scene->detach();
+ m_compositingRunLoop.stopUpdateTimer();
+ m_compositingRunLoop.performTaskSync([this, protectedThis = makeRef(*this)] {
+ m_context = nullptr;
+ m_scene = nullptr;
+ m_viewportController = nullptr;
+ });
m_client = nullptr;
}
void ThreadedCompositor::setNativeSurfaceHandleForCompositing(uint64_t handle)
{
- m_compositingRunLoop->stopUpdateTimer();
- m_compositingRunLoop->performTaskSync([this, protectedThis = makeRef(*this), handle] {
+ m_compositingRunLoop.stopUpdateTimer();
+ m_compositingRunLoop.performTaskSync([this, protectedThis = makeRef(*this), handle] {
m_scene->setActive(!!handle);
// A new native handle can't be set without destroying the previous one first if any.
@@ -81,7 +89,7 @@
void ThreadedCompositor::setDeviceScaleFactor(float scale)
{
- m_compositingRunLoop->performTask([this, protectedThis = makeRef(*this), scale] {
+ m_compositingRunLoop.performTask([this, protectedThis = makeRef(*this), scale] {
m_deviceScaleFactor = scale;
scheduleDisplayImmediately();
});
@@ -89,7 +97,7 @@
void ThreadedCompositor::setDrawsBackground(bool drawsBackground)
{
- m_compositingRunLoop->performTask([this, protectedThis = Ref<ThreadedCompositor>(*this), drawsBackground] {
+ m_compositingRunLoop.performTask([this, protectedThis = Ref<ThreadedCompositor>(*this), drawsBackground] {
m_drawsBackground = drawsBackground;
scheduleDisplayImmediately();
});
@@ -97,7 +105,7 @@
void ThreadedCompositor::didChangeViewportSize(const IntSize& size)
{
- m_compositingRunLoop->performTaskSync([this, protectedThis = makeRef(*this), size] {
+ m_compositingRunLoop.performTaskSync([this, protectedThis = makeRef(*this), size] {
m_viewportController->didChangeViewportSize(size);
});
}
@@ -104,7 +112,7 @@
void ThreadedCompositor::didChangeViewportAttribute(const ViewportAttributes& attr)
{
- m_compositingRunLoop->performTask([this, protectedThis = makeRef(*this), attr] {
+ m_compositingRunLoop.performTask([this, protectedThis = makeRef(*this), attr] {
m_viewportController->didChangeViewportAttribute(attr);
});
}
@@ -111,7 +119,7 @@
void ThreadedCompositor::didChangeContentsSize(const IntSize& size)
{
- m_compositingRunLoop->performTask([this, protectedThis = makeRef(*this), size] {
+ m_compositingRunLoop.performTask([this, protectedThis = makeRef(*this), size] {
m_viewportController->didChangeContentsSize(size);
});
}
@@ -118,7 +126,7 @@
void ThreadedCompositor::scrollTo(const IntPoint& position)
{
- m_compositingRunLoop->performTask([this, protectedThis = makeRef(*this), position] {
+ m_compositingRunLoop.performTask([this, protectedThis = makeRef(*this), position] {
m_viewportController->scrollTo(position);
});
}
@@ -125,7 +133,7 @@
void ThreadedCompositor::scrollBy(const IntSize& delta)
{
- m_compositingRunLoop->performTask([this, protectedThis = makeRef(*this), delta] {
+ m_compositingRunLoop.performTask([this, protectedThis = makeRef(*this), delta] {
m_viewportController->scrollBy(delta);
});
}
@@ -132,22 +140,30 @@
void ThreadedCompositor::purgeBackingStores()
{
+ ASSERT(isMainThread());
m_client->purgeBackingStores();
}
void ThreadedCompositor::renderNextFrame()
{
+ ASSERT(isMainThread());
m_client->renderNextFrame();
}
+void ThreadedCompositor::commitScrollOffset(uint32_t layerID, const IntSize& offset)
+{
+ ASSERT(isMainThread());
+ m_client->commitScrollOffset(layerID, offset);
+}
+
void ThreadedCompositor::updateViewport()
{
- m_compositingRunLoop->startUpdateTimer(CompositingRunLoop::WaitUntilNextFrame);
+ m_compositingRunLoop.startUpdateTimer(CompositingRunLoop::WaitUntilNextFrame);
}
-void ThreadedCompositor::commitScrollOffset(uint32_t layerID, const IntSize& offset)
+void ThreadedCompositor::scheduleDisplayImmediately()
{
- m_client->commitScrollOffset(layerID, offset);
+ m_compositingRunLoop.startUpdateTimer(CompositingRunLoop::Immediate);
}
bool ThreadedCompositor::tryEnsureGLContext()
@@ -180,14 +196,9 @@
return m_context.get();
}
-void ThreadedCompositor::scheduleDisplayImmediately()
-{
- m_compositingRunLoop->startUpdateTimer(CompositingRunLoop::Immediate);
-}
-
void ThreadedCompositor::forceRepaint()
{
- m_compositingRunLoop->performTaskSync([this, protectedThis = makeRef(*this)] {
+ m_compositingRunLoop.performTaskSync([this, protectedThis = makeRef(*this)] {
renderLayerTree();
});
}
@@ -237,55 +248,5 @@
scheduleDisplayImmediately();
}
-void ThreadedCompositor::createCompositingThread()
-{
- if (m_threadIdentifier)
- return;
-
- LockHolder locker(m_initializeRunLoopConditionMutex);
- m_threadIdentifier = createThread("WebKit: ThreadedCompositor", [this] { runCompositingThread(); });
- m_initializeRunLoopCondition.wait(m_initializeRunLoopConditionMutex);
}
-
-void ThreadedCompositor::runCompositingThread()
-{
- {
- LockHolder locker(m_initializeRunLoopConditionMutex);
-
- m_compositingRunLoop = std::make_unique<CompositingRunLoop>([&] {
- renderLayerTree();
- });
- m_scene = adoptRef(new CoordinatedGraphicsScene(this));
- m_viewportController = std::make_unique<SimpleViewportController>(this);
-
- m_initializeRunLoopCondition.notifyOne();
- }
-
- m_compositingRunLoop->run();
-
- m_scene->purgeGLResources();
-
- {
- LockHolder locker(m_terminateRunLoopConditionMutex);
- m_context = nullptr;
- m_scene = nullptr;
- m_viewportController = nullptr;
- m_compositingRunLoop = nullptr;
- m_terminateRunLoopCondition.notifyOne();
- }
-
- detachThread(m_threadIdentifier);
-}
-
-void ThreadedCompositor::terminateCompositingThread()
-{
- LockHolder locker(m_terminateRunLoopConditionMutex);
-
- m_scene->detach();
- m_compositingRunLoop->stop();
-
- m_terminateRunLoopCondition.wait(m_terminateRunLoopConditionMutex);
-}
-
-}
#endif // USE(COORDINATED_GRAPHICS_THREADED)
Modified: trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h (203717 => 203718)
--- trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h 2016-07-26 11:08:28 UTC (rev 203717)
+++ trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h 2016-07-26 13:26:35 UTC (rev 203718)
@@ -28,16 +28,14 @@
#if USE(COORDINATED_GRAPHICS_THREADED)
+#include "CompositingRunLoop.h"
#include "CoordinatedGraphicsScene.h"
#include "SimpleViewportController.h"
#include <WebCore/GLContext.h>
#include <WebCore/IntSize.h>
-#include <WebCore/TransformationMatrix.h>
-#include <wtf/Condition.h>
#include <wtf/FastMalloc.h>
#include <wtf/Noncopyable.h>
#include <wtf/ThreadSafeRefCounted.h>
-#include <wtf/Threading.h>
namespace WebCore {
struct CoordinatedGraphicsState;
@@ -45,7 +43,6 @@
namespace WebKit {
-class CompositingRunLoop;
class CoordinatedGraphicsScene;
class CoordinatedGraphicsSceneClient;
@@ -89,22 +86,18 @@
void updateViewport() override;
void commitScrollOffset(uint32_t layerID, const WebCore::IntSize& offset) override;
+ // SimpleViewportController::Client.
+ void didChangeVisibleRect() override;
+
void renderLayerTree();
void scheduleDisplayImmediately();
- void didChangeVisibleRect() override;
bool tryEnsureGLContext();
WebCore::GLContext* glContext();
- void createCompositingThread();
- void runCompositingThread();
- void terminateCompositingThread();
- static void compositingThreadEntry(void*);
-
- Client* m_client;
+ Client* m_client { nullptr };
RefPtr<CoordinatedGraphicsScene> m_scene;
std::unique_ptr<SimpleViewportController> m_viewportController;
-
std::unique_ptr<WebCore::GLContext> m_context;
WebCore::IntSize m_viewportSize;
@@ -112,13 +105,7 @@
bool m_drawsBackground { true };
uint64_t m_nativeSurfaceHandle { 0 };
- std::unique_ptr<CompositingRunLoop> m_compositingRunLoop;
-
- ThreadIdentifier m_threadIdentifier { 0 };
- Condition m_initializeRunLoopCondition;
- Lock m_initializeRunLoopConditionMutex;
- Condition m_terminateRunLoopCondition;
- Lock m_terminateRunLoopConditionMutex;
+ CompositingRunLoop m_compositingRunLoop;
};
} // namespace WebKit