diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/api/core_api.pro | 8 | ||||
-rw-r--r-- | src/core/content_main_delegate_qt.cpp | 34 | ||||
-rw-r--r-- | src/core/core_module.pro | 4 | ||||
-rw-r--r-- | src/core/delegated_frame_node.cpp | 45 | ||||
-rw-r--r-- | src/core/delegated_frame_node.h | 3 | ||||
-rw-r--r-- | src/core/surface_factory_qt.cpp | 30 | ||||
-rw-r--r-- | src/core/type_conversion.h | 5 | ||||
-rw-r--r-- | src/tools/qwebengine_convert_dict/main.cpp | 6 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginefaviconprovider.cpp | 6 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebengineprofile.cpp | 32 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebengineprofile_p.h | 19 |
11 files changed, 159 insertions, 33 deletions
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro index 05166536e..270595378 100644 --- a/src/core/api/core_api.pro +++ b/src/core/api/core_api.pro @@ -55,3 +55,11 @@ unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!static { SOURCES += qtbug-60565.cpp \ qtbug-61521.cpp } + +msvc { + # Create a list of object files that can be used as response file for the linker. + # This is done to simulate -whole-archive on MSVC. + QMAKE_POST_LINK = \ + "if exist $(DESTDIR_TARGET).objects del $(DESTDIR_TARGET).objects$$escape_expand(\\n\\t)" \ + "for %%a in ($(OBJECTS)) do echo $$shell_quote($$shell_path($$OUT_PWD))\\%%a >> $(DESTDIR_TARGET).objects" +} diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp index 720db77bf..359e0b3d9 100644 --- a/src/core/content_main_delegate_qt.cpp +++ b/src/core/content_main_delegate_qt.cpp @@ -40,19 +40,23 @@ #include "content_main_delegate_qt.h" #include "base/command_line.h" +#include <base/i18n/rtl.h> #include "base/logging.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" +#include <chrome/grit/generated_resources.h> #include "content/public/common/content_paths.h" #include "content/public/common/content_switches.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/ui_base_paths.h" #include "ui/base/resource/resource_bundle.h" +#include <ui/base/webui/jstemplate_builder.h> #include "net/grit/net_resources.h" #include "net/base/net_module.h" #include "content_client_qt.h" #include "renderer/content_renderer_client_qt.h" +#include "type_conversion.h" #include "web_engine_library_info.h" #if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX)) @@ -63,12 +67,38 @@ #include "ui/base/ui_base_switches.h" #endif +#include <QtCore/qcoreapplication.h> + namespace QtWebEngineCore { +// The logic of this function is based on chrome/common/net/net_resource_provider.cc +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE.Chromium file. +static std::string constructDirHeaderHTML() +{ + base::DictionaryValue dict; + dict.SetString("header", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_HEADER)); + dict.SetString("parentDirText", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_PARENT)); + dict.SetString("headerName", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_NAME)); + dict.SetString("headerSize", l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_SIZE)); + dict.SetString("headerDateModified", + l10n_util::GetStringUTF16(IDS_DIRECTORY_LISTING_DATE_MODIFIED)); + dict.SetString("language", l10n_util::GetLanguage(base::i18n::GetConfiguredLocale())); + dict.SetString("listingParsingErrorBoxText", + l10n_util::GetStringFUTF16(IDS_DIRECTORY_LISTING_PARSING_ERROR_BOX_TEXT, + toString16(QCoreApplication::applicationName()))); + dict.SetString("textdirection", base::i18n::IsRTL() ? "rtl" : "ltr"); + std::string html = webui::GetI18nTemplateHtml( + ui::ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_DIR_HEADER_HTML), + &dict); + return html; +} + static base::StringPiece PlatformResourceProvider(int key) { if (key == IDR_DIR_HEADER_HTML) { - base::StringPiece html_data = ui::ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_DIR_HEADER_HTML); - return html_data; + static std::string html_data = constructDirHeaderHTML(); + return base::StringPiece(html_data); } return base::StringPiece(); } diff --git a/src/core/core_module.pro b/src/core/core_module.pro index 55b20cda2..78bb8baee 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -61,7 +61,9 @@ osx { QMAKE_LFLAGS_DEBUG -= /DEBUG QMAKE_LFLAGS_DEBUG += /DEBUG:FASTLINK } - QMAKE_LFLAGS += /WHOLEARCHIVE:$${api_library_path}$${QMAKE_DIR_SEP}$${api_library_name}.lib + # Simulate -whole-archive by passing the list of object files that belong to the public + # API library as response file to the linker. + QMAKE_LFLAGS += @$${api_library_path}$${QMAKE_DIR_SEP}$${api_library_name}.lib.objects } else { LIBS_PRIVATE += -Wl,-whole-archive -l$$api_library_name -Wl,-no-whole-archive } diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp index d0d840ecb..d6ee87950 100644 --- a/src/core/delegated_frame_node.cpp +++ b/src/core/delegated_frame_node.cpp @@ -849,8 +849,8 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, // countering the scale of devicePixel-scaled tiles when rendering them // to the final surface. QMatrix4x4 matrix; - matrix.scale(1 / m_chromiumCompositorData->frameDevicePixelRatio, - 1 / m_chromiumCompositorData->frameDevicePixelRatio); + const float devicePixelRatio = m_chromiumCompositorData->frameDevicePixelRatio; + matrix.scale(1 / devicePixelRatio, 1 / devicePixelRatio); if (QSGTransformNode::matrix() != matrix) setMatrix(matrix); @@ -872,11 +872,19 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, frameData->resource_list.clear(); QScopedPointer<DelegatedNodeTreeHandler> nodeHandler; + const QSizeF viewportSizeInPt = apiDelegate->screenRect().size(); + const QSize viewportSize = (viewportSizeInPt * devicePixelRatio).toSize(); + // We first compare if the render passes from the previous frame data are structurally // equivalent to the render passes in the current frame data. If they are, we are going // to reuse the old nodes. Otherwise, we will delete the old nodes and build a new tree. - cc::CompositorFrame *previousFrameData = &m_chromiumCompositorData->previousFrameData; - const bool buildNewTree = !areRenderPassStructuresEqual(frameData, previousFrameData) || m_sceneGraphNodes.empty(); + // + // Additionally, because we clip (i.e. don't build scene graph nodes for) quads outside + // of the visible area, we also have to rebuild the tree whenever the window is resized. + const bool buildNewTree = + !areRenderPassStructuresEqual(frameData, &m_chromiumCompositorData->previousFrameData) || + m_sceneGraphNodes.empty() || + viewportSize != m_previousViewportSize; m_chromiumCompositorData->previousFrameData = cc::CompositorFrame(); SGObjects previousSGObjects; @@ -904,10 +912,7 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, // All RenderPasses except the last one are rendered to an FBO. cc::RenderPass *rootRenderPass = frameData->render_pass_list.back().get(); - QRectF screenRectQt = apiDelegate->screenRect(); - gfx::Size thisSize(int(screenRectQt.width() * m_chromiumCompositorData->frameDevicePixelRatio), - int(screenRectQt.height() * m_chromiumCompositorData->frameDevicePixelRatio)); - + gfx::Rect viewportRect(toGfx(viewportSize)); for (unsigned i = 0; i < frameData->render_pass_list.size(); ++i) { cc::RenderPass *pass = frameData->render_pass_list.at(i).get(); @@ -939,12 +944,14 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, scissorRect = pass->output_rect; } else { renderPassParent = this; - scissorRect = gfx::Rect(thisSize); + scissorRect = viewportRect; scissorRect += rootRenderPass->output_rect.OffsetFromOrigin(); } - if (scissorRect.IsEmpty()) + if (scissorRect.IsEmpty()) { + holdResources(pass, resourceCandidates); continue; + } QSGNode *renderPassChain = nullptr; if (buildNewTree) @@ -967,8 +974,10 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, if (quadState->is_clipped) targetRect.Intersect(quadState->clip_rect); targetRect.Intersect(scissorRect); - if (targetRect.IsEmpty()) + if (targetRect.IsEmpty()) { + holdResources(quad, resourceCandidates); continue; + } if (quadState->sorting_context_id != currentSortingContextId) { flushPolygons(&polygonQueue, renderPassChain, @@ -1007,6 +1016,8 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, ResourceHolderIterator end = resourceCandidates.constEnd(); for (ResourceHolderIterator it = resourceCandidates.constBegin(); it != end ; ++it) resourcesToRelease->push_back((*it)->returnResource()); + + m_previousViewportSize = viewportSize; } void DelegatedFrameNode::flushPolygons( @@ -1224,6 +1235,18 @@ ResourceHolder *DelegatedFrameNode::findAndHoldResource(unsigned resourceId, QHa return resource.data(); } +void DelegatedFrameNode::holdResources(const cc::DrawQuad *quad, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates) +{ + for (auto resource : quad->resources) + findAndHoldResource(resource, candidates); +} + +void DelegatedFrameNode::holdResources(const cc::RenderPass *pass, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates) +{ + for (const auto &quad : pass->quad_list) + holdResources(quad, candidates); +} + QSGTexture *DelegatedFrameNode::initAndHoldTexture(ResourceHolder *resource, bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate) { // QSGTextures must be destroyed in the scene graph thread as part of the QSGNode tree, diff --git a/src/core/delegated_frame_node.h b/src/core/delegated_frame_node.h index b83f4682a..c627cdf95 100644 --- a/src/core/delegated_frame_node.h +++ b/src/core/delegated_frame_node.h @@ -126,6 +126,8 @@ private: static void fenceAndUnlockQt(DelegatedFrameNode *frameNode); ResourceHolder *findAndHoldResource(unsigned resourceId, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates); + void holdResources(const cc::DrawQuad *quad, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates); + void holdResources(const cc::RenderPass *pass, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates); QSGTexture *initAndHoldTexture(ResourceHolder *resource, bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate = 0); QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData; @@ -143,6 +145,7 @@ private: bool m_contextShared; QScopedPointer<QOffscreenSurface> m_offsurface; #endif + QSize m_previousViewportSize; }; } // namespace QtWebEngineCore diff --git a/src/core/surface_factory_qt.cpp b/src/core/surface_factory_qt.cpp index d0741506a..c976e8b04 100644 --- a/src/core/surface_factory_qt.cpp +++ b/src/core/surface_factory_qt.cpp @@ -56,7 +56,13 @@ #if defined(USE_OZONE) #include <EGL/egl.h> -#include <dlfcn.h> + +#ifndef QT_LIBDIR_EGL +#define QT_LIBDIR_EGL "/usr/lib" +#endif +#ifndef QT_LIBDIR_GLES2 +#define QT_LIBDIR_GLES2 QT_LIBDIR_EGL +#endif namespace QtWebEngineCore { @@ -92,21 +98,29 @@ base::NativeLibrary LoadLibrary(const base::FilePath& filename) { bool GLOzoneQt::LoadGLES2Bindings(gl::GLImplementation /*implementation*/) { - base::NativeLibrary eglgles2Library = dlopen(NULL, RTLD_LAZY); - if (!eglgles2Library) { - LOG(ERROR) << "Failed to open EGL/GLES2 context " << dlerror(); + base::FilePath libEGLPath = QtWebEngineCore::toFilePath(QT_LIBDIR_EGL); + libEGLPath = libEGLPath.Append("libEGL.so.1"); + base::NativeLibrary eglLibrary = LoadLibrary(libEGLPath); + if (!eglLibrary) + return false; + + base::FilePath libGLES2Path = QtWebEngineCore::toFilePath(QT_LIBDIR_GLES2); + libGLES2Path = libGLES2Path.Append("libGLESv2.so.2"); + base::NativeLibrary gles2Library = LoadLibrary(libGLES2Path); + if (!gles2Library) return false; - } - gl::GLGetProcAddressProc get_proc_address = reinterpret_cast<gl::GLGetProcAddressProc>(base::GetFunctionPointerFromNativeLibrary(eglgles2Library, "eglGetProcAddress")); + gl::GLGetProcAddressProc get_proc_address = reinterpret_cast<gl::GLGetProcAddressProc>(base::GetFunctionPointerFromNativeLibrary(eglLibrary, "eglGetProcAddress")); if (!get_proc_address) { LOG(ERROR) << "eglGetProcAddress not found."; - base::UnloadNativeLibrary(eglgles2Library); + base::UnloadNativeLibrary(eglLibrary); + base::UnloadNativeLibrary(gles2Library); return false; } gl::SetGLGetProcAddressProc(get_proc_address); - gl::AddGLNativeLibrary(eglgles2Library); + gl::AddGLNativeLibrary(eglLibrary); + gl::AddGLNativeLibrary(gles2Library); return true; } diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h index d9ba735bd..eb7c9d48b 100644 --- a/src/core/type_conversion.h +++ b/src/core/type_conversion.h @@ -142,6 +142,11 @@ inline QRectF toQt(const gfx::RectF &rect) return QRectF(rect.x(), rect.y(), rect.width(), rect.height()); } +inline gfx::Size toGfx(const QSize &size) +{ + return gfx::Size(size.width(), size.height()); +} + inline QSize toQt(const gfx::Size &size) { return QSize(size.width(), size.height()); diff --git a/src/tools/qwebengine_convert_dict/main.cpp b/src/tools/qwebengine_convert_dict/main.cpp index e7dcc22d9..3a1a1ff64 100644 --- a/src/tools/qwebengine_convert_dict/main.cpp +++ b/src/tools/qwebengine_convert_dict/main.cpp @@ -30,6 +30,7 @@ #include <QTextStream> #include <QLibraryInfo> #include <QDir> +#include <QCoreApplication> // see also src/core/type_conversion.h inline base::FilePath::StringType toFilePathString(const QString &str) @@ -117,6 +118,11 @@ QString frameworkIcuDataPath() int main(int argc, char *argv[]) { + // Required only for making QLibraryInfo::location() return a valid path, when the application + // picks up a qt.conf file (which is the case for official Qt packages). + QCoreApplication app(argc, argv); + Q_UNUSED(app); + QTextStream out(stdout); if (argc != 3) { diff --git a/src/webengine/api/qquickwebenginefaviconprovider.cpp b/src/webengine/api/qquickwebenginefaviconprovider.cpp index b5ad6960a..3255f22be 100644 --- a/src/webengine/api/qquickwebenginefaviconprovider.cpp +++ b/src/webengine/api/qquickwebenginefaviconprovider.cpp @@ -70,7 +70,11 @@ QUrl QQuickWebEngineFaviconProvider::faviconProviderUrl(const QUrl &url) QUrl providerUrl; providerUrl.setScheme(QStringLiteral("image")); providerUrl.setHost(identifier()); - providerUrl.setPath(QStringLiteral("/%1").arg(url.toString())); + providerUrl.setPath(QStringLiteral("/%1").arg(url.toString(QUrl::RemoveQuery | QUrl::RemoveFragment))); + if (url.hasQuery()) + providerUrl.setQuery(url.query(QUrl::FullyDecoded)); + if (url.hasFragment()) + providerUrl.setFragment(url.fragment(QUrl::FullyDecoded)); return providerUrl; } diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp index f844ddcd6..c4de46b67 100644 --- a/src/webenginewidgets/api/qwebengineprofile.cpp +++ b/src/webenginewidgets/api/qwebengineprofile.cpp @@ -145,24 +145,35 @@ using QtWebEngineCore::BrowserContextAdapter; \sa QWebEngineDownloadItem, QWebEnginePage::download() */ -QWebEngineProfilePrivate::QWebEngineProfilePrivate(QSharedPointer<BrowserContextAdapter> browserContext) +QWebEngineBrowserContext::QWebEngineBrowserContext(QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContext, QWebEngineProfilePrivate *profile) + : QObject(BrowserContextAdapter::globalQObjectRoot()) + , browserContextRef(browserContext) + , m_profile(profile) +{ + browserContextRef->addClient(m_profile); +} + +QWebEngineBrowserContext::~QWebEngineBrowserContext() +{ + Q_ASSERT(m_profile); + // In the case the user sets this profile as the parent of the interceptor + // it can be deleted before the browser-context still referencing it is. + browserContextRef->setRequestInterceptor(nullptr); + browserContextRef->removeClient(m_profile); +} + +QWebEngineProfilePrivate::QWebEngineProfilePrivate(QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContext) : m_settings(new QWebEngineSettings()) , m_scriptCollection(new QWebEngineScriptCollection(new QWebEngineScriptCollectionPrivate(browserContext->userResourceController()))) - , m_browserContextRef(browserContext) + , m_browserContext(new QWebEngineBrowserContext(browserContext, this)) { - m_browserContextRef->addClient(this); m_settings->d_ptr->initDefaults(); } QWebEngineProfilePrivate::~QWebEngineProfilePrivate() { - // In the case the user sets this profile as the parent of the interceptor - // it can be deleted before the browser-context still referencing it is. - m_browserContextRef->setRequestInterceptor(nullptr); - delete m_settings; m_settings = 0; - m_browserContextRef->removeClient(this); Q_FOREACH (QWebEngineDownloadItem* download, m_ongoingDownloads) { if (download) @@ -172,6 +183,11 @@ QWebEngineProfilePrivate::~QWebEngineProfilePrivate() m_ongoingDownloads.clear(); } +QSharedPointer<QtWebEngineCore::BrowserContextAdapter> QWebEngineProfilePrivate::browserContext() const +{ + return m_browserContext->browserContextRef; +} + void QWebEngineProfilePrivate::downloadDestroyed(quint32 downloadId) { m_ongoingDownloads.remove(downloadId); diff --git a/src/webenginewidgets/api/qwebengineprofile_p.h b/src/webenginewidgets/api/qwebengineprofile_p.h index c5a75f6d4..7f02307d3 100644 --- a/src/webenginewidgets/api/qwebengineprofile_p.h +++ b/src/webenginewidgets/api/qwebengineprofile_p.h @@ -65,15 +65,30 @@ class BrowserContextAdapter; QT_BEGIN_NAMESPACE +class QWebEngineProfilePrivate; class QWebEngineSettings; +// This is a wrapper class for BrowserContextAdapter. BrowserContextAdapter must be destructed before WebEngineContext +// is destructed. Therefore access it via the QWebEngineBrowserContext which parent is the WebEngineContext::globalQObject. +// This guarantees the destruction together with the WebEngineContext. +class QWebEngineBrowserContext : public QObject { +public: + QWebEngineBrowserContext(QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContext, QWebEngineProfilePrivate *profile); + ~QWebEngineBrowserContext(); + + QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContextRef; + +private: + QWebEngineProfilePrivate *m_profile; +}; + class QWebEngineProfilePrivate : public QtWebEngineCore::BrowserContextAdapterClient { public: Q_DECLARE_PUBLIC(QWebEngineProfile) QWebEngineProfilePrivate(QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContext); ~QWebEngineProfilePrivate(); - QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContext() const { return m_browserContextRef; } + QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContext() const; QWebEngineSettings *settings() const { return m_settings; } void downloadDestroyed(quint32 downloadId); @@ -85,7 +100,7 @@ private: QWebEngineProfile *q_ptr; QWebEngineSettings *m_settings; QScopedPointer<QWebEngineScriptCollection> m_scriptCollection; - QSharedPointer<QtWebEngineCore::BrowserContextAdapter> m_browserContextRef; + QPointer<QWebEngineBrowserContext> m_browserContext; QMap<quint32, QPointer<QWebEngineDownloadItem> > m_ongoingDownloads; }; |