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/basictypes.h"
10 #include "base/bind.h"
11 #include "base/callback_helpers.h"
12 #include "base/command_line.h"
13 #include "base/logging.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/metrics/histogram.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/threading/worker_pool.h"
18 #include "cc/base/latency_info_swap_promise.h"
19 #include "cc/layers/delegated_frame_provider.h"
20 #include "cc/layers/delegated_renderer_layer.h"
21 #include "cc/layers/layer.h"
22 #include "cc/layers/texture_layer.h"
23 #include "cc/output/compositor_frame.h"
24 #include "cc/output/compositor_frame_ack.h"
25 #include "cc/output/copy_output_request.h"
26 #include "cc/output/copy_output_result.h"
27 #include "cc/resources/single_release_callback.h"
28 #include "cc/trees/layer_tree_host.h"
29 #include "content/browser/accessibility/browser_accessibility_manager_android.h"
30 #include "content/browser/android/content_view_core_impl.h"
31 #include "content/browser/android/in_process/synchronous_compositor_impl.h"
32 #include "content/browser/android/overscroll_glow.h"
33 #include "content/browser/devtools/render_view_devtools_agent_host.h"
34 #include "content/browser/gpu/gpu_data_manager_impl.h"
35 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
36 #include "content/browser/gpu/gpu_surface_tracker.h"
37 #include "content/browser/renderer_host/compositor_impl_android.h"
38 #include "content/browser/renderer_host/dip_util.h"
39 #include "content/browser/renderer_host/image_transport_factory_android.h"
40 #include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
41 #include "content/browser/renderer_host/render_process_host_impl.h"
42 #include "content/browser/renderer_host/render_widget_host_impl.h"
43 #include "content/common/gpu/client/gl_helper.h"
44 #include "content/common/gpu/gpu_messages.h"
45 #include "content/common/input_messages.h"
46 #include "content/common/view_messages.h"
47 #include "content/public/browser/devtools_agent_host.h"
48 #include "content/public/browser/render_view_host.h"
49 #include "content/public/common/content_switches.h"
50 #include "gpu/command_buffer/client/gles2_interface.h"
51 #include "gpu/config/gpu_driver_bug_workaround_type.h"
52 #include "skia/ext/image_operations.h"
53 #include "third_party/khronos/GLES2/gl2.h"
54 #include "third_party/khronos/GLES2/gl2ext.h"
55 #include "third_party/skia/include/core/SkCanvas.h"
56 #include "ui/base/android/window_android.h"
57 #include "ui/gfx/android/device_display_info.h"
58 #include "ui/gfx/android/java_bitmap.h"
59 #include "ui/gfx/display.h"
60 #include "ui/gfx/screen.h"
61 #include "ui/gfx/size_conversions.h"
67 const int kUndefinedOutputSurfaceId = -1;
68 static const char kAsyncReadBackString[] = "Compositing.CopyFromSurfaceTime";
70 void InsertSyncPointAndAckForCompositor(
72 uint32 output_surface_id,
74 const gpu::Mailbox& return_mailbox,
75 const gfx::Size return_size) {
76 cc::CompositorFrameAck ack;
77 ack.gl_frame_data.reset(new cc::GLFrameData());
78 if (!return_mailbox.IsZero()) {
79 ack.gl_frame_data->mailbox = return_mailbox;
80 ack.gl_frame_data->size = return_size;
81 ack.gl_frame_data->sync_point =
82 ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint();
84 RenderWidgetHostImpl::SendSwapCompositorFrameAck(
85 route_id, output_surface_id, renderer_host_id, ack);
88 // Sends an acknowledgement to the renderer of a processed IME event.
89 void SendImeEventAck(RenderWidgetHostImpl* host) {
90 host->Send(new ViewMsg_ImeEventAck(host->GetRoutingID()));
93 void CopyFromCompositingSurfaceFinished(
94 const base::Callback<void(bool, const SkBitmap&)>& callback,
95 scoped_ptr<cc::SingleReleaseCallback> release_callback,
96 scoped_ptr<SkBitmap> bitmap,
97 const base::TimeTicks& start_time,
98 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
100 bitmap_pixels_lock.reset();
101 release_callback->Run(0, false);
102 UMA_HISTOGRAM_TIMES(kAsyncReadBackString,
103 base::TimeTicks::Now() - start_time);
104 callback.Run(result, *bitmap);
107 ui::LatencyInfo CreateLatencyInfo(const blink::WebInputEvent& event) {
108 ui::LatencyInfo latency_info;
109 // The latency number should only be added if the timestamp is valid.
110 if (event.timeStampSeconds) {
111 const int64 time_micros = static_cast<int64>(
112 event.timeStampSeconds * base::Time::kMicrosecondsPerSecond);
113 latency_info.AddLatencyNumberWithTimestamp(
114 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
117 base::TimeTicks() + base::TimeDelta::FromMicroseconds(time_micros),
123 } // anonymous namespace
125 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
126 RenderWidgetHostImpl* widget_host,
127 ContentViewCoreImpl* content_view_core)
128 : host_(widget_host),
129 needs_begin_frame_(false),
130 is_showing_(!widget_host->is_hidden()),
131 content_view_core_(NULL),
132 ime_adapter_android_(this),
133 cached_background_color_(SK_ColorWHITE),
134 texture_id_in_layer_(0),
135 last_output_surface_id_(kUndefinedOutputSurfaceId),
136 weak_ptr_factory_(this),
137 overscroll_effect_enabled_(
138 !CommandLine::ForCurrentProcess()->
139 HasSwitch(switches::kDisableOverscrollEdgeEffect)),
140 overscroll_effect_(OverscrollGlow::Create(overscroll_effect_enabled_)),
141 flush_input_requested_(false),
142 accelerated_surface_route_id_(0),
143 using_synchronous_compositor_(SynchronousCompositorImpl::FromID(
144 widget_host->GetProcess()->GetID(),
145 widget_host->GetRoutingID()) != NULL),
146 frame_evictor_(new DelegatedFrameEvictor(this)),
147 using_delegated_renderer_(CommandLine::ForCurrentProcess()->HasSwitch(
148 switches::kEnableDelegatedRenderer) &&
149 !CommandLine::ForCurrentProcess()->HasSwitch(
150 switches::kDisableDelegatedRenderer)) {
151 if (!using_delegated_renderer_) {
152 texture_layer_ = cc::TextureLayer::Create(NULL);
153 layer_ = texture_layer_;
156 host_->SetView(this);
157 SetContentViewCore(content_view_core);
158 ImageTransportFactoryAndroid::AddObserver(this);
161 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
162 ImageTransportFactoryAndroid::RemoveObserver(this);
163 SetContentViewCore(NULL);
164 DCHECK(ack_callbacks_.empty());
165 if (texture_id_in_layer_) {
166 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
167 texture_id_in_layer_);
170 if (texture_layer_.get())
171 texture_layer_->ClearClient();
173 if (resource_collection_.get())
174 resource_collection_->SetClient(NULL);
178 bool RenderWidgetHostViewAndroid::OnMessageReceived(
179 const IPC::Message& message) {
181 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
182 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
183 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor,
184 OnDidChangeBodyBackgroundColor)
185 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame,
186 OnSetNeedsBeginFrame)
187 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
188 OnTextInputStateChanged)
189 IPC_MESSAGE_HANDLER(ViewHostMsg_SmartClipDataExtracted,
190 OnSmartClipDataExtracted)
191 IPC_MESSAGE_UNHANDLED(handled = false)
192 IPC_END_MESSAGE_MAP()
196 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
200 void RenderWidgetHostViewAndroid::InitAsPopup(
201 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
205 void RenderWidgetHostViewAndroid::InitAsFullscreen(
206 RenderWidgetHostView* reference_host_view) {
211 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
215 void RenderWidgetHostViewAndroid::WasShown() {
216 if (!host_ || !host_->is_hidden())
221 if (content_view_core_ && !using_synchronous_compositor_)
222 content_view_core_->GetWindowAndroid()->AddObserver(this);
225 void RenderWidgetHostViewAndroid::WasHidden() {
228 if (!host_ || host_->is_hidden())
231 // Inform the renderer that we are being hidden so it can reduce its resource
235 if (content_view_core_ && !using_synchronous_compositor_)
236 content_view_core_->GetWindowAndroid()->RemoveObserver(this);
239 void RenderWidgetHostViewAndroid::WasResized() {
243 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) {
244 // Ignore the given size as only the Java code has the power to
245 // resize the view on Android.
246 default_size_ = size;
250 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
251 SetSize(rect.size());
254 void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
257 const base::Callback<void(bool, const SkBitmap&)>& result_callback) {
258 if (!IsSurfaceAvailableForCopy()) {
259 result_callback.Run(false, SkBitmap());
263 gfx::Size bounds = layer_->bounds();
264 gfx::Rect src_subrect(bounds);
265 const gfx::Display& display =
266 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
267 float device_scale_factor = display.device_scale_factor();
268 DCHECK_GT(device_scale_factor, 0);
270 gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale / device_scale_factor)));
271 *out_size = dst_size;
272 CopyFromCompositingSurface(
273 src_subrect, dst_size, result_callback, SkBitmap::kARGB_8888_Config);
276 bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(jobject jbitmap) {
277 if (!CompositorImpl::IsInitialized() ||
278 texture_id_in_layer_ == 0 ||
279 texture_size_in_layer_.IsEmpty())
282 gfx::JavaBitmap bitmap(jbitmap);
284 // TODO(dtrainor): Eventually add support for multiple formats here.
285 DCHECK(bitmap.format() == ANDROID_BITMAP_FORMAT_RGBA_8888);
287 GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
289 GLuint texture = helper->CopyAndScaleTexture(
290 texture_id_in_layer_,
291 texture_size_in_layer_,
294 GLHelper::SCALER_QUALITY_FAST);
298 helper->ReadbackTextureSync(texture,
299 gfx::Rect(bitmap.size()),
300 static_cast<unsigned char*> (bitmap.pixels()),
301 SkBitmap::kARGB_8888_Config);
303 gpu::gles2::GLES2Interface* gl =
304 ImageTransportFactoryAndroid::GetInstance()->GetContextGL();
305 gl->DeleteTextures(1, &texture);
310 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
311 if (!content_view_core_)
316 if (texture_size_in_layer_.IsEmpty())
319 if (using_delegated_renderer_) {
320 if (!delegated_renderer_layer_.get())
323 if (texture_id_in_layer_ == 0)
330 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
331 return content_view_core_->GetViewAndroid();
334 gfx::NativeViewId RenderWidgetHostViewAndroid::GetNativeViewId() const {
335 return reinterpret_cast<gfx::NativeViewId>(
336 const_cast<RenderWidgetHostViewAndroid*>(this));
339 gfx::NativeViewAccessible
340 RenderWidgetHostViewAndroid::GetNativeViewAccessible() {
345 void RenderWidgetHostViewAndroid::MovePluginWindows(
346 const gfx::Vector2d& scroll_offset,
347 const std::vector<WebPluginGeometry>& moves) {
348 // We don't have plugin windows on Android. Do nothing. Note: this is called
349 // from RenderWidgetHost::OnUpdateRect which is itself invoked while
350 // processing the corresponding message from Renderer.
353 void RenderWidgetHostViewAndroid::Focus() {
355 host_->SetInputMethodActive(true);
357 if (overscroll_effect_enabled_)
358 overscroll_effect_->Enable();
361 void RenderWidgetHostViewAndroid::Blur() {
362 host_->ExecuteEditCommand("Unselect", "");
363 host_->SetInputMethodActive(false);
365 overscroll_effect_->Disable();
368 bool RenderWidgetHostViewAndroid::HasFocus() const {
369 if (!content_view_core_)
370 return false; // ContentViewCore not created yet.
372 return content_view_core_->HasFocus();
375 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
376 return HasValidFrame();
379 void RenderWidgetHostViewAndroid::Show() {
385 layer_->SetHideLayerAndSubtree(false);
387 frame_evictor_->SetVisible(true);
391 void RenderWidgetHostViewAndroid::Hide() {
397 layer_->SetHideLayerAndSubtree(true);
399 frame_evictor_->SetVisible(false);
403 bool RenderWidgetHostViewAndroid::IsShowing() {
404 // ContentViewCoreImpl represents the native side of the Java
405 // ContentViewCore. It being NULL means that it is not attached
406 // to the View system yet, so we treat this RWHVA as hidden.
407 return is_showing_ && content_view_core_;
410 void RenderWidgetHostViewAndroid::LockResources() {
411 DCHECK(HasValidFrame());
413 DCHECK(!host_->is_hidden());
414 frame_evictor_->LockFrame();
417 void RenderWidgetHostViewAndroid::UnlockResources() {
418 DCHECK(HasValidFrame());
419 frame_evictor_->UnlockFrame();
422 gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const {
423 if (!content_view_core_)
424 return gfx::Rect(default_size_);
426 gfx::Size size = content_view_core_->GetViewportSizeDip();
427 gfx::Size offset = content_view_core_->GetViewportSizeOffsetDip();
428 size.Enlarge(-offset.width(), -offset.height());
430 return gfx::Rect(size);
433 gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
434 if (!content_view_core_)
437 return content_view_core_->GetPhysicalBackingSize();
440 float RenderWidgetHostViewAndroid::GetOverdrawBottomHeight() const {
441 if (!content_view_core_)
444 return content_view_core_->GetOverdrawBottomHeightDip();
447 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& cursor) {
448 // There are no cursors on Android.
451 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading) {
452 // Do nothing. The UI notification is handled through ContentViewClient which
453 // is TabContentsDelegate.
456 void RenderWidgetHostViewAndroid::TextInputTypeChanged(
457 ui::TextInputType type,
458 ui::TextInputMode input_mode,
459 bool can_compose_inline) {
460 // Unused on Android, which uses OnTextInputChanged instead.
463 int RenderWidgetHostViewAndroid::GetNativeImeAdapter() {
464 return reinterpret_cast<int>(&ime_adapter_android_);
467 void RenderWidgetHostViewAndroid::OnTextInputStateChanged(
468 const ViewHostMsg_TextInputState_Params& params) {
469 // If an acknowledgement is required for this event, regardless of how we exit
470 // from this method, we must acknowledge that we processed the input state
472 base::ScopedClosureRunner ack_caller;
473 if (params.require_ack)
474 ack_caller.Reset(base::Bind(&SendImeEventAck, host_));
479 content_view_core_->UpdateImeAdapter(
480 GetNativeImeAdapter(),
481 static_cast<int>(params.type),
482 params.value, params.selection_start, params.selection_end,
483 params.composition_start, params.composition_end,
484 params.show_ime_if_needed, params.require_ack);
487 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor(
489 if (cached_background_color_ == color)
492 cached_background_color_ = color;
493 if (content_view_core_)
494 content_view_core_->OnBackgroundColorChanged(color);
497 void RenderWidgetHostViewAndroid::SendBeginFrame(
498 const cc::BeginFrameArgs& args) {
499 TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::SendBeginFrame");
503 if (flush_input_requested_) {
504 flush_input_requested_ = false;
506 content_view_core_->RemoveBeginFrameSubscriber();
509 host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), args));
512 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame(
514 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame",
516 // ContentViewCoreImpl handles multiple subscribers to the BeginFrame, so
517 // we have to make sure calls to ContentViewCoreImpl's
518 // {Add,Remove}BeginFrameSubscriber are balanced, even if
519 // RenderWidgetHostViewAndroid's may not be.
520 if (content_view_core_ && needs_begin_frame_ != enabled) {
522 content_view_core_->AddBeginFrameSubscriber();
524 content_view_core_->RemoveBeginFrameSubscriber();
525 needs_begin_frame_ = enabled;
529 void RenderWidgetHostViewAndroid::OnStartContentIntent(
530 const GURL& content_url) {
531 if (content_view_core_)
532 content_view_core_->StartContentIntent(content_url);
535 void RenderWidgetHostViewAndroid::OnSmartClipDataExtracted(
536 const base::string16& result) {
537 // Custom serialization over IPC isn't allowed normally for security reasons.
538 // Since this feature is only used in (single-process) WebView, there are no
539 // security issues. Enforce that it's only called in single process mode.
540 CHECK(RenderProcessHost::run_renderer_in_process());
541 if (content_view_core_)
542 content_view_core_->OnSmartClipDataExtracted(result);
545 void RenderWidgetHostViewAndroid::ImeCancelComposition() {
546 ime_adapter_android_.CancelComposition();
549 void RenderWidgetHostViewAndroid::FocusedNodeChanged(bool is_editable_node) {
550 ime_adapter_android_.FocusedNodeChanged(is_editable_node);
553 void RenderWidgetHostViewAndroid::DidUpdateBackingStore(
554 const gfx::Rect& scroll_rect,
555 const gfx::Vector2d& scroll_delta,
556 const std::vector<gfx::Rect>& copy_rects,
557 const std::vector<ui::LatencyInfo>& latency_info) {
561 void RenderWidgetHostViewAndroid::RenderProcessGone(
562 base::TerminationStatus status, int error_code) {
566 void RenderWidgetHostViewAndroid::Destroy() {
568 SetContentViewCore(NULL);
570 // The RenderWidgetHost's destruction led here, so don't call it.
576 void RenderWidgetHostViewAndroid::SetTooltipText(
577 const base::string16& tooltip_text) {
578 // Tooltips don't makes sense on Android.
581 void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16& text,
583 const gfx::Range& range) {
584 RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
586 if (text.empty() || range.is_empty() || !content_view_core_)
588 size_t pos = range.GetMin() - offset;
589 size_t n = range.length();
591 DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
592 if (pos >= text.length()) {
593 NOTREACHED() << "The text can not cover range.";
597 std::string utf8_selection = base::UTF16ToUTF8(text.substr(pos, n));
599 content_view_core_->OnSelectionChanged(utf8_selection);
602 void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
603 const ViewHostMsg_SelectionBounds_Params& params) {
604 if (content_view_core_) {
605 content_view_core_->OnSelectionBoundsChanged(params);
609 void RenderWidgetHostViewAndroid::ScrollOffsetChanged() {
612 BackingStore* RenderWidgetHostViewAndroid::AllocBackingStore(
613 const gfx::Size& size) {
618 void RenderWidgetHostViewAndroid::SetBackground(const SkBitmap& background) {
619 RenderWidgetHostViewBase::SetBackground(background);
620 host_->Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background));
623 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
624 const gfx::Rect& src_subrect,
625 const gfx::Size& dst_size,
626 const base::Callback<void(bool, const SkBitmap&)>& callback,
627 const SkBitmap::Config bitmap_config) {
628 // Only ARGB888 and RGB565 supported as of now.
629 bool format_support = ((bitmap_config == SkBitmap::kRGB_565_Config) ||
630 (bitmap_config == SkBitmap::kARGB_8888_Config));
631 if (!format_support) {
632 DCHECK(format_support);
633 callback.Run(false, SkBitmap());
636 base::TimeTicks start_time = base::TimeTicks::Now();
637 if (!using_synchronous_compositor_ && !IsSurfaceAvailableForCopy()) {
638 callback.Run(false, SkBitmap());
641 ImageTransportFactoryAndroid* factory =
642 ImageTransportFactoryAndroid::GetInstance();
643 GLHelper* gl_helper = factory->GetGLHelper();
646 bool check_rgb565_support = gl_helper->CanUseRgb565Readback();
647 if ((bitmap_config == SkBitmap::kRGB_565_Config) &&
648 !check_rgb565_support) {
649 LOG(ERROR) << "Readbackformat rgb565 not supported";
650 callback.Run(false, SkBitmap());
653 const gfx::Display& display =
654 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
655 float device_scale_factor = display.device_scale_factor();
656 gfx::Size dst_size_in_pixel =
657 ConvertRectToPixel(device_scale_factor, gfx::Rect(dst_size)).size();
658 gfx::Rect src_subrect_in_pixel =
659 ConvertRectToPixel(device_scale_factor, src_subrect);
661 if (using_synchronous_compositor_) {
662 SynchronousCopyContents(src_subrect_in_pixel, dst_size_in_pixel, callback,
664 UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous",
665 base::TimeTicks::Now() - start_time);
668 scoped_ptr<cc::CopyOutputRequest> request;
669 if ((src_subrect_in_pixel.size() == dst_size_in_pixel) &&
670 (bitmap_config == SkBitmap::kARGB_8888_Config)) {
671 request = cc::CopyOutputRequest::CreateBitmapRequest(base::Bind(
672 &RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult,
678 request = cc::CopyOutputRequest::CreateRequest(base::Bind(
679 &RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult,
685 request->set_area(src_subrect_in_pixel);
686 layer_->RequestCopyOfOutput(request.Pass());
689 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
690 const gfx::Rect& src_subrect,
691 const scoped_refptr<media::VideoFrame>& target,
692 const base::Callback<void(bool)>& callback) {
697 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
701 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
702 const gfx::Rect& target_rect, const SkBitmap& zoomed_bitmap) {
703 if (!content_view_core_)
706 content_view_core_->ShowDisambiguationPopup(target_rect, zoomed_bitmap);
709 scoped_ptr<SyntheticGestureTarget>
710 RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
711 return scoped_ptr<SyntheticGestureTarget>(new SyntheticGestureTargetAndroid(
712 host_, content_view_core_->CreateTouchEventSynthesizer()));
715 void RenderWidgetHostViewAndroid::OnAcceleratedCompositingStateChange() {
718 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
719 uint32 output_surface_id) {
720 cc::CompositorFrameAck ack;
721 if (resource_collection_.get())
722 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
723 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_->GetRoutingID(),
725 host_->GetProcess()->GetID(),
729 void RenderWidgetHostViewAndroid::SendReturnedDelegatedResources(
730 uint32 output_surface_id) {
731 DCHECK(resource_collection_);
733 cc::CompositorFrameAck ack;
734 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
735 DCHECK(!ack.resources.empty());
737 RenderWidgetHostImpl::SendReclaimCompositorResources(
738 host_->GetRoutingID(),
740 host_->GetProcess()->GetID(),
744 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
745 if (ack_callbacks_.size())
747 SendReturnedDelegatedResources(last_output_surface_id_);
750 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
752 frame_provider_ = NULL;
753 delegated_renderer_layer_ = NULL;
757 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
758 uint32 output_surface_id,
759 scoped_ptr<cc::DelegatedFrameData> frame_data) {
760 bool has_content = !texture_size_in_layer_.IsEmpty();
762 if (output_surface_id != last_output_surface_id_) {
763 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
764 // any resources from the old output surface with the new output surface id.
765 if (resource_collection_.get()) {
766 if (resource_collection_->LoseAllResources())
767 SendReturnedDelegatedResources(last_output_surface_id_);
769 resource_collection_->SetClient(NULL);
770 resource_collection_ = NULL;
772 DestroyDelegatedContent();
774 last_output_surface_id_ = output_surface_id;
778 DestroyDelegatedContent();
780 if (!resource_collection_.get()) {
781 resource_collection_ = new cc::DelegatedFrameResourceCollection;
782 resource_collection_->SetClient(this);
784 if (!frame_provider_ ||
785 texture_size_in_layer_ != frame_provider_->frame_size()) {
787 frame_provider_ = new cc::DelegatedFrameProvider(
788 resource_collection_.get(), frame_data.Pass());
789 delegated_renderer_layer_ =
790 cc::DelegatedRendererLayer::Create(frame_provider_);
791 layer_ = delegated_renderer_layer_;
794 frame_provider_->SetFrameData(frame_data.Pass());
798 if (delegated_renderer_layer_.get()) {
799 delegated_renderer_layer_->SetDisplaySize(texture_size_in_layer_);
800 delegated_renderer_layer_->SetIsDrawable(true);
801 delegated_renderer_layer_->SetContentsOpaque(true);
802 delegated_renderer_layer_->SetBounds(content_size_in_layer_);
803 delegated_renderer_layer_->SetNeedsDisplay();
806 base::Closure ack_callback =
807 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
808 weak_ptr_factory_.GetWeakPtr(),
811 if (host_->is_hidden())
814 ack_callbacks_.push(ack_callback);
817 void RenderWidgetHostViewAndroid::ComputeContentsSize(
818 const cc::CompositorFrameMetadata& frame_metadata) {
819 // Calculate the content size. This should be 0 if the texture_size is 0.
820 gfx::Vector2dF offset;
821 if (texture_size_in_layer_.GetArea() > 0)
822 offset = frame_metadata.location_bar_content_translation;
823 offset.set_y(offset.y() + frame_metadata.overdraw_bottom_height);
824 offset.Scale(frame_metadata.device_scale_factor);
825 content_size_in_layer_ =
826 gfx::Size(texture_size_in_layer_.width() - offset.x(),
827 texture_size_in_layer_.height() - offset.y());
828 // Content size changes should be reflected in associated animation effects.
829 UpdateAnimationSize(frame_metadata);
832 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
833 uint32 output_surface_id,
834 scoped_ptr<cc::CompositorFrame> frame) {
835 // Always let ContentViewCore know about the new frame first, so it can decide
836 // to schedule a Draw immediately when it sees the texture layer invalidation.
837 UpdateContentViewCoreFrameMetadata(frame->metadata);
839 if (layer_ && layer_->layer_tree_host()) {
840 for (size_t i = 0; i < frame->metadata.latency_info.size(); i++) {
841 scoped_ptr<cc::SwapPromise> swap_promise(
842 new cc::LatencyInfoSwapPromise(frame->metadata.latency_info[i]));
843 layer_->layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
847 if (frame->delegated_frame_data) {
848 DCHECK(using_delegated_renderer_);
850 DCHECK(frame->delegated_frame_data);
851 DCHECK(!frame->delegated_frame_data->render_pass_list.empty());
853 cc::RenderPass* root_pass =
854 frame->delegated_frame_data->render_pass_list.back();
855 texture_size_in_layer_ = root_pass->output_rect.size();
856 ComputeContentsSize(frame->metadata);
858 SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass());
859 frame_evictor_->SwappedFrame(!host_->is_hidden());
863 DCHECK(!using_delegated_renderer_);
865 if (!frame->gl_frame_data || frame->gl_frame_data->mailbox.IsZero())
868 if (output_surface_id != last_output_surface_id_) {
869 current_mailbox_ = gpu::Mailbox();
870 last_output_surface_id_ = kUndefinedOutputSurfaceId;
873 base::Closure callback = base::Bind(&InsertSyncPointAndAckForCompositor,
874 host_->GetProcess()->GetID(),
876 host_->GetRoutingID(),
878 texture_size_in_layer_);
879 ImageTransportFactoryAndroid::GetInstance()->WaitSyncPoint(
880 frame->gl_frame_data->sync_point);
882 texture_size_in_layer_ = frame->gl_frame_data->size;
883 ComputeContentsSize(frame->metadata);
885 BuffersSwapped(frame->gl_frame_data->mailbox, output_surface_id, callback);
886 frame_evictor_->SwappedFrame(!host_->is_hidden());
889 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
890 const cc::CompositorFrameMetadata& frame_metadata) {
891 // This is a subset of OnSwapCompositorFrame() used in the synchronous
893 UpdateContentViewCoreFrameMetadata(frame_metadata);
894 ComputeContentsSize(frame_metadata);
896 // DevTools ScreenCast support for Android WebView.
897 if (DevToolsAgentHost::HasFor(RenderViewHost::From(GetRenderWidgetHost()))) {
898 scoped_refptr<DevToolsAgentHost> dtah =
899 DevToolsAgentHost::GetOrCreateFor(
900 RenderViewHost::From(GetRenderWidgetHost()));
901 // Unblock the compositor.
902 BrowserThread::PostTask(
903 BrowserThread::UI, FROM_HERE,
904 base::Bind(&RenderViewDevToolsAgentHost::SynchronousSwapCompositorFrame,
905 static_cast<RenderViewDevToolsAgentHost*>(dtah.get()),
910 void RenderWidgetHostViewAndroid::SetOverlayVideoMode(bool enabled) {
911 layer_->SetContentsOpaque(!enabled);
914 void RenderWidgetHostViewAndroid::SynchronousCopyContents(
915 const gfx::Rect& src_subrect_in_pixel,
916 const gfx::Size& dst_size_in_pixel,
917 const base::Callback<void(bool, const SkBitmap&)>& callback,
918 const SkBitmap::Config config) {
919 SynchronousCompositor* compositor =
920 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
921 host_->GetRoutingID());
923 callback.Run(false, SkBitmap());
928 bitmap.setConfig(config,
929 dst_size_in_pixel.width(),
930 dst_size_in_pixel.height());
931 bitmap.allocPixels();
932 SkCanvas canvas(bitmap);
934 (float)dst_size_in_pixel.width() / (float)src_subrect_in_pixel.width(),
935 (float)dst_size_in_pixel.height() / (float)src_subrect_in_pixel.height());
936 compositor->DemandDrawSw(&canvas);
937 callback.Run(true, bitmap);
940 void RenderWidgetHostViewAndroid::UpdateContentViewCoreFrameMetadata(
941 const cc::CompositorFrameMetadata& frame_metadata) {
942 if (content_view_core_) {
943 // All offsets and sizes are in CSS pixels.
944 content_view_core_->UpdateFrameInfo(
945 frame_metadata.root_scroll_offset,
946 frame_metadata.page_scale_factor,
947 gfx::Vector2dF(frame_metadata.min_page_scale_factor,
948 frame_metadata.max_page_scale_factor),
949 frame_metadata.root_layer_size,
950 frame_metadata.viewport_size,
951 frame_metadata.location_bar_offset,
952 frame_metadata.location_bar_content_translation,
953 frame_metadata.overdraw_bottom_height);
957 void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int host_id,
959 accelerated_surface_route_id_ = route_id;
962 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
963 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
965 NOTREACHED() << "Need --composite-to-mailbox or --enable-delegated-renderer";
968 void RenderWidgetHostViewAndroid::BuffersSwapped(
969 const gpu::Mailbox& mailbox,
970 uint32_t output_surface_id,
971 const base::Closure& ack_callback) {
972 ImageTransportFactoryAndroid* factory =
973 ImageTransportFactoryAndroid::GetInstance();
975 if (!texture_id_in_layer_) {
976 texture_id_in_layer_ = factory->CreateTexture();
977 texture_layer_->SetTextureId(texture_id_in_layer_);
978 texture_layer_->SetIsDrawable(true);
979 texture_layer_->SetContentsOpaque(true);
982 ImageTransportFactoryAndroid::GetInstance()->AcquireTexture(
983 texture_id_in_layer_, mailbox.name);
987 current_mailbox_ = mailbox;
988 last_output_surface_id_ = output_surface_id;
990 if (host_->is_hidden())
993 ack_callbacks_.push(ack_callback);
996 void RenderWidgetHostViewAndroid::AttachLayers() {
997 if (!content_view_core_)
1002 content_view_core_->AttachLayer(layer_);
1003 if (overscroll_effect_enabled_)
1004 overscroll_effect_->Enable();
1005 layer_->SetHideLayerAndSubtree(!is_showing_);
1008 void RenderWidgetHostViewAndroid::RemoveLayers() {
1009 if (!content_view_core_)
1014 content_view_core_->RemoveLayer(layer_);
1015 overscroll_effect_->Disable();
1018 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) {
1019 return overscroll_effect_->Animate(frame_time);
1022 void RenderWidgetHostViewAndroid::UpdateAnimationSize(
1023 const cc::CompositorFrameMetadata& frame_metadata) {
1024 // Disable edge effects for axes on which scrolling is impossible.
1025 gfx::SizeF ceiled_viewport_size =
1026 gfx::ToCeiledSize(frame_metadata.viewport_size);
1027 overscroll_effect_->set_horizontal_overscroll_enabled(
1028 ceiled_viewport_size.width() < frame_metadata.root_layer_size.width());
1029 overscroll_effect_->set_vertical_overscroll_enabled(
1030 ceiled_viewport_size.height() < frame_metadata.root_layer_size.height());
1031 overscroll_effect_->set_size(content_size_in_layer_);
1034 void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
1035 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
1040 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() {
1044 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
1048 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
1049 if (texture_id_in_layer_) {
1050 texture_layer_->SetTextureId(0);
1051 texture_layer_->SetIsDrawable(false);
1052 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
1053 texture_id_in_layer_);
1054 texture_id_in_layer_ = 0;
1055 current_mailbox_ = gpu::Mailbox();
1056 last_output_surface_id_ = kUndefinedOutputSurfaceId;
1058 if (delegated_renderer_layer_.get())
1059 DestroyDelegatedContent();
1060 frame_evictor_->DiscardedFrame();
1063 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
1064 const gfx::Size& desired_size) {
1069 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) {
1070 // ScreenInfo isn't tied to the widget on Android. Always return the default.
1071 RenderWidgetHostViewBase::GetDefaultScreenInfo(result);
1074 // TODO(jrg): Find out the implications and answer correctly here,
1075 // as we are returning the WebView and not root window bounds.
1076 gfx::Rect RenderWidgetHostViewAndroid::GetBoundsInRootWindow() {
1077 return GetViewBounds();
1080 gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() {
1081 gfx::GLSurfaceHandle handle =
1082 gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::NATIVE_TRANSPORT);
1083 if (CompositorImpl::IsInitialized()) {
1084 handle.parent_client_id =
1085 ImageTransportFactoryAndroid::GetInstance()->GetChannelID();
1090 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
1091 const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
1092 if (content_view_core_)
1093 content_view_core_->ConfirmTouchEvent(ack_result);
1096 void RenderWidgetHostViewAndroid::SetHasHorizontalScrollbar(
1097 bool has_horizontal_scrollbar) {
1098 // intentionally empty, like RenderWidgetHostViewViews
1101 void RenderWidgetHostViewAndroid::SetScrollOffsetPinning(
1102 bool is_pinned_to_left, bool is_pinned_to_right) {
1103 // intentionally empty, like RenderWidgetHostViewViews
1106 void RenderWidgetHostViewAndroid::UnhandledWheelEvent(
1107 const blink::WebMouseWheelEvent& event) {
1108 // intentionally empty, like RenderWidgetHostViewViews
1111 void RenderWidgetHostViewAndroid::GestureEventAck(
1112 const blink::WebGestureEvent& event,
1113 InputEventAckState ack_result) {
1114 if (content_view_core_)
1115 content_view_core_->OnGestureEventAck(event, ack_result);
1118 InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
1119 const blink::WebInputEvent& input_event) {
1120 if (content_view_core_ &&
1121 content_view_core_->FilterInputEvent(input_event))
1122 return INPUT_EVENT_ACK_STATE_CONSUMED;
1125 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1127 if (input_event.type == blink::WebInputEvent::GestureTapDown ||
1128 input_event.type == blink::WebInputEvent::TouchStart) {
1129 GpuDataManagerImpl* gpu_data = GpuDataManagerImpl::GetInstance();
1130 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
1131 if (shim && gpu_data && accelerated_surface_route_id_ &&
1132 gpu_data->IsDriverBugWorkaroundActive(gpu::WAKE_UP_GPU_BEFORE_DRAWING))
1134 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_));
1137 SynchronousCompositorImpl* compositor =
1138 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
1139 host_->GetRoutingID());
1141 return compositor->HandleInputEvent(input_event);
1142 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1145 void RenderWidgetHostViewAndroid::OnSetNeedsFlushInput() {
1146 if (flush_input_requested_ || !content_view_core_)
1148 TRACE_EVENT0("input", "RenderWidgetHostViewAndroid::OnSetNeedsFlushInput");
1149 flush_input_requested_ = true;
1150 content_view_core_->AddBeginFrameSubscriber();
1153 void RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManagerIfNeeded() {
1154 if (!host_ || host_->accessibility_mode() != AccessibilityModeComplete)
1157 if (!GetBrowserAccessibilityManager()) {
1158 base::android::ScopedJavaLocalRef<jobject> obj;
1159 if (content_view_core_)
1160 obj = content_view_core_->GetJavaObject();
1161 SetBrowserAccessibilityManager(
1162 new BrowserAccessibilityManagerAndroid(
1163 obj, BrowserAccessibilityManagerAndroid::GetEmptyDocument(), this));
1167 void RenderWidgetHostViewAndroid::SetAccessibilityFocus(int acc_obj_id) {
1171 host_->AccessibilitySetFocus(acc_obj_id);
1174 void RenderWidgetHostViewAndroid::AccessibilityDoDefaultAction(int acc_obj_id) {
1178 host_->AccessibilityDoDefaultAction(acc_obj_id);
1181 void RenderWidgetHostViewAndroid::AccessibilityScrollToMakeVisible(
1182 int acc_obj_id, gfx::Rect subfocus) {
1186 host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus);
1189 void RenderWidgetHostViewAndroid::AccessibilityScrollToPoint(
1190 int acc_obj_id, gfx::Point point) {
1194 host_->AccessibilityScrollToPoint(acc_obj_id, point);
1197 void RenderWidgetHostViewAndroid::AccessibilitySetTextSelection(
1198 int acc_obj_id, int start_offset, int end_offset) {
1202 host_->AccessibilitySetTextSelection(
1203 acc_obj_id, start_offset, end_offset);
1206 gfx::Point RenderWidgetHostViewAndroid::GetLastTouchEventLocation() const {
1208 // Only used on Win8
1209 return gfx::Point();
1212 void RenderWidgetHostViewAndroid::FatalAccessibilityTreeError() {
1216 host_->FatalAccessibilityTreeError();
1217 SetBrowserAccessibilityManager(NULL);
1220 bool RenderWidgetHostViewAndroid::LockMouse() {
1225 void RenderWidgetHostViewAndroid::UnlockMouse() {
1229 // Methods called from the host to the render
1231 void RenderWidgetHostViewAndroid::SendKeyEvent(
1232 const NativeWebKeyboardEvent& event) {
1234 host_->ForwardKeyboardEvent(event);
1237 void RenderWidgetHostViewAndroid::SendTouchEvent(
1238 const blink::WebTouchEvent& event) {
1240 host_->ForwardTouchEventWithLatencyInfo(event, CreateLatencyInfo(event));
1243 void RenderWidgetHostViewAndroid::SendMouseEvent(
1244 const blink::WebMouseEvent& event) {
1246 host_->ForwardMouseEvent(event);
1249 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
1250 const blink::WebMouseWheelEvent& event) {
1252 host_->ForwardWheelEvent(event);
1255 void RenderWidgetHostViewAndroid::SendGestureEvent(
1256 const blink::WebGestureEvent& event) {
1257 // Sending a gesture that may trigger overscroll should resume the effect.
1258 if (overscroll_effect_enabled_)
1259 overscroll_effect_->Enable();
1262 host_->ForwardGestureEventWithLatencyInfo(event, CreateLatencyInfo(event));
1265 void RenderWidgetHostViewAndroid::SelectRange(const gfx::Point& start,
1266 const gfx::Point& end) {
1268 host_->SelectRange(start, end);
1271 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) {
1273 host_->MoveCaret(point);
1276 void RenderWidgetHostViewAndroid::RequestContentClipping(
1277 const gfx::Rect& clipping,
1278 const gfx::Size& content_size) {
1279 // A focused view provides its own clipping.
1283 ClipContents(clipping, content_size);
1286 void RenderWidgetHostViewAndroid::ResetClipping() {
1287 ClipContents(gfx::Rect(gfx::Point(), content_size_in_layer_),
1288 content_size_in_layer_);
1291 void RenderWidgetHostViewAndroid::ClipContents(const gfx::Rect& clipping,
1292 const gfx::Size& content_size) {
1293 if (!texture_id_in_layer_ || content_size_in_layer_.IsEmpty())
1296 gfx::Size clipped_content(content_size_in_layer_);
1297 clipped_content.SetToMin(clipping.size());
1298 texture_layer_->SetBounds(clipped_content);
1299 texture_layer_->SetNeedsDisplay();
1301 if (texture_size_in_layer_.IsEmpty()) {
1302 texture_layer_->SetUV(gfx::PointF(), gfx::PointF());
1307 clipping.x() + content_size_in_layer_.width() - content_size.width(),
1308 clipping.y() + content_size_in_layer_.height() - content_size.height());
1309 offset.SetToMax(gfx::PointF());
1311 gfx::Vector2dF uv_scale(1.f / texture_size_in_layer_.width(),
1312 1.f / texture_size_in_layer_.height());
1313 texture_layer_->SetUV(
1314 gfx::PointF(offset.x() * uv_scale.x(),
1315 offset.y() * uv_scale.y()),
1316 gfx::PointF((offset.x() + clipped_content.width()) * uv_scale.x(),
1317 (offset.y() + clipped_content.height()) * uv_scale.y()));
1320 SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
1321 return cached_background_color_;
1324 void RenderWidgetHostViewAndroid::OnOverscrolled(
1325 gfx::Vector2dF accumulated_overscroll,
1326 gfx::Vector2dF current_fling_velocity) {
1327 if (!content_view_core_ || !layer_ || !is_showing_)
1330 if (overscroll_effect_->OnOverscrolled(content_view_core_->GetLayer(),
1331 base::TimeTicks::Now(),
1332 accumulated_overscroll,
1333 current_fling_velocity)) {
1334 content_view_core_->SetNeedsAnimate();
1338 void RenderWidgetHostViewAndroid::DidStopFlinging() {
1339 if (content_view_core_)
1340 content_view_core_->DidStopFlinging();
1343 void RenderWidgetHostViewAndroid::SetContentViewCore(
1344 ContentViewCoreImpl* content_view_core) {
1348 if (content_view_core_ && !using_synchronous_compositor_)
1349 content_view_core_->GetWindowAndroid()->RemoveObserver(this);
1351 content_view_core_ = content_view_core;
1353 if (GetBrowserAccessibilityManager()) {
1354 base::android::ScopedJavaLocalRef<jobject> obj;
1355 if (content_view_core_)
1356 obj = content_view_core_->GetJavaObject();
1357 GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerAndroid()->
1358 SetContentViewCore(obj);
1362 if (content_view_core_ && !using_synchronous_compositor_)
1363 content_view_core_->GetWindowAndroid()->AddObserver(this);
1366 void RenderWidgetHostViewAndroid::RunAckCallbacks() {
1367 while (!ack_callbacks_.empty()) {
1368 ack_callbacks_.front().Run();
1369 ack_callbacks_.pop();
1373 void RenderWidgetHostViewAndroid::OnCompositingDidCommit() {
1377 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
1378 DCHECK(content_view_core_);
1379 DCHECK(!using_synchronous_compositor_);
1383 void RenderWidgetHostViewAndroid::OnLostResources() {
1384 if (texture_layer_.get())
1385 texture_layer_->SetIsDrawable(false);
1386 if (delegated_renderer_layer_.get())
1387 DestroyDelegatedContent();
1388 texture_id_in_layer_ = 0;
1393 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
1394 const gfx::Size& dst_size_in_pixel,
1395 const SkBitmap::Config bitmap_config,
1396 const base::TimeTicks& start_time,
1397 const base::Callback<void(bool, const SkBitmap&)>& callback,
1398 scoped_ptr<cc::CopyOutputResult> result) {
1399 base::ScopedClosureRunner scoped_callback_runner(
1400 base::Bind(callback, false, SkBitmap()));
1402 if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty())
1405 scoped_ptr<SkBitmap> bitmap(new SkBitmap);
1406 bitmap->setConfig(bitmap_config,
1407 dst_size_in_pixel.width(),
1408 dst_size_in_pixel.height(),
1409 0, kOpaque_SkAlphaType);
1410 if (!bitmap->allocPixels())
1413 ImageTransportFactoryAndroid* factory =
1414 ImageTransportFactoryAndroid::GetInstance();
1415 GLHelper* gl_helper = factory->GetGLHelper();
1419 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
1420 new SkAutoLockPixels(*bitmap));
1421 uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
1423 cc::TextureMailbox texture_mailbox;
1424 scoped_ptr<cc::SingleReleaseCallback> release_callback;
1425 result->TakeTexture(&texture_mailbox, &release_callback);
1426 DCHECK(texture_mailbox.IsTexture());
1427 if (!texture_mailbox.IsTexture())
1430 ignore_result(scoped_callback_runner.Release());
1432 gl_helper->CropScaleReadbackAndCleanMailbox(
1433 texture_mailbox.mailbox(),
1434 texture_mailbox.sync_point(),
1436 gfx::Rect(result->size()),
1440 base::Bind(&CopyFromCompositingSurfaceFinished,
1442 base::Passed(&release_callback),
1443 base::Passed(&bitmap),
1445 base::Passed(&bitmap_pixels_lock)));
1449 void RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult(
1450 const gfx::Size& dst_size_in_pixel,
1451 const SkBitmap::Config config,
1452 const base::TimeTicks& start_time,
1453 const base::Callback<void(bool, const SkBitmap&)>& callback,
1454 scoped_ptr<cc::CopyOutputResult> result) {
1455 if (config != SkBitmap::kARGB_8888_Config) {
1457 callback.Run(false, SkBitmap());
1460 DCHECK(result->HasBitmap());
1461 base::ScopedClosureRunner scoped_callback_runner(
1462 base::Bind(callback, false, SkBitmap()));
1464 if (!result->HasBitmap() || result->IsEmpty() || result->size().IsEmpty())
1467 scoped_ptr<SkBitmap> source = result->TakeBitmap();
1472 DCHECK_EQ(source->width(), dst_size_in_pixel.width());
1473 DCHECK_EQ(source->height(), dst_size_in_pixel.height());
1475 ignore_result(scoped_callback_runner.Release());
1476 UMA_HISTOGRAM_TIMES(kAsyncReadBackString,
1477 base::TimeTicks::Now() - start_time);
1479 callback.Run(true, *source);
1483 void RenderWidgetHostViewPort::GetDefaultScreenInfo(
1484 blink::WebScreenInfo* results) {
1485 const gfx::Display& display =
1486 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
1487 results->rect = display.bounds();
1488 // TODO(husky): Remove any system controls from availableRect.
1489 results->availableRect = display.work_area();
1490 results->deviceScaleFactor = display.device_scale_factor();
1491 gfx::DeviceDisplayInfo info;
1492 results->depth = info.GetBitsPerPixel();
1493 results->depthPerComponent = info.GetBitsPerComponent();
1494 results->isMonochrome = (results->depthPerComponent == 0);
1497 ////////////////////////////////////////////////////////////////////////////////
1498 // RenderWidgetHostView, public:
1501 RenderWidgetHostView*
1502 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost* widget) {
1503 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget);
1504 return new RenderWidgetHostViewAndroid(rwhi, NULL);
1507 } // namespace content