mirror of
https://github.com/electron/electron.git
synced 2026-01-09 15:38:08 -05:00
feat: offscreen rendering support rgbaf16 hdr output format. (#48265)
* feat: offscreen rendering support rgbaf16 * docs: update doc * docs: update doc.
This commit is contained in:
@@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
* `textureInfo` Object - The shared texture info.
|
* `textureInfo` Object - The shared texture info.
|
||||||
* `widgetType` string - The widget type of the texture. Can be `popup` or `frame`.
|
* `widgetType` string - The widget type of the texture. Can be `popup` or `frame`.
|
||||||
* `pixelFormat` string - The pixel format of the texture. Can be `rgba` or `bgra`.
|
* `pixelFormat` string - The pixel format of the texture.
|
||||||
|
* `rgba` - The texture format is 8-bit unorm RGBA.
|
||||||
|
* `bgra` - The texture format is 8-bit unorm BGRA.
|
||||||
|
* `rgbaf16` - The texture format is 16-bit float RGBA.
|
||||||
* `codedSize` [Size](size.md) - The full dimensions of the video frame.
|
* `codedSize` [Size](size.md) - The full dimensions of the video frame.
|
||||||
* `colorSpace` [ColorSpace](color-space.md) - The color space of the video frame.
|
* `colorSpace` [ColorSpace](color-space.md) - The color space of the video frame.
|
||||||
* `visibleRect` [Rectangle](rectangle.md) - A subsection of [0, 0, codedSize.width, codedSize.height]. In OSR case, it is expected to have the full section area.
|
* `visibleRect` [Rectangle](rectangle.md) - A subsection of [0, 0, codedSize.width, codedSize.height]. In OSR case, it is expected to have the full section area.
|
||||||
|
|||||||
@@ -87,6 +87,11 @@
|
|||||||
paint event. Defaults to `false`. See the
|
paint event. Defaults to `false`. See the
|
||||||
[offscreen rendering tutorial](../../tutorial/offscreen-rendering.md) for
|
[offscreen rendering tutorial](../../tutorial/offscreen-rendering.md) for
|
||||||
more details.
|
more details.
|
||||||
|
* `sharedTexturePixelFormat` string (optional) _Experimental_ - The requested output format of the shared texture. Defaults to `argb`.
|
||||||
|
The name is originated from Chromium [`media::VideoPixelFormat`](https://source.chromium.org/chromium/chromium/src/+/main:media/base/video_types.h) enum suffix and only subset of them are supported.
|
||||||
|
The actual output pixel format and color space of the texture should refer to [`OffscreenSharedTexture`](../structures/offscreen-shared-texture.md) object in the `paint` event.
|
||||||
|
* `argb` - The requested output texture format is 8-bit unorm RGBA, with SRGB SDR color space.
|
||||||
|
* `rgbaf16` - The requested output texture format is 16-bit float RGBA, with scRGB HDR color space.
|
||||||
* `contextIsolation` boolean (optional) - Whether to run Electron APIs and
|
* `contextIsolation` boolean (optional) - Whether to run Electron APIs and
|
||||||
the specified `preload` script in a separate JavaScript context. Defaults
|
the specified `preload` script in a separate JavaScript context. Defaults
|
||||||
to `true`. The context that the `preload` script runs in will only have
|
to `true`. The context that the `preload` script runs in will only have
|
||||||
|
|||||||
@@ -814,6 +814,8 @@ WebContents::WebContents(v8::Isolate* isolate,
|
|||||||
options.Get(options::kOffscreen, &use_offscreen_dict);
|
options.Get(options::kOffscreen, &use_offscreen_dict);
|
||||||
use_offscreen_dict.Get(options::kUseSharedTexture,
|
use_offscreen_dict.Get(options::kUseSharedTexture,
|
||||||
&offscreen_use_shared_texture_);
|
&offscreen_use_shared_texture_);
|
||||||
|
use_offscreen_dict.Get(options::kSharedTexturePixelFormat,
|
||||||
|
&offscreen_shared_texture_pixel_format_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -851,6 +853,7 @@ WebContents::WebContents(v8::Isolate* isolate,
|
|||||||
if (embedder_ && embedder_->IsOffScreen()) {
|
if (embedder_ && embedder_->IsOffScreen()) {
|
||||||
auto* view = new OffScreenWebContentsView(
|
auto* view = new OffScreenWebContentsView(
|
||||||
false, offscreen_use_shared_texture_,
|
false, offscreen_use_shared_texture_,
|
||||||
|
offscreen_shared_texture_pixel_format_,
|
||||||
base::BindRepeating(&WebContents::OnPaint, base::Unretained(this)));
|
base::BindRepeating(&WebContents::OnPaint, base::Unretained(this)));
|
||||||
params.view = view;
|
params.view = view;
|
||||||
params.delegate_view = view;
|
params.delegate_view = view;
|
||||||
@@ -872,6 +875,7 @@ WebContents::WebContents(v8::Isolate* isolate,
|
|||||||
content::WebContents::CreateParams params(session->browser_context());
|
content::WebContents::CreateParams params(session->browser_context());
|
||||||
auto* view = new OffScreenWebContentsView(
|
auto* view = new OffScreenWebContentsView(
|
||||||
transparent, offscreen_use_shared_texture_,
|
transparent, offscreen_use_shared_texture_,
|
||||||
|
offscreen_shared_texture_pixel_format_,
|
||||||
base::BindRepeating(&WebContents::OnPaint, base::Unretained(this)));
|
base::BindRepeating(&WebContents::OnPaint, base::Unretained(this)));
|
||||||
params.view = view;
|
params.view = view;
|
||||||
params.delegate_view = view;
|
params.delegate_view = view;
|
||||||
@@ -1229,6 +1233,7 @@ void WebContents::MaybeOverrideCreateParamsForNewWindow(
|
|||||||
if (is_offscreen) {
|
if (is_offscreen) {
|
||||||
auto* view = new OffScreenWebContentsView(
|
auto* view = new OffScreenWebContentsView(
|
||||||
false, offscreen_use_shared_texture_,
|
false, offscreen_use_shared_texture_,
|
||||||
|
offscreen_shared_texture_pixel_format_,
|
||||||
base::BindRepeating(&WebContents::OnPaint, base::Unretained(this)));
|
base::BindRepeating(&WebContents::OnPaint, base::Unretained(this)));
|
||||||
create_params->view = view;
|
create_params->view = view;
|
||||||
create_params->delegate_view = view;
|
create_params->delegate_view = view;
|
||||||
|
|||||||
@@ -817,6 +817,7 @@ class WebContents final : public ExclusiveAccessContext,
|
|||||||
|
|
||||||
// Whether offscreen rendering use gpu shared texture
|
// Whether offscreen rendering use gpu shared texture
|
||||||
bool offscreen_use_shared_texture_ = false;
|
bool offscreen_use_shared_texture_ = false;
|
||||||
|
std::string offscreen_shared_texture_pixel_format_ = "argb";
|
||||||
|
|
||||||
// Whether window is fullscreened by HTML5 api.
|
// Whether window is fullscreened by HTML5 api.
|
||||||
bool html_fullscreen_ = false;
|
bool html_fullscreen_ = false;
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ class ElectronDelegatedFrameHostClient
|
|||||||
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||||
bool transparent,
|
bool transparent,
|
||||||
bool offscreen_use_shared_texture,
|
bool offscreen_use_shared_texture,
|
||||||
|
const std::string& offscreen_shared_texture_pixel_format,
|
||||||
bool painting,
|
bool painting,
|
||||||
int frame_rate,
|
int frame_rate,
|
||||||
const OnPaintCallback& callback,
|
const OnPaintCallback& callback,
|
||||||
@@ -165,6 +166,8 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
|||||||
parent_host_view_(parent_host_view),
|
parent_host_view_(parent_host_view),
|
||||||
transparent_(transparent),
|
transparent_(transparent),
|
||||||
offscreen_use_shared_texture_(offscreen_use_shared_texture),
|
offscreen_use_shared_texture_(offscreen_use_shared_texture),
|
||||||
|
offscreen_shared_texture_pixel_format_(
|
||||||
|
offscreen_shared_texture_pixel_format),
|
||||||
callback_(callback),
|
callback_(callback),
|
||||||
frame_rate_(frame_rate),
|
frame_rate_(frame_rate),
|
||||||
size_(initial_size),
|
size_(initial_size),
|
||||||
@@ -548,7 +551,8 @@ OffScreenRenderWidgetHostView::CreateViewForWidget(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new OffScreenRenderWidgetHostView(
|
return new OffScreenRenderWidgetHostView(
|
||||||
transparent_, offscreen_use_shared_texture_, true,
|
transparent_, offscreen_use_shared_texture_,
|
||||||
|
offscreen_shared_texture_pixel_format_, true,
|
||||||
embedder_host_view->frame_rate(), callback_, render_widget_host,
|
embedder_host_view->frame_rate(), callback_, render_widget_host,
|
||||||
embedder_host_view, size());
|
embedder_host_view, size());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,8 +69,10 @@ class OffScreenRenderWidgetHostView
|
|||||||
public ui::CompositorDelegate,
|
public ui::CompositorDelegate,
|
||||||
private OffscreenViewProxyObserver {
|
private OffscreenViewProxyObserver {
|
||||||
public:
|
public:
|
||||||
OffScreenRenderWidgetHostView(bool transparent,
|
OffScreenRenderWidgetHostView(
|
||||||
|
bool transparent,
|
||||||
bool offscreen_use_shared_texture,
|
bool offscreen_use_shared_texture,
|
||||||
|
const std::string& offscreen_shared_texture_pixel_format,
|
||||||
bool painting,
|
bool painting,
|
||||||
int frame_rate,
|
int frame_rate,
|
||||||
const OnPaintCallback& callback,
|
const OnPaintCallback& callback,
|
||||||
@@ -238,6 +240,10 @@ class OffScreenRenderWidgetHostView
|
|||||||
return offscreen_use_shared_texture_;
|
return offscreen_use_shared_texture_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string offscreen_shared_texture_pixel_format() const {
|
||||||
|
return offscreen_shared_texture_pixel_format_;
|
||||||
|
}
|
||||||
|
|
||||||
ui::Layer* root_layer() const { return root_layer_.get(); }
|
ui::Layer* root_layer() const { return root_layer_.get(); }
|
||||||
|
|
||||||
content::DelegatedFrameHost* delegated_frame_host() const {
|
content::DelegatedFrameHost* delegated_frame_host() const {
|
||||||
@@ -283,6 +289,7 @@ class OffScreenRenderWidgetHostView
|
|||||||
|
|
||||||
const bool transparent_;
|
const bool transparent_;
|
||||||
const bool offscreen_use_shared_texture_;
|
const bool offscreen_use_shared_texture_;
|
||||||
|
const std::string offscreen_shared_texture_pixel_format_;
|
||||||
OnPaintCallback callback_;
|
OnPaintCallback callback_;
|
||||||
OnPopupPaintCallback parent_callback_;
|
OnPopupPaintCallback parent_callback_;
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,22 @@
|
|||||||
#include "third_party/skia/include/core/SkRegion.h"
|
#include "third_party/skia/include/core/SkRegion.h"
|
||||||
#include "ui/gfx/skbitmap_operations.h"
|
#include "ui/gfx/skbitmap_operations.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
media::VideoPixelFormat GetTargetPixelFormatFromOption(
|
||||||
|
const std::string& pixel_format_option) {
|
||||||
|
if (pixel_format_option == "argb") {
|
||||||
|
return media::PIXEL_FORMAT_ARGB;
|
||||||
|
} else if (pixel_format_option == "rgbaf16") {
|
||||||
|
return media::PIXEL_FORMAT_RGBAF16;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use ARGB as default.
|
||||||
|
return media::PIXEL_FORMAT_ARGB;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace electron {
|
namespace electron {
|
||||||
|
|
||||||
OffScreenVideoConsumer::OffScreenVideoConsumer(
|
OffScreenVideoConsumer::OffScreenVideoConsumer(
|
||||||
@@ -26,7 +42,10 @@ OffScreenVideoConsumer::OffScreenVideoConsumer(
|
|||||||
video_capturer_(view->CreateVideoCapturer()) {
|
video_capturer_(view->CreateVideoCapturer()) {
|
||||||
video_capturer_->SetAutoThrottlingEnabled(false);
|
video_capturer_->SetAutoThrottlingEnabled(false);
|
||||||
video_capturer_->SetMinSizeChangePeriod(base::TimeDelta());
|
video_capturer_->SetMinSizeChangePeriod(base::TimeDelta());
|
||||||
video_capturer_->SetFormat(media::PIXEL_FORMAT_ARGB);
|
|
||||||
|
auto format = GetTargetPixelFormatFromOption(
|
||||||
|
view->offscreen_shared_texture_pixel_format());
|
||||||
|
video_capturer_->SetFormat(format);
|
||||||
|
|
||||||
// https://crrev.org/c/6438681
|
// https://crrev.org/c/6438681
|
||||||
// Disable capturer's animation lock-in feature for offscreen capture to
|
// Disable capturer's animation lock-in feature for offscreen capture to
|
||||||
|
|||||||
@@ -16,9 +16,12 @@ namespace electron {
|
|||||||
OffScreenWebContentsView::OffScreenWebContentsView(
|
OffScreenWebContentsView::OffScreenWebContentsView(
|
||||||
bool transparent,
|
bool transparent,
|
||||||
bool offscreen_use_shared_texture,
|
bool offscreen_use_shared_texture,
|
||||||
|
const std::string& offscreen_shared_texture_pixel_format,
|
||||||
const OnPaintCallback& callback)
|
const OnPaintCallback& callback)
|
||||||
: transparent_(transparent),
|
: transparent_(transparent),
|
||||||
offscreen_use_shared_texture_(offscreen_use_shared_texture),
|
offscreen_use_shared_texture_(offscreen_use_shared_texture),
|
||||||
|
offscreen_shared_texture_pixel_format_(
|
||||||
|
offscreen_shared_texture_pixel_format),
|
||||||
callback_(callback) {
|
callback_(callback) {
|
||||||
#if BUILDFLAG(IS_MAC)
|
#if BUILDFLAG(IS_MAC)
|
||||||
PlatformCreate();
|
PlatformCreate();
|
||||||
@@ -112,7 +115,8 @@ OffScreenWebContentsView::CreateViewForWidget(
|
|||||||
return static_cast<content::RenderWidgetHostViewBase*>(rwhv);
|
return static_cast<content::RenderWidgetHostViewBase*>(rwhv);
|
||||||
|
|
||||||
return new OffScreenRenderWidgetHostView(
|
return new OffScreenRenderWidgetHostView(
|
||||||
transparent_, offscreen_use_shared_texture_, painting_, GetFrameRate(),
|
transparent_, offscreen_use_shared_texture_,
|
||||||
|
offscreen_shared_texture_pixel_format_, painting_, GetFrameRate(),
|
||||||
callback_, render_widget_host, nullptr, GetSize());
|
callback_, render_widget_host, nullptr, GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +136,8 @@ OffScreenWebContentsView::CreateViewForChildWidget(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new OffScreenRenderWidgetHostView(
|
return new OffScreenRenderWidgetHostView(
|
||||||
transparent_, offscreen_use_shared_texture_, painting_,
|
transparent_, offscreen_use_shared_texture_,
|
||||||
|
offscreen_shared_texture_pixel_format_, painting_,
|
||||||
embedder_host_view->frame_rate(), callback_, render_widget_host,
|
embedder_host_view->frame_rate(), callback_, render_widget_host,
|
||||||
embedder_host_view, GetSize());
|
embedder_host_view, GetSize());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,8 +34,10 @@ class OffScreenWebContentsView : public content::WebContentsView,
|
|||||||
public content::RenderViewHostDelegateView,
|
public content::RenderViewHostDelegateView,
|
||||||
private NativeWindowObserver {
|
private NativeWindowObserver {
|
||||||
public:
|
public:
|
||||||
OffScreenWebContentsView(bool transparent,
|
OffScreenWebContentsView(
|
||||||
|
bool transparent,
|
||||||
bool offscreen_use_shared_texture,
|
bool offscreen_use_shared_texture,
|
||||||
|
const std::string& offscreen_shared_texture_pixel_format,
|
||||||
const OnPaintCallback& callback);
|
const OnPaintCallback& callback);
|
||||||
~OffScreenWebContentsView() override;
|
~OffScreenWebContentsView() override;
|
||||||
|
|
||||||
@@ -109,6 +111,7 @@ class OffScreenWebContentsView : public content::WebContentsView,
|
|||||||
|
|
||||||
const bool transparent_;
|
const bool transparent_;
|
||||||
const bool offscreen_use_shared_texture_;
|
const bool offscreen_use_shared_texture_;
|
||||||
|
const std::string offscreen_shared_texture_pixel_format_;
|
||||||
bool painting_ = true;
|
bool painting_ = true;
|
||||||
int frame_rate_ = 60;
|
int frame_rate_ = 60;
|
||||||
OnPaintCallback callback_;
|
OnPaintCallback callback_;
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ std::string OsrVideoPixelFormatToString(media::VideoPixelFormat format) {
|
|||||||
return "bgra";
|
return "bgra";
|
||||||
case media::PIXEL_FORMAT_ABGR:
|
case media::PIXEL_FORMAT_ABGR:
|
||||||
return "rgba";
|
return "rgba";
|
||||||
|
case media::PIXEL_FORMAT_RGBAF16:
|
||||||
|
return "rgbaf16";
|
||||||
default:
|
default:
|
||||||
NOTREACHED();
|
NOTREACHED();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,6 +183,9 @@ inline constexpr std::string_view kOffscreen = "offscreen";
|
|||||||
|
|
||||||
inline constexpr std::string_view kUseSharedTexture = "useSharedTexture";
|
inline constexpr std::string_view kUseSharedTexture = "useSharedTexture";
|
||||||
|
|
||||||
|
inline constexpr std::string_view kSharedTexturePixelFormat =
|
||||||
|
"sharedTexturePixelFormat";
|
||||||
|
|
||||||
inline constexpr std::string_view kNodeIntegrationInSubFrames =
|
inline constexpr std::string_view kNodeIntegrationInSubFrames =
|
||||||
"nodeIntegrationInSubFrames";
|
"nodeIntegrationInSubFrames";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user