1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/render_widget_host_view_android.h"
7 #include <android/bitmap.h>
9 #include "base/android/sys_utils.h"
10 #include "base/basictypes.h"
11 #include "base/bind.h"
12 #include "base/callback_helpers.h"
13 #include "base/command_line.h"
14 #include "base/logging.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/metrics/histogram.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/threading/worker_pool.h"
19 #include "cc/base/latency_info_swap_promise.h"
20 #include "cc/layers/delegated_frame_provider.h"
21 #include "cc/layers/delegated_renderer_layer.h"
22 #include "cc/layers/layer.h"
23 #include "cc/layers/texture_layer.h"
24 #include "cc/output/compositor_frame.h"
25 #include "cc/output/compositor_frame_ack.h"
26 #include "cc/output/copy_output_request.h"
27 #include "cc/output/copy_output_result.h"
28 #include "cc/resources/single_release_callback.h"
29 #include "cc/trees/layer_tree_host.h"
30 #include "content/browser/accessibility/browser_accessibility_manager_android.h"
31 #include "content/browser/android/content_view_core_impl.h"
32 #include "content/browser/android/in_process/synchronous_compositor_impl.h"
33 #include "content/browser/android/overscroll_glow.h"
34 #include "content/browser/devtools/render_view_devtools_agent_host.h"
35 #include "content/browser/gpu/gpu_data_manager_impl.h"
36 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
37 #include "content/browser/gpu/gpu_surface_tracker.h"
38 #include "content/browser/renderer_host/compositor_impl_android.h"
39 #include "content/browser/renderer_host/dip_util.h"
40 #include "content/browser/renderer_host/image_transport_factory_android.h"
41 #include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
42 #include "content/browser/renderer_host/render_process_host_impl.h"
43 #include "content/browser/renderer_host/render_widget_host_impl.h"
44 #include "content/common/gpu/client/gl_helper.h"
45 #include "content/common/gpu/gpu_messages.h"
46 #include "content/common/input_messages.h"
47 #include "content/common/view_messages.h"
48 #include "content/public/browser/devtools_agent_host.h"
49 #include "content/public/browser/render_view_host.h"
50 #include "content/public/common/content_switches.h"
51 #include "gpu/command_buffer/client/gles2_interface.h"
52 #include "gpu/config/gpu_driver_bug_workaround_type.h"
53 #include "skia/ext/image_operations.h"
54 #include "third_party/khronos/GLES2/gl2.h"
55 #include "third_party/khronos/GLES2/gl2ext.h"
56 #include "third_party/skia/include/core/SkCanvas.h"
57 #include "ui/base/android/window_android.h"
58 #include "ui/base/android/window_android_compositor.h"
59 #include "ui/gfx/android/device_display_info.h"
60 #include "ui/gfx/android/java_bitmap.h"
61 #include "ui/gfx/display.h"
62 #include "ui/gfx/screen.h"
63 #include "ui/gfx/size_conversions.h"
69 const int kUndefinedOutputSurfaceId = -1;
70 static const char kAsyncReadBackString[] = "Compositing.CopyFromSurfaceTime";
72 void InsertSyncPointAndAckForCompositor(
74 uint32 output_surface_id,
76 const gpu::Mailbox& return_mailbox,
77 const gfx::Size return_size) {
78 cc::CompositorFrameAck ack;
79 ack.gl_frame_data.reset(new cc::GLFrameData());
80 if (!return_mailbox.IsZero()) {
81 ack.gl_frame_data->mailbox = return_mailbox;
82 ack.gl_frame_data->size = return_size;
83 ack.gl_frame_data->sync_point =
84 ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint();
86 RenderWidgetHostImpl::SendSwapCompositorFrameAck(
87 route_id, output_surface_id, renderer_host_id, ack);
90 // Sends an acknowledgement to the renderer of a processed IME event.
91 void SendImeEventAck(RenderWidgetHostImpl* host) {
92 host->Send(new ViewMsg_ImeEventAck(host->GetRoutingID()));
95 void CopyFromCompositingSurfaceFinished(
96 const base::Callback<void(bool, const SkBitmap&)>& callback,
97 scoped_ptr<cc::SingleReleaseCallback> release_callback,
98 scoped_ptr<SkBitmap> bitmap,
99 const base::TimeTicks& start_time,
100 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
102 bitmap_pixels_lock.reset();
103 release_callback->Run(0, false);
104 UMA_HISTOGRAM_TIMES(kAsyncReadBackString,
105 base::TimeTicks::Now() - start_time);
106 callback.Run(result, *bitmap);
109 ui::LatencyInfo CreateLatencyInfo(const blink::WebInputEvent& event) {
110 ui::LatencyInfo latency_info;
111 // The latency number should only be added if the timestamp is valid.
112 if (event.timeStampSeconds) {
113 const int64 time_micros = static_cast<int64>(
114 event.timeStampSeconds * base::Time::kMicrosecondsPerSecond);
115 latency_info.AddLatencyNumberWithTimestamp(
116 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
119 base::TimeTicks() + base::TimeDelta::FromMicroseconds(time_micros),
125 } // anonymous namespace
127 RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo(
129 scoped_ptr<cc::CompositorFrame> output_frame)
130 : output_surface_id(output_id), frame(output_frame.Pass()) {}
132 RenderWidgetHostViewAndroid::LastFrameInfo::~LastFrameInfo() {}
134 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
135 RenderWidgetHostImpl* widget_host,
136 ContentViewCoreImpl* content_view_core)
137 : host_(widget_host),
138 needs_begin_frame_(false),
139 is_showing_(!widget_host->is_hidden()),
140 content_view_core_(NULL),
141 ime_adapter_android_(this),
142 cached_background_color_(SK_ColorWHITE),
143 texture_id_in_layer_(0),
144 last_output_surface_id_(kUndefinedOutputSurfaceId),
145 weak_ptr_factory_(this),
146 overscroll_effect_enabled_(!CommandLine::ForCurrentProcess()->HasSwitch(
147 switches::kDisableOverscrollEdgeEffect)),
148 overscroll_effect_(OverscrollGlow::Create(overscroll_effect_enabled_)),
149 flush_input_requested_(false),
150 accelerated_surface_route_id_(0),
151 using_synchronous_compositor_(SynchronousCompositorImpl::FromID(
152 widget_host->GetProcess()->GetID(),
153 widget_host->GetRoutingID()) != NULL),
154 frame_evictor_(new DelegatedFrameEvictor(this)),
155 using_delegated_renderer_(CommandLine::ForCurrentProcess()->HasSwitch(
156 switches::kEnableDelegatedRenderer) &&
157 !CommandLine::ForCurrentProcess()->HasSwitch(
158 switches::kDisableDelegatedRenderer)),
159 locks_on_frame_count_(0),
160 root_window_destroyed_(false) {
161 if (!using_delegated_renderer_) {
162 texture_layer_ = cc::TextureLayer::Create(NULL);
163 layer_ = texture_layer_;
166 host_->SetView(this);
167 SetContentViewCore(content_view_core);
168 ImageTransportFactoryAndroid::AddObserver(this);
171 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
172 ImageTransportFactoryAndroid::RemoveObserver(this);
173 SetContentViewCore(NULL);
174 DCHECK(ack_callbacks_.empty());
175 if (texture_id_in_layer_) {
176 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
177 texture_id_in_layer_);
180 if (texture_layer_.get())
181 texture_layer_->ClearClient();
183 if (resource_collection_.get())
184 resource_collection_->SetClient(NULL);
188 bool RenderWidgetHostViewAndroid::OnMessageReceived(
189 const IPC::Message& message) {
191 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
192 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
193 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor,
194 OnDidChangeBodyBackgroundColor)
195 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame,
196 OnSetNeedsBeginFrame)
197 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
198 OnTextInputStateChanged)
199 IPC_MESSAGE_HANDLER(ViewHostMsg_SmartClipDataExtracted,
200 OnSmartClipDataExtracted)
201 IPC_MESSAGE_UNHANDLED(handled = false)
202 IPC_END_MESSAGE_MAP()
206 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
210 void RenderWidgetHostViewAndroid::InitAsPopup(
211 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
215 void RenderWidgetHostViewAndroid::InitAsFullscreen(
216 RenderWidgetHostView* reference_host_view) {
221 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
225 void RenderWidgetHostViewAndroid::WasShown() {
226 if (!host_ || !host_->is_hidden())
231 if (content_view_core_ && !using_synchronous_compositor_)
232 content_view_core_->GetWindowAndroid()->AddObserver(this);
235 void RenderWidgetHostViewAndroid::WasHidden() {
238 if (!host_ || host_->is_hidden())
241 // Inform the renderer that we are being hidden so it can reduce its resource
245 if (content_view_core_ && !using_synchronous_compositor_)
246 content_view_core_->GetWindowAndroid()->RemoveObserver(this);
249 void RenderWidgetHostViewAndroid::WasResized() {
253 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) {
254 // Ignore the given size as only the Java code has the power to
255 // resize the view on Android.
256 default_size_ = size;
260 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
261 SetSize(rect.size());
264 void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
266 SkBitmap::Config bitmap_config,
267 gfx::Rect src_subrect,
268 const base::Callback<void(bool, const SkBitmap&)>& result_callback) {
269 if (!IsSurfaceAvailableForCopy()) {
270 result_callback.Run(false, SkBitmap());
274 gfx::Size bounds = layer_->bounds();
275 if (src_subrect.IsEmpty())
276 src_subrect = gfx::Rect(bounds);
277 DCHECK_LE(src_subrect.width() + src_subrect.x(), bounds.width());
278 DCHECK_LE(src_subrect.height() + src_subrect.y(), bounds.height());
279 const gfx::Display& display =
280 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
281 float device_scale_factor = display.device_scale_factor();
282 DCHECK_GT(device_scale_factor, 0);
284 gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale / device_scale_factor)));
285 CopyFromCompositingSurface(
286 src_subrect, dst_size, result_callback, bitmap_config);
289 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
290 if (!content_view_core_)
295 if (texture_size_in_layer_.IsEmpty())
298 if (!frame_evictor_->HasFrame())
301 if (using_delegated_renderer_) {
302 if (!delegated_renderer_layer_.get())
305 if (texture_id_in_layer_ == 0)
312 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
313 return content_view_core_->GetViewAndroid();
316 gfx::NativeViewId RenderWidgetHostViewAndroid::GetNativeViewId() const {
317 return reinterpret_cast<gfx::NativeViewId>(
318 const_cast<RenderWidgetHostViewAndroid*>(this));
321 gfx::NativeViewAccessible
322 RenderWidgetHostViewAndroid::GetNativeViewAccessible() {
327 void RenderWidgetHostViewAndroid::MovePluginWindows(
328 const gfx::Vector2d& scroll_offset,
329 const std::vector<WebPluginGeometry>& moves) {
330 // We don't have plugin windows on Android. Do nothing. Note: this is called
331 // from RenderWidgetHost::OnUpdateRect which is itself invoked while
332 // processing the corresponding message from Renderer.
335 void RenderWidgetHostViewAndroid::Focus() {
337 host_->SetInputMethodActive(true);
338 if (overscroll_effect_enabled_)
339 overscroll_effect_->Enable();
342 void RenderWidgetHostViewAndroid::Blur() {
343 host_->ExecuteEditCommand("Unselect", "");
344 host_->SetInputMethodActive(false);
346 overscroll_effect_->Disable();
349 bool RenderWidgetHostViewAndroid::HasFocus() const {
350 if (!content_view_core_)
351 return false; // ContentViewCore not created yet.
353 return content_view_core_->HasFocus();
356 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
357 return HasValidFrame();
360 void RenderWidgetHostViewAndroid::Show() {
366 layer_->SetHideLayerAndSubtree(false);
368 frame_evictor_->SetVisible(true);
372 void RenderWidgetHostViewAndroid::Hide() {
378 layer_->SetHideLayerAndSubtree(true);
380 frame_evictor_->SetVisible(false);
384 bool RenderWidgetHostViewAndroid::IsShowing() {
385 // ContentViewCoreImpl represents the native side of the Java
386 // ContentViewCore. It being NULL means that it is not attached
387 // to the View system yet, so we treat this RWHVA as hidden.
388 return is_showing_ && content_view_core_;
391 void RenderWidgetHostViewAndroid::LockCompositingSurface() {
392 DCHECK(HasValidFrame());
394 DCHECK(frame_evictor_->HasFrame());
395 frame_evictor_->LockFrame();
396 locks_on_frame_count_++;
399 void RenderWidgetHostViewAndroid::UnlockCompositingSurface() {
400 if (!frame_evictor_->HasFrame() || locks_on_frame_count_ == 0)
403 DCHECK(HasValidFrame());
404 frame_evictor_->UnlockFrame();
405 locks_on_frame_count_--;
407 if (locks_on_frame_count_ == 0 && last_frame_info_) {
408 InternalSwapCompositorFrame(last_frame_info_->output_surface_id,
409 last_frame_info_->frame.Pass());
410 last_frame_info_.reset();
414 void RenderWidgetHostViewAndroid::ReleaseLocksOnSurface() {
415 if (!frame_evictor_->HasFrame()) {
416 DCHECK_EQ(locks_on_frame_count_, 0u);
419 while (locks_on_frame_count_ > 0) {
420 UnlockCompositingSurface();
425 gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const {
426 if (!content_view_core_)
427 return gfx::Rect(default_size_);
429 gfx::Size size = content_view_core_->GetViewportSizeDip();
430 gfx::Size offset = content_view_core_->GetViewportSizeOffsetDip();
431 size.Enlarge(-offset.width(), -offset.height());
433 return gfx::Rect(size);
436 gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
437 if (!content_view_core_)
440 return content_view_core_->GetPhysicalBackingSize();
443 float RenderWidgetHostViewAndroid::GetOverdrawBottomHeight() const {
444 if (!content_view_core_)
447 return content_view_core_->GetOverdrawBottomHeightDip();
450 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& cursor) {
451 // There are no cursors on Android.
454 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading) {
455 // Do nothing. The UI notification is handled through ContentViewClient which
456 // is TabContentsDelegate.
459 void RenderWidgetHostViewAndroid::TextInputTypeChanged(
460 ui::TextInputType type,
461 ui::TextInputMode input_mode,
462 bool can_compose_inline) {
463 // Unused on Android, which uses OnTextInputChanged instead.
466 long RenderWidgetHostViewAndroid::GetNativeImeAdapter() {
467 return reinterpret_cast<intptr_t>(&ime_adapter_android_);
470 void RenderWidgetHostViewAndroid::OnTextInputStateChanged(
471 const ViewHostMsg_TextInputState_Params& params) {
472 // If an acknowledgement is required for this event, regardless of how we exit
473 // from this method, we must acknowledge that we processed the input state
475 base::ScopedClosureRunner ack_caller;
476 if (params.require_ack)
477 ack_caller.Reset(base::Bind(&SendImeEventAck, host_));
482 content_view_core_->UpdateImeAdapter(
483 GetNativeImeAdapter(),
484 static_cast<int>(params.type),
485 params.value, params.selection_start, params.selection_end,
486 params.composition_start, params.composition_end,
487 params.show_ime_if_needed, params.require_ack);
490 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor(
492 if (cached_background_color_ == color)
495 cached_background_color_ = color;
496 if (content_view_core_)
497 content_view_core_->OnBackgroundColorChanged(color);
500 void RenderWidgetHostViewAndroid::SendBeginFrame(
501 const cc::BeginFrameArgs& args) {
502 TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::SendBeginFrame");
506 if (flush_input_requested_) {
507 flush_input_requested_ = false;
509 content_view_core_->RemoveBeginFrameSubscriber();
512 host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), args));
515 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame(
517 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame",
519 // ContentViewCoreImpl handles multiple subscribers to the BeginFrame, so
520 // we have to make sure calls to ContentViewCoreImpl's
521 // {Add,Remove}BeginFrameSubscriber are balanced, even if
522 // RenderWidgetHostViewAndroid's may not be.
523 if (content_view_core_ && needs_begin_frame_ != enabled) {
525 content_view_core_->AddBeginFrameSubscriber();
527 content_view_core_->RemoveBeginFrameSubscriber();
528 needs_begin_frame_ = enabled;
532 void RenderWidgetHostViewAndroid::OnStartContentIntent(
533 const GURL& content_url) {
534 if (content_view_core_)
535 content_view_core_->StartContentIntent(content_url);
538 void RenderWidgetHostViewAndroid::OnSmartClipDataExtracted(
539 const base::string16& result) {
540 // Custom serialization over IPC isn't allowed normally for security reasons.
541 // Since this feature is only used in (single-process) WebView, there are no
542 // security issues. Enforce that it's only called in single process mode.
543 CHECK(RenderProcessHost::run_renderer_in_process());
544 if (content_view_core_)
545 content_view_core_->OnSmartClipDataExtracted(result);
548 void RenderWidgetHostViewAndroid::ImeCancelComposition() {
549 ime_adapter_android_.CancelComposition();
552 void RenderWidgetHostViewAndroid::FocusedNodeChanged(bool is_editable_node) {
553 ime_adapter_android_.FocusedNodeChanged(is_editable_node);
556 void RenderWidgetHostViewAndroid::DidUpdateBackingStore(
557 const gfx::Rect& scroll_rect,
558 const gfx::Vector2d& scroll_delta,
559 const std::vector<gfx::Rect>& copy_rects,
560 const std::vector<ui::LatencyInfo>& latency_info) {
564 void RenderWidgetHostViewAndroid::RenderProcessGone(
565 base::TerminationStatus status, int error_code) {
569 void RenderWidgetHostViewAndroid::Destroy() {
571 SetContentViewCore(NULL);
573 // The RenderWidgetHost's destruction led here, so don't call it.
579 void RenderWidgetHostViewAndroid::SetTooltipText(
580 const base::string16& tooltip_text) {
581 // Tooltips don't makes sense on Android.
584 void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16& text,
586 const gfx::Range& range) {
587 RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
589 if (text.empty() || range.is_empty() || !content_view_core_)
591 size_t pos = range.GetMin() - offset;
592 size_t n = range.length();
594 DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
595 if (pos >= text.length()) {
596 NOTREACHED() << "The text can not cover range.";
600 std::string utf8_selection = base::UTF16ToUTF8(text.substr(pos, n));
602 content_view_core_->OnSelectionChanged(utf8_selection);
605 void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
606 const ViewHostMsg_SelectionBounds_Params& params) {
607 if (content_view_core_) {
608 content_view_core_->OnSelectionBoundsChanged(params);
612 void RenderWidgetHostViewAndroid::SelectionRootBoundsChanged(
613 const gfx::Rect& bounds) {
614 if (content_view_core_) {
615 content_view_core_->OnSelectionRootBoundsChanged(bounds);
619 void RenderWidgetHostViewAndroid::ScrollOffsetChanged() {
622 BackingStore* RenderWidgetHostViewAndroid::AllocBackingStore(
623 const gfx::Size& size) {
628 void RenderWidgetHostViewAndroid::SetBackground(const SkBitmap& background) {
629 RenderWidgetHostViewBase::SetBackground(background);
630 host_->Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background));
633 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
634 const gfx::Rect& src_subrect,
635 const gfx::Size& dst_size,
636 const base::Callback<void(bool, const SkBitmap&)>& callback,
637 const SkBitmap::Config bitmap_config) {
638 if (!IsReadbackConfigSupported(bitmap_config)) {
639 callback.Run(false, SkBitmap());
642 base::TimeTicks start_time = base::TimeTicks::Now();
643 if (!using_synchronous_compositor_ && !IsSurfaceAvailableForCopy()) {
644 callback.Run(false, SkBitmap());
647 const gfx::Display& display =
648 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
649 float device_scale_factor = display.device_scale_factor();
650 gfx::Size dst_size_in_pixel =
651 ConvertRectToPixel(device_scale_factor, gfx::Rect(dst_size)).size();
652 gfx::Rect src_subrect_in_pixel =
653 ConvertRectToPixel(device_scale_factor, src_subrect);
655 if (using_synchronous_compositor_) {
656 SynchronousCopyContents(src_subrect_in_pixel, dst_size_in_pixel, callback,
658 UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous",
659 base::TimeTicks::Now() - start_time);
663 scoped_ptr<cc::CopyOutputRequest> request;
664 scoped_refptr<cc::Layer> readback_layer;
665 if (using_delegated_renderer_) {
666 DCHECK(content_view_core_);
667 DCHECK(content_view_core_->GetWindowAndroid());
668 ui::WindowAndroidCompositor* compositor =
669 content_view_core_->GetWindowAndroid()->GetCompositor();
671 DCHECK(frame_provider_);
672 scoped_refptr<cc::DelegatedRendererLayer> delegated_layer =
673 cc::DelegatedRendererLayer::Create(frame_provider_);
674 delegated_layer->SetDisplaySize(texture_size_in_layer_);
675 delegated_layer->SetBounds(content_size_in_layer_);
676 delegated_layer->SetHideLayerAndSubtree(true);
677 delegated_layer->SetIsDrawable(true);
678 delegated_layer->SetContentsOpaque(true);
679 compositor->AttachLayerForReadback(delegated_layer);
681 readback_layer = delegated_layer;
682 request = cc::CopyOutputRequest::CreateRequest(
683 base::Bind(&RenderWidgetHostViewAndroid::
684 PrepareTextureCopyOutputResultForDelegatedReadback,
691 readback_layer = layer_;
692 request = cc::CopyOutputRequest::CreateRequest(
693 base::Bind(&RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult,
699 request->set_area(src_subrect_in_pixel);
700 readback_layer->RequestCopyOfOutput(request.Pass());
703 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
704 const gfx::Rect& src_subrect,
705 const scoped_refptr<media::VideoFrame>& target,
706 const base::Callback<void(bool)>& callback) {
711 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
715 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
716 const gfx::Rect& target_rect, const SkBitmap& zoomed_bitmap) {
717 if (!content_view_core_)
720 content_view_core_->ShowDisambiguationPopup(target_rect, zoomed_bitmap);
723 scoped_ptr<SyntheticGestureTarget>
724 RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
725 return scoped_ptr<SyntheticGestureTarget>(new SyntheticGestureTargetAndroid(
726 host_, content_view_core_->CreateTouchEventSynthesizer()));
729 void RenderWidgetHostViewAndroid::OnAcceleratedCompositingStateChange() {
732 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
733 uint32 output_surface_id) {
735 cc::CompositorFrameAck ack;
736 if (resource_collection_.get())
737 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
738 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_->GetRoutingID(),
740 host_->GetProcess()->GetID(),
744 void RenderWidgetHostViewAndroid::SendReturnedDelegatedResources(
745 uint32 output_surface_id) {
746 DCHECK(resource_collection_);
748 cc::CompositorFrameAck ack;
749 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
750 DCHECK(!ack.resources.empty());
752 RenderWidgetHostImpl::SendReclaimCompositorResources(
753 host_->GetRoutingID(),
755 host_->GetProcess()->GetID(),
759 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
760 if (ack_callbacks_.size())
762 SendReturnedDelegatedResources(last_output_surface_id_);
765 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
767 frame_provider_ = NULL;
768 delegated_renderer_layer_ = NULL;
772 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
773 uint32 output_surface_id,
774 scoped_ptr<cc::DelegatedFrameData> frame_data) {
775 bool has_content = !texture_size_in_layer_.IsEmpty();
777 if (output_surface_id != last_output_surface_id_) {
778 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
779 // any resources from the old output surface with the new output surface id.
780 if (resource_collection_.get()) {
781 if (resource_collection_->LoseAllResources())
782 SendReturnedDelegatedResources(last_output_surface_id_);
784 resource_collection_->SetClient(NULL);
785 resource_collection_ = NULL;
787 DestroyDelegatedContent();
789 last_output_surface_id_ = output_surface_id;
793 DestroyDelegatedContent();
795 if (!resource_collection_.get()) {
796 resource_collection_ = new cc::DelegatedFrameResourceCollection;
797 resource_collection_->SetClient(this);
799 if (!frame_provider_ ||
800 texture_size_in_layer_ != frame_provider_->frame_size()) {
802 frame_provider_ = new cc::DelegatedFrameProvider(
803 resource_collection_.get(), frame_data.Pass());
804 delegated_renderer_layer_ =
805 cc::DelegatedRendererLayer::Create(frame_provider_);
806 layer_ = delegated_renderer_layer_;
809 frame_provider_->SetFrameData(frame_data.Pass());
813 if (delegated_renderer_layer_.get()) {
814 delegated_renderer_layer_->SetDisplaySize(texture_size_in_layer_);
815 delegated_renderer_layer_->SetIsDrawable(true);
816 delegated_renderer_layer_->SetContentsOpaque(true);
817 delegated_renderer_layer_->SetBounds(content_size_in_layer_);
818 delegated_renderer_layer_->SetNeedsDisplay();
821 base::Closure ack_callback =
822 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
823 weak_ptr_factory_.GetWeakPtr(),
826 ack_callbacks_.push(ack_callback);
827 if (host_->is_hidden())
831 void RenderWidgetHostViewAndroid::ComputeContentsSize(
832 const cc::CompositorFrameMetadata& frame_metadata) {
833 // Calculate the content size. This should be 0 if the texture_size is 0.
834 gfx::Vector2dF offset;
835 if (texture_size_in_layer_.GetArea() > 0)
836 offset = frame_metadata.location_bar_content_translation;
837 offset.set_y(offset.y() + frame_metadata.overdraw_bottom_height);
838 offset.Scale(frame_metadata.device_scale_factor);
839 content_size_in_layer_ =
840 gfx::Size(texture_size_in_layer_.width() - offset.x(),
841 texture_size_in_layer_.height() - offset.y());
842 // Content size changes should be reflected in associated animation effects.
843 UpdateAnimationSize(frame_metadata);
846 void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame(
847 uint32 output_surface_id,
848 scoped_ptr<cc::CompositorFrame> frame) {
849 if (locks_on_frame_count_ > 0) {
850 DCHECK(HasValidFrame());
851 RetainFrame(output_surface_id, frame.Pass());
855 // Always let ContentViewCore know about the new frame first, so it can decide
856 // to schedule a Draw immediately when it sees the texture layer invalidation.
857 UpdateContentViewCoreFrameMetadata(frame->metadata);
859 if (layer_ && layer_->layer_tree_host()) {
860 for (size_t i = 0; i < frame->metadata.latency_info.size(); i++) {
861 scoped_ptr<cc::SwapPromise> swap_promise(
862 new cc::LatencyInfoSwapPromise(frame->metadata.latency_info[i]));
863 layer_->layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
867 if (frame->delegated_frame_data) {
868 DCHECK(using_delegated_renderer_);
870 DCHECK(frame->delegated_frame_data);
871 DCHECK(!frame->delegated_frame_data->render_pass_list.empty());
873 cc::RenderPass* root_pass =
874 frame->delegated_frame_data->render_pass_list.back();
875 texture_size_in_layer_ = root_pass->output_rect.size();
876 ComputeContentsSize(frame->metadata);
878 SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass());
879 frame_evictor_->SwappedFrame(!host_->is_hidden());
883 DCHECK(!using_delegated_renderer_);
885 if (!frame->gl_frame_data || frame->gl_frame_data->mailbox.IsZero())
888 if (output_surface_id != last_output_surface_id_) {
889 current_mailbox_ = gpu::Mailbox();
890 last_output_surface_id_ = kUndefinedOutputSurfaceId;
893 base::Closure callback = base::Bind(&InsertSyncPointAndAckForCompositor,
894 host_->GetProcess()->GetID(),
896 host_->GetRoutingID(),
898 texture_size_in_layer_);
899 ImageTransportFactoryAndroid::GetInstance()->WaitSyncPoint(
900 frame->gl_frame_data->sync_point);
902 texture_size_in_layer_ = frame->gl_frame_data->size;
903 ComputeContentsSize(frame->metadata);
905 BuffersSwapped(frame->gl_frame_data->mailbox, output_surface_id, callback);
906 frame_evictor_->SwappedFrame(!host_->is_hidden());
909 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
910 uint32 output_surface_id,
911 scoped_ptr<cc::CompositorFrame> frame) {
912 InternalSwapCompositorFrame(output_surface_id, frame.Pass());
915 void RenderWidgetHostViewAndroid::RetainFrame(
916 uint32 output_surface_id,
917 scoped_ptr<cc::CompositorFrame> frame) {
918 DCHECK(locks_on_frame_count_);
920 // Store the incoming frame so that it can be swapped when all the locks have
921 // been released. If there is already a stored frame, then replace and skip
922 // the previous one but make sure we still eventually send the ACK. Holding
923 // the ACK also blocks the renderer when its max_frames_pending is reached.
924 if (last_frame_info_) {
925 base::Closure ack_callback =
926 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
927 weak_ptr_factory_.GetWeakPtr(),
928 last_frame_info_->output_surface_id);
930 ack_callbacks_.push(ack_callback);
933 last_frame_info_.reset(new LastFrameInfo(output_surface_id, frame.Pass()));
936 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
937 const cc::CompositorFrameMetadata& frame_metadata) {
938 // This is a subset of OnSwapCompositorFrame() used in the synchronous
940 UpdateContentViewCoreFrameMetadata(frame_metadata);
941 ComputeContentsSize(frame_metadata);
943 // DevTools ScreenCast support for Android WebView.
944 if (DevToolsAgentHost::HasFor(RenderViewHost::From(GetRenderWidgetHost()))) {
945 scoped_refptr<DevToolsAgentHost> dtah =
946 DevToolsAgentHost::GetOrCreateFor(
947 RenderViewHost::From(GetRenderWidgetHost()));
948 // Unblock the compositor.
949 BrowserThread::PostTask(
950 BrowserThread::UI, FROM_HERE,
951 base::Bind(&RenderViewDevToolsAgentHost::SynchronousSwapCompositorFrame,
952 static_cast<RenderViewDevToolsAgentHost*>(dtah.get()),
957 void RenderWidgetHostViewAndroid::SetOverlayVideoMode(bool enabled) {
958 layer_->SetContentsOpaque(!enabled);
961 void RenderWidgetHostViewAndroid::SynchronousCopyContents(
962 const gfx::Rect& src_subrect_in_pixel,
963 const gfx::Size& dst_size_in_pixel,
964 const base::Callback<void(bool, const SkBitmap&)>& callback,
965 const SkBitmap::Config config) {
966 SynchronousCompositor* compositor =
967 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
968 host_->GetRoutingID());
970 callback.Run(false, SkBitmap());
975 bitmap.setConfig(config,
976 dst_size_in_pixel.width(),
977 dst_size_in_pixel.height());
978 bitmap.allocPixels();
979 SkCanvas canvas(bitmap);
981 (float)dst_size_in_pixel.width() / (float)src_subrect_in_pixel.width(),
982 (float)dst_size_in_pixel.height() / (float)src_subrect_in_pixel.height());
983 compositor->DemandDrawSw(&canvas);
984 callback.Run(true, bitmap);
987 void RenderWidgetHostViewAndroid::UpdateContentViewCoreFrameMetadata(
988 const cc::CompositorFrameMetadata& frame_metadata) {
989 if (content_view_core_) {
990 // All offsets and sizes are in CSS pixels.
991 content_view_core_->UpdateFrameInfo(
992 frame_metadata.root_scroll_offset,
993 frame_metadata.page_scale_factor,
994 gfx::Vector2dF(frame_metadata.min_page_scale_factor,
995 frame_metadata.max_page_scale_factor),
996 frame_metadata.root_layer_size,
997 frame_metadata.viewport_size,
998 frame_metadata.location_bar_offset,
999 frame_metadata.location_bar_content_translation,
1000 frame_metadata.overdraw_bottom_height);
1004 void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int host_id,
1006 accelerated_surface_route_id_ = route_id;
1009 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
1010 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
1012 NOTREACHED() << "Need --composite-to-mailbox or --enable-delegated-renderer";
1015 void RenderWidgetHostViewAndroid::BuffersSwapped(
1016 const gpu::Mailbox& mailbox,
1017 uint32_t output_surface_id,
1018 const base::Closure& ack_callback) {
1019 ImageTransportFactoryAndroid* factory =
1020 ImageTransportFactoryAndroid::GetInstance();
1022 if (!texture_id_in_layer_) {
1023 texture_id_in_layer_ = factory->CreateTexture();
1024 texture_layer_->SetTextureId(texture_id_in_layer_);
1025 texture_layer_->SetIsDrawable(true);
1026 texture_layer_->SetContentsOpaque(true);
1029 ImageTransportFactoryAndroid::GetInstance()->AcquireTexture(
1030 texture_id_in_layer_, mailbox.name);
1032 current_mailbox_ = mailbox;
1033 last_output_surface_id_ = output_surface_id;
1035 ack_callbacks_.push(ack_callback);
1036 if (host_->is_hidden())
1040 void RenderWidgetHostViewAndroid::AttachLayers() {
1041 if (!content_view_core_)
1046 content_view_core_->AttachLayer(layer_);
1047 if (overscroll_effect_enabled_)
1048 overscroll_effect_->Enable();
1049 layer_->SetHideLayerAndSubtree(!is_showing_);
1052 void RenderWidgetHostViewAndroid::RemoveLayers() {
1053 if (!content_view_core_)
1058 content_view_core_->RemoveLayer(layer_);
1059 overscroll_effect_->Disable();
1062 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) {
1063 return overscroll_effect_->Animate(frame_time);
1066 void RenderWidgetHostViewAndroid::UpdateAnimationSize(
1067 const cc::CompositorFrameMetadata& frame_metadata) {
1068 // Disable edge effects for axes on which scrolling is impossible.
1069 gfx::SizeF ceiled_viewport_size =
1070 gfx::ToCeiledSize(frame_metadata.viewport_size);
1071 overscroll_effect_->set_horizontal_overscroll_enabled(
1072 ceiled_viewport_size.width() < frame_metadata.root_layer_size.width());
1073 overscroll_effect_->set_vertical_overscroll_enabled(
1074 ceiled_viewport_size.height() < frame_metadata.root_layer_size.height());
1075 overscroll_effect_->set_size(content_size_in_layer_);
1078 void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
1079 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
1084 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() {
1088 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
1092 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
1093 if (texture_id_in_layer_) {
1094 texture_layer_->SetTextureId(0);
1095 texture_layer_->SetIsDrawable(false);
1096 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
1097 texture_id_in_layer_);
1098 texture_id_in_layer_ = 0;
1099 current_mailbox_ = gpu::Mailbox();
1100 last_output_surface_id_ = kUndefinedOutputSurfaceId;
1102 if (delegated_renderer_layer_.get())
1103 DestroyDelegatedContent();
1104 frame_evictor_->DiscardedFrame();
1107 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
1108 const gfx::Size& desired_size) {
1113 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) {
1114 // ScreenInfo isn't tied to the widget on Android. Always return the default.
1115 RenderWidgetHostViewBase::GetDefaultScreenInfo(result);
1118 // TODO(jrg): Find out the implications and answer correctly here,
1119 // as we are returning the WebView and not root window bounds.
1120 gfx::Rect RenderWidgetHostViewAndroid::GetBoundsInRootWindow() {
1121 return GetViewBounds();
1124 gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() {
1125 gfx::GLSurfaceHandle handle =
1126 gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::NATIVE_TRANSPORT);
1127 if (CompositorImpl::IsInitialized()) {
1128 handle.parent_client_id =
1129 ImageTransportFactoryAndroid::GetInstance()->GetChannelID();
1134 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
1135 const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
1136 if (content_view_core_)
1137 content_view_core_->ConfirmTouchEvent(ack_result);
1140 void RenderWidgetHostViewAndroid::SetHasHorizontalScrollbar(
1141 bool has_horizontal_scrollbar) {
1142 // intentionally empty, like RenderWidgetHostViewViews
1145 void RenderWidgetHostViewAndroid::SetScrollOffsetPinning(
1146 bool is_pinned_to_left, bool is_pinned_to_right) {
1147 // intentionally empty, like RenderWidgetHostViewViews
1150 void RenderWidgetHostViewAndroid::UnhandledWheelEvent(
1151 const blink::WebMouseWheelEvent& event) {
1152 // intentionally empty, like RenderWidgetHostViewViews
1155 void RenderWidgetHostViewAndroid::GestureEventAck(
1156 const blink::WebGestureEvent& event,
1157 InputEventAckState ack_result) {
1158 if (content_view_core_)
1159 content_view_core_->OnGestureEventAck(event, ack_result);
1162 InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
1163 const blink::WebInputEvent& input_event) {
1164 if (content_view_core_ &&
1165 content_view_core_->FilterInputEvent(input_event))
1166 return INPUT_EVENT_ACK_STATE_CONSUMED;
1169 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1171 if (input_event.type == blink::WebInputEvent::GestureTapDown ||
1172 input_event.type == blink::WebInputEvent::TouchStart) {
1173 GpuDataManagerImpl* gpu_data = GpuDataManagerImpl::GetInstance();
1174 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
1175 if (shim && gpu_data && accelerated_surface_route_id_ &&
1176 gpu_data->IsDriverBugWorkaroundActive(gpu::WAKE_UP_GPU_BEFORE_DRAWING))
1178 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_));
1181 SynchronousCompositorImpl* compositor =
1182 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
1183 host_->GetRoutingID());
1185 return compositor->HandleInputEvent(input_event);
1186 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1189 void RenderWidgetHostViewAndroid::OnSetNeedsFlushInput() {
1190 if (flush_input_requested_ || !content_view_core_)
1192 TRACE_EVENT0("input", "RenderWidgetHostViewAndroid::OnSetNeedsFlushInput");
1193 flush_input_requested_ = true;
1194 content_view_core_->AddBeginFrameSubscriber();
1197 void RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManagerIfNeeded() {
1198 if (!host_ || host_->accessibility_mode() != AccessibilityModeComplete)
1201 if (!GetBrowserAccessibilityManager()) {
1202 base::android::ScopedJavaLocalRef<jobject> obj;
1203 if (content_view_core_)
1204 obj = content_view_core_->GetJavaObject();
1205 SetBrowserAccessibilityManager(
1206 new BrowserAccessibilityManagerAndroid(
1207 obj, BrowserAccessibilityManagerAndroid::GetEmptyDocument(), this));
1211 void RenderWidgetHostViewAndroid::SetAccessibilityFocus(int acc_obj_id) {
1215 host_->AccessibilitySetFocus(acc_obj_id);
1218 void RenderWidgetHostViewAndroid::AccessibilityDoDefaultAction(int acc_obj_id) {
1222 host_->AccessibilityDoDefaultAction(acc_obj_id);
1225 void RenderWidgetHostViewAndroid::AccessibilityScrollToMakeVisible(
1226 int acc_obj_id, gfx::Rect subfocus) {
1230 host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus);
1233 void RenderWidgetHostViewAndroid::AccessibilityScrollToPoint(
1234 int acc_obj_id, gfx::Point point) {
1238 host_->AccessibilityScrollToPoint(acc_obj_id, point);
1241 void RenderWidgetHostViewAndroid::AccessibilitySetTextSelection(
1242 int acc_obj_id, int start_offset, int end_offset) {
1246 host_->AccessibilitySetTextSelection(
1247 acc_obj_id, start_offset, end_offset);
1250 gfx::Point RenderWidgetHostViewAndroid::GetLastTouchEventLocation() const {
1252 // Only used on Win8
1253 return gfx::Point();
1256 void RenderWidgetHostViewAndroid::FatalAccessibilityTreeError() {
1260 host_->FatalAccessibilityTreeError();
1261 SetBrowserAccessibilityManager(NULL);
1264 bool RenderWidgetHostViewAndroid::LockMouse() {
1269 void RenderWidgetHostViewAndroid::UnlockMouse() {
1273 // Methods called from the host to the render
1275 void RenderWidgetHostViewAndroid::SendKeyEvent(
1276 const NativeWebKeyboardEvent& event) {
1278 host_->ForwardKeyboardEvent(event);
1281 void RenderWidgetHostViewAndroid::SendTouchEvent(
1282 const blink::WebTouchEvent& event) {
1284 host_->ForwardTouchEventWithLatencyInfo(event, CreateLatencyInfo(event));
1287 void RenderWidgetHostViewAndroid::SendMouseEvent(
1288 const blink::WebMouseEvent& event) {
1290 host_->ForwardMouseEvent(event);
1293 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
1294 const blink::WebMouseWheelEvent& event) {
1296 host_->ForwardWheelEvent(event);
1299 void RenderWidgetHostViewAndroid::SendGestureEvent(
1300 const blink::WebGestureEvent& event) {
1301 // Sending a gesture that may trigger overscroll should resume the effect.
1302 if (overscroll_effect_enabled_)
1303 overscroll_effect_->Enable();
1306 host_->ForwardGestureEventWithLatencyInfo(event, CreateLatencyInfo(event));
1309 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) {
1311 host_->MoveCaret(point);
1314 SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
1315 return cached_background_color_;
1318 void RenderWidgetHostViewAndroid::OnOverscrolled(
1319 gfx::Vector2dF accumulated_overscroll,
1320 gfx::Vector2dF current_fling_velocity) {
1321 if (!content_view_core_ || !layer_ || !is_showing_)
1324 if (overscroll_effect_->OnOverscrolled(content_view_core_->GetLayer(),
1325 base::TimeTicks::Now(),
1326 accumulated_overscroll,
1327 current_fling_velocity)) {
1328 content_view_core_->SetNeedsAnimate();
1332 void RenderWidgetHostViewAndroid::DidStopFlinging() {
1333 if (content_view_core_)
1334 content_view_core_->DidStopFlinging();
1337 void RenderWidgetHostViewAndroid::SetContentViewCore(
1338 ContentViewCoreImpl* content_view_core) {
1340 // TODO: crbug.com/324341
1341 // WindowAndroid and Compositor should outlive all WebContents.
1342 // Allowing this here at runtime is a bandaid.
1343 DCHECK(!root_window_destroyed_);
1344 if (content_view_core_ && !root_window_destroyed_ &&
1345 !using_synchronous_compositor_) {
1346 content_view_core_->GetWindowAndroid()->RemoveObserver(this);
1349 if (content_view_core != content_view_core_)
1350 ReleaseLocksOnSurface();
1352 content_view_core_ = content_view_core;
1354 if (GetBrowserAccessibilityManager()) {
1355 base::android::ScopedJavaLocalRef<jobject> obj;
1356 if (content_view_core_)
1357 obj = content_view_core_->GetJavaObject();
1358 GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerAndroid()->
1359 SetContentViewCore(obj);
1363 if (content_view_core_ && !root_window_destroyed_ &&
1364 !using_synchronous_compositor_) {
1365 content_view_core_->GetWindowAndroid()->AddObserver(this);
1369 void RenderWidgetHostViewAndroid::RunAckCallbacks() {
1370 while (!ack_callbacks_.empty()) {
1371 ack_callbacks_.front().Run();
1372 ack_callbacks_.pop();
1376 void RenderWidgetHostViewAndroid::OnCompositingDidCommit() {
1380 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
1381 DCHECK(content_view_core_);
1382 DCHECK(!using_synchronous_compositor_);
1383 root_window_destroyed_ = true;
1387 void RenderWidgetHostViewAndroid::OnLostResources() {
1388 ReleaseLocksOnSurface();
1389 if (texture_layer_.get())
1390 texture_layer_->SetIsDrawable(false);
1391 if (delegated_renderer_layer_.get())
1392 DestroyDelegatedContent();
1393 texture_id_in_layer_ = 0;
1394 DCHECK(ack_callbacks_.empty());
1399 RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResultForDelegatedReadback(
1400 const gfx::Size& dst_size_in_pixel,
1401 const SkBitmap::Config config,
1402 const base::TimeTicks& start_time,
1403 scoped_refptr<cc::Layer> readback_layer,
1404 const base::Callback<void(bool, const SkBitmap&)>& callback,
1405 scoped_ptr<cc::CopyOutputResult> result) {
1406 readback_layer->RemoveFromParent();
1407 PrepareTextureCopyOutputResult(
1408 dst_size_in_pixel, config, start_time, callback, result.Pass());
1412 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
1413 const gfx::Size& dst_size_in_pixel,
1414 const SkBitmap::Config bitmap_config,
1415 const base::TimeTicks& start_time,
1416 const base::Callback<void(bool, const SkBitmap&)>& callback,
1417 scoped_ptr<cc::CopyOutputResult> result) {
1418 base::ScopedClosureRunner scoped_callback_runner(
1419 base::Bind(callback, false, SkBitmap()));
1421 if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty())
1424 scoped_ptr<SkBitmap> bitmap(new SkBitmap);
1425 bitmap->setConfig(bitmap_config,
1426 dst_size_in_pixel.width(),
1427 dst_size_in_pixel.height(),
1428 0, kOpaque_SkAlphaType);
1429 if (!bitmap->allocPixels())
1432 ImageTransportFactoryAndroid* factory =
1433 ImageTransportFactoryAndroid::GetInstance();
1434 GLHelper* gl_helper = factory->GetGLHelper();
1439 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
1440 new SkAutoLockPixels(*bitmap));
1441 uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
1443 cc::TextureMailbox texture_mailbox;
1444 scoped_ptr<cc::SingleReleaseCallback> release_callback;
1445 result->TakeTexture(&texture_mailbox, &release_callback);
1446 DCHECK(texture_mailbox.IsTexture());
1447 if (!texture_mailbox.IsTexture())
1450 ignore_result(scoped_callback_runner.Release());
1452 gl_helper->CropScaleReadbackAndCleanMailbox(
1453 texture_mailbox.mailbox(),
1454 texture_mailbox.sync_point(),
1456 gfx::Rect(result->size()),
1460 base::Bind(&CopyFromCompositingSurfaceFinished,
1462 base::Passed(&release_callback),
1463 base::Passed(&bitmap),
1465 base::Passed(&bitmap_pixels_lock)));
1468 bool RenderWidgetHostViewAndroid::IsReadbackConfigSupported(
1469 SkBitmap::Config bitmap_config) {
1470 ImageTransportFactoryAndroid* factory =
1471 ImageTransportFactoryAndroid::GetInstance();
1472 GLHelper* gl_helper = factory->GetGLHelper();
1475 return gl_helper->IsReadbackConfigSupported(bitmap_config);
1478 SkBitmap::Config RenderWidgetHostViewAndroid::PreferredReadbackFormat() {
1479 // Define the criteria here. If say the 16 texture readback is
1480 // supported we should go with that (this degrades quality)
1481 // or stick back to the default format.
1482 if (base::android::SysUtils::IsLowEndDevice()) {
1483 if (IsReadbackConfigSupported(SkBitmap::kRGB_565_Config))
1484 return SkBitmap::kRGB_565_Config;
1486 return SkBitmap::kARGB_8888_Config;
1490 void RenderWidgetHostViewPort::GetDefaultScreenInfo(
1491 blink::WebScreenInfo* results) {
1492 const gfx::Display& display =
1493 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
1494 results->rect = display.bounds();
1495 // TODO(husky): Remove any system controls from availableRect.
1496 results->availableRect = display.work_area();
1497 results->deviceScaleFactor = display.device_scale_factor();
1498 gfx::DeviceDisplayInfo info;
1499 results->depth = info.GetBitsPerPixel();
1500 results->depthPerComponent = info.GetBitsPerComponent();
1501 results->isMonochrome = (results->depthPerComponent == 0);
1504 ////////////////////////////////////////////////////////////////////////////////
1505 // RenderWidgetHostView, public:
1508 RenderWidgetHostView*
1509 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost* widget) {
1510 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget);
1511 return new RenderWidgetHostViewAndroid(rwhi, NULL);
1514 } // namespace content