fix: port OSR code to new viz compositor codepath (#17538)

* fix: make OSR work with viz compositor

* fix: update OSR patch

* fix: update patch again

* fix: update viz_osr.patch for macOS

* fix: gn check warnings

* chore: no need to change SoftwareOutputDeviceWinProxy

* chore: add check in case we missed something

* fix: consider scale factor when compare size

* fix: make GPU OSR work

* fix: autofill popups with OSR

* chore: use UNIX line ending for osr_video_consumer

* chore: code is already in defined(OS_MACOSX)

* fix: share same OSR implementation on macOS

This should also fix the crash when there is navigation on macOS.

* test: osr window should not crash after navigation

* fix: make osr work on Mac properly

* fix: software osr on windows

* fix: software osr on Linux

* fix: compilation error introduced with rebase

* fix: split local surface id allocation into two

* Update osr_host_display_client_mac.mm

* chore: update copyright year

* fix: update patch
This commit is contained in:
Heilig Benedek 2019-04-17 23:10:04 +02:00 committed by Shelley Vohr
parent 1478bd36fd
commit 81bf15877f
22 changed files with 1302 additions and 777 deletions

View file

@ -20,14 +20,15 @@
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
#include "components/viz/common/gl_helper.h"
#include "components/viz/common/quads/render_pass.h"
#include "content/browser/renderer_host/cursor_manager.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h"
#include "content/browser/renderer_host/cursor_manager.h" // nogncheck
#include "content/browser/renderer_host/input/synthetic_gesture_target.h" // nogncheck
#include "content/browser/renderer_host/render_widget_host_delegate.h" // nogncheck
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h" // nogncheck
#include "content/common/view_messages.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/context_factory.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/render_process_host.h"
#include "media/base/video_frame.h"
#include "third_party/blink/public/platform/web_input_event.h"
@ -50,7 +51,6 @@ namespace atom {
namespace {
const float kDefaultScaleFactor = 1.0;
const int kFrameRetryLimit = 2;
ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
ui::EventType type = ui::EventType::ET_UNKNOWN;
@ -120,105 +120,6 @@ ui::MouseWheelEvent UiMouseWheelEventFromWebMouseEvent(
} // namespace
class AtomCopyFrameGenerator {
public:
AtomCopyFrameGenerator(OffScreenRenderWidgetHostView* view,
int frame_rate_threshold_us)
: view_(view),
frame_duration_(
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us)),
weak_ptr_factory_(this) {
last_time_ = base::Time::Now();
}
void GenerateCopyFrame(const gfx::Rect& damage_rect) {
if (!view_->render_widget_host() || !view_->IsPainting())
return;
auto request = std::make_unique<viz::CopyOutputRequest>(
viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
base::BindOnce(
&AtomCopyFrameGenerator::CopyFromCompositingSurfaceHasResult,
weak_ptr_factory_.GetWeakPtr(), damage_rect));
request->set_area(gfx::Rect(view_->GetCompositorViewportPixelSize()));
view_->GetRootLayer()->RequestCopyOfOutput(std::move(request));
}
void set_frame_rate_threshold_us(int frame_rate_threshold_us) {
frame_duration_ =
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us);
}
private:
void CopyFromCompositingSurfaceHasResult(
const gfx::Rect& damage_rect,
std::unique_ptr<viz::CopyOutputResult> result) {
if (result->IsEmpty() || result->size().IsEmpty() ||
!view_->render_widget_host()) {
OnCopyFrameCaptureFailure(damage_rect);
return;
}
DCHECK(!result->IsEmpty());
auto source = std::make_unique<SkBitmap>(result->AsSkBitmap());
DCHECK(source->readyToDraw());
if (source) {
base::AutoLock autolock(lock_);
std::shared_ptr<SkBitmap> bitmap(source.release());
base::TimeTicks now = base::TimeTicks::Now();
base::TimeDelta next_frame_in = next_frame_time_ - now;
if (next_frame_in > frame_duration_ / 4) {
next_frame_time_ += frame_duration_;
base::PostDelayedTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&AtomCopyFrameGenerator::OnCopyFrameCaptureSuccess,
weak_ptr_factory_.GetWeakPtr(), damage_rect, bitmap),
next_frame_in);
} else {
next_frame_time_ = now + frame_duration_;
OnCopyFrameCaptureSuccess(damage_rect, bitmap);
}
frame_retry_count_ = 0;
} else {
OnCopyFrameCaptureFailure(damage_rect);
}
}
void OnCopyFrameCaptureFailure(const gfx::Rect& damage_rect) {
const bool force_frame = (++frame_retry_count_ <= kFrameRetryLimit);
if (force_frame) {
// Retry with the same |damage_rect|.
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&AtomCopyFrameGenerator::GenerateCopyFrame,
weak_ptr_factory_.GetWeakPtr(), damage_rect));
}
}
void OnCopyFrameCaptureSuccess(const gfx::Rect& damage_rect,
const std::shared_ptr<SkBitmap>& bitmap) {
base::AutoLock lock(onPaintLock_);
view_->OnPaint(damage_rect, *bitmap);
}
base::Lock lock_;
base::Lock onPaintLock_;
OffScreenRenderWidgetHostView* view_;
base::Time last_time_;
int frame_retry_count_ = 0;
base::TimeTicks next_frame_time_ = base::TimeTicks::Now();
base::TimeDelta frame_duration_;
base::WeakPtrFactory<AtomCopyFrameGenerator> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(AtomCopyFrameGenerator);
};
class AtomBeginFrameTimer : public viz::DelayBasedTimeSourceClient {
public:
AtomBeginFrameTimer(int frame_rate_threshold_us,
@ -253,7 +154,6 @@ class AtomBeginFrameTimer : public viz::DelayBasedTimeSourceClient {
DISALLOW_COPY_AND_ASSIGN(AtomBeginFrameTimer);
};
#if !defined(OS_MACOSX)
class AtomDelegatedFrameHostClient : public content::DelegatedFrameHostClient {
public:
explicit AtomDelegatedFrameHostClient(OffScreenRenderWidgetHostView* view)
@ -297,7 +197,6 @@ class AtomDelegatedFrameHostClient : public content::DelegatedFrameHostClient {
DISALLOW_COPY_AND_ASSIGN(AtomDelegatedFrameHostClient);
};
#endif // !defined(OS_MACOSX)
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
bool transparent,
@ -315,19 +214,23 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
frame_rate_(frame_rate),
size_(initial_size),
painting_(painting),
is_showing_(!render_widget_host_->is_hidden()),
is_showing_(false),
cursor_manager_(new content::CursorManager(this)),
mouse_wheel_phase_handler_(this),
backing_(new SkBitmap),
weak_ptr_factory_(this) {
DCHECK(render_widget_host_);
bool is_guest_view_hack = parent_host_view_ != nullptr;
current_device_scale_factor_ = kDefaultScaleFactor;
#if !defined(OS_MACOSX)
local_surface_id_allocator_.GenerateId();
local_surface_id_allocation_ =
local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
delegated_frame_host_allocator_.GenerateId();
delegated_frame_host_allocation_ =
delegated_frame_host_allocator_.GetCurrentLocalSurfaceIdAllocation();
compositor_allocator_.GenerateId();
compositor_allocation_ =
compositor_allocator_.GetCurrentLocalSurfaceIdAllocation();
delegated_frame_host_client_.reset(new AtomDelegatedFrameHostClient(this));
delegated_frame_host_ = std::make_unique<content::DelegatedFrameHost>(
AllocateFrameSinkId(is_guest_view_hack),
@ -335,59 +238,49 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
true /* should_register_frame_sink_id */);
root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
#endif
#if defined(OS_MACOSX)
last_frame_root_background_color_ = SK_ColorTRANSPARENT;
CreatePlatformWidget(is_guest_view_hack);
#endif
bool opaque = SkColorGetA(background_color_) == SK_AlphaOPAQUE;
GetRootLayer()->SetFillsBoundsOpaquely(opaque);
GetRootLayer()->SetColor(background_color_);
#if !defined(OS_MACOSX)
// On macOS the ui::Compositor is created/owned by the platform view.
content::ImageTransportFactory* factory =
content::ImageTransportFactory::GetInstance();
ui::ContextFactoryPrivate* context_factory_private =
factory->GetContextFactoryPrivate();
compositor_.reset(new ui::Compositor(
context_factory_private->AllocateFrameSinkId(),
content::GetContextFactory(), context_factory_private,
base::ThreadTaskRunnerHandle::Get(), false /* enable_pixel_canvas */));
compositor_.reset(
new ui::Compositor(context_factory_private->AllocateFrameSinkId(),
content::GetContextFactory(), context_factory_private,
base::ThreadTaskRunnerHandle::Get(),
false /* enable_pixel_canvas */, this));
compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
compositor_->SetRootLayer(root_layer_.get());
#endif
GetCompositor()->SetDelegate(this);
ResizeRootLayer(false);
render_widget_host_->SetView(this);
InstallTransparency();
if (content::GpuDataManager::GetInstance()->HardwareAccelerationEnabled()) {
video_consumer_.reset(new OffScreenVideoConsumer(
this, base::Bind(&OffScreenRenderWidgetHostView::OnPaint,
weak_ptr_factory_.GetWeakPtr())));
video_consumer_->SetActive(IsPainting());
video_consumer_->SetFrameRate(GetFrameRate());
}
}
OffScreenRenderWidgetHostView::~OffScreenRenderWidgetHostView() {
#if defined(OS_MACOSX)
if (is_showing_)
browser_compositor_->SetRenderWidgetHostIsHidden(true);
#else
// Marking the DelegatedFrameHost as removed from the window hierarchy is
// necessary to remove all connections to its old ui::Compositor.
if (is_showing_)
delegated_frame_host_->WasHidden();
delegated_frame_host_->DetachFromCompositor();
#endif
if (copy_frame_generator_.get())
copy_frame_generator_.reset(NULL);
#if defined(OS_MACOSX)
DestroyPlatformWidget();
#else
delegated_frame_host_.reset(NULL);
compositor_.reset(NULL);
root_layer_.reset(NULL);
#endif
}
content::BrowserAccessibilityManager*
@ -422,8 +315,17 @@ void OffScreenRenderWidgetHostView::SendBeginFrame(
DCHECK(begin_frame_args.IsValid());
begin_frame_number_++;
if (renderer_compositor_frame_sink_)
renderer_compositor_frame_sink_->OnBeginFrame(begin_frame_args, {});
compositor_->context_factory_private()->IssueExternalBeginFrame(
compositor_.get(), begin_frame_args);
}
void OffScreenRenderWidgetHostView::OnDisplayDidFinishFrame(
const viz::BeginFrameAck& ack) {}
void OffScreenRenderWidgetHostView::OnNeedsExternalBeginFrames(
bool needs_begin_frames) {
SetupFrameRate(true);
begin_frame_timer_->SetActive(needs_begin_frames);
}
void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
@ -437,7 +339,7 @@ void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
parent_host_view_->Hide();
ResizeRootLayer(false);
Show();
SetPainting(parent_host_view_->IsPainting());
}
void OffScreenRenderWidgetHostView::SetSize(const gfx::Size& size) {
@ -478,14 +380,10 @@ void OffScreenRenderWidgetHostView::Show() {
is_showing_ = true;
#if defined(OS_MACOSX)
browser_compositor_->SetRenderWidgetHostIsHidden(false);
#else
delegated_frame_host_->AttachToCompositor(compositor_.get());
delegated_frame_host_->WasShown(
GetLocalSurfaceIdAllocation().local_surface_id(),
GetRootLayer()->bounds().size(), false);
#endif
if (render_widget_host_)
render_widget_host_->WasShown(false);
@ -498,12 +396,8 @@ void OffScreenRenderWidgetHostView::Hide() {
if (render_widget_host_)
render_widget_host_->WasHidden();
#if defined(OS_MACOSX)
browser_compositor_->SetRenderWidgetHostIsHidden(true);
#else
GetDelegatedFrameHost()->WasHidden();
GetDelegatedFrameHost()->DetachFromCompositor();
#endif
is_showing_ = false;
}
@ -576,67 +470,17 @@ void OffScreenRenderWidgetHostView::DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) {
renderer_compositor_frame_sink_ = renderer_compositor_frame_sink;
#if defined(OS_MACOSX)
browser_compositor_->DidCreateNewRendererCompositorFrameSink(
renderer_compositor_frame_sink_);
#else
if (GetDelegatedFrameHost()) {
GetDelegatedFrameHost()->DidCreateNewRendererCompositorFrameSink(
renderer_compositor_frame_sink_);
}
#endif
}
void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
viz::CompositorFrame frame,
base::Optional<viz::HitTestRegionList> hit_test_region_list) {
#if defined(OS_MACOSX)
last_frame_root_background_color_ = frame.metadata.root_background_color;
#endif
if (frame.metadata.root_scroll_offset != last_scroll_offset_) {
last_scroll_offset_ = frame.metadata.root_scroll_offset;
}
if (!frame.render_pass_list.empty()) {
if (software_output_device_) {
if (!begin_frame_timer_.get() || IsPopupWidget()) {
software_output_device_->SetActive(painting_, false);
}
// The compositor will draw directly to the SoftwareOutputDevice which
// then calls OnPaint.
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
// macOS, however it contains compositor resize logic that we don't want.
// Consequently we instead call the SubmitCompositorFrame method directly.
GetDelegatedFrameHost()->SubmitCompositorFrame(
local_surface_id, std::move(frame), std::move(hit_test_region_list));
} else {
if (!copy_frame_generator_.get()) {
copy_frame_generator_.reset(
new AtomCopyFrameGenerator(this, frame_rate_threshold_us_));
}
// Determine the damage rectangle for the current frame. This is the same
// calculation that SwapDelegatedFrame uses.
viz::RenderPass* root_pass = frame.render_pass_list.back().get();
gfx::Size frame_size = root_pass->output_rect.size();
gfx::Rect damage_rect =
gfx::ToEnclosingRect(gfx::RectF(root_pass->damage_rect));
damage_rect.Intersect(gfx::Rect(frame_size));
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
// macOS, however it contains compositor resize logic that we don't want.
// Consequently we instead call the SubmitCompositorFrame method directly.
GetDelegatedFrameHost()->SubmitCompositorFrame(
local_surface_id, std::move(frame), std::move(hit_test_region_list));
// Request a copy of the last compositor frame which will eventually call
// OnPaint asynchronously.
copy_frame_generator_->GenerateCopyFrame(damage_rect);
}
}
NOTREACHED();
}
void OffScreenRenderWidgetHostView::ClearCompositorFrame() {
@ -651,13 +495,13 @@ void OffScreenRenderWidgetHostView::InitAsPopup(
content::RenderWidgetHostView* parent_host_view,
const gfx::Rect& pos) {
DCHECK_EQ(parent_host_view_, parent_host_view);
DCHECK_EQ(widget_type_, content::WidgetType::kPopup);
if (parent_host_view_->popup_host_view_) {
parent_host_view_->popup_host_view_->CancelWidget();
}
parent_host_view_->set_popup_host_view(this);
parent_host_view_->popup_bitmap_.reset(new SkBitmap);
parent_callback_ =
base::Bind(&OffScreenRenderWidgetHostView::OnPopupPaint,
parent_host_view_->weak_ptr_factory_.GetWeakPtr());
@ -665,6 +509,10 @@ void OffScreenRenderWidgetHostView::InitAsPopup(
popup_position_ = pos;
ResizeRootLayer(false);
SetPainting(parent_host_view_->IsPainting());
if (video_consumer_) {
video_consumer_->SizeChanged();
}
Show();
}
@ -698,7 +546,6 @@ void OffScreenRenderWidgetHostView::Destroy() {
} else {
if (popup_host_view_)
popup_host_view_->CancelWidget();
popup_bitmap_.reset();
if (child_host_view_)
child_host_view_->CancelWidget();
if (!guest_host_views_.empty()) {
@ -748,6 +595,7 @@ 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(
@ -763,6 +611,12 @@ viz::SurfaceId OffScreenRenderWidgetHostView::GetCurrentSurfaceId() const {
: viz::SurfaceId();
}
std::unique_ptr<content::SyntheticGestureTarget>
OffScreenRenderWidgetHostView::CreateSyntheticGestureTarget() {
NOTIMPLEMENTED();
return nullptr;
}
void OffScreenRenderWidgetHostView::ImeCompositionRangeChanged(
const gfx::Range&,
const std::vector<gfx::Rect>&) {}
@ -800,12 +654,8 @@ const viz::FrameSinkId& OffScreenRenderWidgetHostView::GetFrameSinkId() const {
void OffScreenRenderWidgetHostView::DidNavigate() {
ResizeRootLayer(true);
#if defined(OS_MACOSX)
browser_compositor_->DidNavigate();
#else
if (delegated_frame_host_)
delegated_frame_host_->DidNavigate();
#endif
}
bool OffScreenRenderWidgetHostView::TransformPointToLocalCoordSpaceLegacy(
@ -829,8 +679,7 @@ bool OffScreenRenderWidgetHostView::TransformPointToLocalCoordSpaceLegacy(
bool OffScreenRenderWidgetHostView::TransformPointToCoordSpaceForView(
const gfx::PointF& point,
RenderWidgetHostViewBase* target_view,
gfx::PointF* transformed_point,
viz::EventSource source) {
gfx::PointF* transformed_point) {
if (target_view == this) {
*transformed_point = point;
return true;
@ -847,7 +696,6 @@ void OffScreenRenderWidgetHostView::CancelWidget() {
if (parent_host_view_) {
if (parent_host_view_->popup_host_view_ == this) {
parent_host_view_->set_popup_host_view(NULL);
parent_host_view_->popup_bitmap_.reset();
} else if (parent_host_view_->child_host_view_ == this) {
parent_host_view_->set_child_host_view(NULL);
parent_host_view_->Show();
@ -890,29 +738,21 @@ void OffScreenRenderWidgetHostView::ProxyViewDestroyed(
Invalidate();
}
std::unique_ptr<viz::SoftwareOutputDevice>
OffScreenRenderWidgetHostView::CreateSoftwareOutputDevice(
std::unique_ptr<viz::HostDisplayClient>
OffScreenRenderWidgetHostView::CreateHostDisplayClient(
ui::Compositor* compositor) {
DCHECK_EQ(GetCompositor(), compositor);
DCHECK(!copy_frame_generator_);
DCHECK(!software_output_device_);
ResizeRootLayer(false);
software_output_device_ = new OffScreenOutputDevice(
transparent_, base::Bind(&OffScreenRenderWidgetHostView::OnPaint,
weak_ptr_factory_.GetWeakPtr()));
return base::WrapUnique(software_output_device_);
host_display_client_ = new OffScreenHostDisplayClient(
gfx::kNullAcceleratedWidget,
base::Bind(&OffScreenRenderWidgetHostView::OnPaint,
weak_ptr_factory_.GetWeakPtr()));
host_display_client_->SetActive(IsPainting());
return base::WrapUnique(host_display_client_);
}
bool OffScreenRenderWidgetHostView::InstallTransparency() {
if (transparent_) {
SetBackgroundColor(SkColor());
#if defined(OS_MACOSX)
browser_compositor_->SetBackgroundColor(SK_ColorTRANSPARENT);
#else
compositor_->SetBackgroundColor(SK_ColorTRANSPARENT);
#endif
return true;
}
return false;
@ -921,76 +761,99 @@ bool OffScreenRenderWidgetHostView::InstallTransparency() {
void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
bool needs_begin_frames) {
SetupFrameRate(true);
begin_frame_timer_->SetActive(needs_begin_frames);
if (software_output_device_) {
software_output_device_->SetActive(painting_, false);
}
}
void OffScreenRenderWidgetHostView::SetWantsAnimateOnlyBeginFrames() {
if (GetDelegatedFrameHost()) {
GetDelegatedFrameHost()->SetWantsAnimateOnlyBeginFrames();
}
void OffScreenRenderWidgetHostView::SetWantsAnimateOnlyBeginFrames() {}
#if defined(OS_MACOSX)
void OffScreenRenderWidgetHostView::SetActive(bool active) {}
void OffScreenRenderWidgetHostView::ShowDefinitionForSelection() {}
void OffScreenRenderWidgetHostView::SpeakSelection() {}
bool OffScreenRenderWidgetHostView::UpdateNSViewAndDisplay() {
return false;
}
#endif
void OffScreenRenderWidgetHostView::OnPaint(const gfx::Rect& damage_rect,
const SkBitmap& bitmap) {
backing_.reset(new SkBitmap());
backing_->allocN32Pixels(bitmap.width(), bitmap.height(), !transparent_);
bitmap.readPixels(backing_->pixmap());
if (IsPopupWidget() && parent_callback_) {
parent_callback_.Run(this->popup_position_);
} else {
CompositeFrame(damage_rect);
}
}
gfx::Size OffScreenRenderWidgetHostView::SizeInPixels() {
if (IsPopupWidget()) {
return gfx::ConvertSizeToPixel(current_device_scale_factor_,
popup_position_.size());
} else {
return gfx::ConvertSizeToPixel(current_device_scale_factor_,
GetViewBounds().size());
}
}
void OffScreenRenderWidgetHostView::CompositeFrame(
const gfx::Rect& damage_rect) {
HoldResize();
if (parent_callback_) {
parent_callback_.Run(damage_rect, bitmap);
gfx::Size size_in_pixels = SizeInPixels();
SkBitmap frame;
// Optimize for the case when there is no popup
if (proxy_views_.size() == 0 && !popup_host_view_) {
frame = GetBacking();
} else {
gfx::Rect damage(damage_rect);
frame.allocN32Pixels(size_in_pixels.width(), size_in_pixels.height(),
false);
if (!GetBacking().drawsNothing()) {
SkCanvas canvas(frame);
canvas.writePixels(GetBacking(), 0, 0);
gfx::Size size_in_pixels = gfx::ConvertSizeToPixel(
current_device_scale_factor_, GetViewBounds().size());
if (popup_host_view_ && !popup_host_view_->GetBacking().drawsNothing()) {
gfx::Rect rect = popup_host_view_->popup_position_;
gfx::Point origin_in_pixels = gfx::ConvertPointToPixel(
current_device_scale_factor_, rect.origin());
canvas.writePixels(popup_host_view_->GetBacking(), origin_in_pixels.x(),
origin_in_pixels.y());
}
SkBitmap backing;
backing.allocN32Pixels(size_in_pixels.width(), size_in_pixels.height(),
false);
SkCanvas canvas(backing);
canvas.writePixels(bitmap, 0, 0);
if (popup_host_view_ && popup_bitmap_.get()) {
gfx::Rect rect = popup_host_view_->popup_position_;
gfx::Point origin_in_pixels =
gfx::ConvertPointToPixel(current_device_scale_factor_, rect.origin());
damage.Union(rect);
canvas.writePixels(*popup_bitmap_.get(), origin_in_pixels.x(),
origin_in_pixels.y());
for (auto* proxy_view : proxy_views_) {
gfx::Rect rect = proxy_view->GetBounds();
gfx::Point origin_in_pixels = gfx::ConvertPointToPixel(
current_device_scale_factor_, rect.origin());
canvas.writePixels(*proxy_view->GetBitmap(), origin_in_pixels.x(),
origin_in_pixels.y());
}
}
for (auto* proxy_view : proxy_views_) {
gfx::Rect rect = proxy_view->GetBounds();
gfx::Point origin_in_pixels =
gfx::ConvertPointToPixel(current_device_scale_factor_, rect.origin());
damage.Union(rect);
canvas.writePixels(*proxy_view->GetBitmap(), origin_in_pixels.x(),
origin_in_pixels.y());
}
damage.Intersect(GetViewBounds());
paint_callback_running_ = true;
callback_.Run(damage, backing);
paint_callback_running_ = false;
}
paint_callback_running_ = true;
callback_.Run(gfx::IntersectRects(gfx::Rect(size_in_pixels), damage_rect),
frame);
paint_callback_running_ = false;
ReleaseResize();
}
void OffScreenRenderWidgetHostView::OnPopupPaint(const gfx::Rect& damage_rect,
const SkBitmap& bitmap) {
if (popup_host_view_ && popup_bitmap_.get())
popup_bitmap_.reset(new SkBitmap(bitmap));
InvalidateBounds(popup_host_view_->popup_position_);
void OffScreenRenderWidgetHostView::OnPopupPaint(const gfx::Rect& damage_rect) {
InvalidateBounds(
gfx::ConvertRectToPixel(current_device_scale_factor_, damage_rect));
}
void OffScreenRenderWidgetHostView::OnProxyViewPaint(
const gfx::Rect& damage_rect) {
InvalidateBounds(damage_rect);
InvalidateBounds(
gfx::ConvertRectToPixel(current_device_scale_factor_, damage_rect));
}
void OffScreenRenderWidgetHostView::HoldResize() {
@ -1020,7 +883,7 @@ void OffScreenRenderWidgetHostView::SynchronizeVisualProperties() {
return;
}
ResizeRootLayer(false);
ResizeRootLayer(true);
}
void OffScreenRenderWidgetHostView::SendMouseEvent(
@ -1147,8 +1010,17 @@ void OffScreenRenderWidgetHostView::SendMouseWheelEvent(
void OffScreenRenderWidgetHostView::SetPainting(bool painting) {
painting_ = painting;
if (software_output_device_) {
software_output_device_->SetActive(painting_, !paint_callback_running_);
if (popup_host_view_) {
popup_host_view_->SetPainting(painting);
}
for (auto* guest_host_view : guest_host_views_)
guest_host_view->SetPainting(painting);
if (video_consumer_) {
video_consumer_->SetActive(IsPainting());
} else if (host_display_client_) {
host_display_client_->SetActive(IsPainting());
}
}
@ -1173,6 +1045,10 @@ void OffScreenRenderWidgetHostView::SetFrameRate(int frame_rate) {
SetupFrameRate(true);
if (video_consumer_) {
video_consumer_->SetFrameRate(GetFrameRate());
}
for (auto* guest_host_view : guest_host_views_)
guest_host_view->SetFrameRate(frame_rate);
}
@ -1181,7 +1057,6 @@ int OffScreenRenderWidgetHostView::GetFrameRate() const {
return frame_rate_;
}
#if !defined(OS_MACOSX)
ui::Compositor* OffScreenRenderWidgetHostView::GetCompositor() const {
return compositor_.get();
}
@ -1190,18 +1065,15 @@ ui::Layer* OffScreenRenderWidgetHostView::GetRootLayer() const {
return root_layer_.get();
}
#if !defined(OS_MACOSX)
const viz::LocalSurfaceIdAllocation&
OffScreenRenderWidgetHostView::GetLocalSurfaceIdAllocation() const {
return local_surface_id_allocation_;
return delegated_frame_host_allocation_;
}
#endif // defined(OS_MACOSX)
content::DelegatedFrameHost*
OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const {
return delegated_frame_host_.get();
}
#endif
void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
if (!force && frame_rate_threshold_us_ != 0)
@ -1209,11 +1081,6 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
frame_rate_threshold_us_ = 1000000 / frame_rate_;
if (copy_frame_generator_.get()) {
copy_frame_generator_->set_frame_rate_threshold_us(
frame_rate_threshold_us_);
}
if (begin_frame_timer_.get()) {
begin_frame_timer_->SetFrameRateThresholdUs(frame_rate_threshold_us_);
} else {
@ -1225,15 +1092,11 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
}
void OffScreenRenderWidgetHostView::Invalidate() {
InvalidateBounds(GetViewBounds());
InvalidateBounds(gfx::Rect(GetRequestedRendererSize()));
}
void OffScreenRenderWidgetHostView::InvalidateBounds(const gfx::Rect& bounds) {
if (software_output_device_) {
software_output_device_->OnPaint(bounds);
} else if (copy_frame_generator_) {
copy_frame_generator_->GenerateCopyFrame(bounds);
}
CompositeFrame(bounds);
}
void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
@ -1259,23 +1122,24 @@ void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
GetRootLayer()->SetBounds(gfx::Rect(size));
#if defined(OS_MACOSX)
bool resized = UpdateNSViewAndDisplay();
#else
const gfx::Size& size_in_pixels =
gfx::ConvertSizeToPixel(current_device_scale_factor_, size);
local_surface_id_allocator_.GenerateId();
local_surface_id_allocation_ =
local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
compositor_allocator_.GenerateId();
compositor_allocation_ =
compositor_allocator_.GetCurrentLocalSurfaceIdAllocation();
GetCompositor()->SetScaleAndSize(current_device_scale_factor_, size_in_pixels,
local_surface_id_allocation_);
compositor_allocation_);
delegated_frame_host_allocator_.GenerateId();
delegated_frame_host_allocation_ =
delegated_frame_host_allocator_.GetCurrentLocalSurfaceIdAllocation();
bool resized = true;
GetDelegatedFrameHost()->EmbedSurface(
local_surface_id_allocation_.local_surface_id(), size,
delegated_frame_host_allocation_.local_surface_id(), size,
cc::DeadlinePolicy::UseDefaultDeadline());
#endif
// Note that |render_widget_host_| will retrieve resize parameters from the
// DelegatedFrameHost, so it must have SynchronizeVisualProperties called