Implement DelegatedFrameResourceCollectionClient::UnusedResourcesAreAvailable for...
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_host_view_android.cc
blob9e9148adcd3c8044f89dafffc157e3bb1c14d78f
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"
63 namespace content {
65 namespace {
67 const int kUndefinedOutputSurfaceId = -1;
68 static const char kAsyncReadBackString[] = "Compositing.CopyFromSurfaceTime";
70 void InsertSyncPointAndAckForCompositor(
71 int renderer_host_id,
72 uint32 output_surface_id,
73 int route_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,
99 bool result) {
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 bool UsingDelegatedRenderer() {
108 bool using_delegated_renderer = false;
110 using_delegated_renderer |= CommandLine::ForCurrentProcess()->HasSwitch(
111 switches::kEnableDelegatedRenderer);
113 using_delegated_renderer &= !CommandLine::ForCurrentProcess()->HasSwitch(
114 switches::kDisableDelegatedRenderer);
116 return using_delegated_renderer;
119 ui::LatencyInfo CreateLatencyInfo(const blink::WebInputEvent event) {
120 ui::LatencyInfo latency_info;
121 // The latency number should only be added if the timestamp is valid.
122 if (event.timeStampSeconds) {
123 const int64 time_micros = static_cast<int64>(
124 event.timeStampSeconds * base::Time::kMicrosecondsPerSecond);
125 latency_info.AddLatencyNumberWithTimestamp(
126 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
129 base::TimeTicks() + base::TimeDelta::FromMicroseconds(time_micros),
132 return latency_info;
135 } // anonymous namespace
137 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
138 RenderWidgetHostImpl* widget_host,
139 ContentViewCoreImpl* content_view_core)
140 : host_(widget_host),
141 needs_begin_frame_(false),
142 is_showing_(!widget_host->is_hidden()),
143 content_view_core_(NULL),
144 ime_adapter_android_(this),
145 cached_background_color_(SK_ColorWHITE),
146 texture_id_in_layer_(0),
147 last_output_surface_id_(kUndefinedOutputSurfaceId),
148 weak_ptr_factory_(this),
149 overscroll_effect_enabled_(
150 !CommandLine::ForCurrentProcess()->
151 HasSwitch(switches::kDisableOverscrollEdgeEffect)),
152 overscroll_effect_(OverscrollGlow::Create(overscroll_effect_enabled_)),
153 flush_input_requested_(false),
154 accelerated_surface_route_id_(0),
155 using_synchronous_compositor_(SynchronousCompositorImpl::FromID(
156 widget_host->GetProcess()->GetID(),
157 widget_host->GetRoutingID()) != NULL),
158 frame_evictor_(new DelegatedFrameEvictor(this)) {
159 if (!UsingDelegatedRenderer()) {
160 texture_layer_ = cc::TextureLayer::Create(NULL);
161 layer_ = texture_layer_;
164 host_->SetView(this);
165 SetContentViewCore(content_view_core);
166 ImageTransportFactoryAndroid::AddObserver(this);
169 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
170 ImageTransportFactoryAndroid::RemoveObserver(this);
171 SetContentViewCore(NULL);
172 DCHECK(ack_callbacks_.empty());
173 if (texture_id_in_layer_) {
174 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
175 texture_id_in_layer_);
178 if (texture_layer_.get())
179 texture_layer_->ClearClient();
181 if (resource_collection_.get())
182 resource_collection_->SetClient(NULL);
186 bool RenderWidgetHostViewAndroid::OnMessageReceived(
187 const IPC::Message& message) {
188 bool handled = true;
189 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
190 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
191 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor,
192 OnDidChangeBodyBackgroundColor)
193 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame,
194 OnSetNeedsBeginFrame)
195 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
196 OnTextInputStateChanged)
197 IPC_MESSAGE_HANDLER(ViewHostMsg_SmartClipDataExtracted,
198 OnSmartClipDataExtracted)
199 IPC_MESSAGE_UNHANDLED(handled = false)
200 IPC_END_MESSAGE_MAP()
201 return handled;
204 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
205 NOTIMPLEMENTED();
208 void RenderWidgetHostViewAndroid::InitAsPopup(
209 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
210 NOTIMPLEMENTED();
213 void RenderWidgetHostViewAndroid::InitAsFullscreen(
214 RenderWidgetHostView* reference_host_view) {
215 NOTIMPLEMENTED();
218 RenderWidgetHost*
219 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
220 return host_;
223 void RenderWidgetHostViewAndroid::WasShown() {
224 if (!host_ || !host_->is_hidden())
225 return;
227 host_->WasShown();
229 if (content_view_core_ && !using_synchronous_compositor_)
230 content_view_core_->GetWindowAndroid()->AddObserver(this);
233 void RenderWidgetHostViewAndroid::WasHidden() {
234 RunAckCallbacks();
236 if (!host_ || host_->is_hidden())
237 return;
239 // Inform the renderer that we are being hidden so it can reduce its resource
240 // utilization.
241 host_->WasHidden();
243 if (content_view_core_ && !using_synchronous_compositor_)
244 content_view_core_->GetWindowAndroid()->RemoveObserver(this);
247 void RenderWidgetHostViewAndroid::WasResized() {
248 host_->WasResized();
251 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) {
252 // Ignore the given size as only the Java code has the power to
253 // resize the view on Android.
254 default_size_ = size;
255 WasResized();
258 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
259 SetSize(rect.size());
262 void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
263 float scale,
264 gfx::Size* out_size,
265 const base::Callback<void(bool, const SkBitmap&)>& result_callback) {
266 if (!IsSurfaceAvailableForCopy()) {
267 result_callback.Run(false, SkBitmap());
268 return;
271 gfx::Size bounds = layer_->bounds();
272 gfx::Rect src_subrect(bounds);
273 const gfx::Display& display =
274 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
275 float device_scale_factor = display.device_scale_factor();
276 DCHECK_GT(device_scale_factor, 0);
277 gfx::Size dst_size(
278 gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale / device_scale_factor)));
279 *out_size = dst_size;
280 CopyFromCompositingSurface(
281 src_subrect, dst_size, result_callback, SkBitmap::kARGB_8888_Config);
284 bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(jobject jbitmap) {
285 if (!CompositorImpl::IsInitialized() ||
286 texture_id_in_layer_ == 0 ||
287 texture_size_in_layer_.IsEmpty())
288 return false;
290 gfx::JavaBitmap bitmap(jbitmap);
292 // TODO(dtrainor): Eventually add support for multiple formats here.
293 DCHECK(bitmap.format() == ANDROID_BITMAP_FORMAT_RGBA_8888);
295 GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
297 GLuint texture = helper->CopyAndScaleTexture(
298 texture_id_in_layer_,
299 texture_size_in_layer_,
300 bitmap.size(),
301 true,
302 GLHelper::SCALER_QUALITY_FAST);
303 if (texture == 0u)
304 return false;
306 helper->ReadbackTextureSync(texture,
307 gfx::Rect(bitmap.size()),
308 static_cast<unsigned char*> (bitmap.pixels()),
309 SkBitmap::kARGB_8888_Config);
311 gpu::gles2::GLES2Interface* gl =
312 ImageTransportFactoryAndroid::GetInstance()->GetContextGL();
313 gl->DeleteTextures(1, &texture);
315 return true;
318 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
319 if (!content_view_core_)
320 return false;
321 if (!layer_)
322 return false;
324 if (texture_size_in_layer_.IsEmpty())
325 return false;
327 if (UsingDelegatedRenderer()) {
328 if (!delegated_renderer_layer_.get())
329 return false;
330 } else {
331 if (texture_id_in_layer_ == 0)
332 return false;
335 return true;
338 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
339 return content_view_core_->GetViewAndroid();
342 gfx::NativeViewId RenderWidgetHostViewAndroid::GetNativeViewId() const {
343 return reinterpret_cast<gfx::NativeViewId>(
344 const_cast<RenderWidgetHostViewAndroid*>(this));
347 gfx::NativeViewAccessible
348 RenderWidgetHostViewAndroid::GetNativeViewAccessible() {
349 NOTIMPLEMENTED();
350 return NULL;
353 void RenderWidgetHostViewAndroid::MovePluginWindows(
354 const gfx::Vector2d& scroll_offset,
355 const std::vector<WebPluginGeometry>& moves) {
356 // We don't have plugin windows on Android. Do nothing. Note: this is called
357 // from RenderWidgetHost::OnUpdateRect which is itself invoked while
358 // processing the corresponding message from Renderer.
361 void RenderWidgetHostViewAndroid::Focus() {
362 host_->Focus();
363 host_->SetInputMethodActive(true);
364 ResetClipping();
365 if (overscroll_effect_enabled_)
366 overscroll_effect_->Enable();
369 void RenderWidgetHostViewAndroid::Blur() {
370 host_->ExecuteEditCommand("Unselect", "");
371 host_->SetInputMethodActive(false);
372 host_->Blur();
373 overscroll_effect_->Disable();
376 bool RenderWidgetHostViewAndroid::HasFocus() const {
377 if (!content_view_core_)
378 return false; // ContentViewCore not created yet.
380 return content_view_core_->HasFocus();
383 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
384 return HasValidFrame();
387 void RenderWidgetHostViewAndroid::Show() {
388 if (is_showing_)
389 return;
391 is_showing_ = true;
392 if (layer_)
393 layer_->SetHideLayerAndSubtree(false);
395 frame_evictor_->SetVisible(true);
396 WasShown();
399 void RenderWidgetHostViewAndroid::Hide() {
400 if (!is_showing_)
401 return;
403 is_showing_ = false;
404 if (layer_)
405 layer_->SetHideLayerAndSubtree(true);
407 frame_evictor_->SetVisible(false);
408 WasHidden();
411 bool RenderWidgetHostViewAndroid::IsShowing() {
412 // ContentViewCoreImpl represents the native side of the Java
413 // ContentViewCore. It being NULL means that it is not attached
414 // to the View system yet, so we treat this RWHVA as hidden.
415 return is_showing_ && content_view_core_;
418 void RenderWidgetHostViewAndroid::LockResources() {
419 DCHECK(HasValidFrame());
420 DCHECK(host_);
421 DCHECK(!host_->is_hidden());
422 frame_evictor_->LockFrame();
425 void RenderWidgetHostViewAndroid::UnlockResources() {
426 DCHECK(HasValidFrame());
427 frame_evictor_->UnlockFrame();
430 gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const {
431 if (!content_view_core_)
432 return gfx::Rect(default_size_);
434 gfx::Size size = content_view_core_->GetViewportSizeDip();
435 gfx::Size offset = content_view_core_->GetViewportSizeOffsetDip();
436 size.Enlarge(-offset.width(), -offset.height());
438 return gfx::Rect(size);
441 gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
442 if (!content_view_core_)
443 return gfx::Size();
445 return content_view_core_->GetPhysicalBackingSize();
448 float RenderWidgetHostViewAndroid::GetOverdrawBottomHeight() const {
449 if (!content_view_core_)
450 return 0.f;
452 return content_view_core_->GetOverdrawBottomHeightDip();
455 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& cursor) {
456 // There are no cursors on Android.
459 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading) {
460 // Do nothing. The UI notification is handled through ContentViewClient which
461 // is TabContentsDelegate.
464 void RenderWidgetHostViewAndroid::TextInputTypeChanged(
465 ui::TextInputType type,
466 ui::TextInputMode input_mode,
467 bool can_compose_inline) {
468 // Unused on Android, which uses OnTextInputChanged instead.
471 int RenderWidgetHostViewAndroid::GetNativeImeAdapter() {
472 return reinterpret_cast<int>(&ime_adapter_android_);
475 void RenderWidgetHostViewAndroid::OnTextInputStateChanged(
476 const ViewHostMsg_TextInputState_Params& params) {
477 // If an acknowledgement is required for this event, regardless of how we exit
478 // from this method, we must acknowledge that we processed the input state
479 // change.
480 base::ScopedClosureRunner ack_caller;
481 if (params.require_ack)
482 ack_caller.Reset(base::Bind(&SendImeEventAck, host_));
484 if (!IsShowing())
485 return;
487 content_view_core_->UpdateImeAdapter(
488 GetNativeImeAdapter(),
489 static_cast<int>(params.type),
490 params.value, params.selection_start, params.selection_end,
491 params.composition_start, params.composition_end,
492 params.show_ime_if_needed, params.require_ack);
495 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor(
496 SkColor color) {
497 if (cached_background_color_ == color)
498 return;
500 cached_background_color_ = color;
501 if (content_view_core_)
502 content_view_core_->OnBackgroundColorChanged(color);
505 void RenderWidgetHostViewAndroid::SendBeginFrame(
506 const cc::BeginFrameArgs& args) {
507 TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::SendBeginFrame");
508 if (!host_)
509 return;
511 if (flush_input_requested_) {
512 flush_input_requested_ = false;
513 host_->FlushInput();
514 content_view_core_->RemoveBeginFrameSubscriber();
517 host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), args));
520 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame(
521 bool enabled) {
522 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame",
523 "enabled", enabled);
524 // ContentViewCoreImpl handles multiple subscribers to the BeginFrame, so
525 // we have to make sure calls to ContentViewCoreImpl's
526 // {Add,Remove}BeginFrameSubscriber are balanced, even if
527 // RenderWidgetHostViewAndroid's may not be.
528 if (content_view_core_ && needs_begin_frame_ != enabled) {
529 if (enabled)
530 content_view_core_->AddBeginFrameSubscriber();
531 else
532 content_view_core_->RemoveBeginFrameSubscriber();
533 needs_begin_frame_ = enabled;
537 void RenderWidgetHostViewAndroid::OnStartContentIntent(
538 const GURL& content_url) {
539 if (content_view_core_)
540 content_view_core_->StartContentIntent(content_url);
543 void RenderWidgetHostViewAndroid::OnSmartClipDataExtracted(
544 const base::string16& result) {
545 // Custom serialization over IPC isn't allowed normally for security reasons.
546 // Since this feature is only used in (single-process) WebView, there are no
547 // security issues. Enforce that it's only called in single process mode.
548 CHECK(RenderProcessHost::run_renderer_in_process());
549 if (content_view_core_)
550 content_view_core_->OnSmartClipDataExtracted(result);
553 void RenderWidgetHostViewAndroid::ImeCancelComposition() {
554 ime_adapter_android_.CancelComposition();
557 void RenderWidgetHostViewAndroid::FocusedNodeChanged(bool is_editable_node) {
558 ime_adapter_android_.FocusedNodeChanged(is_editable_node);
561 void RenderWidgetHostViewAndroid::DidUpdateBackingStore(
562 const gfx::Rect& scroll_rect,
563 const gfx::Vector2d& scroll_delta,
564 const std::vector<gfx::Rect>& copy_rects,
565 const std::vector<ui::LatencyInfo>& latency_info) {
566 NOTIMPLEMENTED();
569 void RenderWidgetHostViewAndroid::RenderProcessGone(
570 base::TerminationStatus status, int error_code) {
571 Destroy();
574 void RenderWidgetHostViewAndroid::Destroy() {
575 RemoveLayers();
576 SetContentViewCore(NULL);
578 // The RenderWidgetHost's destruction led here, so don't call it.
579 host_ = NULL;
581 delete this;
584 void RenderWidgetHostViewAndroid::SetTooltipText(
585 const base::string16& tooltip_text) {
586 // Tooltips don't makes sense on Android.
589 void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16& text,
590 size_t offset,
591 const gfx::Range& range) {
592 RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
594 if (text.empty() || range.is_empty() || !content_view_core_)
595 return;
596 size_t pos = range.GetMin() - offset;
597 size_t n = range.length();
599 DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
600 if (pos >= text.length()) {
601 NOTREACHED() << "The text can not cover range.";
602 return;
605 std::string utf8_selection = base::UTF16ToUTF8(text.substr(pos, n));
607 content_view_core_->OnSelectionChanged(utf8_selection);
610 void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
611 const ViewHostMsg_SelectionBounds_Params& params) {
612 if (content_view_core_) {
613 content_view_core_->OnSelectionBoundsChanged(params);
617 void RenderWidgetHostViewAndroid::ScrollOffsetChanged() {
620 BackingStore* RenderWidgetHostViewAndroid::AllocBackingStore(
621 const gfx::Size& size) {
622 NOTIMPLEMENTED();
623 return NULL;
626 void RenderWidgetHostViewAndroid::SetBackground(const SkBitmap& background) {
627 RenderWidgetHostViewBase::SetBackground(background);
628 host_->Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background));
631 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
632 const gfx::Rect& src_subrect,
633 const gfx::Size& dst_size,
634 const base::Callback<void(bool, const SkBitmap&)>& callback,
635 const SkBitmap::Config bitmap_config) {
636 // Only ARGB888 and RGB565 supported as of now.
637 bool format_support = ((bitmap_config == SkBitmap::kRGB_565_Config) ||
638 (bitmap_config == SkBitmap::kARGB_8888_Config));
639 if (!format_support) {
640 DCHECK(format_support);
641 callback.Run(false, SkBitmap());
642 return;
644 base::TimeTicks start_time = base::TimeTicks::Now();
645 if (!using_synchronous_compositor_ && !IsSurfaceAvailableForCopy()) {
646 callback.Run(false, SkBitmap());
647 return;
649 ImageTransportFactoryAndroid* factory =
650 ImageTransportFactoryAndroid::GetInstance();
651 GLHelper* gl_helper = factory->GetGLHelper();
652 if (!gl_helper)
653 return;
654 bool check_rgb565_support = gl_helper->CanUseRgb565Readback();
655 if ((bitmap_config == SkBitmap::kRGB_565_Config) &&
656 !check_rgb565_support) {
657 LOG(ERROR) << "Readbackformat rgb565 not supported";
658 callback.Run(false, SkBitmap());
659 return;
661 const gfx::Display& display =
662 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
663 float device_scale_factor = display.device_scale_factor();
665 DCHECK_EQ(device_scale_factor,
666 ui::GetImageScale(GetScaleFactorForView(this)));
668 const gfx::Size& dst_size_in_pixel = ConvertViewSizeToPixel(this, dst_size);
669 gfx::Rect src_subrect_in_pixel =
670 ConvertRectToPixel(device_scale_factor, src_subrect);
672 if (using_synchronous_compositor_) {
673 SynchronousCopyContents(src_subrect_in_pixel, dst_size_in_pixel, callback);
674 UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous",
675 base::TimeTicks::Now() - start_time);
676 return;
678 scoped_ptr<cc::CopyOutputRequest> request;
679 if (src_subrect_in_pixel.size() == dst_size_in_pixel) {
680 request = cc::CopyOutputRequest::CreateBitmapRequest(base::Bind(
681 &RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult,
682 dst_size_in_pixel,
683 start_time,
684 callback));
685 } else {
686 request = cc::CopyOutputRequest::CreateRequest(base::Bind(
687 &RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult,
688 dst_size_in_pixel,
689 bitmap_config,
690 start_time,
691 callback));
693 request->set_area(src_subrect_in_pixel);
694 layer_->RequestCopyOfOutput(request.Pass());
697 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
698 const gfx::Rect& src_subrect,
699 const scoped_refptr<media::VideoFrame>& target,
700 const base::Callback<void(bool)>& callback) {
701 NOTIMPLEMENTED();
702 callback.Run(false);
705 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
706 return false;
709 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
710 const gfx::Rect& target_rect, const SkBitmap& zoomed_bitmap) {
711 if (!content_view_core_)
712 return;
714 content_view_core_->ShowDisambiguationPopup(target_rect, zoomed_bitmap);
717 scoped_ptr<SyntheticGestureTarget>
718 RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
719 return scoped_ptr<SyntheticGestureTarget>(new SyntheticGestureTargetAndroid(
720 host_, content_view_core_->CreateTouchEventSynthesizer()));
723 void RenderWidgetHostViewAndroid::OnAcceleratedCompositingStateChange() {
726 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
727 uint32 output_surface_id) {
728 cc::CompositorFrameAck ack;
729 if (resource_collection_.get())
730 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
731 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_->GetRoutingID(),
732 output_surface_id,
733 host_->GetProcess()->GetID(),
734 ack);
737 void RenderWidgetHostViewAndroid::SendReturnedDelegatedResources(
738 uint32 output_surface_id) {
739 DCHECK(resource_collection_);
741 cc::CompositorFrameAck ack;
742 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
743 DCHECK(!ack.resources.empty());
745 RenderWidgetHostImpl::SendReclaimCompositorResources(
746 host_->GetRoutingID(),
747 output_surface_id,
748 host_->GetProcess()->GetID(),
749 ack);
752 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
753 if (ack_callbacks_.size())
754 return;
755 SendReturnedDelegatedResources(last_output_surface_id_);
758 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
759 RemoveLayers();
760 frame_provider_ = NULL;
761 delegated_renderer_layer_ = NULL;
762 layer_ = NULL;
765 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
766 uint32 output_surface_id,
767 scoped_ptr<cc::DelegatedFrameData> frame_data) {
768 bool has_content = !texture_size_in_layer_.IsEmpty();
770 if (output_surface_id != last_output_surface_id_) {
771 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
772 // any resources from the old output surface with the new output surface id.
773 if (resource_collection_.get()) {
774 if (resource_collection_->LoseAllResources())
775 SendReturnedDelegatedResources(last_output_surface_id_);
777 resource_collection_->SetClient(NULL);
778 resource_collection_ = NULL;
780 DestroyDelegatedContent();
782 last_output_surface_id_ = output_surface_id;
785 if (!has_content) {
786 DestroyDelegatedContent();
787 } else {
788 if (!resource_collection_.get()) {
789 resource_collection_ = new cc::DelegatedFrameResourceCollection;
790 resource_collection_->SetClient(this);
792 if (!frame_provider_ ||
793 texture_size_in_layer_ != frame_provider_->frame_size()) {
794 RemoveLayers();
795 frame_provider_ = new cc::DelegatedFrameProvider(
796 resource_collection_.get(), frame_data.Pass());
797 delegated_renderer_layer_ =
798 cc::DelegatedRendererLayer::Create(frame_provider_);
799 layer_ = delegated_renderer_layer_;
800 AttachLayers();
801 } else {
802 frame_provider_->SetFrameData(frame_data.Pass());
806 if (delegated_renderer_layer_.get()) {
807 delegated_renderer_layer_->SetDisplaySize(texture_size_in_layer_);
808 delegated_renderer_layer_->SetIsDrawable(true);
809 delegated_renderer_layer_->SetContentsOpaque(true);
810 delegated_renderer_layer_->SetBounds(content_size_in_layer_);
811 delegated_renderer_layer_->SetNeedsDisplay();
814 base::Closure ack_callback =
815 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
816 weak_ptr_factory_.GetWeakPtr(),
817 output_surface_id);
819 if (host_->is_hidden())
820 ack_callback.Run();
821 else
822 ack_callbacks_.push(ack_callback);
825 void RenderWidgetHostViewAndroid::ComputeContentsSize(
826 const cc::CompositorFrameMetadata& frame_metadata) {
827 // Calculate the content size. This should be 0 if the texture_size is 0.
828 gfx::Vector2dF offset;
829 if (texture_size_in_layer_.GetArea() > 0)
830 offset = frame_metadata.location_bar_content_translation;
831 offset.set_y(offset.y() + frame_metadata.overdraw_bottom_height);
832 offset.Scale(frame_metadata.device_scale_factor);
833 content_size_in_layer_ =
834 gfx::Size(texture_size_in_layer_.width() - offset.x(),
835 texture_size_in_layer_.height() - offset.y());
836 // Content size changes should be reflected in associated animation effects.
837 UpdateAnimationSize(frame_metadata);
840 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
841 uint32 output_surface_id,
842 scoped_ptr<cc::CompositorFrame> frame) {
843 // Always let ContentViewCore know about the new frame first, so it can decide
844 // to schedule a Draw immediately when it sees the texture layer invalidation.
845 UpdateContentViewCoreFrameMetadata(frame->metadata);
847 if (frame->delegated_frame_data) {
848 DCHECK(UsingDelegatedRenderer());
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());
860 return;
863 DCHECK(!UsingDelegatedRenderer());
865 if (!frame->gl_frame_data || frame->gl_frame_data->mailbox.IsZero())
866 return;
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(),
875 output_surface_id,
876 host_->GetRoutingID(),
877 current_mailbox_,
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 if (layer_->layer_tree_host()) {
886 for (size_t i = 0; i < frame->metadata.latency_info.size(); i++) {
887 scoped_ptr<cc::SwapPromise> swap_promise(
888 new cc::LatencyInfoSwapPromise(frame->metadata.latency_info[i]));
889 layer_->layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
893 BuffersSwapped(frame->gl_frame_data->mailbox, output_surface_id, callback);
894 frame_evictor_->SwappedFrame(!host_->is_hidden());
897 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
898 const cc::CompositorFrameMetadata& frame_metadata) {
899 // This is a subset of OnSwapCompositorFrame() used in the synchronous
900 // compositor flow.
901 UpdateContentViewCoreFrameMetadata(frame_metadata);
902 ComputeContentsSize(frame_metadata);
904 // DevTools ScreenCast support for Android WebView.
905 if (DevToolsAgentHost::HasFor(RenderViewHost::From(GetRenderWidgetHost()))) {
906 scoped_refptr<DevToolsAgentHost> dtah =
907 DevToolsAgentHost::GetOrCreateFor(
908 RenderViewHost::From(GetRenderWidgetHost()));
909 // Unblock the compositor.
910 BrowserThread::PostTask(
911 BrowserThread::UI, FROM_HERE,
912 base::Bind(&RenderViewDevToolsAgentHost::SynchronousSwapCompositorFrame,
913 static_cast<RenderViewDevToolsAgentHost*>(dtah.get()),
914 frame_metadata));
918 void RenderWidgetHostViewAndroid::SetOverlayVideoMode(bool enabled) {
919 layer_->SetContentsOpaque(!enabled);
922 void RenderWidgetHostViewAndroid::SynchronousCopyContents(
923 const gfx::Rect& src_subrect_in_pixel,
924 const gfx::Size& dst_size_in_pixel,
925 const base::Callback<void(bool, const SkBitmap&)>& callback) {
926 SynchronousCompositor* compositor =
927 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
928 host_->GetRoutingID());
929 if (!compositor) {
930 callback.Run(false, SkBitmap());
931 return;
934 SkBitmap bitmap;
935 bitmap.setConfig(SkBitmap::kARGB_8888_Config,
936 dst_size_in_pixel.width(),
937 dst_size_in_pixel.height());
938 bitmap.allocPixels();
939 SkCanvas canvas(bitmap);
940 canvas.scale(
941 (float)dst_size_in_pixel.width() / (float)src_subrect_in_pixel.width(),
942 (float)dst_size_in_pixel.height() / (float)src_subrect_in_pixel.height());
943 compositor->DemandDrawSw(&canvas);
944 callback.Run(true, bitmap);
947 void RenderWidgetHostViewAndroid::UpdateContentViewCoreFrameMetadata(
948 const cc::CompositorFrameMetadata& frame_metadata) {
949 if (content_view_core_) {
950 // All offsets and sizes are in CSS pixels.
951 content_view_core_->UpdateFrameInfo(
952 frame_metadata.root_scroll_offset,
953 frame_metadata.page_scale_factor,
954 gfx::Vector2dF(frame_metadata.min_page_scale_factor,
955 frame_metadata.max_page_scale_factor),
956 frame_metadata.root_layer_size,
957 frame_metadata.viewport_size,
958 frame_metadata.location_bar_offset,
959 frame_metadata.location_bar_content_translation,
960 frame_metadata.overdraw_bottom_height);
964 void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int host_id,
965 int route_id) {
966 accelerated_surface_route_id_ = route_id;
969 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
970 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
971 int gpu_host_id) {
972 NOTREACHED() << "Need --composite-to-mailbox or --enable-delegated-renderer";
975 void RenderWidgetHostViewAndroid::BuffersSwapped(
976 const gpu::Mailbox& mailbox,
977 uint32_t output_surface_id,
978 const base::Closure& ack_callback) {
979 ImageTransportFactoryAndroid* factory =
980 ImageTransportFactoryAndroid::GetInstance();
982 if (!texture_id_in_layer_) {
983 texture_id_in_layer_ = factory->CreateTexture();
984 texture_layer_->SetTextureId(texture_id_in_layer_);
985 texture_layer_->SetIsDrawable(true);
986 texture_layer_->SetContentsOpaque(true);
989 ImageTransportFactoryAndroid::GetInstance()->AcquireTexture(
990 texture_id_in_layer_, mailbox.name);
992 ResetClipping();
994 current_mailbox_ = mailbox;
995 last_output_surface_id_ = output_surface_id;
997 if (host_->is_hidden())
998 ack_callback.Run();
999 else
1000 ack_callbacks_.push(ack_callback);
1003 void RenderWidgetHostViewAndroid::AttachLayers() {
1004 if (!content_view_core_)
1005 return;
1006 if (!layer_.get())
1007 return;
1009 content_view_core_->AttachLayer(layer_);
1010 if (overscroll_effect_enabled_)
1011 overscroll_effect_->Enable();
1012 layer_->SetHideLayerAndSubtree(!is_showing_);
1015 void RenderWidgetHostViewAndroid::RemoveLayers() {
1016 if (!content_view_core_)
1017 return;
1018 if (!layer_.get())
1019 return;
1021 content_view_core_->RemoveLayer(layer_);
1022 overscroll_effect_->Disable();
1025 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) {
1026 return overscroll_effect_->Animate(frame_time);
1029 void RenderWidgetHostViewAndroid::UpdateAnimationSize(
1030 const cc::CompositorFrameMetadata& frame_metadata) {
1031 // Disable edge effects for axes on which scrolling is impossible.
1032 gfx::SizeF ceiled_viewport_size =
1033 gfx::ToCeiledSize(frame_metadata.viewport_size);
1034 overscroll_effect_->set_horizontal_overscroll_enabled(
1035 ceiled_viewport_size.width() < frame_metadata.root_layer_size.width());
1036 overscroll_effect_->set_vertical_overscroll_enabled(
1037 ceiled_viewport_size.height() < frame_metadata.root_layer_size.height());
1038 overscroll_effect_->set_size(content_size_in_layer_);
1041 void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
1042 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
1043 int gpu_host_id) {
1044 NOTREACHED();
1047 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() {
1048 NOTREACHED();
1051 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
1052 NOTREACHED();
1055 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
1056 if (texture_id_in_layer_) {
1057 texture_layer_->SetTextureId(0);
1058 texture_layer_->SetIsDrawable(false);
1059 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
1060 texture_id_in_layer_);
1061 texture_id_in_layer_ = 0;
1062 current_mailbox_ = gpu::Mailbox();
1063 last_output_surface_id_ = kUndefinedOutputSurfaceId;
1065 if (delegated_renderer_layer_.get())
1066 DestroyDelegatedContent();
1067 frame_evictor_->DiscardedFrame();
1070 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
1071 const gfx::Size& desired_size) {
1072 NOTREACHED();
1073 return false;
1076 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) {
1077 // ScreenInfo isn't tied to the widget on Android. Always return the default.
1078 RenderWidgetHostViewBase::GetDefaultScreenInfo(result);
1081 // TODO(jrg): Find out the implications and answer correctly here,
1082 // as we are returning the WebView and not root window bounds.
1083 gfx::Rect RenderWidgetHostViewAndroid::GetBoundsInRootWindow() {
1084 return GetViewBounds();
1087 gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() {
1088 gfx::GLSurfaceHandle handle =
1089 gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::NATIVE_TRANSPORT);
1090 if (CompositorImpl::IsInitialized()) {
1091 handle.parent_client_id =
1092 ImageTransportFactoryAndroid::GetInstance()->GetChannelID();
1094 return handle;
1097 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
1098 const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
1099 if (content_view_core_)
1100 content_view_core_->ConfirmTouchEvent(ack_result);
1103 void RenderWidgetHostViewAndroid::SetHasHorizontalScrollbar(
1104 bool has_horizontal_scrollbar) {
1105 // intentionally empty, like RenderWidgetHostViewViews
1108 void RenderWidgetHostViewAndroid::SetScrollOffsetPinning(
1109 bool is_pinned_to_left, bool is_pinned_to_right) {
1110 // intentionally empty, like RenderWidgetHostViewViews
1113 void RenderWidgetHostViewAndroid::UnhandledWheelEvent(
1114 const blink::WebMouseWheelEvent& event) {
1115 // intentionally empty, like RenderWidgetHostViewViews
1118 void RenderWidgetHostViewAndroid::GestureEventAck(
1119 const blink::WebGestureEvent& event,
1120 InputEventAckState ack_result) {
1121 if (content_view_core_)
1122 content_view_core_->OnGestureEventAck(event, ack_result);
1125 InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
1126 const blink::WebInputEvent& input_event) {
1127 if (content_view_core_ &&
1128 content_view_core_->FilterInputEvent(input_event))
1129 return INPUT_EVENT_ACK_STATE_CONSUMED;
1131 if (!host_)
1132 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1134 if (input_event.type == blink::WebInputEvent::GestureTapDown ||
1135 input_event.type == blink::WebInputEvent::TouchStart) {
1136 GpuDataManagerImpl* gpu_data = GpuDataManagerImpl::GetInstance();
1137 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
1138 if (shim && gpu_data && accelerated_surface_route_id_ &&
1139 gpu_data->IsDriverBugWorkaroundActive(gpu::WAKE_UP_GPU_BEFORE_DRAWING))
1140 shim->Send(
1141 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_));
1144 SynchronousCompositorImpl* compositor =
1145 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
1146 host_->GetRoutingID());
1147 if (compositor)
1148 return compositor->HandleInputEvent(input_event);
1149 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1152 void RenderWidgetHostViewAndroid::OnSetNeedsFlushInput() {
1153 if (flush_input_requested_ || !content_view_core_)
1154 return;
1155 flush_input_requested_ = true;
1156 content_view_core_->AddBeginFrameSubscriber();
1159 void RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManagerIfNeeded() {
1160 if (!host_ || host_->accessibility_mode() != AccessibilityModeComplete)
1161 return;
1163 if (!GetBrowserAccessibilityManager()) {
1164 base::android::ScopedJavaLocalRef<jobject> obj;
1165 if (content_view_core_)
1166 obj = content_view_core_->GetJavaObject();
1167 SetBrowserAccessibilityManager(
1168 new BrowserAccessibilityManagerAndroid(
1169 obj, BrowserAccessibilityManagerAndroid::GetEmptyDocument(), this));
1173 void RenderWidgetHostViewAndroid::SetAccessibilityFocus(int acc_obj_id) {
1174 if (!host_)
1175 return;
1177 host_->AccessibilitySetFocus(acc_obj_id);
1180 void RenderWidgetHostViewAndroid::AccessibilityDoDefaultAction(int acc_obj_id) {
1181 if (!host_)
1182 return;
1184 host_->AccessibilityDoDefaultAction(acc_obj_id);
1187 void RenderWidgetHostViewAndroid::AccessibilityScrollToMakeVisible(
1188 int acc_obj_id, gfx::Rect subfocus) {
1189 if (!host_)
1190 return;
1192 host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus);
1195 void RenderWidgetHostViewAndroid::AccessibilityScrollToPoint(
1196 int acc_obj_id, gfx::Point point) {
1197 if (!host_)
1198 return;
1200 host_->AccessibilityScrollToPoint(acc_obj_id, point);
1203 void RenderWidgetHostViewAndroid::AccessibilitySetTextSelection(
1204 int acc_obj_id, int start_offset, int end_offset) {
1205 if (!host_)
1206 return;
1208 host_->AccessibilitySetTextSelection(
1209 acc_obj_id, start_offset, end_offset);
1212 gfx::Point RenderWidgetHostViewAndroid::GetLastTouchEventLocation() const {
1213 NOTIMPLEMENTED();
1214 // Only used on Win8
1215 return gfx::Point();
1218 void RenderWidgetHostViewAndroid::FatalAccessibilityTreeError() {
1219 if (!host_)
1220 return;
1222 host_->FatalAccessibilityTreeError();
1223 SetBrowserAccessibilityManager(NULL);
1226 bool RenderWidgetHostViewAndroid::LockMouse() {
1227 NOTIMPLEMENTED();
1228 return false;
1231 void RenderWidgetHostViewAndroid::UnlockMouse() {
1232 NOTIMPLEMENTED();
1235 // Methods called from the host to the render
1237 void RenderWidgetHostViewAndroid::SendKeyEvent(
1238 const NativeWebKeyboardEvent& event) {
1239 if (host_)
1240 host_->ForwardKeyboardEvent(event);
1243 void RenderWidgetHostViewAndroid::SendTouchEvent(
1244 const blink::WebTouchEvent& event) {
1245 if (host_)
1246 host_->ForwardTouchEventWithLatencyInfo(event, CreateLatencyInfo(event));
1249 void RenderWidgetHostViewAndroid::SendMouseEvent(
1250 const blink::WebMouseEvent& event) {
1251 if (host_)
1252 host_->ForwardMouseEvent(event);
1255 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
1256 const blink::WebMouseWheelEvent& event) {
1257 if (host_)
1258 host_->ForwardWheelEvent(event);
1261 void RenderWidgetHostViewAndroid::SendGestureEvent(
1262 const blink::WebGestureEvent& event) {
1263 // Sending a gesture that may trigger overscroll should resume the effect.
1264 if (overscroll_effect_enabled_)
1265 overscroll_effect_->Enable();
1267 if (host_)
1268 host_->ForwardGestureEventWithLatencyInfo(event, CreateLatencyInfo(event));
1271 void RenderWidgetHostViewAndroid::SelectRange(const gfx::Point& start,
1272 const gfx::Point& end) {
1273 if (host_)
1274 host_->SelectRange(start, end);
1277 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) {
1278 if (host_)
1279 host_->MoveCaret(point);
1282 void RenderWidgetHostViewAndroid::RequestContentClipping(
1283 const gfx::Rect& clipping,
1284 const gfx::Size& content_size) {
1285 // A focused view provides its own clipping.
1286 if (HasFocus())
1287 return;
1289 ClipContents(clipping, content_size);
1292 void RenderWidgetHostViewAndroid::ResetClipping() {
1293 ClipContents(gfx::Rect(gfx::Point(), content_size_in_layer_),
1294 content_size_in_layer_);
1297 void RenderWidgetHostViewAndroid::ClipContents(const gfx::Rect& clipping,
1298 const gfx::Size& content_size) {
1299 if (!texture_id_in_layer_ || content_size_in_layer_.IsEmpty())
1300 return;
1302 gfx::Size clipped_content(content_size_in_layer_);
1303 clipped_content.SetToMin(clipping.size());
1304 texture_layer_->SetBounds(clipped_content);
1305 texture_layer_->SetNeedsDisplay();
1307 if (texture_size_in_layer_.IsEmpty()) {
1308 texture_layer_->SetUV(gfx::PointF(), gfx::PointF());
1309 return;
1312 gfx::PointF offset(
1313 clipping.x() + content_size_in_layer_.width() - content_size.width(),
1314 clipping.y() + content_size_in_layer_.height() - content_size.height());
1315 offset.SetToMax(gfx::PointF());
1317 gfx::Vector2dF uv_scale(1.f / texture_size_in_layer_.width(),
1318 1.f / texture_size_in_layer_.height());
1319 texture_layer_->SetUV(
1320 gfx::PointF(offset.x() * uv_scale.x(),
1321 offset.y() * uv_scale.y()),
1322 gfx::PointF((offset.x() + clipped_content.width()) * uv_scale.x(),
1323 (offset.y() + clipped_content.height()) * uv_scale.y()));
1326 SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
1327 return cached_background_color_;
1330 void RenderWidgetHostViewAndroid::OnOverscrolled(
1331 gfx::Vector2dF accumulated_overscroll,
1332 gfx::Vector2dF current_fling_velocity) {
1333 if (!content_view_core_ || !layer_ || !is_showing_)
1334 return;
1336 if (overscroll_effect_->OnOverscrolled(content_view_core_->GetLayer(),
1337 base::TimeTicks::Now(),
1338 accumulated_overscroll,
1339 current_fling_velocity)) {
1340 content_view_core_->SetNeedsAnimate();
1344 void RenderWidgetHostViewAndroid::DidStopFlinging() {
1345 if (content_view_core_)
1346 content_view_core_->DidStopFlinging();
1349 void RenderWidgetHostViewAndroid::SetContentViewCore(
1350 ContentViewCoreImpl* content_view_core) {
1351 RunAckCallbacks();
1353 RemoveLayers();
1354 if (content_view_core_ && !using_synchronous_compositor_)
1355 content_view_core_->GetWindowAndroid()->RemoveObserver(this);
1357 content_view_core_ = content_view_core;
1359 if (GetBrowserAccessibilityManager()) {
1360 base::android::ScopedJavaLocalRef<jobject> obj;
1361 if (content_view_core_)
1362 obj = content_view_core_->GetJavaObject();
1363 GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerAndroid()->
1364 SetContentViewCore(obj);
1367 AttachLayers();
1368 if (content_view_core_ && !using_synchronous_compositor_)
1369 content_view_core_->GetWindowAndroid()->AddObserver(this);
1372 void RenderWidgetHostViewAndroid::RunAckCallbacks() {
1373 while (!ack_callbacks_.empty()) {
1374 ack_callbacks_.front().Run();
1375 ack_callbacks_.pop();
1379 void RenderWidgetHostViewAndroid::HasTouchEventHandlers(
1380 bool need_touch_events) {
1383 void RenderWidgetHostViewAndroid::OnCompositingDidCommit() {
1384 RunAckCallbacks();
1387 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
1388 DCHECK(content_view_core_);
1389 DCHECK(!using_synchronous_compositor_);
1390 RunAckCallbacks();
1393 void RenderWidgetHostViewAndroid::OnLostResources() {
1394 if (texture_layer_.get())
1395 texture_layer_->SetIsDrawable(false);
1396 if (delegated_renderer_layer_.get())
1397 DestroyDelegatedContent();
1398 texture_id_in_layer_ = 0;
1399 RunAckCallbacks();
1402 // static
1403 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
1404 const gfx::Size& dst_size_in_pixel,
1405 const SkBitmap::Config bitmap_config,
1406 const base::TimeTicks& start_time,
1407 const base::Callback<void(bool, const SkBitmap&)>& callback,
1408 scoped_ptr<cc::CopyOutputResult> result) {
1409 base::ScopedClosureRunner scoped_callback_runner(
1410 base::Bind(callback, false, SkBitmap()));
1412 if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty())
1413 return;
1415 scoped_ptr<SkBitmap> bitmap(new SkBitmap);
1416 bitmap->setConfig(bitmap_config,
1417 dst_size_in_pixel.width(),
1418 dst_size_in_pixel.height(),
1419 0, kOpaque_SkAlphaType);
1420 if (!bitmap->allocPixels())
1421 return;
1423 ImageTransportFactoryAndroid* factory =
1424 ImageTransportFactoryAndroid::GetInstance();
1425 GLHelper* gl_helper = factory->GetGLHelper();
1426 if (!gl_helper)
1427 return;
1429 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
1430 new SkAutoLockPixels(*bitmap));
1431 uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
1433 cc::TextureMailbox texture_mailbox;
1434 scoped_ptr<cc::SingleReleaseCallback> release_callback;
1435 result->TakeTexture(&texture_mailbox, &release_callback);
1436 DCHECK(texture_mailbox.IsTexture());
1437 if (!texture_mailbox.IsTexture())
1438 return;
1440 ignore_result(scoped_callback_runner.Release());
1442 gl_helper->CropScaleReadbackAndCleanMailbox(
1443 texture_mailbox.mailbox(),
1444 texture_mailbox.sync_point(),
1445 result->size(),
1446 gfx::Rect(result->size()),
1447 dst_size_in_pixel,
1448 pixels,
1449 bitmap_config,
1450 base::Bind(&CopyFromCompositingSurfaceFinished,
1451 callback,
1452 base::Passed(&release_callback),
1453 base::Passed(&bitmap),
1454 start_time,
1455 base::Passed(&bitmap_pixels_lock)));
1458 // static
1459 void RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult(
1460 const gfx::Size& dst_size_in_pixel,
1461 const base::TimeTicks& start_time,
1462 const base::Callback<void(bool, const SkBitmap&)>& callback,
1463 scoped_ptr<cc::CopyOutputResult> result) {
1464 DCHECK(result->HasBitmap());
1465 base::ScopedClosureRunner scoped_callback_runner(
1466 base::Bind(callback, false, SkBitmap()));
1468 if (!result->HasBitmap() || result->IsEmpty() || result->size().IsEmpty())
1469 return;
1471 scoped_ptr<SkBitmap> source = result->TakeBitmap();
1472 DCHECK(source);
1473 if (!source)
1474 return;
1476 DCHECK_EQ(source->width(), dst_size_in_pixel.width());
1477 DCHECK_EQ(source->height(), dst_size_in_pixel.height());
1479 ignore_result(scoped_callback_runner.Release());
1480 UMA_HISTOGRAM_TIMES(kAsyncReadBackString,
1481 base::TimeTicks::Now() - start_time);
1483 callback.Run(true, *source);
1486 // static
1487 void RenderWidgetHostViewPort::GetDefaultScreenInfo(
1488 blink::WebScreenInfo* results) {
1489 const gfx::Display& display =
1490 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
1491 results->rect = display.bounds();
1492 // TODO(husky): Remove any system controls from availableRect.
1493 results->availableRect = display.work_area();
1494 results->deviceScaleFactor = display.device_scale_factor();
1495 gfx::DeviceDisplayInfo info;
1496 results->depth = info.GetBitsPerPixel();
1497 results->depthPerComponent = info.GetBitsPerComponent();
1498 results->isMonochrome = (results->depthPerComponent == 0);
1501 ////////////////////////////////////////////////////////////////////////////////
1502 // RenderWidgetHostView, public:
1504 // static
1505 RenderWidgetHostView*
1506 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost* widget) {
1507 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget);
1508 return new RenderWidgetHostViewAndroid(rwhi, NULL);
1511 } // namespace content