fix: revive offscreen rendering support (#22160)

This commit is contained in:
Andy Dill 2020-02-27 11:00:07 -08:00 committed by GitHub
parent e28f7aadc7
commit 36f982aee2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 722 additions and 206 deletions

View file

@ -6,7 +6,6 @@
#include <utility>
#include "base/memory/shared_memory.h"
#include "components/viz/common/resources/resource_format.h"
#include "components/viz/common/resources/resource_sizes.h"
#include "mojo/public/cpp/system/platform_handle.h"
@ -23,9 +22,9 @@
namespace electron {
LayeredWindowUpdater::LayeredWindowUpdater(
viz::mojom::LayeredWindowUpdaterRequest request,
mojo::PendingReceiver<viz::mojom::LayeredWindowUpdater> receiver,
OnPaintCallback callback)
: callback_(callback), binding_(this, std::move(request)) {}
: callback_(callback), receiver_(this, std::move(receiver)) {}
LayeredWindowUpdater::~LayeredWindowUpdater() = default;
@ -96,10 +95,15 @@ void OffScreenHostDisplayClient::IsOffscreen(IsOffscreenCallback callback) {
}
void OffScreenHostDisplayClient::CreateLayeredWindowUpdater(
viz::mojom::LayeredWindowUpdaterRequest request) {
mojo::PendingReceiver<viz::mojom::LayeredWindowUpdater> receiver) {
layered_window_updater_ =
std::make_unique<LayeredWindowUpdater>(std::move(request), callback_);
std::make_unique<LayeredWindowUpdater>(std::move(receiver), callback_);
layered_window_updater_->SetActive(active_);
}
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
void OffScreenHostDisplayClient::DidCompleteSwapWithNewSize(
const gfx::Size& size) {}
#endif
} // namespace electron

View file

@ -21,8 +21,9 @@ typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
class LayeredWindowUpdater : public viz::mojom::LayeredWindowUpdater {
public:
explicit LayeredWindowUpdater(viz::mojom::LayeredWindowUpdaterRequest request,
OnPaintCallback callback);
explicit LayeredWindowUpdater(
mojo::PendingReceiver<viz::mojom::LayeredWindowUpdater> receiver,
OnPaintCallback callback);
~LayeredWindowUpdater() override;
void SetActive(bool active);
@ -34,7 +35,7 @@ class LayeredWindowUpdater : public viz::mojom::LayeredWindowUpdater {
private:
OnPaintCallback callback_;
mojo::Binding<viz::mojom::LayeredWindowUpdater> binding_;
mojo::Receiver<viz::mojom::LayeredWindowUpdater> receiver_;
std::unique_ptr<SkCanvas> canvas_;
bool active_ = false;
@ -62,7 +63,12 @@ class OffScreenHostDisplayClient : public viz::HostDisplayClient {
#endif
void CreateLayeredWindowUpdater(
viz::mojom::LayeredWindowUpdaterRequest request) override;
mojo::PendingReceiver<viz::mojom::LayeredWindowUpdater> receiver)
override;
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
void DidCompleteSwapWithNewSize(const gfx::Size& size) override;
#endif
std::unique_ptr<LayeredWindowUpdater> layered_window_updater_;
OnPaintCallback callback_;

View file

@ -17,6 +17,7 @@
#include "base/task/post_task.h"
#include "base/time/time.h"
#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
#include "components/viz/common/gl_helper.h"
@ -102,10 +103,10 @@ ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
}
ui::MouseEvent ui_event(type,
gfx::Point(std::floor(event.PositionInWidget().x),
std::floor(event.PositionInWidget().y)),
gfx::Point(std::floor(event.PositionInWidget().x),
std::floor(event.PositionInWidget().y)),
gfx::Point(std::floor(event.PositionInWidget().x()),
std::floor(event.PositionInWidget().y())),
gfx::Point(std::floor(event.PositionInWidget().x()),
std::floor(event.PositionInWidget().y())),
ui::EventTimeForNow(), button_flags, button_flags);
ui_event.SetClickCount(event.click_count);
@ -121,38 +122,6 @@ ui::MouseWheelEvent UiMouseWheelEventFromWebMouseEvent(
} // namespace
class ElectronBeginFrameTimer : public viz::DelayBasedTimeSourceClient {
public:
ElectronBeginFrameTimer(int frame_rate_threshold_us,
const base::Closure& callback)
: callback_(callback) {
time_source_ = std::make_unique<viz::DelayBasedTimeSource>(
base::CreateSingleThreadTaskRunner({content::BrowserThread::UI}).get());
time_source_->SetTimebaseAndInterval(
base::TimeTicks(),
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us));
time_source_->SetClient(this);
}
void SetActive(bool active) { time_source_->SetActive(active); }
bool IsActive() const { return time_source_->Active(); }
void SetFrameRateThresholdUs(int frame_rate_threshold_us) {
time_source_->SetTimebaseAndInterval(
base::TimeTicks::Now(),
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us));
}
private:
void OnTimerTick() override { callback_.Run(); }
const base::Closure callback_;
std::unique_ptr<viz::DelayBasedTimeSource> time_source_;
DISALLOW_COPY_AND_ASSIGN(ElectronBeginFrameTimer);
};
class ElectronDelegatedFrameHostClient
: public content::DelegatedFrameHostClient {
public:
@ -189,7 +158,6 @@ class ElectronDelegatedFrameHostClient
bool ShouldShowStaleContentOnEviction() override { return false; }
void OnBeginFrame(base::TimeTicks frame_time) override {}
void InvalidateLocalSurfaceIdOnEviction() override {}
private:
@ -220,7 +188,7 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
backing_(new SkBitmap),
weak_ptr_factory_(this) {
DCHECK(render_widget_host_);
bool is_guest_view_hack = parent_host_view_ != nullptr;
DCHECK(!render_widget_host_->GetView());
current_device_scale_factor_ = kDefaultScaleFactor;
@ -234,8 +202,7 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
delegated_frame_host_client_ =
std::make_unique<ElectronDelegatedFrameHostClient>(this);
delegated_frame_host_ = std::make_unique<content::DelegatedFrameHost>(
AllocateFrameSinkId(is_guest_view_hack),
delegated_frame_host_client_.get(),
AllocateFrameSinkId(), delegated_frame_host_client_.get(),
true /* should_register_frame_sink_id */);
root_layer_ = std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
@ -244,21 +211,17 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
GetRootLayer()->SetFillsBoundsOpaquely(opaque);
GetRootLayer()->SetColor(background_color_);
content::ImageTransportFactory* factory =
content::ImageTransportFactory::GetInstance();
ui::ContextFactoryPrivate* context_factory_private =
factory->GetContextFactoryPrivate();
content::GetContextFactoryPrivate();
compositor_ = std::make_unique<ui::Compositor>(
context_factory_private->AllocateFrameSinkId(),
content::GetContextFactory(), context_factory_private,
base::ThreadTaskRunnerHandle::Get(), false /* enable_pixel_canvas */,
false /* use_external_begin_frame_control */);
compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
compositor_->SetDelegate(this);
compositor_->SetRootLayer(root_layer_.get());
GetCompositor()->SetDelegate(this);
ResizeRootLayer(false);
render_widget_host_->SetView(this);
InstallTransparency();
@ -292,36 +255,6 @@ OffScreenRenderWidgetHostView::CreateBrowserAccessibilityManager(
return nullptr;
}
void OffScreenRenderWidgetHostView::OnBeginFrameTimerTick() {
const base::TimeTicks frame_time = base::TimeTicks::Now();
const base::TimeDelta vsync_period =
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_);
SendBeginFrame(frame_time, vsync_period);
}
void OffScreenRenderWidgetHostView::SendBeginFrame(
base::TimeTicks frame_time,
base::TimeDelta vsync_period) {
base::TimeTicks display_time = frame_time + vsync_period;
base::TimeDelta estimated_browser_composite_time =
base::TimeDelta::FromMicroseconds(
(1.0f * base::Time::kMicrosecondsPerSecond) / (3.0f * 60));
base::TimeTicks deadline = display_time - estimated_browser_composite_time;
const viz::BeginFrameArgs& begin_frame_args = viz::BeginFrameArgs::Create(
BEGINFRAME_FROM_HERE, begin_frame_source_.source_id(),
begin_frame_number_, frame_time, deadline, vsync_period,
viz::BeginFrameArgs::NORMAL);
DCHECK(begin_frame_args.IsValid());
begin_frame_number_++;
compositor_->context_factory_private()->IssueExternalBeginFrame(
compositor_.get(), begin_frame_args, /* force */ true,
base::NullCallback());
}
void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
DCHECK(parent_host_view_);
@ -450,8 +383,6 @@ void OffScreenRenderWidgetHostView::TakeFallbackContentFrom(
content::RenderWidgetHostView* view) {
DCHECK(!static_cast<content::RenderWidgetHostViewBase*>(view)
->IsRenderWidgetHostViewChildFrame());
DCHECK(!static_cast<content::RenderWidgetHostViewBase*>(view)
->IsRenderWidgetHostViewGuest());
OffScreenRenderWidgetHostView* view_osr =
static_cast<OffScreenRenderWidgetHostView*>(view);
SetBackgroundColor(view_osr->background_color_);
@ -462,23 +393,6 @@ void OffScreenRenderWidgetHostView::TakeFallbackContentFrom(
host()->GetContentRenderingTimeoutFrom(view_osr->host());
}
void OffScreenRenderWidgetHostView::DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) {
renderer_compositor_frame_sink_ = renderer_compositor_frame_sink;
if (GetDelegatedFrameHost()) {
GetDelegatedFrameHost()->DidCreateNewRendererCompositorFrameSink(
renderer_compositor_frame_sink_);
}
}
void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
viz::CompositorFrame frame,
base::Optional<viz::HitTestRegionList> hit_test_region_list) {
NOTREACHED();
}
void OffScreenRenderWidgetHostView::ResetFallbackToFirstNavigationSurface() {
GetDelegatedFrameHost()->ResetFallbackToFirstNavigationSurface();
}
@ -582,13 +496,6 @@ void OffScreenRenderWidgetHostView::GetScreenInfo(
screen_info->available_rect = gfx::Rect(size_);
}
void OffScreenRenderWidgetHostView::InitAsGuest(
content::RenderWidgetHostView* parent_host_view,
content::RenderWidgetHostViewGuest* guest_view) {
parent_host_view_->AddGuestHostView(this);
SetPainting(parent_host_view_->IsPainting());
}
void OffScreenRenderWidgetHostView::TransformPointToRootSurface(
gfx::PointF* point) {}
@ -730,14 +637,6 @@ bool OffScreenRenderWidgetHostView::InstallTransparency() {
return false;
}
void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
bool needs_begin_frames) {
SetupFrameRate(true);
begin_frame_timer_->SetActive(needs_begin_frames);
}
void OffScreenRenderWidgetHostView::SetWantsAnimateOnlyBeginFrames() {}
#if defined(OS_MACOSX)
void OffScreenRenderWidgetHostView::SetActive(bool active) {}
@ -862,12 +761,12 @@ void OffScreenRenderWidgetHostView::SendMouseEvent(
const blink::WebMouseEvent& event) {
for (auto* proxy_view : proxy_views_) {
gfx::Rect bounds = proxy_view->GetBounds();
if (bounds.Contains(event.PositionInWidget().x,
event.PositionInWidget().y)) {
if (bounds.Contains(event.PositionInWidget().x(),
event.PositionInWidget().y())) {
blink::WebMouseEvent proxy_event(event);
proxy_event.SetPositionInWidget(
proxy_event.PositionInWidget().x - bounds.x(),
proxy_event.PositionInWidget().y - bounds.y());
proxy_event.PositionInWidget().x() - bounds.x(),
proxy_event.PositionInWidget().y() - bounds.y());
ui::MouseEvent ui_event = UiMouseEventFromWebMouseEvent(proxy_event);
proxy_view->OnEvent(&ui_event);
@ -878,12 +777,12 @@ void OffScreenRenderWidgetHostView::SendMouseEvent(
if (!IsPopupWidget()) {
if (popup_host_view_ &&
popup_host_view_->popup_position_.Contains(
event.PositionInWidget().x, event.PositionInWidget().y)) {
event.PositionInWidget().x(), event.PositionInWidget().y())) {
blink::WebMouseEvent popup_event(event);
popup_event.SetPositionInWidget(
popup_event.PositionInWidget().x -
popup_event.PositionInWidget().x() -
popup_host_view_->popup_position_.x(),
popup_event.PositionInWidget().y -
popup_event.PositionInWidget().y() -
popup_host_view_->popup_position_.y());
popup_host_view_->ProcessMouseEvent(popup_event, ui::LatencyInfo());
@ -900,12 +799,12 @@ void OffScreenRenderWidgetHostView::SendMouseWheelEvent(
const blink::WebMouseWheelEvent& event) {
for (auto* proxy_view : proxy_views_) {
gfx::Rect bounds = proxy_view->GetBounds();
if (bounds.Contains(event.PositionInWidget().x,
event.PositionInWidget().y)) {
if (bounds.Contains(event.PositionInWidget().x(),
event.PositionInWidget().y())) {
blink::WebMouseWheelEvent proxy_event(event);
proxy_event.SetPositionInWidget(
proxy_event.PositionInWidget().x - bounds.x(),
proxy_event.PositionInWidget().y - bounds.y());
proxy_event.PositionInWidget().x() - bounds.x(),
proxy_event.PositionInWidget().y() - bounds.y());
ui::MouseWheelEvent ui_event =
UiMouseWheelEventFromWebMouseEvent(proxy_event);
@ -927,17 +826,17 @@ void OffScreenRenderWidgetHostView::SendMouseWheelEvent(
if (!IsPopupWidget()) {
if (popup_host_view_) {
if (popup_host_view_->popup_position_.Contains(
mouse_wheel_event.PositionInWidget().x,
mouse_wheel_event.PositionInWidget().y)) {
mouse_wheel_event.PositionInWidget().x(),
mouse_wheel_event.PositionInWidget().y())) {
blink::WebMouseWheelEvent popup_mouse_wheel_event(mouse_wheel_event);
popup_mouse_wheel_event.SetPositionInWidget(
mouse_wheel_event.PositionInWidget().x -
mouse_wheel_event.PositionInWidget().x() -
popup_host_view_->popup_position_.x(),
mouse_wheel_event.PositionInWidget().y -
mouse_wheel_event.PositionInWidget().y() -
popup_host_view_->popup_position_.y());
popup_mouse_wheel_event.SetPositionInScreen(
popup_mouse_wheel_event.PositionInWidget().x,
popup_mouse_wheel_event.PositionInWidget().y);
popup_mouse_wheel_event.PositionInWidget().x(),
popup_mouse_wheel_event.PositionInWidget().y());
popup_host_view_->SendMouseWheelEvent(popup_mouse_wheel_event);
return;
@ -958,15 +857,15 @@ void OffScreenRenderWidgetHostView::SendMouseWheelEvent(
}
const gfx::Rect& guest_bounds =
guest_host_view->render_widget_host_->GetView()->GetViewBounds();
if (guest_bounds.Contains(mouse_wheel_event.PositionInWidget().x,
mouse_wheel_event.PositionInWidget().y)) {
if (guest_bounds.Contains(mouse_wheel_event.PositionInWidget().x(),
mouse_wheel_event.PositionInWidget().y())) {
blink::WebMouseWheelEvent guest_mouse_wheel_event(mouse_wheel_event);
guest_mouse_wheel_event.SetPositionInWidget(
mouse_wheel_event.PositionInWidget().x - guest_bounds.x(),
mouse_wheel_event.PositionInWidget().y - guest_bounds.y());
mouse_wheel_event.PositionInWidget().x() - guest_bounds.x(),
mouse_wheel_event.PositionInWidget().y() - guest_bounds.y());
guest_mouse_wheel_event.SetPositionInScreen(
guest_mouse_wheel_event.PositionInWidget().x,
guest_mouse_wheel_event.PositionInWidget().y);
guest_mouse_wheel_event.PositionInWidget().x(),
guest_mouse_wheel_event.PositionInWidget().y());
guest_host_view->SendMouseWheelEvent(guest_mouse_wheel_event);
return;
@ -1053,14 +952,10 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
frame_rate_threshold_us_ = 1000000 / frame_rate_;
if (begin_frame_timer_.get()) {
begin_frame_timer_->SetFrameRateThresholdUs(frame_rate_threshold_us_);
} else {
begin_frame_timer_ = std::make_unique<ElectronBeginFrameTimer>(
frame_rate_threshold_us_,
base::BindRepeating(
&OffScreenRenderWidgetHostView::OnBeginFrameTimerTick,
weak_ptr_factory_.GetWeakPtr()));
if (compositor_) {
compositor_->SetDisplayVSyncParameters(
base::TimeTicks::Now(),
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_));
}
}
@ -1098,18 +993,18 @@ void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
const gfx::Size& size_in_pixels =
gfx::ConvertSizeToPixel(current_device_scale_factor_, size);
compositor_allocator_.GenerateId();
compositor_allocation_ =
compositor_allocator_.GetCurrentLocalSurfaceIdAllocation();
GetCompositor()->SetScaleAndSize(current_device_scale_factor_, size_in_pixels,
compositor_allocation_);
if (compositor_) {
compositor_allocator_.GenerateId();
compositor_allocation_ =
compositor_allocator_.GetCurrentLocalSurfaceIdAllocation();
compositor_->SetScaleAndSize(current_device_scale_factor_, size_in_pixels,
compositor_allocation_);
}
delegated_frame_host_allocator_.GenerateId();
delegated_frame_host_allocation_ =
delegated_frame_host_allocator_.GetCurrentLocalSurfaceIdAllocation();
bool resized = true;
GetDelegatedFrameHost()->EmbedSurface(
delegated_frame_host_allocation_.local_surface_id(), size,
cc::DeadlinePolicy::UseDefaultDeadline());
@ -1117,25 +1012,15 @@ void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
// Note that |render_widget_host_| will retrieve resize parameters from the
// DelegatedFrameHost, so it must have SynchronizeVisualProperties called
// after.
if (resized && render_widget_host_) {
if (render_widget_host_) {
render_widget_host_->SynchronizeVisualProperties();
}
}
viz::FrameSinkId OffScreenRenderWidgetHostView::AllocateFrameSinkId(
bool is_guest_view_hack) {
// GuestViews have two RenderWidgetHostViews and so we need to make sure
// we don't have FrameSinkId collisions.
// The FrameSinkId generated here must be unique with FrameSinkId allocated
// in ContextFactoryPrivate.
content::ImageTransportFactory* factory =
content::ImageTransportFactory::GetInstance();
return is_guest_view_hack
? factory->GetContextFactoryPrivate()->AllocateFrameSinkId()
: viz::FrameSinkId(base::checked_cast<uint32_t>(
render_widget_host_->GetProcess()->GetID()),
base::checked_cast<uint32_t>(
render_widget_host_->GetRoutingID()));
viz::FrameSinkId OffScreenRenderWidgetHostView::AllocateFrameSinkId() {
return viz::FrameSinkId(
base::checked_cast<uint32_t>(render_widget_host_->GetProcess()->GetID()),
base::checked_cast<uint32_t>(render_widget_host_->GetRoutingID()));
}
void OffScreenRenderWidgetHostView::UpdateBackgroundColorFromRenderer(

View file

@ -17,11 +17,8 @@
#include "base/process/kill.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "content/browser/frame_host/render_widget_host_view_guest.h" // nogncheck
#include "content/browser/renderer_host/delegated_frame_host.h" // nogncheck
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h" // nogncheck
#include "content/browser/renderer_host/render_widget_host_impl.h" // nogncheck
@ -99,8 +96,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
bool LockMouse(bool request_unadjusted_movement) override;
void UnlockMouse(void) override;
void TakeFallbackContentFrom(content::RenderWidgetHostView* view) override;
void SetNeedsBeginFrames(bool needs_begin_frames) override;
void SetWantsAnimateOnlyBeginFrames() override;
#if defined(OS_MACOSX)
void SetActive(bool active) override;
void ShowDefinitionForSelection() override;
@ -109,13 +104,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
#endif // defined(OS_MACOSX)
// content::RenderWidgetHostViewBase:
void DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink)
override;
void SubmitCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
viz::CompositorFrame frame,
base::Optional<viz::HitTestRegionList> hit_test_region_list) override;
void ResetFallbackToFirstNavigationSurface() override;
void InitAsPopup(content::RenderWidgetHostView* rwhv,
@ -134,8 +122,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
const gfx::Size& output_size,
base::OnceCallback<void(const SkBitmap&)> callback) override;
void GetScreenInfo(content::ScreenInfo* results) override;
void InitAsGuest(content::RenderWidgetHostView*,
content::RenderWidgetHostViewGuest*) override;
void TransformPointToRootSurface(gfx::PointF* point) override;
gfx::Rect GetBoundsInRootWindow(void) override;
viz::SurfaceId GetCurrentSurfaceId() const override;
@ -167,9 +153,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
bool InstallTransparency();
void OnBeginFrameTimerTick();
void SendBeginFrame(base::TimeTicks frame_time, base::TimeDelta vsync_period);
void CancelWidget();
void AddGuestHostView(OffScreenRenderWidgetHostView* guest_host);
void RemoveGuestHostView(OffScreenRenderWidgetHostView* guest_host);
@ -230,7 +213,7 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
void SetupFrameRate(bool force);
void ResizeRootLayer(bool force);
viz::FrameSinkId AllocateFrameSinkId(bool is_guest_view_hack);
viz::FrameSinkId AllocateFrameSinkId();
// Applies background color without notifying the RenderWidget about
// opaqueness changes.
@ -279,22 +262,14 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
std::unique_ptr<content::CursorManager> cursor_manager_;
std::unique_ptr<ElectronBeginFrameTimer> begin_frame_timer_;
OffScreenHostDisplayClient* host_display_client_;
std::unique_ptr<OffScreenVideoConsumer> video_consumer_;
// Provides |source_id| for BeginFrameArgs that we create.
viz::StubBeginFrameSource begin_frame_source_;
uint64_t begin_frame_number_ = viz::BeginFrameArgs::kStartingFrameNumber;
std::unique_ptr<ElectronDelegatedFrameHostClient>
delegated_frame_host_client_;
content::MouseWheelPhaseHandler mouse_wheel_phase_handler_;
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink_ =
nullptr;
// Latest capture sequence number which is incremented when the caller
// requests surfaces be synchronized via
// EnsureSurfaceSynchronizedForWebTest().

View file

@ -54,7 +54,8 @@ void OffScreenVideoConsumer::OnFrameCaptured(
base::ReadOnlySharedMemoryRegion data,
::media::mojom::VideoFrameInfoPtr info,
const gfx::Rect& content_rect,
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) {
mojo::PendingRemote<viz::mojom::FrameSinkVideoConsumerFrameCallbacks>
callbacks) {
if (!CheckContentRect(content_rect)) {
gfx::Size view_size = view_->SizeInPixels();
video_capturer_->SetResolutionConstraints(view_size, view_size, true);
@ -62,18 +63,23 @@ void OffScreenVideoConsumer::OnFrameCaptured(
return;
}
mojo::Remote<viz::mojom::FrameSinkVideoConsumerFrameCallbacks>
callbacks_remote(std::move(callbacks));
if (!data.IsValid()) {
callbacks->Done();
callbacks_remote->Done();
return;
}
base::ReadOnlySharedMemoryMapping mapping = data.Map();
if (!mapping.IsValid()) {
DLOG(ERROR) << "Shared memory mapping failed.";
callbacks_remote->Done();
return;
}
if (mapping.size() <
media::VideoFrame::AllocationSize(info->pixel_format, info->coded_size)) {
DLOG(ERROR) << "Shared memory size was less than expected.";
callbacks_remote->Done();
return;
}
@ -89,7 +95,8 @@ void OffScreenVideoConsumer::OnFrameCaptured(
base::ReadOnlySharedMemoryMapping mapping;
// Prevents FrameSinkVideoCapturer from recycling the shared memory that
// backs |frame_|.
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr releaser;
mojo::PendingRemote<viz::mojom::FrameSinkVideoConsumerFrameCallbacks>
releaser;
};
SkBitmap bitmap;
@ -102,7 +109,7 @@ void OffScreenVideoConsumer::OnFrameCaptured(
[](void* addr, void* context) {
delete static_cast<FramePinner*>(context);
},
new FramePinner{std::move(mapping), std::move(callbacks)});
new FramePinner{std::move(mapping), callbacks_remote.Unbind()});
bitmap.setImmutable();
media::VideoFrameMetadata metadata;
@ -110,7 +117,7 @@ void OffScreenVideoConsumer::OnFrameCaptured(
gfx::Rect damage_rect;
auto UPDATE_RECT = media::VideoFrameMetadata::CAPTURE_UPDATE_RECT;
if (!metadata.GetRect(UPDATE_RECT, &damage_rect)) {
if (!metadata.GetRect(UPDATE_RECT, &damage_rect) || damage_rect.IsEmpty()) {
damage_rect = content_rect;
}

View file

@ -10,6 +10,7 @@
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "components/viz/host/client_frame_sink_video_capturer.h"
#include "media/capture/mojom/video_capture_types.mojom.h"
namespace electron {
@ -34,7 +35,8 @@ class OffScreenVideoConsumer : public viz::mojom::FrameSinkVideoConsumer {
base::ReadOnlySharedMemoryRegion data,
::media::mojom::VideoFrameInfoPtr info,
const gfx::Rect& content_rect,
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) override;
mojo::PendingRemote<viz::mojom::FrameSinkVideoConsumerFrameCallbacks>
callbacks) override;
void OnStopped() override;
bool CheckContentRect(const gfx::Rect& content_rect);