diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-10-23 17:29:19 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-11-08 07:15:03 +0000 |
commit | 7db70f1e85f628f78df84eb195473fb315e812fe (patch) | |
tree | cafdfd0b01e9d2e3acb82f84858d1f8984227a3a | |
parent | 0ef5bbc16781fc0d0ea72e396b1d6e23cd588dc9 (diff) |
Implement CopyFromSurface
Means we can get screenshots in devtools.
Change-Id: I7b50d6ac5a54d236573bcf5f58ae872bd50dccad
Reviewed-by: Jüri Valdmann <juri.valdmann@qt.io>
-rw-r--r-- | src/core/render_widget_host_view_qt.cpp | 13 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt.h | 3 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt_delegate.h | 1 | ||||
-rw-r--r-- | src/core/type_conversion.cpp | 38 | ||||
-rw-r--r-- | src/core/type_conversion.h | 2 | ||||
-rw-r--r-- | src/core/web_engine_context.cpp | 2 | ||||
-rw-r--r-- | src/webengine/render_widget_host_view_qt_delegate_quick.cpp | 11 | ||||
-rw-r--r-- | src/webengine/render_widget_host_view_qt_delegate_quick.h | 1 | ||||
-rw-r--r-- | src/webengine/render_widget_host_view_qt_delegate_quickwindow.h | 1 | ||||
-rw-r--r-- | src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp | 9 | ||||
-rw-r--r-- | src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h | 1 |
11 files changed, 81 insertions, 1 deletions
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 1c5382fe7..9706ac070 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -403,7 +403,18 @@ bool RenderWidgetHostViewQt::HasFocus() const bool RenderWidgetHostViewQt::IsSurfaceAvailableForCopy() const { - return false; + return true; +} + +void RenderWidgetHostViewQt::CopyFromSurface(const gfx::Rect &src_rect, + const gfx::Size &output_size, + base::OnceCallback<void(const SkBitmap &)> callback) +{ + QImage image; + if (m_delegate->copySurface(toQt(src_rect), toQt(output_size), image)) + std::move(callback).Run(toSkBitmap(image)); + else + std::move(callback).Run(SkBitmap()); } void RenderWidgetHostViewQt::Show() diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index 6a1134ac0..8db3351f4 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -124,6 +124,9 @@ public: void Focus() override; bool HasFocus() const override; bool IsSurfaceAvailableForCopy() const override; + void CopyFromSurface(const gfx::Rect &src_rect, + const gfx::Size &output_size, + base::OnceCallback<void(const SkBitmap &)> callback) override; void Show() override; void Hide() override; bool IsShowing() override; diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h index 991c26ea8..5ce595502 100644 --- a/src/core/render_widget_host_view_qt_delegate.h +++ b/src/core/render_widget_host_view_qt_delegate.h @@ -114,6 +114,7 @@ public: virtual void inputMethodStateChanged(bool editorVisible, bool passwordInput) = 0; virtual void setInputMethodHints(Qt::InputMethodHints hints) = 0; virtual void setClearColor(const QColor &color) = 0; + virtual bool copySurface(const QRect &, const QSize &, QImage &) = 0; }; } // namespace QtWebEngineCore diff --git a/src/core/type_conversion.cpp b/src/core/type_conversion.cpp index 4aff2cff6..d35426ac3 100644 --- a/src/core/type_conversion.cpp +++ b/src/core/type_conversion.cpp @@ -137,6 +137,44 @@ QImage toQImage(const gfx::ImageSkiaRep &imageSkiaRep) return image; } +SkBitmap toSkBitmap(const QImage &image) +{ + SkBitmap bitmap; + SkImageInfo imageInfo; + + switch (image.format()) { + case QImage::Format_RGB32: + imageInfo = SkImageInfo::Make(image.width(), image.height(), kBGRA_8888_SkColorType, kOpaque_SkAlphaType); + break; + case QImage::Format_ARGB32: + imageInfo = SkImageInfo::Make(image.width(), image.height(), kBGRA_8888_SkColorType, kUnpremul_SkAlphaType); + break; + case QImage::Format_ARGB32_Premultiplied: + imageInfo = SkImageInfo::Make(image.width(), image.height(), kBGRA_8888_SkColorType, kPremul_SkAlphaType); + break; + case QImage::Format_RGBX8888: + imageInfo = SkImageInfo::Make(image.width(), image.height(), kRGBA_8888_SkColorType, kOpaque_SkAlphaType); + break; + case QImage::Format_RGBA8888: + imageInfo = SkImageInfo::Make(image.width(), image.height(), kRGBA_8888_SkColorType, kUnpremul_SkAlphaType); + break; + case QImage::Format_RGBA8888_Premultiplied: + imageInfo = SkImageInfo::Make(image.width(), image.height(), kRGBA_8888_SkColorType, kPremul_SkAlphaType); + break; + default: + return toSkBitmap(image.convertToFormat(QImage::Format_ARGB32_Premultiplied)); + } + + bitmap.installPixels(imageInfo, (void *)image.bits(), image.bytesPerLine()); + + // Ensure we copy the pixels + SkBitmap bitmapCopy; + bitmapCopy.allocPixels(imageInfo); + bitmapCopy.writePixels(bitmap.pixmap()); + + return bitmapCopy; +} + QIcon toQIcon(const std::vector<SkBitmap> &bitmaps) { if (!bitmaps.size()) diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h index b9e210c22..afc3c3336 100644 --- a/src/core/type_conversion.h +++ b/src/core/type_conversion.h @@ -194,6 +194,8 @@ inline QImage toQImage(const SkBitmap &bitmap, QImage::Format format) QImage toQImage(const SkBitmap &bitmap); QImage toQImage(const gfx::ImageSkiaRep &imageSkiaRep); +SkBitmap toSkBitmap(const QImage &image); + QIcon toQIcon(const std::vector<SkBitmap> &bitmaps); inline QMatrix4x4 toQt(const SkMatrix44 &m) diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 62ed3c2fd..1361ebbed 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -428,6 +428,8 @@ WebEngineContext::WebEngineContext() appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kEnableSurfaceSynchronization.name); // The video-capture service is not functioning at this moment (since 69) appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kMojoVideoCapture.name); + // We do not yet support the internal video capture API. + appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kUseVideoCaptureApiForDevToolsSnapshots.name); if (useEmbeddedSwitches) { // embedded switches are based on the switches for Android, see content/browser/android/content_startup_flags.cc diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp index abdd4a8b3..1176573fd 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp @@ -376,4 +376,15 @@ void RenderWidgetHostViewQtDelegateQuick::onHide() m_client->forwardEvent(&event); } +bool RenderWidgetHostViewQtDelegateQuick::copySurface(const QRect &rect, const QSize &size, QImage &image) +{ + image = QQuickItem::window()->grabWindow(); + if (image.isNull()) + return false; + QRect subrect = !rect.isEmpty() ? rect : image.rect(); + image = image.copy(subrect); + image = image.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + return true; +} + } // namespace QtWebEngineCore diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h index 2d9dc991b..6f6cd1509 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.h +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h @@ -82,6 +82,7 @@ public: void setInputMethodHints(Qt::InputMethodHints) override { } // The QtQuick view doesn't have a backbuffer of its own and doesn't need this void setClearColor(const QColor &) override { } + bool copySurface(const QRect &rect, const QSize &size, QImage &image) override; protected: bool event(QEvent *event) override; diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h index df241bf3a..36e4ddd8a 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h +++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h @@ -78,6 +78,7 @@ public: void inputMethodStateChanged(bool, bool) override {} void setInputMethodHints(Qt::InputMethodHints) override { } void setClearColor(const QColor &) override { } + bool copySurface(const QRect &, const QSize &, QImage &) override { return false; } private: QScopedPointer<RenderWidgetHostViewQtDelegate> m_realDelegate; diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp index 7bbd85091..dd183585a 100644 --- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp +++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp @@ -411,6 +411,15 @@ void RenderWidgetHostViewQtDelegateWidget::hideEvent(QHideEvent *event) m_client->notifyHidden(); } +bool RenderWidgetHostViewQtDelegateWidget::copySurface(const QRect &rect, const QSize &size, QImage &image) +{ + QPixmap pixmap = rect.isEmpty() ? QQuickWidget::grab(QQuickWidget::rect()) : QQuickWidget::grab(rect); + if (pixmap.isNull()) + return false; + image = pixmap.toImage().scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + return true; +} + bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event) { bool handled = false; diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h index 74c9e3413..e78a9b119 100644 --- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h +++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h @@ -88,6 +88,7 @@ public: void inputMethodStateChanged(bool editorVisible, bool passwordInput) override; void setInputMethodHints(Qt::InputMethodHints) override; void setClearColor(const QColor &color) override; + bool copySurface(const QRect &, const QSize &, QImage &) override; protected: bool event(QEvent *event) override; |