summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
m---------3rdparty0
-rw-r--r--lib/lib.pro4
-rw-r--r--lib/quick/qquickwebengineview.cpp12
-rw-r--r--lib/quick/render_widget_host_view_qt_delegate_quick.cpp28
-rw-r--r--lib/quick/render_widget_host_view_qt_delegate_quick.h23
-rw-r--r--lib/render_widget_host_view_qt.cpp31
-rw-r--r--lib/render_widget_host_view_qt.h10
-rw-r--r--lib/render_widget_host_view_qt_delegate.cpp336
-rw-r--r--lib/render_widget_host_view_qt_delegate.h14
-rw-r--r--lib/type_conversion.h23
-rw-r--r--lib/web_contents_adapter_client.h1
-rw-r--r--lib/web_contents_view_qt.cpp4
-rw-r--r--patches/0001-Solve-conflicts-when-including-both-QtOpenGL-headers.patch77
-rwxr-xr-xpatches/patch-chromium.sh1
14 files changed, 548 insertions, 16 deletions
diff --git a/3rdparty b/3rdparty
-Subproject 679147eead574d186ebf3069647b4c23e8ccace
+Subproject c9d97c73d7b1295b8c714ccaf1e5b717841bccc
diff --git a/lib/lib.pro b/lib/lib.pro
index dbfde8c59..eda03287d 100644
--- a/lib/lib.pro
+++ b/lib/lib.pro
@@ -9,6 +9,10 @@ TEMPLATE = lib
TARGET = Qt5WebEngineCore
+QT += qml quick
+QT_PRIVATE += qml-private quick-private gui-private core-private
+qtHaveModule(v8): QT_PRIVATE += v8-private
+
# Defining keywords such as 'signal' clashes with the chromium code base.
DEFINES += QT_NO_KEYWORDS \
Q_FORWARD_DECLARE_OBJC_CLASS=QT_FORWARD_DECLARE_CLASS
diff --git a/lib/quick/qquickwebengineview.cpp b/lib/quick/qquickwebengineview.cpp
index 55d871093..dfab8ea0e 100644
--- a/lib/quick/qquickwebengineview.cpp
+++ b/lib/quick/qquickwebengineview.cpp
@@ -56,8 +56,12 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
adapter->initialize(this);
}
-RenderWidgetHostViewQtDelegate *QQuickWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegate(CompositingMode)
+RenderWidgetHostViewQtDelegate *QQuickWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegate(CompositingMode mode)
{
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
+ if (mode == DelegatedCompositing)
+ return new RenderWidgetHostViewQtDelegateQuick;
+#endif
return new RenderWidgetHostViewQtDelegateQuickPainted;
}
@@ -207,7 +211,11 @@ void QQuickWebEngineView::geometryChanged(const QRectF &newGeometry, const QRect
QQuickItem::geometryChanged(newGeometry, oldGeometry);
Q_FOREACH(QQuickItem *child, childItems()) {
- Q_ASSERT(qobject_cast<RenderWidgetHostViewQtDelegateQuickPainted *>(child));
+ Q_ASSERT(
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
+ qobject_cast<RenderWidgetHostViewQtDelegateQuick *>(child) ||
+#endif
+ qobject_cast<RenderWidgetHostViewQtDelegateQuickPainted *>(child));
child->setSize(newGeometry.size());
}
}
diff --git a/lib/quick/render_widget_host_view_qt_delegate_quick.cpp b/lib/quick/render_widget_host_view_qt_delegate_quick.cpp
index 6f8243690..b77503f2c 100644
--- a/lib/quick/render_widget_host_view_qt_delegate_quick.cpp
+++ b/lib/quick/render_widget_host_view_qt_delegate_quick.cpp
@@ -41,6 +41,30 @@
#include "render_widget_host_view_qt_delegate_quick.h"
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
+RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(QQuickItem *parent)
+ : RenderWidgetHostViewQtDelegateQuickBase<QQuickItem>(parent)
+{
+ setFlag(ItemHasContents);
+}
+
+WId RenderWidgetHostViewQtDelegateQuick::nativeWindowIdForCompositor() const
+{
+ return QQuickItem::window()->winId();
+}
+
+void RenderWidgetHostViewQtDelegateQuick::update(const QRect&)
+{
+ QQuickItem::update();
+}
+
+QSGNode *RenderWidgetHostViewQtDelegateQuick::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ return RenderWidgetHostViewQtDelegate::updatePaintNode(oldNode, QQuickItem::window());
+}
+#endif // QT_VERSION
+
+
RenderWidgetHostViewQtDelegateQuickPainted::RenderWidgetHostViewQtDelegateQuickPainted(QQuickItem *parent)
: RenderWidgetHostViewQtDelegateQuickBase<QQuickPaintedItem>(parent)
{
@@ -48,9 +72,7 @@ RenderWidgetHostViewQtDelegateQuickPainted::RenderWidgetHostViewQtDelegateQuickP
WId RenderWidgetHostViewQtDelegateQuickPainted::nativeWindowIdForCompositor() const
{
- // Only used to enable accelerated compositing by the compositor
- // directly on our native window, which we want to eventually do
- // through the delegated renderer instead.
+ // This causes a failure of the compositor initialization which ends up disabling it completely.
return 0;
}
diff --git a/lib/quick/render_widget_host_view_qt_delegate_quick.h b/lib/quick/render_widget_host_view_qt_delegate_quick.h
index 67c38a75d..ce4d87c3d 100644
--- a/lib/quick/render_widget_host_view_qt_delegate_quick.h
+++ b/lib/quick/render_widget_host_view_qt_delegate_quick.h
@@ -42,15 +42,6 @@
#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICK_H
#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICK_H
-// On Mac we need to reset this define in order to prevent definition
-// of "check" macros etc. The "check" macro collides with a member function name in QtQuick.
-// See AssertMacros.h in the Mac SDK.
-#include <QtGlobal> // We need this for the Q_OS_MAC define.
-#if defined(Q_OS_MAC)
-#undef __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES
-#define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
-#endif
-
#include "render_widget_host_view_qt_delegate.h"
#include "qquickwebengineview_p.h"
@@ -186,6 +177,20 @@ protected:
}
};
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
+class RenderWidgetHostViewQtDelegateQuick : public RenderWidgetHostViewQtDelegateQuickBase<QQuickItem>
+{
+ Q_OBJECT
+public:
+ RenderWidgetHostViewQtDelegateQuick(QQuickItem *parent = 0);
+
+ virtual WId nativeWindowIdForCompositor() const;
+ virtual void update(const QRect& rect = QRect());
+
+ virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+};
+#endif // QT_VERSION
+
class RenderWidgetHostViewQtDelegateQuickPainted : public RenderWidgetHostViewQtDelegateQuickBase<QQuickPaintedItem>
{
Q_OBJECT
diff --git a/lib/render_widget_host_view_qt.cpp b/lib/render_widget_host_view_qt.cpp
index 99bf94653..d9f1a48df 100644
--- a/lib/render_widget_host_view_qt.cpp
+++ b/lib/render_widget_host_view_qt.cpp
@@ -47,6 +47,7 @@
#include "shared/shared_globals.h"
+#include "cc/output/compositor_frame_ack.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/ui_events_helper.h"
#include "content/common/gpu/gpu_messages.h"
@@ -161,6 +162,18 @@ bool RenderWidgetHostViewQt::handleEvent(QEvent* event) {
return true;
}
+void RenderWidgetHostViewQt::releaseAndAckDelegatedFrame()
+{
+ cc::CompositorFrameAck ack;
+ // FIXME: This releases all resources of the frame for now.
+ ack.resources = m_pendingFrameData->resource_list;
+ content::RenderWidgetHostImpl::SendSwapCompositorFrameAck(
+ m_host->GetRoutingID(), m_pendingOutputSurfaceId,
+ m_host->GetProcess()->GetID(), ack);
+
+ m_pendingFrameData.reset();
+}
+
BackingStoreQt* RenderWidgetHostViewQt::GetBackingStore()
{
bool force_create = !m_host->empty();
@@ -554,6 +567,15 @@ bool RenderWidgetHostViewQt::HasAcceleratedSurface(const gfx::Size&)
return false;
}
+void RenderWidgetHostViewQt::OnSwapCompositorFrame(uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame)
+{
+ Q_ASSERT(frame->delegated_frame_data);
+ SwapDelegatedFrame(output_surface_id,
+ frame->delegated_frame_data.Pass(),
+ frame->metadata.device_scale_factor,
+ frame->metadata.latency_info);
+}
+
void RenderWidgetHostViewQt::GetScreenInfo(WebKit::WebScreenInfo* results)
{
QWindow* window = m_delegate->window();
@@ -617,6 +639,15 @@ void RenderWidgetHostViewQt::Paint(const gfx::Rect& damage_rect)
m_delegate->update(r);
}
+void RenderWidgetHostViewQt::SwapDelegatedFrame(uint32 output_surface_id, scoped_ptr<cc::DelegatedFrameData> frame_data, float frame_device_scale_factor, const ui::LatencyInfo& latency_info) {
+ gfx::Size frame_size_in_dip;
+ if (!frame_data->render_pass_list.empty())
+ frame_size_in_dip = gfx::ToFlooredSize(gfx::ScaleSize(frame_data->render_pass_list.back()->output_rect.size(), 1.f/frame_device_scale_factor));
+
+ m_pendingOutputSurfaceId = output_surface_id;
+ m_pendingFrameData = frame_data.Pass();
+ m_delegate->update();
+}
void RenderWidgetHostViewQt::ProcessGestures(ui::GestureRecognizer::Gestures *gestures)
{
diff --git a/lib/render_widget_host_view_qt.h b/lib/render_widget_host_view_qt.h
index 97261ca92..337351b69 100644
--- a/lib/render_widget_host_view_qt.h
+++ b/lib/render_widget_host_view_qt.h
@@ -45,6 +45,7 @@
#include "shared/shared_globals.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "ui/base/gestures/gesture_recognizer.h"
#include "ui/base/gestures/gesture_types.h"
@@ -87,6 +88,7 @@ class RenderWidgetHostViewQt
: public content::RenderWidgetHostViewBase
, public ui::GestureConsumer
, public ui::GestureEventHelper
+ , public base::SupportsWeakPtr<RenderWidgetHostViewQt>
{
public:
RenderWidgetHostViewQt(content::RenderWidgetHost* widget);
@@ -95,6 +97,8 @@ public:
void setDelegate(RenderWidgetHostViewQtDelegate *delegate);
void setAdapterClient(WebContentsAdapterClient *adapterClient);
bool handleEvent(QEvent* event);
+ cc::DelegatedFrameData *pendingDelegatedFrame() const { return m_pendingFrameData.get(); }
+ void releaseAndAckDelegatedFrame();
BackingStoreQt* GetBackingStore();
virtual content::BackingStore *AllocBackingStore(const gfx::Size &size);
@@ -147,6 +151,7 @@ public:
virtual void AcceleratedSurfaceSuspend();
virtual void AcceleratedSurfaceRelease();
virtual bool HasAcceleratedSurface(const gfx::Size&);
+ virtual void OnSwapCompositorFrame(uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) Q_DECL_OVERRIDE;
virtual void GetScreenInfo(WebKit::WebScreenInfo* results);
virtual gfx::Rect GetBoundsInRootWindow();
virtual gfx::GLSurfaceHandle GetCompositingSurface();
@@ -182,6 +187,7 @@ public:
private:
void Paint(const gfx::Rect& damage_rect);
+ void SwapDelegatedFrame(uint32 output_surface_id, scoped_ptr<cc::DelegatedFrameData> frame_data, float frame_device_scale_factor, const ui::LatencyInfo& latency_info);
void ProcessGestures(ui::GestureRecognizer::Gestures *gestures);
int GetMappedTouch(int qtTouchId);
void RemoveExpiredMappings(QTouchEvent *ev);
@@ -193,6 +199,10 @@ private:
QMap<int, int> m_touchIdMapping;
WebKit::WebTouchEvent m_accumTouchEvent;
scoped_ptr<RenderWidgetHostViewQtDelegate> m_delegate;
+
+ uint32 m_pendingOutputSurfaceId;
+ scoped_ptr<cc::DelegatedFrameData> m_pendingFrameData;
+
WebContentsAdapterClient *m_adapterClient;
MultipleMouseClickHelper m_clickHelper;
diff --git a/lib/render_widget_host_view_qt_delegate.cpp b/lib/render_widget_host_view_qt_delegate.cpp
index 0a3a5106f..3ec9d450a 100644
--- a/lib/render_widget_host_view_qt_delegate.cpp
+++ b/lib/render_widget_host_view_qt_delegate.cpp
@@ -43,9 +43,243 @@
#include "backing_store_qt.h"
#include "render_widget_host_view_qt.h"
+#include "type_conversion.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
-#include <QPainter>
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
+#include "cc/quads/draw_quad.h"
+#include "cc/quads/render_pass_draw_quad.h"
+#include "cc/quads/texture_draw_quad.h"
+#include "cc/quads/tile_draw_quad.h"
+#include <QSGNode>
+#include <QSGSimpleTextureNode>
+#include <QSGTexture>
+#include <QtQuick/private/qquickclipnode_p.h>
+#include <QtQuick/private/qquickwindow_p.h>
+#include <QtQuick/private/qsgcontext_p.h>
+#include <QtQuick/private/qsgrenderer_p.h>
+
+class RenderPassTexture : public QSGTexture
+{
+public:
+ RenderPassTexture(const cc::RenderPass::Id &id, QSGContext *context);
+
+ const cc::RenderPass::Id &id() const { return m_id; }
+ void bind();
+
+ int textureId() const { return m_fbo ? m_fbo->texture() : 0; }
+ QSize textureSize() const { return m_rect.size(); }
+ bool hasAlphaChannel() const { return m_format != GL_RGB; }
+ bool hasMipmaps() const { return false; }
+
+ void setRect(const QRect &rect) { m_rect = rect; }
+ void setFormat(GLenum format) { m_format = format; }
+ void setDevicePixelRatio(qreal ratio) { m_device_pixel_ratio = ratio; }
+ QSGNode *rootNode() { return m_rootNode.data(); }
+
+ void grab();
+
+private:
+ cc::RenderPass::Id m_id;
+ QRect m_rect;
+ qreal m_device_pixel_ratio;
+ GLenum m_format;
+
+ QScopedPointer<QSGRootNode> m_rootNode;
+ QScopedPointer<QSGRenderer> m_renderer;
+ QScopedPointer<QOpenGLFramebufferObject> m_fbo;
+
+ QSGContext *m_context;
+};
+
+RenderPassTexture::RenderPassTexture(const cc::RenderPass::Id &id, QSGContext *context)
+ : QSGTexture()
+ , m_id(id)
+ , m_device_pixel_ratio(1)
+ , m_format(GL_RGBA)
+ , m_rootNode(new QSGRootNode)
+ , m_context(context)
+{
+}
+
+void RenderPassTexture::bind()
+{
+ glBindTexture(GL_TEXTURE_2D, m_fbo ? m_fbo->texture() : 0);
+ updateBindOptions();
+}
+
+void RenderPassTexture::grab()
+{
+ if (!m_rootNode->firstChild()) {
+ m_renderer.reset();
+ m_fbo.reset();
+ return;
+ }
+ if (!m_renderer) {
+ m_renderer.reset(m_context->createRenderer());
+ m_renderer->setRootNode(m_rootNode.data());
+ }
+ m_renderer->setDevicePixelRatio(m_device_pixel_ratio);
+
+ if (!m_fbo || m_fbo->size() != m_rect.size() || m_fbo->format().internalTextureFormat() != m_format)
+ {
+ QOpenGLFramebufferObjectFormat format;
+ format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+ format.setInternalTextureFormat(m_format);
+
+ m_fbo.reset(new QOpenGLFramebufferObject(m_rect.size(), format));
+ glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
+ updateBindOptions(true);
+ }
+
+ m_rootNode->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip and opacity update.
+ m_renderer->nodeChanged(m_rootNode.data(), QSGNode::DirtyForceUpdate); // Force render list update.
+
+ m_renderer->setDeviceRect(m_rect.size());
+ m_renderer->setViewportRect(m_rect.size());
+ QRectF mirrored(m_rect.left(), m_rect.bottom(), m_rect.width(), -m_rect.height());
+ m_renderer->setProjectionMatrixToRect(mirrored);
+ m_renderer->setClearColor(Qt::transparent);
+
+ m_context->renderNextFrame(m_renderer.data(), m_fbo->handle());
+}
+
+class RawTextureNode : public QSGSimpleTextureNode {
+public:
+ RawTextureNode(GLuint textureId, const QSize &textureSize, bool hasAlpha, QQuickWindow *window);
+
+private:
+ QScopedPointer<QSGTexture> m_texture;
+};
+
+RawTextureNode::RawTextureNode(GLuint textureId, const QSize &textureSize, bool hasAlpha, QQuickWindow *window)
+ : m_texture(window->createTextureFromId(textureId, textureSize, QQuickWindow::CreateTextureOption(hasAlpha ? QQuickWindow::TextureHasAlphaChannel : 0)))
+{
+ setTexture(m_texture.data());
+}
+
+class DelegatedFrameNode : public QSGNode {
+public:
+ DelegatedFrameNode();
+ ~DelegatedFrameNode();
+ void preprocess();
+ QList<QSharedPointer<RenderPassTexture> > renderPassTextures;
+
+ const size_t testTexturesSize;
+ GLuint testTextures[Qt::transparent - Qt::red];
+};
+
+DelegatedFrameNode::DelegatedFrameNode()
+ : testTexturesSize(sizeof(testTextures) / sizeof(GLuint))
+{
+ setFlag(UsePreprocess);
+
+ // Generate plain color textures to be used until we can use the real textures from the ResourceProvider.
+ glGenTextures(testTexturesSize, testTextures);
+ for (unsigned i = 0; i < testTexturesSize; ++i) {
+ QImage image(1, 1, QImage::Format_ARGB32_Premultiplied);
+ image.fill(static_cast<Qt::GlobalColor>(i + Qt::red));
+
+ // Swizzle
+ const int width = image.width();
+ const int height = image.height();
+ for (int j = 0; j < height; ++j) {
+ uint *p = (uint *) image.scanLine(j);
+ for (int x = 0; x < width; ++x)
+ p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
+ }
+
+ glBindTexture(GL_TEXTURE_2D, testTextures[i]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.constBits() );
+ }
+}
+
+DelegatedFrameNode::~DelegatedFrameNode()
+{
+ glDeleteTextures(testTexturesSize, testTextures);
+}
+
+void DelegatedFrameNode::preprocess()
+{
+ // Render any intermediate RenderPass in order.
+ Q_FOREACH (const QSharedPointer<RenderPassTexture> &texture, renderPassTextures)
+ texture->grab();
+}
+
+static inline QSharedPointer<RenderPassTexture> findRenderPassTexture(const cc::RenderPass::Id &id, const QList<QSharedPointer<RenderPassTexture> > &list)
+{
+ Q_FOREACH (const QSharedPointer<RenderPassTexture> &texture, list)
+ if (texture->id() == id)
+ return texture;
+ return QSharedPointer<RenderPassTexture>();
+}
+
+static QSGNode *buildRenderPassChain(QSGNode *chainParent, const cc::RenderPass *renderPass)
+{
+ // Chromium already ordered the quads from back to front for us, however the
+ // Qt scene graph layers individual geometries in their own z-range and uses
+ // the depth buffer to visually stack nodes according to their item tree order.
+ // This finds the z-span of all layers so that we can z-compress them to fit
+ // them between 0.0 and 1.0 on the z axis.
+ double minZ = 0;
+ double maxZ = 1;
+ double src2[8];
+ double dst4[16];
+ // topleft.x, topleft.y, topRight.y and bottomLeft.x
+ src2[0] = src2[1] = src2[3] = src2[4] = 0;
+
+ // Go through each layer in this pass and find out their transformed rect.
+ cc::SharedQuadStateList::const_iterator it = renderPass->shared_quad_state_list.begin();
+ cc::SharedQuadStateList::const_iterator sharedStateEnd = renderPass->shared_quad_state_list.end();
+ for (; it != sharedStateEnd; ++it) {
+ gfx::Size &layerSize = (*it)->content_bounds;
+ // topRight.x
+ src2[2] = layerSize.width();
+ // bottomLeft.y
+ src2[5] = layerSize.height();
+ // bottomRight
+ src2[6] = layerSize.width();
+ src2[7] = layerSize.height();
+ (*it)->content_to_target_transform.matrix().map2(src2, 4, dst4);
+ // Check the mapped corner's z value and track the boundaries.
+ minZ = std::min(std::min(std::min(std::min(minZ, dst4[2]), dst4[6]), dst4[10]), dst4[14]);
+ maxZ = std::max(std::max(std::max(std::max(maxZ, dst4[2]), dst4[6]), dst4[10]), dst4[14]);
+ }
+
+ QSGTransformNode *zCompressNode = new QSGTransformNode;
+ QMatrix4x4 zCompressMatrix;
+ zCompressMatrix.scale(1, 1, 1 / (maxZ - minZ));
+ zCompressMatrix.translate(0, 0, -minZ);
+ zCompressNode->setMatrix(zCompressMatrix);
+ chainParent->appendChildNode(zCompressNode);
+ return zCompressNode;
+}
+
+static QSGNode *buildLayerChain(QSGNode *chainParent, const cc::SharedQuadState *layerState)
+{
+ QSGNode *layerChain = chainParent;
+ if (layerState->is_clipped) {
+ QQuickDefaultClipNode *clipNode = new QQuickDefaultClipNode(toQt(layerState->clip_rect));
+ clipNode->update();
+ layerChain->appendChildNode(clipNode);
+ layerChain = clipNode;
+ }
+ if (!layerState->content_to_target_transform.IsIdentity()) {
+ QSGTransformNode *transformNode = new QSGTransformNode;
+ transformNode->setMatrix(toQt(layerState->content_to_target_transform.matrix()));
+ layerChain->appendChildNode(transformNode);
+ layerChain = transformNode;
+ }
+ if (layerState->opacity < 1.0) {
+ QSGOpacityNode *opacityNode = new QSGOpacityNode;
+ opacityNode->setOpacity(layerState->opacity);
+ layerChain->appendChildNode(opacityNode);
+ layerChain = opacityNode;
+ }
+ return layerChain;
+}
+#endif // QT_VERSION
RenderWidgetHostViewQtDelegate::RenderWidgetHostViewQtDelegate()
: m_view(0), m_backingStore(0)
@@ -62,6 +296,106 @@ void RenderWidgetHostViewQtDelegate::paint(QPainter *painter, const QRectF &boun
m_backingStore->paintToTarget(painter, boundingRect);
}
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
+QSGNode *RenderWidgetHostViewQtDelegate::updatePaintNode(QSGNode *oldNode, QQuickWindow *window)
+{
+ cc::DelegatedFrameData *frameData = m_view->pendingDelegatedFrame();
+ if (!frameData) {
+ delete oldNode;
+ return 0;
+ }
+ DelegatedFrameNode *frameNode = static_cast<DelegatedFrameNode *>(oldNode);
+ if (!frameNode)
+ frameNode = new DelegatedFrameNode;
+
+ // Keep the old list around to find the ones we can re-use.
+ QList<QSharedPointer<RenderPassTexture> > oldRenderPassTextures;
+ frameNode->renderPassTextures.swap(oldRenderPassTextures);
+
+ // The RenderPasses list is actually a tree where a parent RenderPass is connected
+ // to its dependencies through a RenderPass::Id reference in one or more RenderPassQuads.
+ // The list is already ordered with intermediate RenderPasses placed before their
+ // parent, with the last one in the list being the root RenderPass, the one
+ // that we displayed to the user.
+ // All RenderPasses except the last one are rendered to an FBO.
+ cc::RenderPass *rootRenderPass = frameData->render_pass_list.back();
+
+ for (unsigned i = 0; i < frameData->render_pass_list.size(); ++i) {
+ cc::RenderPass *pass = frameData->render_pass_list.at(i);
+
+ QSGNode *renderPassParent = 0;
+ if (pass != rootRenderPass) {
+ QSharedPointer<RenderPassTexture> rpTexture = findRenderPassTexture(pass->id, oldRenderPassTextures);
+ if (!rpTexture) {
+ QSGContext *sgContext = QQuickWindowPrivate::get(window)->context;
+ rpTexture = QSharedPointer<RenderPassTexture>(new RenderPassTexture(pass->id, sgContext));
+ }
+ frameNode->renderPassTextures.append(rpTexture);
+ rpTexture->setDevicePixelRatio(window->devicePixelRatio());
+ rpTexture->setRect(toQt(pass->output_rect));
+ rpTexture->setFormat(pass->has_transparent_background ? GL_RGBA : GL_RGB);
+ renderPassParent = rpTexture->rootNode();
+ } else
+ renderPassParent = frameNode;
+
+ // There is currently no way to know which and how quads changed since the last frame.
+ // We have to reconstruct the node chain with their geometries on every update.
+ while (QSGNode *oldChain = renderPassParent->firstChild())
+ delete oldChain;
+
+ QSGNode *renderPassChain = buildRenderPassChain(renderPassParent, pass);
+ const cc::SharedQuadState *currentLayerState = 0;
+ QSGNode *currentLayerChain = 0;
+
+ cc::QuadList::ConstBackToFrontIterator it = pass->quad_list.BackToFrontBegin();
+ cc::QuadList::ConstBackToFrontIterator end = pass->quad_list.BackToFrontEnd();
+ for (; it != end; ++it) {
+ cc::DrawQuad *quad = *it;
+
+ if (currentLayerState != quad->shared_quad_state) {
+ currentLayerState = quad->shared_quad_state;
+ currentLayerChain = buildLayerChain(renderPassChain, currentLayerState);
+ }
+
+ QSGSimpleTextureNode *textureNode = 0;
+ switch (quad->material) {
+ case cc::DrawQuad::RENDER_PASS: {
+ const cc::RenderPassDrawQuad *renderPassQuad = cc::RenderPassDrawQuad::MaterialCast(quad);
+ QSGTexture *texture = findRenderPassTexture(renderPassQuad->render_pass_id, frameNode->renderPassTextures).data();
+ if (texture) {
+ textureNode = new QSGSimpleTextureNode;
+ textureNode->setTexture(texture);
+ } else {
+ qWarning("Unknown RenderPass layer: Id %d", renderPassQuad->render_pass_id.layer_id);
+ textureNode = new RawTextureNode(0, QSize(1, 1), false, window);
+ }
+ break;
+ } case cc::DrawQuad::TEXTURE_CONTENT: {
+ uint32 resourceId = cc::TextureDrawQuad::MaterialCast(quad)->resource_id;
+ textureNode = new RawTextureNode(frameNode->testTextures[resourceId % frameNode->testTexturesSize], QSize(1, 1), false, window);
+ break;
+ } case cc::DrawQuad::TILED_CONTENT: {
+ uint32 resourceId = cc::TileDrawQuad::MaterialCast(quad)->resource_id;
+ textureNode = new RawTextureNode(frameNode->testTextures[resourceId % frameNode->testTexturesSize], QSize(1, 1), false, window);
+ break;
+ } default:
+ qWarning("Unimplemented quad material: %d", quad->material);
+ textureNode = new RawTextureNode(0, QSize(1, 1), false, window);
+ }
+
+ textureNode->setRect(toQt(quad->rect));
+ textureNode->setFiltering(QSGTexture::Linear);
+ currentLayerChain->appendChildNode(textureNode);
+ }
+ }
+
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&RenderWidgetHostViewQt::releaseAndAckDelegatedFrame, m_view->AsWeakPtr()));
+
+ return frameNode;
+}
+#endif // QT_VERSION
+
void RenderWidgetHostViewQtDelegate::fetchBackingStore()
{
Q_ASSERT(m_view);
diff --git a/lib/render_widget_host_view_qt_delegate.h b/lib/render_widget_host_view_qt_delegate.h
index c73aa9aec..f84d1a085 100644
--- a/lib/render_widget_host_view_qt_delegate.h
+++ b/lib/render_widget_host_view_qt_delegate.h
@@ -42,6 +42,15 @@
#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_H
#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_H
+// On Mac we need to reset this define in order to prevent definition
+// of "check" macros etc. The "check" macro collides with a member function name in QtQuick.
+// See AssertMacros.h in the Mac SDK.
+#include <QtGlobal> // We need this for the Q_OS_MAC define.
+#if defined(Q_OS_MAC)
+#undef __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES
+#define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
+#endif
+
#include "qtwebengineglobal.h"
#include <QRect>
@@ -54,6 +63,8 @@ QT_BEGIN_NAMESPACE
class QCursor;
class QEvent;
class QPainter;
+class QQuickWindow;
+class QSGNode;
class QWindow;
QT_END_NAMESPACE
@@ -80,6 +91,9 @@ public:
protected:
RenderWidgetHostViewQtDelegate();
void paint(QPainter*, const QRectF& boundingRect);
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
+ QSGNode *updatePaintNode(QSGNode *, QQuickWindow *);
+#endif
void fetchBackingStore();
void notifyResize();
bool forwardEvent(QEvent*);
diff --git a/lib/type_conversion.h b/lib/type_conversion.h
index 51a543f73..2b7dee25b 100644
--- a/lib/type_conversion.h
+++ b/lib/type_conversion.h
@@ -42,9 +42,13 @@
#ifndef TYPE_CONVERSION_H
#define TYPE_CONVERSION_H
+#include <QMatrix4x4>
+#include <QRect>
#include <QString>
#include <QUrl>
#include "base/files/file_path.h"
+#include "third_party/skia/include/utils/SkMatrix44.h"
+#include "ui/gfx/rect.h"
#include "url/gurl.h"
inline QString toQt(const string16 &string)
@@ -62,6 +66,25 @@ inline GURL toGurl(const QUrl& url)
return GURL(url.toString().toStdString());
}
+inline QRect toQt(const gfx::Rect &rect)
+{
+ return QRect(rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+inline QSize toQt(const gfx::Size &size)
+{
+ return QSize(size.width(), size.height());
+}
+
+inline QMatrix4x4 toQt(const SkMatrix44 &m)
+{
+ return QMatrix4x4(
+ m.get(0, 0), m.get(0, 1), m.get(0, 2), m.get(0, 3),
+ m.get(1, 0), m.get(1, 1), m.get(1, 2), m.get(1, 3),
+ m.get(2, 0), m.get(2, 1), m.get(2, 2), m.get(2, 3),
+ m.get(3, 0), m.get(3, 1), m.get(3, 2), m.get(3, 3));
+}
+
inline base::FilePath::StringType toFilePathString(const QString &str)
{
#if defined(OS_POSIX)
diff --git a/lib/web_contents_adapter_client.h b/lib/web_contents_adapter_client.h
index 8e92ead7c..d85c55173 100644
--- a/lib/web_contents_adapter_client.h
+++ b/lib/web_contents_adapter_client.h
@@ -73,6 +73,7 @@ class QWEBENGINE_EXPORT WebContentsAdapterClient {
public:
enum CompositingMode {
NoCompositing,
+ DelegatedCompositing,
ForcedGpuProcessCompositing
};
diff --git a/lib/web_contents_view_qt.cpp b/lib/web_contents_view_qt.cpp
index 8fc7f5b12..35445ccff 100644
--- a/lib/web_contents_view_qt.cpp
+++ b/lib/web_contents_view_qt.cpp
@@ -64,7 +64,9 @@ content::RenderWidgetHostView* WebContentsViewQt::CreateViewForWidget(content::R
RenderWidgetHostViewQt *view = new RenderWidgetHostViewQt(render_widget_host);
WebContentsAdapterClient::CompositingMode compositingMode = WebContentsAdapterClient::NoCompositing;
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kForceCompositingMode))
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableDelegatedRenderer))
+ compositingMode = WebContentsAdapterClient::DelegatedCompositing;
+ else if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kForceCompositingMode))
compositingMode = WebContentsAdapterClient::ForcedGpuProcessCompositing;
Q_ASSERT(m_factoryClient);
diff --git a/patches/0001-Solve-conflicts-when-including-both-QtOpenGL-headers.patch b/patches/0001-Solve-conflicts-when-including-both-QtOpenGL-headers.patch
new file mode 100644
index 000000000..837870c24
--- /dev/null
+++ b/patches/0001-Solve-conflicts-when-including-both-QtOpenGL-headers.patch
@@ -0,0 +1,77 @@
+From 08012c5c84dc6f63c1c91d8035ec11b497e6e11c Mon Sep 17 00:00:00 2001
+From: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
+Date: Fri, 6 Sep 2013 17:08:45 +0200
+Subject: [PATCH] Solve conflicts when including both QtOpenGL headers and
+ resource_provider.h
+
+If resource_provider.h is going to be used to integrate delegated frame
+to external compositors, it should avoid conflicting with the system's gl.h.
+
+Change-Id: Ie37d6cde263157e6717cc006a9896f0b9ebdaa5d
+Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
+---
+ cc/layers/texture_layer.cc | 1 +
+ cc/output/delegating_renderer.cc | 1 +
+ cc/quads/content_draw_quad_base.h | 1 -
+ cc/resources/resource_provider.h | 5 ++++-
+ 4 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/cc/layers/texture_layer.cc b/cc/layers/texture_layer.cc
+index 316042b..2325a80 100644
+--- a/cc/layers/texture_layer.cc
++++ b/cc/layers/texture_layer.cc
+@@ -10,6 +10,7 @@
+ #include "cc/layers/texture_layer_client.h"
+ #include "cc/layers/texture_layer_impl.h"
+ #include "cc/trees/layer_tree_host.h"
++#include "third_party/khronos/GLES2/gl2.h"
+ #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
+
+ namespace cc {
+diff --git a/cc/output/delegating_renderer.cc b/cc/output/delegating_renderer.cc
+index bd1c5d1..0c3051c 100644
+--- a/cc/output/delegating_renderer.cc
++++ b/cc/output/delegating_renderer.cc
+@@ -23,6 +23,7 @@
+ #include "cc/quads/yuv_video_draw_quad.h"
+ #include "cc/resources/resource_provider.h"
+ #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
++#include "third_party/khronos/GLES2/gl2.h"
+ #include "third_party/khronos/GLES2/gl2ext.h"
+
+ using WebKit::WebGraphicsContext3D;
+diff --git a/cc/quads/content_draw_quad_base.h b/cc/quads/content_draw_quad_base.h
+index cbf18ca..6229d61 100644
+--- a/cc/quads/content_draw_quad_base.h
++++ b/cc/quads/content_draw_quad_base.h
+@@ -8,7 +8,6 @@
+ #include "base/memory/scoped_ptr.h"
+ #include "cc/base/cc_export.h"
+ #include "cc/quads/draw_quad.h"
+-#include "third_party/khronos/GLES2/gl2.h"
+ #include "ui/gfx/point.h"
+ #include "ui/gfx/size.h"
+
+diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h
+index b5dccc8..1d51a27 100644
+--- a/cc/resources/resource_provider.h
++++ b/cc/resources/resource_provider.h
+@@ -20,11 +20,14 @@
+ #include "cc/output/output_surface.h"
+ #include "cc/resources/texture_mailbox.h"
+ #include "cc/resources/transferable_resource.h"
+-#include "third_party/khronos/GLES2/gl2.h"
+ #include "third_party/skia/include/core/SkBitmap.h"
+ #include "third_party/skia/include/core/SkCanvas.h"
+ #include "ui/gfx/size.h"
+
++// A correct fix would be not to use GL types in this interal API file.
++typedef unsigned int GLenum;
++typedef int GLint;
++
+ namespace WebKit { class WebGraphicsContext3D; }
+
+ namespace gfx {
+--
+1.8.4
+
diff --git a/patches/patch-chromium.sh b/patches/patch-chromium.sh
index 3a9e9278e..c917f87f5 100755
--- a/patches/patch-chromium.sh
+++ b/patches/patch-chromium.sh
@@ -65,6 +65,7 @@ git am $PATCH_DIR/0001-Mac-Do-not-modify-the-child-path.patch
git am $PATCH_DIR/0001-Do-not-warn-for-header-hygiene.patch
git am $PATCH_DIR/0001-Build-files-necessary-for-touch-and-gestures.patch
git am $PATCH_DIR/0001-remove-Wno-deprecated-register-from-common.gypi.patch
+git am $PATCH_DIR/0001-Solve-conflicts-when-including-both-QtOpenGL-headers.patch
cd $CHROMIUM_SRC_DIR/third_party/WebKit
echo "Entering $PWD"