Changeset 109748 in webkit
- Timestamp:
- Mar 5, 2012 7:52:16 AM (12 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r109695 r109748 1 2012-03-05 No'am Rosenthal <noam.rosenthal@nokia.com> 2 3 [Qt] [WK2] Support threaded renderer in WK2 4 https://bugs.webkit.org/show_bug.cgi?id=76661 5 6 Made the appropriate fixes in the UI process code to make rendering thread-safe. 7 - Separated the scenegraph node code to QtWebPageSGNode. QtWebPageSGNode has direct access 8 to LayerTreeHostProxy. 9 10 - Each function in LayerTreeHostProxy can be either called from the main thread (handling 11 messages from the web process), or from the renderer thread (handling the GL context). 12 The render-queue is locked with a mutex, and messages back to the web process are sent 13 via callOnMainThread. 14 15 - LayerTreeHostProxy is now ThreadSafeRefCounted. That is done to make sure that the GL 16 resources it creates are only freed when the QtWebPageSGNode is deleted, which can be 17 before or after the owning DrawingAreaProxy is deleted. This ensures that the class is 18 deleted only after its GL resources are freed, otherwise those resources may leak. 19 20 Based on a patch by Viatcheslav Ostapenko. 21 22 Reviewed by Kenneth Rohde Christiansen. 23 24 * Target.pri: Added new files. 25 * UIProcess/API/qt/qquickwebpage.cpp: Moved QtWebPageSGNode out. 26 (QQuickWebPage::updatePaintNode): Call QtWebPageSGNode 27 (QQuickWebPagePrivate::updateSize): Call QtWebPageSGNode 28 (QQuickWebPagePrivate::didDeleteSGWebPageNode): Override QtWebPageSGNode::Client 29 (QQuickWebPagePrivate::~QQuickWebPagePrivate): 30 * UIProcess/API/qt/qquickwebpage_p_p.h: 31 (QQuickWebPagePrivate): 32 * UIProcess/DrawingAreaProxy.h: 33 (WebKit): 34 (WebKit::DrawingAreaProxy::layerTreeHostProxy): Made LayerTreeHostProxy ref-counted. 35 (DrawingAreaProxy): 36 * UIProcess/DrawingAreaProxyImpl.cpp: 37 (WebKit::DrawingAreaProxyImpl::DrawingAreaProxyImpl): 38 (WebKit::DrawingAreaProxyImpl::enterAcceleratedCompositingMode): 39 * UIProcess/LayerTreeHostProxy.h: 40 (WebKit): 41 (WebKit::LayerTreeHostProxy::create): 42 (LayerTreeHostProxy): 43 * UIProcess/qt/LayerTreeHostProxyQt.cpp: 44 (WebKit::LayerTreeHostProxy::paintToCurrentGLContext): 45 (WebKit): 46 (MainThreadGuardedInvoker): 47 A class that allows invoking functions in the main thread, while guarding a ref- 48 counted object. 49 50 (WebKit::MainThreadGuardedInvoker::call): 51 (WebKit::MainThreadGuardedInvoker::MainThreadGuardedInvoker): 52 (WebKit::MainThreadGuardedInvoker::invoke): 53 (WebKit::LayerTreeHostProxy::syncAnimations): 54 (WebKit::LayerTreeHostProxy::updateViewport): 55 (WebKit::LayerTreeHostProxy::detachDrawingArea): 56 (WebKit::LayerTreeHostProxy::syncLayerParameters): 57 (WebKit::LayerTreeHostProxy::setShouldRenderNextFrame): 58 (WebKit::LayerTreeHostProxy::flushLayerChanges): 59 (WebKit::LayerTreeHostProxy::ensureRootLayer): 60 (WebKit::LayerTreeHostProxy::syncRemoteContent): 61 (WebKit::LayerTreeHostProxy::dispatchUpdate): 62 (WebKit::LayerTreeHostProxy::createDirectlyCompositedImage): 63 (WebKit::LayerTreeHostProxy::purgeGLResources): 64 * UIProcess/qt/QtWebPageSGNode.cpp: Added. 65 * UIProcess/qt/QtWebPageSGNode.h: Added. 66 1 67 2012-03-04 Raphael Kubo da Costa <kubo@profusion.mobi> 2 68 -
trunk/Source/WebKit2/Target.pri
r109669 r109748 262 262 UIProcess/qt/QtPanGestureRecognizer.h \ 263 263 UIProcess/qt/QtPinchGestureRecognizer.h \ 264 UIProcess/qt/QtWebPageSGNode.h \ 264 265 UIProcess/qt/QtTapGestureRecognizer.h \ 265 266 UIProcess/qt/QtWebError.h \ … … 593 594 UIProcess/qt/QtPanGestureRecognizer.cpp \ 594 595 UIProcess/qt/QtPinchGestureRecognizer.cpp \ 596 UIProcess/qt/QtWebPageSGNode.cpp \ 595 597 UIProcess/qt/QtTapGestureRecognizer.cpp \ 596 598 UIProcess/qt/QtWebError.cpp \ -
trunk/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp
r109664 r109748 24 24 #include "LayerTreeHostProxy.h" 25 25 #include "QtWebPageEventHandler.h" 26 #include "QtWebPageSGNode.h" 26 27 #include "TransformationMatrix.h" 27 28 #include "qquickwebpage_p_p.h" 28 29 #include "qquickwebview_p.h" 29 #include <QtQuick/QQuickCanvas>30 #include <QtQuick/QSGGeometryNode>31 #include <QtQuick/QSGMaterial>32 #include <private/qsgrendernode_p.h>33 30 34 31 QQuickWebPage::QQuickWebPage(QQuickWebView* viewportItem) … … 78 75 } 79 76 80 void QQuickWebPagePrivate::paintToCurrentGLContext(const QTransform& transform, float opacity)81 {82 if (!q->isVisible())83 return;84 85 QRectF clipRect = viewportItem->mapRectToScene(viewportItem->boundingRect());86 87 if (!clipRect.isValid())88 return;89 90 DrawingAreaProxy* drawingArea = webPageProxy->drawingArea();91 if (!drawingArea)92 return;93 94 drawingArea->paintToCurrentGLContext(QTransform(transform).scale(contentsScale, contentsScale), opacity, clipRect);95 }96 97 struct PageProxyNode : public QSGRenderNode {98 PageProxyNode(QQuickWebPagePrivate* page)99 : m_pagePrivate(page)100 {101 }102 103 virtual StateFlags changedStates()104 {105 return StateFlags(StencilState) | ColorState | BlendState;106 }107 108 virtual void render(const RenderState&)109 {110 if (!m_pagePrivate)111 return;112 QTransform transform = matrix() ? matrix()->toTransform() : QTransform();113 m_pagePrivate->paintToCurrentGLContext(transform, inheritedOpacity());114 }115 116 ~PageProxyNode()117 {118 if (m_pagePrivate)119 m_pagePrivate->resetPaintNode();120 }121 122 QQuickWebPagePrivate* m_pagePrivate;123 };124 77 125 78 QSGNode* QQuickWebPage::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) … … 131 84 } 132 85 133 PageProxyNode* proxyNode = static_cast<PageProxyNode*>(oldNode); 134 if (!proxyNode) { 135 proxyNode = new PageProxyNode(d); 136 d->m_paintNode = proxyNode; 86 QtWebPageSGNode* sceneNode = static_cast<QtWebPageSGNode*>(oldNode); 87 if (sceneNode) 88 return sceneNode; 89 sceneNode = new QtWebPageSGNode(d->webPageProxy->drawingArea()->layerTreeHostProxy(), d); 90 { 91 MutexLocker lock(d->m_paintNodeMutex); 92 d->m_paintNode = sceneNode; 137 93 } 138 139 return proxyNode;94 d->updateSize(); 95 return sceneNode; 140 96 } 141 97 … … 189 145 q->setSize(scaledSize); 190 146 viewportItem->updateContentsSize(scaledSize); 147 QRectF clipRect = viewportItem->mapRectToScene(viewportItem->boundingRect()); 148 149 MutexLocker lock(m_paintNodeMutex); 150 if (!m_paintNode) 151 return; 152 m_paintNode->setClipRect(clipRect); 153 m_paintNode->setContentsScale(contentsScale); 191 154 } 192 155 193 void QQuickWebPagePrivate:: resetPaintNode()156 void QQuickWebPagePrivate::willDeleteScenegraphNode() 194 157 { 158 MutexLocker lock(m_paintNodeMutex); 195 159 m_paintNode = 0; 196 DrawingAreaProxy* drawingArea = webPageProxy->drawingArea();197 if (drawingArea && drawingArea->layerTreeHostProxy())198 drawingArea->layerTreeHostProxy()->purgeGLResources();199 160 } 200 161 201 162 QQuickWebPagePrivate::~QQuickWebPagePrivate() 202 163 { 203 if (m_paintNode)204 static_cast<PageProxyNode*>(m_paintNode)->m_pagePrivate = 0;205 164 } 206 165 -
trunk/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h
r109664 r109748 22 22 #define qquickwebpage_p_p_h 23 23 24 #include "QtWebPageSGNode.h" 24 25 #include "qquickwebpage_p.h" 25 26 #include <QTransform> … … 32 33 class QtWebPageEventHandler; 33 34 34 class QQuickWebPagePrivate {35 class QQuickWebPagePrivate : public QtWebPageSGNode::Client { 35 36 public: 36 37 QQuickWebPagePrivate(QQuickWebPage* q, QQuickWebView* viewportItem); 37 38 ~QQuickWebPagePrivate(); 39 virtual void willDeleteScenegraphNode(); 38 40 39 41 void initialize(WebKit::WebPageProxy*); … … 41 43 42 44 void updateSize(); 43 44 void paintToCurrentGLContext(const QTransform&, float opacity);45 45 void paint(QPainter*); 46 46 void resetPaintNode(); … … 51 51 WebKit::WebPageProxy* webPageProxy; 52 52 bool paintingIsInitialized; 53 QSGNode* m_paintNode; 53 QtWebPageSGNode* m_paintNode; 54 Mutex m_paintNodeMutex; 54 55 55 56 QSizeF contentsSize; -
trunk/Source/WebKit2/UIProcess/DrawingAreaProxy.h
r109302 r109748 30 30 #include "BackingStore.h" 31 31 #include "DrawingAreaInfo.h" 32 #include "LayerTreeHostProxy.h" 32 33 #include <WebCore/IntRect.h> 33 34 #include <WebCore/IntSize.h> … … 55 56 56 57 class LayerTreeContext; 57 class LayerTreeHostProxy;58 58 class UpdateInfo; 59 59 class WebLayerTreeInfo; … … 91 91 virtual void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float, const WebCore::FloatRect&) { } 92 92 virtual void paintLayerTree(BackingStore::PlatformGraphicsContext) { } 93 LayerTreeHostProxy* layerTreeHostProxy() const { return m_layerTreeHostProxy.get(); }93 PassRefPtr<LayerTreeHostProxy> layerTreeHostProxy() const { return m_layerTreeHostProxy; } 94 94 virtual void setVisibleContentsRectForScaling(const WebCore::IntRect& visibleContentsRect, float scale) { } 95 95 virtual void setVisibleContentsRectForPanning(const WebCore::IntRect& visibleContentsRect, const WebCore::FloatPoint& trajectoryVector) { } … … 111 111 112 112 #if USE(UI_SIDE_COMPOSITING) 113 OwnPtr<LayerTreeHostProxy> m_layerTreeHostProxy;113 RefPtr<LayerTreeHostProxy> m_layerTreeHostProxy; 114 114 #endif 115 115 -
trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp
r109302 r109748 62 62 // Construct the proxy early to allow messages to be sent to the web process while AC is entered there. 63 63 if (webPageProxy->pageGroup()->preferences()->forceCompositingMode()) 64 m_layerTreeHostProxy = adoptPtr(new LayerTreeHostProxy(this));64 m_layerTreeHostProxy = LayerTreeHostProxy::create(this); 65 65 #endif 66 66 } … … 338 338 #if USE(UI_SIDE_COMPOSITING) 339 339 if (!m_layerTreeHostProxy) 340 m_layerTreeHostProxy = adoptPtr(new LayerTreeHostProxy(this));340 m_layerTreeHostProxy = LayerTreeHostProxy::create(this); 341 341 #endif 342 342 } -
trunk/Source/WebKit2/UIProcess/LayerTreeHostProxy.h
r109302 r109748 24 24 25 25 #include "BackingStore.h" 26 #include " DrawingAreaProxy.h"26 #include "Connection.h" 27 27 #include "Region.h" 28 28 #include "TextureMapper.h" … … 37 37 #include <wtf/Functional.h> 38 38 #include <wtf/HashSet.h> 39 39 #include <wtf/ThreadingPrimitives.h> 40 40 41 41 namespace WebKit { 42 42 43 class DrawingAreaProxy; 43 44 class LayerBackingStore; 44 45 class WebLayerInfo; 45 46 class WebLayerUpdateInfo; 46 47 47 class LayerTreeHostProxy : public WebCore::GraphicsLayerClient {48 class LayerTreeHostProxy : public ThreadSafeRefCounted<LayerTreeHostProxy>, public WebCore::GraphicsLayerClient { 48 49 public: 49 LayerTreeHostProxy(DrawingAreaProxy*);50 50 virtual ~LayerTreeHostProxy(); 51 51 void syncCompositingLayerState(const WebLayerInfo&); … … 69 69 void updateViewport(); 70 70 71 static PassRefPtr<LayerTreeHostProxy> create(DrawingAreaProxy* drawingArea) { return adoptRef(new LayerTreeHostProxy(drawingArea)); } 72 71 73 protected: 72 74 PassOwnPtr<WebCore::GraphicsLayer> createLayer(WebLayerID); … … 89 91 90 92 Vector<Function<void()> > m_renderQueue; 93 WTF::Mutex m_renderQueueMutex; 91 94 void dispatchUpdate(const Function<void()>&); 95 void detachDrawingArea(); 96 void setShouldRenderNextFrame(); 92 97 93 98 #if USE(TEXTURE_MAPPER) … … 114 119 void swapBuffers(); 115 120 void syncAnimations(); 121 void updateViewportOnMainThread(); 122 LayerTreeHostProxy(DrawingAreaProxy*); 116 123 117 124 OwnPtr<WebCore::GraphicsLayer> m_rootLayer; … … 120 127 LayerMap m_layers; 121 128 WebLayerID m_rootLayerID; 122 int m_id;123 129 }; 124 130 -
trunk/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp
r109302 r109748 96 96 } 97 97 98 template<class T> 99 class MainThreadGuardedInvoker { 100 public: 101 static void call(PassRefPtr<T> objectToGuard, const Function<void()>& function) 102 { 103 MainThreadGuardedInvoker<T>* invoker = new MainThreadGuardedInvoker<T>(objectToGuard, function); 104 callOnMainThread(invoke, invoker); 105 } 106 107 private: 108 MainThreadGuardedInvoker(PassRefPtr<T> object, const Function<void()>& newFunction) 109 : objectToGuard(object) 110 , function(newFunction) 111 { 112 } 113 114 RefPtr<T> objectToGuard; 115 Function<void()> function; 116 static void invoke(void* data) 117 { 118 MainThreadGuardedInvoker<T>* invoker = static_cast<MainThreadGuardedInvoker<T>*>(data); 119 invoker->function(); 120 delete invoker; 121 } 122 }; 123 98 124 void LayerTreeHostProxy::syncAnimations() 99 125 { … … 103 129 layer->syncAnimationsRecursively(); 104 130 if (layer->descendantsOrSelfHaveRunningAnimations()) 105 updateViewport();131 MainThreadGuardedInvoker<LayerTreeHostProxy>::call(this, bind(&LayerTreeHostProxy::updateViewport, this)); 106 132 } 107 133 … … 128 154 void LayerTreeHostProxy::updateViewport() 129 155 { 130 m_drawingAreaProxy->updateViewport(); 156 if (m_drawingAreaProxy) 157 m_drawingAreaProxy->updateViewport(); 158 } 159 160 void LayerTreeHostProxy::detachDrawingArea() 161 { 162 m_drawingAreaProxy = 0; 131 163 } 132 164 … … 186 218 layer->removeAnimation(anim.name); 187 219 break; 188 case WebKit::WebLayerAnimation::PauseAnimation: 220 case WebKit::WebLayerAnimation::PauseAnimation: { 189 221 double offset = WTF::currentTime() - anim.startTime; 190 222 layer->pauseAnimation(anim.name, offset); 223 break; 224 } 225 default: 191 226 break; 192 227 } … … 296 331 } 297 332 333 void LayerTreeHostProxy::setShouldRenderNextFrame() 334 { 335 // The pending tiles state is on its way to the screen, tell the web process to render the next one. 336 m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::RenderNextFrame(), m_drawingAreaProxy->page()->pageID()); 337 } 338 298 339 void LayerTreeHostProxy::flushLayerChanges() 299 340 { 300 341 m_rootLayer->syncCompositingState(FloatRect()); 301 342 swapBuffers(); 302 303 // The pending tiles state is on its way for the screen, tell the web process to render the next one. 304 m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::RenderNextFrame(), m_drawingAreaProxy->page()->pageID()); 343 MainThreadGuardedInvoker<LayerTreeHostProxy>::call(this, bind(&LayerTreeHostProxy::setShouldRenderNextFrame, this)); 305 344 } 306 345 … … 316 355 // The root layer should not have zero size, or it would be optimized out. 317 356 m_rootLayer->setSize(FloatSize(1.0, 1.0)); 318 if (!m_textureMapper)319 m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);320 357 toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get()); 321 358 } … … 324 361 { 325 362 // We enqueue messages and execute them during paint, as they require an active GL context. 363 MutexLocker locker(m_renderQueueMutex); 326 364 ensureRootLayer(); 327 365 … … 334 372 void LayerTreeHostProxy::dispatchUpdate(const Function<void()>& function) 335 373 { 374 MutexLocker locker(m_renderQueueMutex); 336 375 m_renderQueue.append(function); 337 376 updateViewport(); … … 358 397 } 359 398 360 361 399 void LayerTreeHostProxy::deleteCompositingLayer(WebLayerID id) 362 400 { … … 381 419 void LayerTreeHostProxy::createDirectlyCompositedImage(int64_t key, const WebKit::ShareableBitmap::Handle& handle) 382 420 { 421 // Even though ShareableBitmap is not ThreadSafeRefCounted, we can safely move it to the renderer thread as the main thread will not touch it anymore. 383 422 RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle); 384 423 dispatchUpdate(bind(&LayerTreeHostProxy::createImage, this, key, bitmap)); … … 404 443 void LayerTreeHostProxy::purgeGLResources() 405 444 { 445 MutexLocker locker(m_renderQueueMutex); 446 m_renderQueue.clear(); 406 447 TextureMapperLayer* layer = toTextureMapperLayer(rootLayer()); 407 448 -
trunk/Tools/ChangeLog
r109734 r109748 1 2012-03-05 No'am Rosenthal <noam.rosenthal@nokia.com> 2 3 [Qt] [WK2] Support threaded renderer in WK2 4 https://bugs.webkit.org/show_bug.cgi?id=76661 5 6 Remove the QML_NO_THREADED_RENDERER environment variable from MiniBrowser. 7 8 Reviewed by Kenneth Rohde Christiansen. 9 10 * MiniBrowser/qt/main.cpp: 11 (main): 12 1 13 2012-03-05 Alexander Færøy <alexander.faeroy@nokia.com> 2 14 -
trunk/Tools/MiniBrowser/qt/main.cpp
r104556 r109748 40 40 int main(int argc, char** argv) 41 41 { 42 // FIXME: We must add support for the threaded rendering as it is the default.43 qputenv("QML_NO_THREADED_RENDERER", QByteArray("1"));44 45 42 MiniBrowserApplication app(argc, argv); 46 43
Note: See TracChangeset
for help on using the changeset viewer.