fixes offscreen rendering on macos

This commit is contained in:
Gellert Hegyi 2017-07-08 21:25:15 +02:00 committed by Aleksei Kuzmin
parent 1d132565c9
commit ca4a6e4692
3 changed files with 67 additions and 29 deletions

View file

@ -339,6 +339,8 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
popup_position_(gfx::Rect()),
hold_resize_(false),
pending_resize_(false),
renderer_compositor_frame_sink_(nullptr),
background_color_(SkColor()),
weak_ptr_factory_(this) {
DCHECK(render_widget_host_);
bool is_guest_view_hack = parent_host_view_ != nullptr;
@ -557,14 +559,18 @@ gfx::Rect OffScreenRenderWidgetHostView::GetViewBounds() const {
}
void OffScreenRenderWidgetHostView::SetBackgroundColor(SkColor color) {
if (transparent_)
color = SkColorSetARGB(SK_AlphaTRANSPARENT, 0, 0, 0);
// The renderer will feed its color back to us with the first CompositorFrame.
// We short-cut here to show a sensible color before that happens.
UpdateBackgroundColorFromRenderer(color);
content::RenderWidgetHostViewBase::SetBackgroundColor(color);
if (render_widget_host_) {
render_widget_host_->SetBackgroundOpaque(SkColorGetA(color) ==
SK_AlphaOPAQUE);
}
}
const bool opaque = !transparent_ && GetBackgroundOpaque();
if (render_widget_host_)
render_widget_host_->SetBackgroundOpaque(opaque);
SkColor OffScreenRenderWidgetHostView::background_color() const {
return background_color_;
}
gfx::Size OffScreenRenderWidgetHostView::GetVisibleViewportSize() const {
@ -581,11 +587,20 @@ bool OffScreenRenderWidgetHostView::LockMouse() {
void OffScreenRenderWidgetHostView::UnlockMouse() {
}
void OffScreenRenderWidgetHostView::OnSwapCompositorFrame(
uint32_t output_surface_id,
cc::CompositorFrame frame) {
void OffScreenRenderWidgetHostView::DidCreateNewRendererCompositorFrameSink(
cc::mojom::MojoCompositorFrameSinkClient* renderer_compositor_frame_sink) {
renderer_compositor_frame_sink_ = renderer_compositor_frame_sink;
if (GetDelegatedFrameHost()) {
GetDelegatedFrameHost()->DidCreateNewRendererCompositorFrameSink(
renderer_compositor_frame_sink_);
}
}
void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
const cc::LocalSurfaceId& local_surface_id,
cc::CompositorFrame frame) {
TRACE_EVENT0("electron",
"OffScreenRenderWidgetHostView::OnSwapCompositorFrame");
"OffScreenRenderWidgetHostView::SubmitCompositorFrame");
if (frame.metadata.root_scroll_offset != last_scroll_offset_) {
last_scroll_offset_ = frame.metadata.root_scroll_offset;
@ -599,11 +614,11 @@ void OffScreenRenderWidgetHostView::OnSwapCompositorFrame(
// The compositor will draw directly to the SoftwareOutputDevice which
// then calls OnPaint.
// We would normally call BrowserCompositorMac::SwapCompositorFrame on
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
// macOS, however it contains compositor resize logic that we don't want.
// Consequently we instead call the SwapDelegatedFrame method directly.
GetDelegatedFrameHost()->SwapDelegatedFrame(output_surface_id,
std::move(frame));
// Consequently we instead call the SubmitCompositorFrame method directly.
GetDelegatedFrameHost()->SubmitCompositorFrame(local_surface_id,
std::move(frame));
} else {
if (!copy_frame_generator_.get()) {
copy_frame_generator_.reset(
@ -618,11 +633,11 @@ void OffScreenRenderWidgetHostView::OnSwapCompositorFrame(
gfx::ToEnclosingRect(gfx::RectF(root_pass->damage_rect));
damage_rect.Intersect(gfx::Rect(frame_size));
// We would normally call BrowserCompositorMac::SwapCompositorFrame on
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
// macOS, however it contains compositor resize logic that we don't want.
// Consequently we instead call the SwapDelegatedFrame method directly.
GetDelegatedFrameHost()->SwapDelegatedFrame(output_surface_id,
std::move(frame));
// Consequently we instead call the SubmitCompositorFrame method directly.
GetDelegatedFrameHost()->SubmitCompositorFrame(local_surface_id,
std::move(frame));
// Request a copy of the last compositor frame which will eventually call
// OnPaint asynchronously.
@ -688,8 +703,14 @@ void OffScreenRenderWidgetHostView::Destroy() {
popup_bitmap_.reset();
if (child_host_view_)
child_host_view_->CancelWidget();
for (auto guest_host_view : guest_host_views_)
guest_host_view->CancelWidget();
if (!guest_host_views_.empty()) {
// Guest RWHVs will be destroyed when the associated RWHVGuest is
// destroyed. This parent RWHV may be destroyed first, so disassociate
// the guest RWHVs here without destroying them.
for (auto guest_host_view : guest_host_views_)
guest_host_view->parent_host_view_ = nullptr;
guest_host_views_.clear();
}
for (auto proxy_view : proxy_views_)
proxy_view->RemoveObserver();
Hide();
@ -1318,4 +1339,15 @@ cc::FrameSinkId OffScreenRenderWidgetHostView::AllocateFrameSinkId(
render_widget_host_->GetRoutingID()));
}
void OffScreenRenderWidgetHostView::UpdateBackgroundColorFromRenderer(
SkColor color) {
if (color == background_color())
return;
background_color_ = color;
bool opaque = SkColorGetA(color) == SK_AlphaOPAQUE;
GetRootLayer()->SetFillsBoundsOpaquely(opaque);
GetRootLayer()->SetColor(color);
}
} // namespace atom

View file

@ -99,6 +99,7 @@ class OffScreenRenderWidgetHostView
gfx::Size GetVisibleViewportSize() const override;
void SetInsets(const gfx::Insets&) override;
void SetBackgroundColor(SkColor color) override;
SkColor background_color() const override;
bool LockMouse(void) override;
void UnlockMouse(void) override;
void SetNeedsBeginFrames(bool needs_begin_frames) override;
@ -113,6 +114,12 @@ class OffScreenRenderWidgetHostView
#endif // defined(OS_MACOSX)
// content::RenderWidgetHostViewBase:
void DidCreateNewRendererCompositorFrameSink(
cc::mojom::MojoCompositorFrameSinkClient* renderer_compositor_frame_sink)
override;
void SubmitCompositorFrame(const cc::LocalSurfaceId& local_surface_id,
cc::CompositorFrame frame) override;
void ClearCompositorFrame(void) override;
void InitAsPopup(content::RenderWidgetHostView *rwhv, const gfx::Rect& rect)
override;
@ -269,6 +276,10 @@ class OffScreenRenderWidgetHostView
cc::FrameSinkId AllocateFrameSinkId(bool is_guest_view_hack);
// Applies background color without notifying the RenderWidget about
// opaqueness changes.
void UpdateBackgroundColorFromRenderer(SkColor color);
// Weak ptrs.
content::RenderWidgetHostImpl* render_widget_host_;
@ -326,6 +337,10 @@ class OffScreenRenderWidgetHostView
std::string selected_text_;
#endif
cc::mojom::MojoCompositorFrameSinkClient* renderer_compositor_frame_sink_;
SkColor background_color_;
base::WeakPtrFactory<OffScreenRenderWidgetHostView> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(OffScreenRenderWidgetHostView);

View file

@ -38,15 +38,6 @@ class MacHelper :
return color;
}
void BrowserCompositorMacSendReclaimCompositorResources(
int output_surface_id,
bool is_swap_ack,
const cc::ReturnedResourceArray& resources) override {
view_->render_widget_host()->Send(new ViewMsg_ReclaimCompositorResources(
view_->render_widget_host()->GetRoutingID(), output_surface_id,
is_swap_ack, resources));
}
void BrowserCompositorMacSendBeginFrame(
const cc::BeginFrameArgs& args) override {
view_->render_widget_host()->Send(