diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
commit | 40736c5763bf61337c8c14e16d8587db021a87d4 (patch) | |
tree | b17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/WebKit2/UIProcess/qt/QtSGUpdateQueue.cpp | |
download | qtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz |
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/WebKit2/UIProcess/qt/QtSGUpdateQueue.cpp')
-rw-r--r-- | Source/WebKit2/UIProcess/qt/QtSGUpdateQueue.cpp | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/qt/QtSGUpdateQueue.cpp b/Source/WebKit2/UIProcess/qt/QtSGUpdateQueue.cpp new file mode 100644 index 000000000..7b1675dfe --- /dev/null +++ b/Source/WebKit2/UIProcess/qt/QtSGUpdateQueue.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" +#include "QtSGUpdateQueue.h" + +#include "PassOwnPtr.h" +#include "QtSGTileNode.h" +#include <QtQuick/QQuickItem> + +namespace WebKit { + +struct NodeUpdateCreateTile : public NodeUpdate { + NodeUpdateCreateTile(int nodeID, float scale) + : NodeUpdate(CreateTile) + , nodeID(nodeID) + , scale(scale) + { } + int nodeID; + float scale; +}; + +struct NodeUpdateRemoveTile : public NodeUpdate { + NodeUpdateRemoveTile(int nodeID) + : NodeUpdate(RemoveTile) + , nodeID(nodeID) + { } + int nodeID; +}; + +struct NodeUpdateSetBackBuffer : public NodeUpdate { + NodeUpdateSetBackBuffer(int nodeID, const QImage& backBuffer, const QRect& sourceRect, const QRect& targetRect) + : NodeUpdate(SetBackBuffer) + , nodeID(nodeID) + , backBuffer(backBuffer) + , sourceRect(sourceRect) + , targetRect(targetRect) + { } + int nodeID; + QImage backBuffer; + QRect sourceRect; + QRect targetRect; +}; + +struct NodeUpdateSwapTileBuffers : public NodeUpdate { + NodeUpdateSwapTileBuffers() + : NodeUpdate(SwapTileBuffers) + { } +}; + +QtSGUpdateQueue::QtSGUpdateQueue(QQuickItem *item) + : item(item) + , lastScale(0) + , lastScaleNode(0) + , nextNodeID(1) + , m_isSwapPending(false) +{ +} + +int QtSGUpdateQueue::createTileNode(float scale) +{ + int nodeID = nextNodeID++; + nodeUpdateQueue.append(adoptPtr(new NodeUpdateCreateTile(nodeID, scale))); + item->update(); + return nodeID; +} + +void QtSGUpdateQueue::removeTileNode(int nodeID) +{ + nodeUpdateQueue.append(adoptPtr(new NodeUpdateRemoveTile(nodeID))); + item->update(); +} + +void QtSGUpdateQueue::setNodeBackBuffer(int nodeID, const QImage& backBuffer, const QRect& sourceRect, const QRect& targetRect) +{ + nodeUpdateQueue.append(adoptPtr(new NodeUpdateSetBackBuffer(nodeID, backBuffer, sourceRect, targetRect))); + item->update(); +} + +void QtSGUpdateQueue::swapTileBuffers() +{ + nodeUpdateQueue.append(adoptPtr(new NodeUpdateSwapTileBuffers())); + m_isSwapPending = true; + item->update(); +} + +void QtSGUpdateQueue::applyUpdates(QSGNode* itemNode) +{ + while (!nodeUpdateQueue.isEmpty()) { + OwnPtr<NodeUpdate> nodeUpdate(nodeUpdateQueue.takeFirst()); + switch (nodeUpdate->type) { + case NodeUpdate::CreateTile: { + NodeUpdateCreateTile* createTileUpdate = static_cast<NodeUpdateCreateTile*>(nodeUpdate.get()); + QtSGTileNode* tileNode = new QtSGTileNode(item->sceneGraphEngine()); + getScaleNode(createTileUpdate->scale, itemNode)->prependChildNode(tileNode); + nodes.set(createTileUpdate->nodeID, tileNode); + break; + } + case NodeUpdate::RemoveTile: { + NodeUpdateRemoveTile* removeUpdate = static_cast<NodeUpdateRemoveTile*>(nodeUpdate.get()); + QSGNode* node = nodes.take(removeUpdate->nodeID); + QSGNode* scaleNode = node->parent(); + + scaleNode->removeChildNode(node); + if (!scaleNode->childCount()) { + if (scaleNode == lastScaleNode) { + lastScale = 0; + lastScaleNode = 0; + } + delete scaleNode; + } + delete node; + break; + } + case NodeUpdate::SetBackBuffer: { + NodeUpdateSetBackBuffer* setBackBufferUpdate = static_cast<NodeUpdateSetBackBuffer*>(nodeUpdate.get()); + QtSGTileNode* tileNode = nodes.get(setBackBufferUpdate->nodeID); + tileNode->setBackBuffer(setBackBufferUpdate->backBuffer, setBackBufferUpdate->sourceRect, setBackBufferUpdate->targetRect); + break; + } + case NodeUpdate::SwapTileBuffers: { + HashMap<int, QtSGTileNode*>::iterator end = nodes.end(); + for (HashMap<int, QtSGTileNode*>::iterator it = nodes.begin(); it != end; ++it) + it->second->swapBuffersIfNeeded(); + m_isSwapPending = false; + break; + } + default: + ASSERT_NOT_REACHED(); + } + } +} + +QSGNode* QtSGUpdateQueue::getScaleNode(float scale, QSGNode* itemNode) +{ + if (scale == lastScale) + return lastScaleNode; + + QSGTransformNode* scaleNode = new QSGTransformNode; + QMatrix4x4 scaleMatrix; + // Use scale(float,float) to prevent scaling the Z component. + // Reverse the item's transform scale since our tiles were generated for this specific scale. + scaleMatrix.scale(1 / scale, 1 / scale); + scaleNode->setMatrix(scaleMatrix); + // Prepend instead of append to paint the new, incomplete, scale before/behind the previous one. + itemNode->prependChildNode(scaleNode); + + lastScale = scale; + lastScaleNode = scaleNode; + return lastScaleNode; +} + +} |