Index: content/browser/renderer_host/render_widget_host_view_cast.cc |
diff --git a/content/browser/renderer_host/render_widget_host_view_cast.cc b/content/browser/renderer_host/render_widget_host_view_cast.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..98d9e3f093037922d3341ab3e7263a2570f9c66b |
--- /dev/null |
+++ b/content/browser/renderer_host/render_widget_host_view_cast.cc |
@@ -0,0 +1,414 @@ |
+// 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/renderer_host/render_widget_host_view_cast.h" |
+ |
+#include "base/debug/trace_event.h" |
+#include "base/logging.h" |
+#include "base/message_loop/message_loop.h" |
+#include "content/browser/renderer_host/render_view_host_impl.h" |
+#include "content/common/gpu/gpu_messages.h" |
+#include "content/common/host_shared_bitmap_manager.h" |
+#include "content/common/view_messages.h" |
+#include "content/port/browser/render_widget_host_view_port.h" |
+#include "skia/ext/platform_canvas.h" |
+#include "third_party/WebKit/public/platform/WebScreenInfo.h" |
+#include "ui/gfx/chromecast/gfx_plane.h" |
+#include "ui/gfx/chromecast/surface.h" |
+ |
+namespace content { |
+ |
+namespace { |
+const int kARGBSizeInBytes = 4; |
+} // namespace |
+ |
+// static |
+void RenderWidgetHostViewPort::GetDefaultScreenInfo( |
+ blink::WebScreenInfo* results) { |
+ results->depthPerComponent = 8; |
+ results->depth = 8; |
+ results->isMonochrome = false; |
+ results->rect = blink::WebRect(0, 0, 1280, 720); |
+ results->availableRect = results->rect; |
+ NOTIMPLEMENTED(); |
+} |
+ |
+RenderWidgetHostViewCast::RenderWidgetHostViewCast( |
+ RenderWidgetHost* widget_host) |
+ : host_(RenderWidgetHostImpl::From(widget_host)), |
+ about_to_validate_and_paint_(false), |
+ is_hidden_(false), |
+ is_loading_(false), |
+ is_fullscreen_(false) { |
+ host_->SetView(this); |
+} |
+ |
+RenderWidgetHostViewCast::~RenderWidgetHostViewCast() { |
+ UnlockMouse(); |
+} |
+ |
+void RenderWidgetHostViewCast::InitAsChild( |
+ gfx::NativeView parent_view) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void RenderWidgetHostViewCast::InitAsPopup( |
+ RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void RenderWidgetHostViewCast::InitAsFullscreen( |
+ RenderWidgetHostView* parent_view) { |
+ is_fullscreen_ = true; |
+ NOTIMPLEMENTED(); |
+} |
+ |
+RenderWidgetHost* RenderWidgetHostViewCast::GetRenderWidgetHost() const { |
+ return host_; |
+} |
+ |
+void RenderWidgetHostViewCast::WasShown() { |
+ if (!is_hidden_) |
+ return; |
+ |
+ is_hidden_ = false; |
+ host_->WasShown(); |
+} |
+ |
+void RenderWidgetHostViewCast::WasHidden() { |
+ if (is_hidden_) |
+ return; |
+ |
+ // If we receive any more paint messages while we are hidden, we want to |
+ // ignore them so we don't re-allocate the backing store. We will paint |
+ // everything again when we become selected again. |
+ is_hidden_ = true; |
+ |
+ // If we have a renderer, then inform it that we are being hidden so it can |
+ // reduce its resource utilization. |
+ host_->WasHidden(); |
+} |
+ |
+void RenderWidgetHostViewCast::SetSize(const gfx::Size& size) { |
+ // Update the size of the RWH. |
+ if (requested_size_.width() != size.width() || |
+ requested_size_.height() != size.height()) { |
+ requested_size_ = size; |
+ host_->WasResized(); |
+ } |
+} |
+ |
+void RenderWidgetHostViewCast::SetBounds(const gfx::Rect& rect) { |
+ // This is called when webkit has sent us a Move message. |
+ SetSize(rect.size()); |
+} |
+ |
+gfx::NativeView RenderWidgetHostViewCast::GetNativeView() const { |
+ NOTIMPLEMENTED(); |
+ return NULL; |
+} |
+ |
+gfx::NativeViewId RenderWidgetHostViewCast::GetNativeViewId() const { |
+ NOTIMPLEMENTED(); |
+ return 0; |
+} |
+ |
+gfx::NativeViewAccessible |
+RenderWidgetHostViewCast::GetNativeViewAccessible() { |
+ NOTIMPLEMENTED(); |
+ return NULL; |
+} |
+ |
+void RenderWidgetHostViewCast::MovePluginWindows( |
+ const gfx::Vector2d& scroll_offset, |
+ const std::vector<WebPluginGeometry>& moves) { |
+ // Nothing to do since Chromecast doesn't use plugin. |
+} |
+ |
+void RenderWidgetHostViewCast::Focus() { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void RenderWidgetHostViewCast::Blur() { |
+ host_->Blur(); |
+} |
+ |
+bool RenderWidgetHostViewCast::HasFocus() const { |
+ NOTIMPLEMENTED() << "Bogus value returned"; |
+ return true; |
+} |
+ |
+bool RenderWidgetHostViewCast::IsSurfaceAvailableForCopy() const { |
+ return true; |
+} |
+ |
+void RenderWidgetHostViewCast::Show() { |
+ is_hidden_ = false; |
+} |
+ |
+void RenderWidgetHostViewCast::Hide() { |
+ is_hidden_ = true; |
+} |
+ |
+bool RenderWidgetHostViewCast::IsShowing() { |
+ return !is_hidden_; |
+} |
+ |
+gfx::Rect RenderWidgetHostViewCast::GetViewBounds() const { |
+ return gfx::Rect(0, 0, requested_size_.width(), requested_size_.height()); |
+} |
+ |
+void RenderWidgetHostViewCast::UpdateCursor(const WebCursor& cursor) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void RenderWidgetHostViewCast::SetIsLoading(bool is_loading) { |
+ is_loading_ = is_loading; |
+} |
+ |
+void RenderWidgetHostViewCast::TextInputTypeChanged( |
+ ui::TextInputType type, ui::TextInputMode mode, bool can_compose_inline) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void RenderWidgetHostViewCast::ImeCancelComposition() { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void RenderWidgetHostViewCast::DidUpdateBackingStore( |
+ const gfx::Rect& scroll_rect, |
+ const gfx::Vector2d& scroll_delta, |
+ const std::vector<gfx::Rect>& copy_rects, |
+ const std::vector<ui::LatencyInfo>& latency_info) { |
+ for (size_t i = 0; i < latency_info.size(); i++) |
+ software_latency_info_.push_back(latency_info[i]); |
+ TRACE_EVENT0("ui::chromecast", |
+ "RenderWidgetHostViewCast::DidUpdateBackingStore"); |
+ |
+ if (is_hidden_) |
+ return; |
+ |
+ if (about_to_validate_and_paint_) |
+ invalid_rect_.Union(scroll_rect); |
+ else |
+ Paint(scroll_rect); |
+ |
+ for (size_t i = 0; i < copy_rects.size(); ++i) { |
+ // Avoid double painting. NOTE: This is only relevant given the call to |
+ // Paint(scroll_rect) above. |
+ gfx::Rect rect = gfx::SubtractRects(copy_rects[i], scroll_rect); |
+ if (rect.IsEmpty()) |
+ continue; |
+ |
+ if (about_to_validate_and_paint_) |
+ invalid_rect_.Union(rect); |
+ else |
+ Paint(rect); |
+ } |
+} |
+ |
+void RenderWidgetHostViewCast::RenderProcessGone( |
+ base::TerminationStatus status, int error_code) { |
+ Destroy(); |
+} |
+ |
+void RenderWidgetHostViewCast::Destroy() { |
+ // The RenderWidgetHost's destruction led here, so don't call it. |
+ host_ = NULL; |
+ |
+ // Delete the surface so that GfxPlane will not complain if/when we |
+ // destroy the plane. |
+ if (surface_) { |
+ VLOG(1) << "gfx surface on the primary plane deleted."; |
+ surface_.reset(); |
+ } |
+ |
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
+} |
+ |
+void RenderWidgetHostViewCast::SetTooltipText( |
+ const base::string16& tooltip_text) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void RenderWidgetHostViewCast::SelectionBoundsChanged( |
+ const ViewHostMsg_SelectionBounds_Params& params) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void RenderWidgetHostViewCast::ScrollOffsetChanged() { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void RenderWidgetHostViewCast::CopyFromCompositingSurface( |
+ const gfx::Rect& subrect, |
+ const gfx::Size& size, |
+ const base::Callback<void(bool, const SkBitmap&)>& callback, |
+ const SkBitmap::Config config) { |
+ NOTIMPLEMENTED(); |
+ callback.Run(false, SkBitmap()); |
+} |
+ |
+void RenderWidgetHostViewCast::CopyFromCompositingSurfaceToVideoFrame( |
+ const gfx::Rect& src_subrect, |
+ const scoped_refptr<media::VideoFrame>& target, |
+ const base::Callback<void(bool)>& callback) { |
+ NOTIMPLEMENTED(); |
+ callback.Run(false); |
+} |
+ |
+bool RenderWidgetHostViewCast::CanCopyToVideoFrame() const { |
+ return false; |
+} |
+ |
+void RenderWidgetHostViewCast::AcceleratedSurfaceInitialized(int host_id, |
+ int route_id) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void RenderWidgetHostViewCast::AcceleratedSurfaceBuffersSwapped( |
+ const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, |
+ int gpu_host_id) { |
+ AcceleratedSurfaceMsg_BufferPresented_Params ack_params; |
+ ack_params.sync_point = 0; |
+ RenderWidgetHostImpl::AcknowledgeBufferPresent( |
+ params.route_id, gpu_host_id, ack_params); |
+} |
+ |
+void RenderWidgetHostViewCast::AcceleratedSurfacePostSubBuffer( |
+ const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, |
+ int gpu_host_id) { |
+ AcceleratedSurfaceMsg_BufferPresented_Params ack_params; |
+ ack_params.sync_point = 0; |
+ RenderWidgetHostImpl::AcknowledgeBufferPresent( |
+ params.route_id, gpu_host_id, ack_params); |
+} |
+ |
+void RenderWidgetHostViewCast::AcceleratedSurfaceSuspend() { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void RenderWidgetHostViewCast::AcceleratedSurfaceRelease() { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+bool RenderWidgetHostViewCast::HasAcceleratedSurface( |
+ const gfx::Size& desired_size) { |
+ return false; |
+} |
+ |
+void RenderWidgetHostViewCast::SetBackground(const SkBitmap& background) { |
+ RenderWidgetHostViewBase::SetBackground(background); |
+ host_->Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background)); |
+} |
+ |
+void RenderWidgetHostViewCast::Paint(const gfx::Rect& damage_rect) { |
+ TRACE_EVENT0("ui::chromecast", "RenderWidgetHostViewCast::Paint"); |
+ |
+ // If the GPU process is rendering directly into the View, |
+ // call the compositor directly. |
+ RenderWidgetHostImpl* render_widget_host = |
+ RenderWidgetHostImpl::From(GetRenderWidgetHost()); |
+ if (render_widget_host->is_accelerated_compositing_active()) { |
+ host_->ScheduleComposite(); |
+ return; |
+ } |
+ NOTREACHED() << "Software rendering is deprecated"; |
+} |
+ |
+void RenderWidgetHostViewCast::SetHasHorizontalScrollbar( |
+ bool has_horizontal_scrollbar) { |
+} |
+ |
+void RenderWidgetHostViewCast::SetScrollOffsetPinning( |
+ bool is_pinned_to_left, bool is_pinned_to_right) { |
+} |
+ |
+void RenderWidgetHostViewCast::OnAcceleratedCompositingStateChange() { |
+ // TODO(lcwu): Work out if this is the right place to create the surface. |
+ if (host_->is_accelerated_compositing_active()) { |
+ DCHECK(!surface_); |
+ VLOG(1) << "Creating chromecast surface"; |
+ surface_.reset(gfx::chromecast::GfxPlane::GetPrimary()->CreateSurface( |
+ requested_size_)); |
+ } else { |
+ surface_.reset(); |
+ } |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void RenderWidgetHostViewCast::GetScreenInfo(blink::WebScreenInfo* results) { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+gfx::Rect RenderWidgetHostViewCast::GetBoundsInRootWindow() { |
+ NOTIMPLEMENTED() << "Bogus size returned"; |
+ return gfx::Rect(0, 0, 1280, 720); |
+} |
+ |
+gfx::GLSurfaceHandle RenderWidgetHostViewCast::GetCompositingSurface() { |
+ NOTIMPLEMENTED(); |
+ return gfx::GLSurfaceHandle(); |
+} |
+ |
+bool RenderWidgetHostViewCast::LockMouse() { |
+ NOTIMPLEMENTED(); |
+ return false; |
+} |
+ |
+void RenderWidgetHostViewCast::UnlockMouse() { |
+ NOTIMPLEMENTED(); |
+} |
+ |
+void RenderWidgetHostViewCast::OnSwapCompositorFrame( |
+ uint32 output_surface_id, |
+ scoped_ptr<cc::CompositorFrame> frame) { |
+ DCHECK(frame->software_frame_data); |
+ scoped_ptr<cc::SoftwareFrameData> sw_frame_data( |
+ frame->software_frame_data.Pass()); |
+ if (surface_) { |
+ const gfx::Size& frame_size = sw_frame_data->size; |
+ const gfx::Rect& damage_rect = sw_frame_data->damage_rect; |
+ VLOG(1) << "damaged rect: " << damage_rect.ToString(); |
+ |
+ scoped_ptr<cc::SharedBitmap> bitmap = |
+ HostSharedBitmapManager::current()->GetSharedBitmapFromId( |
+ frame_size, sw_frame_data->bitmap_id); |
+ if (!bitmap) { |
+ LOG(ERROR) << "Cannot get the shared bitmap by id."; |
+ return; |
+ } |
+ |
+ base::SharedMemory* shared_memory = bitmap->memory(); |
+ |
+ const size_t size_in_bytes = kARGBSizeInBytes * frame_size.GetArea(); |
+ shared_memory->Map(size_in_bytes); |
+ |
+ void* memory = shared_memory->memory(); |
+ |
+ gfx::Rect fullFrame(frame_size.width(), frame_size.height()); |
+ |
+ surface_->CopyBitmap(static_cast<char*>(memory), fullFrame, damage_rect, |
+ damage_rect.origin()); |
+ |
+ surface_->Display(damage_rect, damage_rect.origin()); |
+ } |
+ |
+ cc::CompositorFrameAck ack; |
+ ack.last_software_frame_id = sw_frame_data->id; |
+ RenderWidgetHostImpl::SendSwapCompositorFrameAck( |
+ host_->GetRoutingID(), output_surface_id, host_->GetProcess()->GetID(), |
+ ack); |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+// RenderWidgetHostView, public: |
+ |
+// static |
+RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( |
+ RenderWidgetHost* widget) { |
+ return new RenderWidgetHostViewCast(widget); |
+} |
+ |
+} // namespace content |