blob: fb68c4c376863c2c3d80cddf762989a412e65148 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/frame_host/render_widget_host_view_child_frame.h"
#include <algorithm>
#include <utility>
#include <vector>
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
#include "cc/surfaces/surface.h"
#include "cc/surfaces/surface_factory.h"
#include "cc/surfaces/surface_manager.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/frame_host/cross_process_frame_connector.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/renderer_host/render_view_host_impl.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_input_event_router.h"
#include "content/common/text_input_state.h"
#include "content/common/view_messages.h"
#include "content/public/browser/guest_mode.h"
#include "content/public/browser/render_process_host.h"
#include "gpu/ipc/common/gpu_messages.h"
#include "third_party/WebKit/public/platform/WebTouchEvent.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/geometry/size_f.h"
namespace content {
// static
RenderWidgetHostViewChildFrame* RenderWidgetHostViewChildFrame::Create(
RenderWidgetHost* widget) {
RenderWidgetHostViewChildFrame* view =
new RenderWidgetHostViewChildFrame(widget);
view->Init();
return view;
}
RenderWidgetHostViewChildFrame::RenderWidgetHostViewChildFrame(
RenderWidgetHost* widget_host)
: host_(RenderWidgetHostImpl::From(widget_host)),
frame_sink_id_(
base::checked_cast<uint32_t>(widget_host->GetProcess()->GetID()),
base::checked_cast<uint32_t>(widget_host->GetRoutingID())),
next_surface_sequence_(1u),
last_compositor_frame_sink_id_(0),
current_surface_scale_factor_(1.f),
frame_connector_(nullptr),
weak_factory_(this) {
id_allocator_.reset(new cc::LocalSurfaceIdAllocator());
GetSurfaceManager()->RegisterFrameSinkId(frame_sink_id_);
CreateCompositorFrameSinkSupport();
}
RenderWidgetHostViewChildFrame::~RenderWidgetHostViewChildFrame() {
ResetCompositorFrameSinkSupport();
if (GetSurfaceManager())
GetSurfaceManager()->InvalidateFrameSinkId(frame_sink_id_);
}
void RenderWidgetHostViewChildFrame::Init() {
RegisterFrameSinkId();
host_->SetView(this);
GetTextInputManager();
}
void RenderWidgetHostViewChildFrame::SetCrossProcessFrameConnector(
CrossProcessFrameConnector* frame_connector) {
if (frame_connector_ == frame_connector)
return;
if (frame_connector_) {
if (parent_frame_sink_id_.is_valid()) {
GetSurfaceManager()->UnregisterFrameSinkHierarchy(parent_frame_sink_id_,
frame_sink_id_);
}
parent_frame_sink_id_ = cc::FrameSinkId();
// Unlocks the mouse if this RenderWidgetHostView holds the lock.
UnlockMouse();
}
frame_connector_ = frame_connector;
if (frame_connector_) {
RenderWidgetHostViewBase* parent_view =
frame_connector_->GetParentRenderWidgetHostView();
if (parent_view) {
parent_frame_sink_id_ = parent_view->GetFrameSinkId();
DCHECK(parent_frame_sink_id_.is_valid());
GetSurfaceManager()->RegisterFrameSinkHierarchy(parent_frame_sink_id_,
frame_sink_id_);
}
}
}
void RenderWidgetHostViewChildFrame::InitAsChild(
gfx::NativeView parent_view) {
NOTREACHED();
}
RenderWidgetHost* RenderWidgetHostViewChildFrame::GetRenderWidgetHost() const {
return host_;
}
void RenderWidgetHostViewChildFrame::SetSize(const gfx::Size& size) {
host_->WasResized();
}
void RenderWidgetHostViewChildFrame::SetBounds(const gfx::Rect& rect) {
SetSize(rect.size());
if (rect != last_screen_rect_) {
last_screen_rect_ = rect;
host_->SendScreenRects();
}
}
void RenderWidgetHostViewChildFrame::Focus() {
}
bool RenderWidgetHostViewChildFrame::HasFocus() const {
if (frame_connector_)
return frame_connector_->HasFocus();
return false;
}
bool RenderWidgetHostViewChildFrame::IsSurfaceAvailableForCopy() const {
return local_surface_id_.is_valid();
}
void RenderWidgetHostViewChildFrame::Show() {
if (!host_->is_hidden())
return;
host_->WasShown(ui::LatencyInfo());
}
void RenderWidgetHostViewChildFrame::Hide() {
if (host_->is_hidden())
return;
host_->WasHidden();
}
bool RenderWidgetHostViewChildFrame::IsShowing() {
return !host_->is_hidden();
}
gfx::Rect RenderWidgetHostViewChildFrame::GetViewBounds() const {
gfx::Rect rect;
if (frame_connector_) {
rect = frame_connector_->ChildFrameRect();
RenderWidgetHostView* parent_view =
frame_connector_->GetParentRenderWidgetHostView();
// The parent_view can be null in tests when using a TestWebContents.
if (parent_view) {
// Translate frame_rect by the parent's RenderWidgetHostView offset.
rect.Offset(parent_view->GetViewBounds().OffsetFromOrigin());
}
}
return rect;
}
gfx::Size RenderWidgetHostViewChildFrame::GetVisibleViewportSize() const {
// For subframes, the visual viewport corresponds to the main frame size, so
// this bubbles up to the parent until it hits the main frame's
// RenderWidgetHostView.
//
// Currently this excludes webview guests, since they expect the visual
// viewport to return the guest's size rather than the page's; one reason why
// is that Blink ends up using the visual viewport to calculate things like
// window.innerWidth/innerHeight for main frames, and a guest is considered
// to be a main frame. This should be cleaned up eventually.
bool is_guest = BrowserPluginGuest::IsGuest(RenderViewHostImpl::From(host_));
if (frame_connector_ && !is_guest) {
RenderWidgetHostView* parent_view =
frame_connector_->GetParentRenderWidgetHostView();
// The parent_view can be null in unit tests when using a TestWebContents.
if (parent_view)
return parent_view->GetVisibleViewportSize();
}
return GetViewBounds().size();
}
gfx::Vector2dF RenderWidgetHostViewChildFrame::GetLastScrollOffset() const {
return last_scroll_offset_;
}
gfx::NativeView RenderWidgetHostViewChildFrame::GetNativeView() const {
// TODO(ekaramad): To accomodate MimeHandlerViewGuest while embedded inside
// OOPIF-webview, we need to return the native view to be used by
// RenderWidgetHostViewGuest. Remove this once https://crbug.com/642826 is
// fixed.
if (frame_connector_)
return frame_connector_->GetParentRenderWidgetHostView()->GetNativeView();
return nullptr;
}
gfx::NativeViewAccessible
RenderWidgetHostViewChildFrame::GetNativeViewAccessible() {
NOTREACHED();
return nullptr;
}
void RenderWidgetHostViewChildFrame::SetBackgroundColor(SkColor color) {
RenderWidgetHostViewBase::SetBackgroundColor(color);
bool opaque = GetBackgroundOpaque();
host_->SetBackgroundOpaque(opaque);
}
gfx::Size RenderWidgetHostViewChildFrame::GetPhysicalBackingSize() const {
gfx::Size size;
if (frame_connector_) {
content::ScreenInfo screen_info;
host_->GetScreenInfo(&screen_info);
size = gfx::ScaleToCeiledSize(frame_connector_->ChildFrameRect().size(),
screen_info.device_scale_factor);
}
return size;
}
void RenderWidgetHostViewChildFrame::InitAsPopup(
RenderWidgetHostView* parent_host_view,
const gfx::Rect& bounds) {
NOTREACHED();
}
void RenderWidgetHostViewChildFrame::InitAsFullscreen(
RenderWidgetHostView* reference_host_view) {
NOTREACHED();
}
void RenderWidgetHostViewChildFrame::UpdateCursor(const WebCursor& cursor) {
if (frame_connector_)
frame_connector_->UpdateCursor(cursor);
}
void RenderWidgetHostViewChildFrame::SetIsLoading(bool is_loading) {
// It is valid for an inner WebContents's SetIsLoading() to end up here.
// This is because an inner WebContents's main frame's RenderWidgetHostView
// is a RenderWidgetHostViewChildFrame. In contrast, when there is no
// inner/outer WebContents, only subframe's RenderWidgetHostView can be a
// RenderWidgetHostViewChildFrame which do not get a SetIsLoading() call.
if (GuestMode::IsCrossProcessFrameGuest(
WebContents::FromRenderViewHost(RenderViewHost::From(host_))))
return;
NOTREACHED();
}
void RenderWidgetHostViewChildFrame::RenderProcessGone(
base::TerminationStatus status,
int error_code) {
if (frame_connector_)
frame_connector_->RenderProcessGone();
Destroy();
}
void RenderWidgetHostViewChildFrame::Destroy() {
// FrameSinkIds registered with RenderWidgetHostInputEventRouter
// have already been cleared when RenderWidgetHostViewBase notified its
// observers of our impending destruction.
if (frame_connector_) {
frame_connector_->set_view(nullptr);
SetCrossProcessFrameConnector(nullptr);
}
// We notify our observers about shutdown here since we are about to release
// host_ and do not want any event calls coming from
// RenderWidgetHostInputEventRouter afterwards.
NotifyObserversAboutShutdown();
host_->SetView(nullptr);
host_ = nullptr;
delete this;
}
void RenderWidgetHostViewChildFrame::SetTooltipText(
const base::string16& tooltip_text) {
frame_connector_->GetRootRenderWidgetHostView()->SetTooltipText(tooltip_text);
}
RenderWidgetHostViewBase* RenderWidgetHostViewChildFrame::GetParentView() {
if (!frame_connector_)
return nullptr;
return frame_connector_->GetParentRenderWidgetHostView();
}
void RenderWidgetHostViewChildFrame::RegisterFrameSinkId() {
// If Destroy() has been called before we get here, host_ may be null.
if (host_ && host_->delegate() && host_->delegate()->GetInputEventRouter()) {
RenderWidgetHostInputEventRouter* router =
host_->delegate()->GetInputEventRouter();
if (!router->is_registered(frame_sink_id_))
router->AddFrameSinkIdOwner(frame_sink_id_, this);
}
}
void RenderWidgetHostViewChildFrame::UnregisterFrameSinkId() {
DCHECK(host_);
if (host_->delegate() && host_->delegate()->GetInputEventRouter()) {
host_->delegate()->GetInputEventRouter()->RemoveFrameSinkIdOwner(
frame_sink_id_);
}
}
void RenderWidgetHostViewChildFrame::UpdateViewportIntersection(
const gfx::Rect& viewport_intersection) {
if (host_)
host_->Send(new ViewMsg_SetViewportIntersection(host_->GetRoutingID(),
viewport_intersection));
}
void RenderWidgetHostViewChildFrame::GestureEventAck(
const blink::WebGestureEvent& event,
InputEventAckState ack_result) {
bool not_consumed = ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED ||
ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
// GestureScrollBegin is consumed by the target frame and not forwarded,
// because we don't know whether we will need to bubble scroll until we
// receive a GestureScrollUpdate ACK. GestureScrollUpdate with unused
// scroll extent is forwarded for bubbling, while GestureScrollEnd is
// always forwarded and handled according to current scroll state in the
// RenderWidgetHostInputEventRouter.
if (!frame_connector_)
return;
if ((event.type() == blink::WebInputEvent::GestureScrollUpdate &&
not_consumed) ||
event.type() == blink::WebInputEvent::GestureScrollEnd)
frame_connector_->BubbleScrollEvent(event);
}
void RenderWidgetHostViewChildFrame::DidReceiveCompositorFrameAck() {
if (!host_)
return;
host_->Send(new ViewMsg_ReclaimCompositorResources(
host_->GetRoutingID(), last_compositor_frame_sink_id_,
true /* is_swap_ack */, cc::ReturnedResourceArray()));
}
bool RenderWidgetHostViewChildFrame::ShouldCreateNewSurfaceId(
uint32_t compositor_frame_sink_id,
const cc::CompositorFrame& frame) {
gfx::Size new_frame_size = frame.render_pass_list.back()->output_rect.size();
float new_scale_factor = frame.metadata.device_scale_factor;
return compositor_frame_sink_id != last_compositor_frame_sink_id_ ||
new_frame_size != current_surface_size_ ||
new_scale_factor != current_surface_scale_factor_;
}
void RenderWidgetHostViewChildFrame::ProcessCompositorFrame(
uint32_t compositor_frame_sink_id,
cc::CompositorFrame frame) {
if (ShouldCreateNewSurfaceId(compositor_frame_sink_id, frame)) {
ClearCompositorSurfaceIfNecessary();
// If the renderer changed its frame sink, reset the
// CompositorFrameSinkSupport to avoid returning stale resources.
if (compositor_frame_sink_id != last_compositor_frame_sink_id_) {
ResetCompositorFrameSinkSupport();
CreateCompositorFrameSinkSupport();
}
last_compositor_frame_sink_id_ = compositor_frame_sink_id;
current_surface_size_ = frame.render_pass_list.back()->output_rect.size();
current_surface_scale_factor_ = frame.metadata.device_scale_factor;
}
bool allocated_new_local_surface_id = false;
if (!local_surface_id_.is_valid()) {
local_surface_id_ = id_allocator_->GenerateId();
allocated_new_local_surface_id = true;
}
support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
if (allocated_new_local_surface_id)
SendSurfaceInfoToEmbedder();
ProcessFrameSwappedCallbacks();
}
void RenderWidgetHostViewChildFrame::SendSurfaceInfoToEmbedder() {
cc::SurfaceSequence sequence =
cc::SurfaceSequence(frame_sink_id_, next_surface_sequence_++);
cc::SurfaceManager* manager = GetSurfaceManager();
cc::SurfaceId surface_id(frame_sink_id_, local_surface_id_);
// The renderer process will satisfy this dependency when it creates a
// SurfaceLayer.
manager->GetSurfaceForId(surface_id)->AddDestructionDependency(sequence);
cc::SurfaceInfo surface_info(surface_id, current_surface_scale_factor_,
current_surface_size_);
SendSurfaceInfoToEmbedderImpl(surface_info, sequence);
}
void RenderWidgetHostViewChildFrame::SendSurfaceInfoToEmbedderImpl(
const cc::SurfaceInfo& surface_info,
const cc::SurfaceSequence& sequence) {
frame_connector_->SetChildFrameSurface(surface_info, sequence);
}
void RenderWidgetHostViewChildFrame::OnSwapCompositorFrame(
uint32_t compositor_frame_sink_id,
cc::CompositorFrame frame) {
TRACE_EVENT0("content",
"RenderWidgetHostViewChildFrame::OnSwapCompositorFrame");
last_scroll_offset_ = frame.metadata.root_scroll_offset;
if (!frame_connector_)
return;
ProcessCompositorFrame(compositor_frame_sink_id, std::move(frame));
}
void RenderWidgetHostViewChildFrame::ProcessFrameSwappedCallbacks() {
// We only use callbacks once, therefore we make a new list for registration
// before we start, and discard the old list entries when we are done.
FrameSwappedCallbackList process_callbacks;
process_callbacks.swap(frame_swapped_callbacks_);
for (std::unique_ptr<base::Closure>& callback : process_callbacks)
callback->Run();
}
gfx::Rect RenderWidgetHostViewChildFrame::GetBoundsInRootWindow() {
gfx::Rect rect;
if (frame_connector_) {
RenderWidgetHostViewBase* root_view =
frame_connector_->GetRootRenderWidgetHostView();
// The root_view can be null in tests when using a TestWebContents.
if (root_view)
rect = root_view->GetBoundsInRootWindow();
}
return rect;
}
void RenderWidgetHostViewChildFrame::ProcessAckedTouchEvent(
const TouchEventWithLatencyInfo& touch,
InputEventAckState ack_result) {
if (!frame_connector_)
return;
frame_connector_->ForwardProcessAckedTouchEvent(touch, ack_result);
}
bool RenderWidgetHostViewChildFrame::LockMouse() {
if (frame_connector_)
return frame_connector_->LockMouse();
return false;
}
void RenderWidgetHostViewChildFrame::UnlockMouse() {
if (host_->delegate() && host_->delegate()->HasMouseLock(host_) &&
frame_connector_)
frame_connector_->UnlockMouse();
}
bool RenderWidgetHostViewChildFrame::IsMouseLocked() {
if (!host_->delegate())
return false;
return host_->delegate()->HasMouseLock(host_);
}
cc::FrameSinkId RenderWidgetHostViewChildFrame::GetFrameSinkId() {
return frame_sink_id_;
}
void RenderWidgetHostViewChildFrame::ProcessKeyboardEvent(
const NativeWebKeyboardEvent& event) {
host_->ForwardKeyboardEvent(event);
}
void RenderWidgetHostViewChildFrame::ProcessMouseEvent(
const blink::WebMouseEvent& event,
const ui::LatencyInfo& latency) {
host_->ForwardMouseEventWithLatencyInfo(event, latency);
}
void RenderWidgetHostViewChildFrame::ProcessMouseWheelEvent(
const blink::WebMouseWheelEvent& event,
const ui::LatencyInfo& latency) {
if (event.deltaX != 0 || event.deltaY != 0)
host_->ForwardWheelEventWithLatencyInfo(event, latency);
}
void RenderWidgetHostViewChildFrame::ProcessTouchEvent(
const blink::WebTouchEvent& event,
const ui::LatencyInfo& latency) {
if (event.type() == blink::WebInputEvent::TouchStart && frame_connector_ &&
!frame_connector_->HasFocus()) {
frame_connector_->FocusRootView();
}
host_->ForwardTouchEventWithLatencyInfo(event, latency);
}
void RenderWidgetHostViewChildFrame::ProcessGestureEvent(
const blink::WebGestureEvent& event,
const ui::LatencyInfo& latency) {
host_->ForwardGestureEventWithLatencyInfo(event, latency);
}
gfx::Point RenderWidgetHostViewChildFrame::TransformPointToRootCoordSpace(
const gfx::Point& point) {
if (!frame_connector_ || !local_surface_id_.is_valid())
return point;
return frame_connector_->TransformPointToRootCoordSpace(
point, cc::SurfaceId(frame_sink_id_, local_surface_id_));
}
bool RenderWidgetHostViewChildFrame::TransformPointToLocalCoordSpace(
const gfx::Point& point,
const cc::SurfaceId& original_surface,
gfx::Point* transformed_point) {
*transformed_point = point;
if (!frame_connector_ || !local_surface_id_.is_valid())
return false;
return frame_connector_->TransformPointToLocalCoordSpace(
point, original_surface, cc::SurfaceId(frame_sink_id_, local_surface_id_),
transformed_point);
}
bool RenderWidgetHostViewChildFrame::TransformPointToCoordSpaceForView(
const gfx::Point& point,
RenderWidgetHostViewBase* target_view,
gfx::Point* transformed_point) {
if (!frame_connector_ || !local_surface_id_.is_valid())
return false;
if (target_view == this) {
*transformed_point = point;
return true;
}
return frame_connector_->TransformPointToCoordSpaceForView(
point, target_view, cc::SurfaceId(frame_sink_id_, local_surface_id_),
transformed_point);
}
bool RenderWidgetHostViewChildFrame::IsRenderWidgetHostViewChildFrame() {
return true;
}
#if defined(OS_MACOSX)
ui::AcceleratedWidgetMac*
RenderWidgetHostViewChildFrame::GetAcceleratedWidgetMac() const {
return nullptr;
}
void RenderWidgetHostViewChildFrame::SetActive(bool active) {
}
void RenderWidgetHostViewChildFrame::ShowDefinitionForSelection() {
}
bool RenderWidgetHostViewChildFrame::SupportsSpeech() const {
return false;
}
void RenderWidgetHostViewChildFrame::SpeakSelection() {
}
bool RenderWidgetHostViewChildFrame::IsSpeaking() const {
return false;
}
void RenderWidgetHostViewChildFrame::StopSpeaking() {}
#endif // defined(OS_MACOSX)
void RenderWidgetHostViewChildFrame::RegisterFrameSwappedCallback(
std::unique_ptr<base::Closure> callback) {
frame_swapped_callbacks_.push_back(std::move(callback));
}
void RenderWidgetHostViewChildFrame::CopyFromSurface(
const gfx::Rect& src_rect,
const gfx::Size& output_size,
const ReadbackRequestCallback& callback,
const SkColorType preferred_color_type) {
if (!IsSurfaceAvailableForCopy()) {
// Defer submitting the copy request until after a frame is drawn, at which
// point we should be guaranteed that the surface is available.
RegisterFrameSwappedCallback(base::MakeUnique<base::Closure>(base::Bind(
&RenderWidgetHostViewChildFrame::SubmitSurfaceCopyRequest, AsWeakPtr(),
src_rect, output_size, callback, preferred_color_type)));
return;
}
SubmitSurfaceCopyRequest(src_rect, output_size, callback,
preferred_color_type);
}
void RenderWidgetHostViewChildFrame::SubmitSurfaceCopyRequest(
const gfx::Rect& src_subrect,
const gfx::Size& output_size,
const ReadbackRequestCallback& callback,
const SkColorType preferred_color_type) {
DCHECK(IsSurfaceAvailableForCopy());
DCHECK(support_);
std::unique_ptr<cc::CopyOutputRequest> request =
cc::CopyOutputRequest::CreateRequest(
base::Bind(&CopyFromCompositingSurfaceHasResult, output_size,
preferred_color_type, callback));
if (!src_subrect.IsEmpty())
request->set_area(src_subrect);
support_->RequestCopyOfSurface(std::move(request));
}
bool RenderWidgetHostViewChildFrame::HasAcceleratedSurface(
const gfx::Size& desired_size) {
return false;
}
void RenderWidgetHostViewChildFrame::ReclaimResources(
const cc::ReturnedResourceArray& resources) {
if (!host_)
return;
host_->Send(new ViewMsg_ReclaimCompositorResources(
host_->GetRoutingID(), last_compositor_frame_sink_id_,
false /* is_swap_ack */, resources));
}
void RenderWidgetHostViewChildFrame::OnBeginFrame(
const cc::BeginFrameArgs& args) {
host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), args));
}
void RenderWidgetHostViewChildFrame::SetNeedsBeginFrames(
bool needs_begin_frames) {
if (support_)
support_->SetNeedsBeginFrame(needs_begin_frames);
}
InputEventAckState RenderWidgetHostViewChildFrame::FilterInputEvent(
const blink::WebInputEvent& input_event) {
if (input_event.type() == blink::WebInputEvent::GestureFlingStart) {
const blink::WebGestureEvent& gesture_event =
static_cast<const blink::WebGestureEvent&>(input_event);
// Zero-velocity touchpad flings are an Aura-specific signal that the
// touchpad scroll has ended, and should not be forwarded to the renderer.
if (gesture_event.sourceDevice == blink::WebGestureDeviceTouchpad &&
!gesture_event.data.flingStart.velocityX &&
!gesture_event.data.flingStart.velocityY) {
// Here we indicate that there was no consumer for this event, as
// otherwise the fling animation system will try to run an animation
// and will also expect a notification when the fling ends. Since
// CrOS just uses the GestureFlingStart with zero-velocity as a means
// of indicating that touchpad scroll has ended, we don't actually want
// a fling animation.
// Note: this event handling is modeled on similar code in
// TenderWidgetHostViewAura::FilterInputEvent().
return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
}
}
return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
}
BrowserAccessibilityManager*
RenderWidgetHostViewChildFrame::CreateBrowserAccessibilityManager(
BrowserAccessibilityDelegate* delegate, bool for_root_frame) {
return BrowserAccessibilityManager::Create(
BrowserAccessibilityManager::GetEmptyDocument(), delegate);
}
void RenderWidgetHostViewChildFrame::ClearCompositorSurfaceIfNecessary() {
if (support_)
support_->EvictFrame();
local_surface_id_ = cc::LocalSurfaceId();
}
bool RenderWidgetHostViewChildFrame::IsChildFrameForTesting() const {
return true;
}
cc::SurfaceId RenderWidgetHostViewChildFrame::SurfaceIdForTesting() const {
return cc::SurfaceId(frame_sink_id_, local_surface_id_);
};
void RenderWidgetHostViewChildFrame::CreateCompositorFrameSinkSupport() {
DCHECK(!support_);
support_ = base::MakeUnique<cc::CompositorFrameSinkSupport>(
this, GetSurfaceManager(), frame_sink_id_, false /* is_root */,
false /* handles_frame_sink_id_invalidation */,
true /* needs_sync_points */);
if (parent_frame_sink_id_.is_valid()) {
GetSurfaceManager()->RegisterFrameSinkHierarchy(parent_frame_sink_id_,
frame_sink_id_);
}
if (host_->needs_begin_frames())
support_->SetNeedsBeginFrame(true);
}
void RenderWidgetHostViewChildFrame::ResetCompositorFrameSinkSupport() {
if (!support_)
return;
if (parent_frame_sink_id_.is_valid()) {
GetSurfaceManager()->UnregisterFrameSinkHierarchy(parent_frame_sink_id_,
frame_sink_id_);
}
support_.reset();
}
} // namespace content