Notify that text is dirty (modified by script etc.) from Blink to browser
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_host_view_android.cc
blob90ea7478559348659a6bb1ed8c63bc363c040ef5
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/render_widget_host_view_android.h"
7 #include <android/bitmap.h>
9 #include "base/android/sys_utils.h"
10 #include "base/basictypes.h"
11 #include "base/bind.h"
12 #include "base/callback_helpers.h"
13 #include "base/command_line.h"
14 #include "base/logging.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/metrics/histogram.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/threading/worker_pool.h"
19 #include "cc/base/latency_info_swap_promise.h"
20 #include "cc/layers/delegated_frame_provider.h"
21 #include "cc/layers/delegated_renderer_layer.h"
22 #include "cc/layers/layer.h"
23 #include "cc/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/compositor_util.h"
35 #include "content/browser/gpu/gpu_data_manager_impl.h"
36 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
37 #include "content/browser/gpu/gpu_surface_tracker.h"
38 #include "content/browser/renderer_host/compositor_impl_android.h"
39 #include "content/browser/renderer_host/dip_util.h"
40 #include "content/browser/renderer_host/image_transport_factory_android.h"
41 #include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
42 #include "content/browser/renderer_host/render_process_host_impl.h"
43 #include "content/browser/renderer_host/render_widget_host_impl.h"
44 #include "content/common/gpu/client/gl_helper.h"
45 #include "content/common/gpu/gpu_messages.h"
46 #include "content/common/input_messages.h"
47 #include "content/common/view_messages.h"
48 #include "content/public/browser/devtools_agent_host.h"
49 #include "content/public/browser/render_view_host.h"
50 #include "content/public/common/content_switches.h"
51 #include "gpu/command_buffer/client/gles2_interface.h"
52 #include "gpu/config/gpu_driver_bug_workaround_type.h"
53 #include "skia/ext/image_operations.h"
54 #include "third_party/khronos/GLES2/gl2.h"
55 #include "third_party/khronos/GLES2/gl2ext.h"
56 #include "third_party/skia/include/core/SkCanvas.h"
57 #include "ui/base/android/window_android.h"
58 #include "ui/base/android/window_android_compositor.h"
59 #include "ui/gfx/android/device_display_info.h"
60 #include "ui/gfx/android/java_bitmap.h"
61 #include "ui/gfx/display.h"
62 #include "ui/gfx/screen.h"
63 #include "ui/gfx/size_conversions.h"
65 namespace content {
67 namespace {
69 const int kUndefinedOutputSurfaceId = -1;
70 static const char kAsyncReadBackString[] = "Compositing.CopyFromSurfaceTime";
72 // Sends an acknowledgement to the renderer of a processed IME event.
73 void SendImeEventAck(RenderWidgetHostImpl* host) {
74 host->Send(new ViewMsg_ImeEventAck(host->GetRoutingID()));
77 void CopyFromCompositingSurfaceFinished(
78 const base::Callback<void(bool, const SkBitmap&)>& callback,
79 scoped_ptr<cc::SingleReleaseCallback> release_callback,
80 scoped_ptr<SkBitmap> bitmap,
81 const base::TimeTicks& start_time,
82 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
83 bool result) {
84 bitmap_pixels_lock.reset();
85 release_callback->Run(0, false);
86 UMA_HISTOGRAM_TIMES(kAsyncReadBackString,
87 base::TimeTicks::Now() - start_time);
88 callback.Run(result, *bitmap);
91 ui::LatencyInfo CreateLatencyInfo(const blink::WebInputEvent& event) {
92 ui::LatencyInfo latency_info;
93 // The latency number should only be added if the timestamp is valid.
94 if (event.timeStampSeconds) {
95 const int64 time_micros = static_cast<int64>(
96 event.timeStampSeconds * base::Time::kMicrosecondsPerSecond);
97 latency_info.AddLatencyNumberWithTimestamp(
98 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
101 base::TimeTicks() + base::TimeDelta::FromMicroseconds(time_micros),
104 return latency_info;
107 } // anonymous namespace
109 RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo(
110 uint32 output_id,
111 scoped_ptr<cc::CompositorFrame> output_frame)
112 : output_surface_id(output_id), frame(output_frame.Pass()) {}
114 RenderWidgetHostViewAndroid::LastFrameInfo::~LastFrameInfo() {}
116 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
117 RenderWidgetHostImpl* widget_host,
118 ContentViewCoreImpl* content_view_core)
119 : host_(widget_host),
120 needs_begin_frame_(false),
121 is_showing_(!widget_host->is_hidden()),
122 content_view_core_(NULL),
123 ime_adapter_android_(this),
124 cached_background_color_(SK_ColorWHITE),
125 last_output_surface_id_(kUndefinedOutputSurfaceId),
126 weak_ptr_factory_(this),
127 overscroll_effect_enabled_(!CommandLine::ForCurrentProcess()->HasSwitch(
128 switches::kDisableOverscrollEdgeEffect)),
129 overscroll_effect_(OverscrollGlow::Create(overscroll_effect_enabled_)),
130 flush_input_requested_(false),
131 accelerated_surface_route_id_(0),
132 using_synchronous_compositor_(SynchronousCompositorImpl::FromID(
133 widget_host->GetProcess()->GetID(),
134 widget_host->GetRoutingID()) != NULL),
135 frame_evictor_(new DelegatedFrameEvictor(this)),
136 locks_on_frame_count_(0),
137 root_window_destroyed_(false) {
138 host_->SetView(this);
139 SetContentViewCore(content_view_core);
140 ImageTransportFactoryAndroid::AddObserver(this);
143 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
144 ImageTransportFactoryAndroid::RemoveObserver(this);
145 SetContentViewCore(NULL);
146 DCHECK(ack_callbacks_.empty());
147 if (resource_collection_.get())
148 resource_collection_->SetClient(NULL);
152 bool RenderWidgetHostViewAndroid::OnMessageReceived(
153 const IPC::Message& message) {
154 bool handled = true;
155 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
156 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
157 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor,
158 OnDidChangeBodyBackgroundColor)
159 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame,
160 OnSetNeedsBeginFrame)
161 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
162 OnTextInputStateChanged)
163 IPC_MESSAGE_HANDLER(ViewHostMsg_SmartClipDataExtracted,
164 OnSmartClipDataExtracted)
165 IPC_MESSAGE_UNHANDLED(handled = false)
166 IPC_END_MESSAGE_MAP()
167 return handled;
170 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
171 NOTIMPLEMENTED();
174 void RenderWidgetHostViewAndroid::InitAsPopup(
175 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
176 NOTIMPLEMENTED();
179 void RenderWidgetHostViewAndroid::InitAsFullscreen(
180 RenderWidgetHostView* reference_host_view) {
181 NOTIMPLEMENTED();
184 RenderWidgetHost*
185 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
186 return host_;
189 void RenderWidgetHostViewAndroid::WasShown() {
190 if (!host_ || !host_->is_hidden())
191 return;
193 host_->WasShown();
195 if (content_view_core_ && !using_synchronous_compositor_)
196 content_view_core_->GetWindowAndroid()->AddObserver(this);
199 void RenderWidgetHostViewAndroid::WasHidden() {
200 RunAckCallbacks();
202 if (!host_ || host_->is_hidden())
203 return;
205 // Inform the renderer that we are being hidden so it can reduce its resource
206 // utilization.
207 host_->WasHidden();
209 if (content_view_core_ && !using_synchronous_compositor_)
210 content_view_core_->GetWindowAndroid()->RemoveObserver(this);
213 void RenderWidgetHostViewAndroid::WasResized() {
214 host_->WasResized();
217 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) {
218 // Ignore the given size as only the Java code has the power to
219 // resize the view on Android.
220 default_size_ = size;
221 WasResized();
224 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
225 SetSize(rect.size());
228 void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
229 float scale,
230 SkBitmap::Config bitmap_config,
231 gfx::Rect src_subrect,
232 const base::Callback<void(bool, const SkBitmap&)>& result_callback) {
233 if (!IsSurfaceAvailableForCopy()) {
234 result_callback.Run(false, SkBitmap());
235 return;
238 gfx::Size bounds = layer_->bounds();
239 if (src_subrect.IsEmpty())
240 src_subrect = gfx::Rect(bounds);
241 DCHECK_LE(src_subrect.width() + src_subrect.x(), bounds.width());
242 DCHECK_LE(src_subrect.height() + src_subrect.y(), bounds.height());
243 const gfx::Display& display =
244 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
245 float device_scale_factor = display.device_scale_factor();
246 DCHECK_GT(device_scale_factor, 0);
247 gfx::Size dst_size(
248 gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale / device_scale_factor)));
249 CopyFromCompositingSurface(
250 src_subrect, dst_size, result_callback, bitmap_config);
253 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
254 if (!content_view_core_)
255 return false;
256 if (!layer_)
257 return false;
259 if (texture_size_in_layer_.IsEmpty())
260 return false;
262 if (!frame_evictor_->HasFrame())
263 return false;
265 return true;
268 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
269 return content_view_core_->GetViewAndroid();
272 gfx::NativeViewId RenderWidgetHostViewAndroid::GetNativeViewId() const {
273 return reinterpret_cast<gfx::NativeViewId>(
274 const_cast<RenderWidgetHostViewAndroid*>(this));
277 gfx::NativeViewAccessible
278 RenderWidgetHostViewAndroid::GetNativeViewAccessible() {
279 NOTIMPLEMENTED();
280 return NULL;
283 void RenderWidgetHostViewAndroid::MovePluginWindows(
284 const gfx::Vector2d& scroll_offset,
285 const std::vector<WebPluginGeometry>& moves) {
286 // We don't have plugin windows on Android. Do nothing. Note: this is called
287 // from RenderWidgetHost::OnUpdateRect which is itself invoked while
288 // processing the corresponding message from Renderer.
291 void RenderWidgetHostViewAndroid::Focus() {
292 host_->Focus();
293 host_->SetInputMethodActive(true);
294 if (overscroll_effect_enabled_)
295 overscroll_effect_->Enable();
298 void RenderWidgetHostViewAndroid::Blur() {
299 host_->ExecuteEditCommand("Unselect", "");
300 host_->SetInputMethodActive(false);
301 host_->Blur();
302 overscroll_effect_->Disable();
305 bool RenderWidgetHostViewAndroid::HasFocus() const {
306 if (!content_view_core_)
307 return false; // ContentViewCore not created yet.
309 return content_view_core_->HasFocus();
312 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
313 return HasValidFrame();
316 void RenderWidgetHostViewAndroid::Show() {
317 if (is_showing_)
318 return;
320 is_showing_ = true;
321 if (layer_)
322 layer_->SetHideLayerAndSubtree(false);
324 frame_evictor_->SetVisible(true);
325 WasShown();
328 void RenderWidgetHostViewAndroid::Hide() {
329 if (!is_showing_)
330 return;
332 is_showing_ = false;
333 if (layer_ && locks_on_frame_count_ == 0)
334 layer_->SetHideLayerAndSubtree(true);
336 frame_evictor_->SetVisible(false);
337 WasHidden();
340 bool RenderWidgetHostViewAndroid::IsShowing() {
341 // ContentViewCoreImpl represents the native side of the Java
342 // ContentViewCore. It being NULL means that it is not attached
343 // to the View system yet, so we treat this RWHVA as hidden.
344 return is_showing_ && content_view_core_;
347 void RenderWidgetHostViewAndroid::LockCompositingSurface() {
348 DCHECK(HasValidFrame());
349 DCHECK(host_);
350 DCHECK(frame_evictor_->HasFrame());
351 frame_evictor_->LockFrame();
352 locks_on_frame_count_++;
355 void RenderWidgetHostViewAndroid::UnlockCompositingSurface() {
356 if (!frame_evictor_->HasFrame() || locks_on_frame_count_ == 0)
357 return;
359 DCHECK(HasValidFrame());
360 frame_evictor_->UnlockFrame();
361 locks_on_frame_count_--;
363 if (locks_on_frame_count_ == 0) {
364 if (last_frame_info_) {
365 InternalSwapCompositorFrame(last_frame_info_->output_surface_id,
366 last_frame_info_->frame.Pass());
367 last_frame_info_.reset();
370 if (!is_showing_ && layer_)
371 layer_->SetHideLayerAndSubtree(true);
375 void RenderWidgetHostViewAndroid::ReleaseLocksOnSurface() {
376 if (!frame_evictor_->HasFrame()) {
377 DCHECK_EQ(locks_on_frame_count_, 0u);
378 return;
380 while (locks_on_frame_count_ > 0) {
381 UnlockCompositingSurface();
383 RunAckCallbacks();
386 gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const {
387 if (!content_view_core_)
388 return gfx::Rect(default_size_);
390 gfx::Size size = content_view_core_->GetViewportSizeDip();
391 gfx::Size offset = content_view_core_->GetViewportSizeOffsetDip();
392 size.Enlarge(-offset.width(), -offset.height());
394 return gfx::Rect(size);
397 gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
398 if (!content_view_core_)
399 return gfx::Size();
401 return content_view_core_->GetPhysicalBackingSize();
404 float RenderWidgetHostViewAndroid::GetOverdrawBottomHeight() const {
405 if (!content_view_core_)
406 return 0.f;
408 return content_view_core_->GetOverdrawBottomHeightDip();
411 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& cursor) {
412 // There are no cursors on Android.
415 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading) {
416 // Do nothing. The UI notification is handled through ContentViewClient which
417 // is TabContentsDelegate.
420 void RenderWidgetHostViewAndroid::TextInputTypeChanged(
421 ui::TextInputType type,
422 ui::TextInputMode input_mode,
423 bool can_compose_inline) {
424 // Unused on Android, which uses OnTextInputChanged instead.
427 long RenderWidgetHostViewAndroid::GetNativeImeAdapter() {
428 return reinterpret_cast<intptr_t>(&ime_adapter_android_);
431 void RenderWidgetHostViewAndroid::OnTextInputStateChanged(
432 const ViewHostMsg_TextInputState_Params& params) {
433 // If the change is not originated from IME (e.g. Javascript, autofill),
434 // send back the renderer an acknowledgement, regardless of how we exit from
435 // this method.
436 base::ScopedClosureRunner ack_caller;
437 if (params.is_non_ime_change)
438 ack_caller.Reset(base::Bind(&SendImeEventAck, host_));
440 if (!IsShowing())
441 return;
443 content_view_core_->UpdateImeAdapter(
444 GetNativeImeAdapter(),
445 static_cast<int>(params.type),
446 params.value, params.selection_start, params.selection_end,
447 params.composition_start, params.composition_end,
448 params.show_ime_if_needed, params.is_non_ime_change);
451 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor(
452 SkColor color) {
453 if (cached_background_color_ == color)
454 return;
456 cached_background_color_ = color;
457 if (content_view_core_)
458 content_view_core_->OnBackgroundColorChanged(color);
461 void RenderWidgetHostViewAndroid::SendBeginFrame(
462 const cc::BeginFrameArgs& args) {
463 TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::SendBeginFrame");
464 if (!host_)
465 return;
467 if (flush_input_requested_) {
468 flush_input_requested_ = false;
469 host_->FlushInput();
470 content_view_core_->RemoveBeginFrameSubscriber();
473 host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), args));
476 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame(
477 bool enabled) {
478 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame",
479 "enabled", enabled);
480 // ContentViewCoreImpl handles multiple subscribers to the BeginFrame, so
481 // we have to make sure calls to ContentViewCoreImpl's
482 // {Add,Remove}BeginFrameSubscriber are balanced, even if
483 // RenderWidgetHostViewAndroid's may not be.
484 if (content_view_core_ && needs_begin_frame_ != enabled) {
485 if (enabled)
486 content_view_core_->AddBeginFrameSubscriber();
487 else
488 content_view_core_->RemoveBeginFrameSubscriber();
489 needs_begin_frame_ = enabled;
493 void RenderWidgetHostViewAndroid::OnStartContentIntent(
494 const GURL& content_url) {
495 if (content_view_core_)
496 content_view_core_->StartContentIntent(content_url);
499 void RenderWidgetHostViewAndroid::OnSmartClipDataExtracted(
500 const base::string16& result) {
501 // Custom serialization over IPC isn't allowed normally for security reasons.
502 // Since this feature is only used in (single-process) WebView, there are no
503 // security issues. Enforce that it's only called in single process mode.
504 CHECK(RenderProcessHost::run_renderer_in_process());
505 if (content_view_core_)
506 content_view_core_->OnSmartClipDataExtracted(result);
509 void RenderWidgetHostViewAndroid::ImeCancelComposition() {
510 ime_adapter_android_.CancelComposition();
513 void RenderWidgetHostViewAndroid::FocusedNodeChanged(bool is_editable_node) {
514 ime_adapter_android_.FocusedNodeChanged(is_editable_node);
517 void RenderWidgetHostViewAndroid::DidUpdateBackingStore(
518 const gfx::Rect& scroll_rect,
519 const gfx::Vector2d& scroll_delta,
520 const std::vector<gfx::Rect>& copy_rects,
521 const std::vector<ui::LatencyInfo>& latency_info) {
522 NOTIMPLEMENTED();
525 void RenderWidgetHostViewAndroid::RenderProcessGone(
526 base::TerminationStatus status, int error_code) {
527 Destroy();
530 void RenderWidgetHostViewAndroid::Destroy() {
531 RemoveLayers();
532 SetContentViewCore(NULL);
534 // The RenderWidgetHost's destruction led here, so don't call it.
535 host_ = NULL;
537 delete this;
540 void RenderWidgetHostViewAndroid::SetTooltipText(
541 const base::string16& tooltip_text) {
542 // Tooltips don't makes sense on Android.
545 void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16& text,
546 size_t offset,
547 const gfx::Range& range) {
548 RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
550 if (text.empty() || range.is_empty() || !content_view_core_)
551 return;
552 size_t pos = range.GetMin() - offset;
553 size_t n = range.length();
555 DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
556 if (pos >= text.length()) {
557 NOTREACHED() << "The text can not cover range.";
558 return;
561 std::string utf8_selection = base::UTF16ToUTF8(text.substr(pos, n));
563 content_view_core_->OnSelectionChanged(utf8_selection);
566 void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
567 const ViewHostMsg_SelectionBounds_Params& params) {
568 if (content_view_core_) {
569 content_view_core_->OnSelectionBoundsChanged(params);
573 void RenderWidgetHostViewAndroid::SelectionRootBoundsChanged(
574 const gfx::Rect& bounds) {
575 if (content_view_core_) {
576 content_view_core_->OnSelectionRootBoundsChanged(bounds);
580 void RenderWidgetHostViewAndroid::ScrollOffsetChanged() {
583 BackingStore* RenderWidgetHostViewAndroid::AllocBackingStore(
584 const gfx::Size& size) {
585 NOTIMPLEMENTED();
586 return NULL;
589 void RenderWidgetHostViewAndroid::SetBackground(const SkBitmap& background) {
590 RenderWidgetHostViewBase::SetBackground(background);
591 host_->Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background));
594 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
595 const gfx::Rect& src_subrect,
596 const gfx::Size& dst_size,
597 const base::Callback<void(bool, const SkBitmap&)>& callback,
598 const SkBitmap::Config bitmap_config) {
599 if (!IsReadbackConfigSupported(bitmap_config)) {
600 callback.Run(false, SkBitmap());
601 return;
603 base::TimeTicks start_time = base::TimeTicks::Now();
604 if (!using_synchronous_compositor_ && !IsSurfaceAvailableForCopy()) {
605 callback.Run(false, SkBitmap());
606 return;
608 const gfx::Display& display =
609 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
610 float device_scale_factor = display.device_scale_factor();
611 gfx::Size dst_size_in_pixel =
612 ConvertRectToPixel(device_scale_factor, gfx::Rect(dst_size)).size();
613 gfx::Rect src_subrect_in_pixel =
614 ConvertRectToPixel(device_scale_factor, src_subrect);
616 if (using_synchronous_compositor_) {
617 SynchronousCopyContents(src_subrect_in_pixel, dst_size_in_pixel, callback,
618 bitmap_config);
619 UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous",
620 base::TimeTicks::Now() - start_time);
621 return;
624 scoped_ptr<cc::CopyOutputRequest> request;
625 scoped_refptr<cc::Layer> readback_layer;
626 DCHECK(content_view_core_);
627 DCHECK(content_view_core_->GetWindowAndroid());
628 ui::WindowAndroidCompositor* compositor =
629 content_view_core_->GetWindowAndroid()->GetCompositor();
630 DCHECK(compositor);
631 DCHECK(frame_provider_);
632 scoped_refptr<cc::DelegatedRendererLayer> delegated_layer =
633 cc::DelegatedRendererLayer::Create(frame_provider_);
634 delegated_layer->SetDisplaySize(texture_size_in_layer_);
635 delegated_layer->SetBounds(content_size_in_layer_);
636 delegated_layer->SetHideLayerAndSubtree(true);
637 delegated_layer->SetIsDrawable(true);
638 delegated_layer->SetContentsOpaque(true);
639 compositor->AttachLayerForReadback(delegated_layer);
641 readback_layer = delegated_layer;
642 request = cc::CopyOutputRequest::CreateRequest(
643 base::Bind(&RenderWidgetHostViewAndroid::
644 PrepareTextureCopyOutputResultForDelegatedReadback,
645 dst_size_in_pixel,
646 bitmap_config,
647 start_time,
648 readback_layer,
649 callback));
650 request->set_area(src_subrect_in_pixel);
651 readback_layer->RequestCopyOfOutput(request.Pass());
654 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
655 const gfx::Rect& src_subrect,
656 const scoped_refptr<media::VideoFrame>& target,
657 const base::Callback<void(bool)>& callback) {
658 NOTIMPLEMENTED();
659 callback.Run(false);
662 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
663 return false;
666 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
667 const gfx::Rect& target_rect, const SkBitmap& zoomed_bitmap) {
668 if (!content_view_core_)
669 return;
671 content_view_core_->ShowDisambiguationPopup(target_rect, zoomed_bitmap);
674 scoped_ptr<SyntheticGestureTarget>
675 RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
676 return scoped_ptr<SyntheticGestureTarget>(new SyntheticGestureTargetAndroid(
677 host_, content_view_core_->CreateTouchEventSynthesizer()));
680 void RenderWidgetHostViewAndroid::OnAcceleratedCompositingStateChange() {
683 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
684 uint32 output_surface_id) {
685 DCHECK(host_);
686 cc::CompositorFrameAck ack;
687 if (resource_collection_.get())
688 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
689 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_->GetRoutingID(),
690 output_surface_id,
691 host_->GetProcess()->GetID(),
692 ack);
695 void RenderWidgetHostViewAndroid::SendReturnedDelegatedResources(
696 uint32 output_surface_id) {
697 DCHECK(resource_collection_);
699 cc::CompositorFrameAck ack;
700 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
701 DCHECK(!ack.resources.empty());
703 RenderWidgetHostImpl::SendReclaimCompositorResources(
704 host_->GetRoutingID(),
705 output_surface_id,
706 host_->GetProcess()->GetID(),
707 ack);
710 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
711 if (ack_callbacks_.size())
712 return;
713 SendReturnedDelegatedResources(last_output_surface_id_);
716 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
717 RemoveLayers();
718 frame_provider_ = NULL;
719 layer_ = NULL;
722 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
723 uint32 output_surface_id,
724 scoped_ptr<cc::DelegatedFrameData> frame_data) {
725 bool has_content = !texture_size_in_layer_.IsEmpty();
727 if (output_surface_id != last_output_surface_id_) {
728 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
729 // any resources from the old output surface with the new output surface id.
730 if (resource_collection_.get()) {
731 if (resource_collection_->LoseAllResources())
732 SendReturnedDelegatedResources(last_output_surface_id_);
734 resource_collection_->SetClient(NULL);
735 resource_collection_ = NULL;
737 DestroyDelegatedContent();
739 last_output_surface_id_ = output_surface_id;
742 if (!has_content) {
743 DestroyDelegatedContent();
744 } else {
745 if (!resource_collection_.get()) {
746 resource_collection_ = new cc::DelegatedFrameResourceCollection;
747 resource_collection_->SetClient(this);
749 if (!frame_provider_ ||
750 texture_size_in_layer_ != frame_provider_->frame_size()) {
751 RemoveLayers();
752 frame_provider_ = new cc::DelegatedFrameProvider(
753 resource_collection_.get(), frame_data.Pass());
754 layer_ = cc::DelegatedRendererLayer::Create(frame_provider_);
755 AttachLayers();
756 } else {
757 frame_provider_->SetFrameData(frame_data.Pass());
761 if (layer_.get()) {
762 layer_->SetDisplaySize(texture_size_in_layer_);
763 layer_->SetIsDrawable(true);
764 layer_->SetContentsOpaque(true);
765 layer_->SetBounds(content_size_in_layer_);
766 layer_->SetNeedsDisplay();
769 base::Closure ack_callback =
770 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
771 weak_ptr_factory_.GetWeakPtr(),
772 output_surface_id);
774 ack_callbacks_.push(ack_callback);
775 if (host_->is_hidden())
776 RunAckCallbacks();
779 void RenderWidgetHostViewAndroid::ComputeContentsSize(
780 const cc::CompositorFrameMetadata& frame_metadata) {
781 // Calculate the content size. This should be 0 if the texture_size is 0.
782 gfx::Vector2dF offset;
783 if (texture_size_in_layer_.GetArea() > 0)
784 offset = frame_metadata.location_bar_content_translation;
785 offset.set_y(offset.y() + frame_metadata.overdraw_bottom_height);
786 offset.Scale(frame_metadata.device_scale_factor);
787 content_size_in_layer_ =
788 gfx::Size(texture_size_in_layer_.width() - offset.x(),
789 texture_size_in_layer_.height() - offset.y());
790 // Content size changes should be reflected in associated animation effects.
791 UpdateAnimationSize(frame_metadata);
794 void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame(
795 uint32 output_surface_id,
796 scoped_ptr<cc::CompositorFrame> frame) {
797 if (!frame->delegated_frame_data) {
798 LOG(ERROR) << "Non-delegated renderer path no longer supported";
799 return;
802 if (locks_on_frame_count_ > 0) {
803 DCHECK(HasValidFrame());
804 RetainFrame(output_surface_id, frame.Pass());
805 return;
808 // Always let ContentViewCore know about the new frame first, so it can decide
809 // to schedule a Draw immediately when it sees the texture layer invalidation.
810 UpdateContentViewCoreFrameMetadata(frame->metadata);
812 if (layer_ && layer_->layer_tree_host()) {
813 for (size_t i = 0; i < frame->metadata.latency_info.size(); i++) {
814 scoped_ptr<cc::SwapPromise> swap_promise(
815 new cc::LatencyInfoSwapPromise(frame->metadata.latency_info[i]));
816 layer_->layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
820 DCHECK(!frame->delegated_frame_data->render_pass_list.empty());
822 cc::RenderPass* root_pass =
823 frame->delegated_frame_data->render_pass_list.back();
824 texture_size_in_layer_ = root_pass->output_rect.size();
825 ComputeContentsSize(frame->metadata);
827 SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass());
828 frame_evictor_->SwappedFrame(!host_->is_hidden());
831 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
832 uint32 output_surface_id,
833 scoped_ptr<cc::CompositorFrame> frame) {
834 InternalSwapCompositorFrame(output_surface_id, frame.Pass());
837 void RenderWidgetHostViewAndroid::RetainFrame(
838 uint32 output_surface_id,
839 scoped_ptr<cc::CompositorFrame> frame) {
840 DCHECK(locks_on_frame_count_);
842 // Store the incoming frame so that it can be swapped when all the locks have
843 // been released. If there is already a stored frame, then replace and skip
844 // the previous one but make sure we still eventually send the ACK. Holding
845 // the ACK also blocks the renderer when its max_frames_pending is reached.
846 if (last_frame_info_) {
847 base::Closure ack_callback =
848 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
849 weak_ptr_factory_.GetWeakPtr(),
850 last_frame_info_->output_surface_id);
852 ack_callbacks_.push(ack_callback);
855 last_frame_info_.reset(new LastFrameInfo(output_surface_id, frame.Pass()));
858 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
859 const cc::CompositorFrameMetadata& frame_metadata) {
860 // This is a subset of OnSwapCompositorFrame() used in the synchronous
861 // compositor flow.
862 UpdateContentViewCoreFrameMetadata(frame_metadata);
863 ComputeContentsSize(frame_metadata);
865 // DevTools ScreenCast support for Android WebView.
866 if (DevToolsAgentHost::HasFor(RenderViewHost::From(GetRenderWidgetHost()))) {
867 scoped_refptr<DevToolsAgentHost> dtah =
868 DevToolsAgentHost::GetOrCreateFor(
869 RenderViewHost::From(GetRenderWidgetHost()));
870 // Unblock the compositor.
871 BrowserThread::PostTask(
872 BrowserThread::UI, FROM_HERE,
873 base::Bind(&RenderViewDevToolsAgentHost::SynchronousSwapCompositorFrame,
874 static_cast<RenderViewDevToolsAgentHost*>(dtah.get()),
875 frame_metadata));
879 void RenderWidgetHostViewAndroid::SetOverlayVideoMode(bool enabled) {
880 layer_->SetContentsOpaque(!enabled);
883 void RenderWidgetHostViewAndroid::SynchronousCopyContents(
884 const gfx::Rect& src_subrect_in_pixel,
885 const gfx::Size& dst_size_in_pixel,
886 const base::Callback<void(bool, const SkBitmap&)>& callback,
887 const SkBitmap::Config config) {
888 SynchronousCompositor* compositor =
889 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
890 host_->GetRoutingID());
891 if (!compositor) {
892 callback.Run(false, SkBitmap());
893 return;
896 SkBitmap bitmap;
897 bitmap.setConfig(config,
898 dst_size_in_pixel.width(),
899 dst_size_in_pixel.height());
900 bitmap.allocPixels();
901 SkCanvas canvas(bitmap);
902 canvas.scale(
903 (float)dst_size_in_pixel.width() / (float)src_subrect_in_pixel.width(),
904 (float)dst_size_in_pixel.height() / (float)src_subrect_in_pixel.height());
905 compositor->DemandDrawSw(&canvas);
906 callback.Run(true, bitmap);
909 void RenderWidgetHostViewAndroid::UpdateContentViewCoreFrameMetadata(
910 const cc::CompositorFrameMetadata& frame_metadata) {
911 if (content_view_core_) {
912 // All offsets and sizes are in CSS pixels.
913 content_view_core_->UpdateFrameInfo(
914 frame_metadata.root_scroll_offset,
915 frame_metadata.page_scale_factor,
916 gfx::Vector2dF(frame_metadata.min_page_scale_factor,
917 frame_metadata.max_page_scale_factor),
918 frame_metadata.root_layer_size,
919 frame_metadata.viewport_size,
920 frame_metadata.location_bar_offset,
921 frame_metadata.location_bar_content_translation,
922 frame_metadata.overdraw_bottom_height);
926 void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int host_id,
927 int route_id) {
928 accelerated_surface_route_id_ = route_id;
931 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
932 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
933 int gpu_host_id) {
934 NOTREACHED() << "Need --composite-to-mailbox or --enable-delegated-renderer";
937 void RenderWidgetHostViewAndroid::AttachLayers() {
938 if (!content_view_core_)
939 return;
940 if (!layer_.get())
941 return;
943 content_view_core_->AttachLayer(layer_);
944 if (overscroll_effect_enabled_)
945 overscroll_effect_->Enable();
946 layer_->SetHideLayerAndSubtree(!is_showing_);
949 void RenderWidgetHostViewAndroid::RemoveLayers() {
950 if (!content_view_core_)
951 return;
952 if (!layer_.get())
953 return;
955 content_view_core_->RemoveLayer(layer_);
956 overscroll_effect_->Disable();
959 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) {
960 return overscroll_effect_->Animate(frame_time);
963 void RenderWidgetHostViewAndroid::UpdateAnimationSize(
964 const cc::CompositorFrameMetadata& frame_metadata) {
965 // Disable edge effects for axes on which scrolling is impossible.
966 gfx::SizeF ceiled_viewport_size =
967 gfx::ToCeiledSize(frame_metadata.viewport_size);
968 overscroll_effect_->set_horizontal_overscroll_enabled(
969 ceiled_viewport_size.width() < frame_metadata.root_layer_size.width());
970 overscroll_effect_->set_vertical_overscroll_enabled(
971 ceiled_viewport_size.height() < frame_metadata.root_layer_size.height());
972 overscroll_effect_->set_size(content_size_in_layer_);
975 void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
976 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
977 int gpu_host_id) {
978 NOTREACHED();
981 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() {
982 NOTREACHED();
985 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
986 NOTREACHED();
989 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
990 if (layer_.get())
991 DestroyDelegatedContent();
992 frame_evictor_->DiscardedFrame();
995 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
996 const gfx::Size& desired_size) {
997 NOTREACHED();
998 return false;
1001 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) {
1002 // ScreenInfo isn't tied to the widget on Android. Always return the default.
1003 RenderWidgetHostViewBase::GetDefaultScreenInfo(result);
1006 // TODO(jrg): Find out the implications and answer correctly here,
1007 // as we are returning the WebView and not root window bounds.
1008 gfx::Rect RenderWidgetHostViewAndroid::GetBoundsInRootWindow() {
1009 return GetViewBounds();
1012 gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() {
1013 gfx::GLSurfaceHandle handle =
1014 gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::NATIVE_TRANSPORT);
1015 if (CompositorImpl::IsInitialized()) {
1016 handle.parent_client_id =
1017 ImageTransportFactoryAndroid::GetInstance()->GetChannelID();
1019 return handle;
1022 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
1023 const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
1024 if (content_view_core_)
1025 content_view_core_->ConfirmTouchEvent(ack_result);
1028 void RenderWidgetHostViewAndroid::SetHasHorizontalScrollbar(
1029 bool has_horizontal_scrollbar) {
1030 // intentionally empty, like RenderWidgetHostViewViews
1033 void RenderWidgetHostViewAndroid::SetScrollOffsetPinning(
1034 bool is_pinned_to_left, bool is_pinned_to_right) {
1035 // intentionally empty, like RenderWidgetHostViewViews
1038 void RenderWidgetHostViewAndroid::GestureEventAck(
1039 const blink::WebGestureEvent& event,
1040 InputEventAckState ack_result) {
1041 if (content_view_core_)
1042 content_view_core_->OnGestureEventAck(event, ack_result);
1045 InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
1046 const blink::WebInputEvent& input_event) {
1047 if (content_view_core_ &&
1048 content_view_core_->FilterInputEvent(input_event))
1049 return INPUT_EVENT_ACK_STATE_CONSUMED;
1051 if (!host_)
1052 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1054 if (input_event.type == blink::WebInputEvent::GestureTapDown ||
1055 input_event.type == blink::WebInputEvent::TouchStart) {
1056 GpuDataManagerImpl* gpu_data = GpuDataManagerImpl::GetInstance();
1057 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
1058 if (shim && gpu_data && accelerated_surface_route_id_ &&
1059 gpu_data->IsDriverBugWorkaroundActive(gpu::WAKE_UP_GPU_BEFORE_DRAWING))
1060 shim->Send(
1061 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_));
1064 SynchronousCompositorImpl* compositor =
1065 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
1066 host_->GetRoutingID());
1067 if (compositor)
1068 return compositor->HandleInputEvent(input_event);
1069 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1072 void RenderWidgetHostViewAndroid::OnSetNeedsFlushInput() {
1073 if (flush_input_requested_ || !content_view_core_)
1074 return;
1075 TRACE_EVENT0("input", "RenderWidgetHostViewAndroid::OnSetNeedsFlushInput");
1076 flush_input_requested_ = true;
1077 content_view_core_->AddBeginFrameSubscriber();
1080 void RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManagerIfNeeded() {
1081 if (!host_ || host_->accessibility_mode() != AccessibilityModeComplete)
1082 return;
1084 if (!GetBrowserAccessibilityManager()) {
1085 base::android::ScopedJavaLocalRef<jobject> obj;
1086 if (content_view_core_)
1087 obj = content_view_core_->GetJavaObject();
1088 SetBrowserAccessibilityManager(
1089 new BrowserAccessibilityManagerAndroid(
1090 obj, BrowserAccessibilityManagerAndroid::GetEmptyDocument(), this));
1094 void RenderWidgetHostViewAndroid::SetAccessibilityFocus(int acc_obj_id) {
1095 if (!host_)
1096 return;
1098 host_->AccessibilitySetFocus(acc_obj_id);
1101 void RenderWidgetHostViewAndroid::AccessibilityDoDefaultAction(int acc_obj_id) {
1102 if (!host_)
1103 return;
1105 host_->AccessibilityDoDefaultAction(acc_obj_id);
1108 void RenderWidgetHostViewAndroid::AccessibilityScrollToMakeVisible(
1109 int acc_obj_id, gfx::Rect subfocus) {
1110 if (!host_)
1111 return;
1113 host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus);
1116 void RenderWidgetHostViewAndroid::AccessibilityScrollToPoint(
1117 int acc_obj_id, gfx::Point point) {
1118 if (!host_)
1119 return;
1121 host_->AccessibilityScrollToPoint(acc_obj_id, point);
1124 void RenderWidgetHostViewAndroid::AccessibilitySetTextSelection(
1125 int acc_obj_id, int start_offset, int end_offset) {
1126 if (!host_)
1127 return;
1129 host_->AccessibilitySetTextSelection(
1130 acc_obj_id, start_offset, end_offset);
1133 gfx::Point RenderWidgetHostViewAndroid::GetLastTouchEventLocation() const {
1134 NOTIMPLEMENTED();
1135 // Only used on Win8
1136 return gfx::Point();
1139 void RenderWidgetHostViewAndroid::FatalAccessibilityTreeError() {
1140 if (!host_)
1141 return;
1143 host_->FatalAccessibilityTreeError();
1144 SetBrowserAccessibilityManager(NULL);
1147 bool RenderWidgetHostViewAndroid::LockMouse() {
1148 NOTIMPLEMENTED();
1149 return false;
1152 void RenderWidgetHostViewAndroid::UnlockMouse() {
1153 NOTIMPLEMENTED();
1156 // Methods called from the host to the render
1158 void RenderWidgetHostViewAndroid::SendKeyEvent(
1159 const NativeWebKeyboardEvent& event) {
1160 if (host_)
1161 host_->ForwardKeyboardEvent(event);
1164 void RenderWidgetHostViewAndroid::SendTouchEvent(
1165 const blink::WebTouchEvent& event) {
1166 if (host_)
1167 host_->ForwardTouchEventWithLatencyInfo(event, CreateLatencyInfo(event));
1170 void RenderWidgetHostViewAndroid::SendMouseEvent(
1171 const blink::WebMouseEvent& event) {
1172 if (host_)
1173 host_->ForwardMouseEvent(event);
1176 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
1177 const blink::WebMouseWheelEvent& event) {
1178 if (host_)
1179 host_->ForwardWheelEvent(event);
1182 void RenderWidgetHostViewAndroid::SendGestureEvent(
1183 const blink::WebGestureEvent& event) {
1184 // Sending a gesture that may trigger overscroll should resume the effect.
1185 if (overscroll_effect_enabled_)
1186 overscroll_effect_->Enable();
1188 if (host_)
1189 host_->ForwardGestureEventWithLatencyInfo(event, CreateLatencyInfo(event));
1192 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) {
1193 if (host_)
1194 host_->MoveCaret(point);
1197 SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
1198 return cached_background_color_;
1201 void RenderWidgetHostViewAndroid::OnOverscrolled(
1202 gfx::Vector2dF accumulated_overscroll,
1203 gfx::Vector2dF current_fling_velocity) {
1204 if (!content_view_core_ || !layer_ || !is_showing_)
1205 return;
1207 if (overscroll_effect_->OnOverscrolled(content_view_core_->GetLayer(),
1208 base::TimeTicks::Now(),
1209 accumulated_overscroll,
1210 current_fling_velocity)) {
1211 content_view_core_->SetNeedsAnimate();
1215 void RenderWidgetHostViewAndroid::DidStopFlinging() {
1216 if (content_view_core_)
1217 content_view_core_->DidStopFlinging();
1220 void RenderWidgetHostViewAndroid::SetContentViewCore(
1221 ContentViewCoreImpl* content_view_core) {
1222 RemoveLayers();
1223 // TODO: crbug.com/324341
1224 // WindowAndroid and Compositor should outlive all WebContents.
1225 // Allowing this here at runtime is a bandaid.
1226 DCHECK(!root_window_destroyed_);
1227 if (content_view_core_ && !root_window_destroyed_ &&
1228 !using_synchronous_compositor_) {
1229 content_view_core_->GetWindowAndroid()->RemoveObserver(this);
1232 if (content_view_core != content_view_core_)
1233 ReleaseLocksOnSurface();
1235 content_view_core_ = content_view_core;
1237 if (GetBrowserAccessibilityManager()) {
1238 base::android::ScopedJavaLocalRef<jobject> obj;
1239 if (content_view_core_)
1240 obj = content_view_core_->GetJavaObject();
1241 GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerAndroid()->
1242 SetContentViewCore(obj);
1245 AttachLayers();
1246 if (content_view_core_ && !root_window_destroyed_ &&
1247 !using_synchronous_compositor_) {
1248 content_view_core_->GetWindowAndroid()->AddObserver(this);
1252 void RenderWidgetHostViewAndroid::RunAckCallbacks() {
1253 while (!ack_callbacks_.empty()) {
1254 ack_callbacks_.front().Run();
1255 ack_callbacks_.pop();
1259 void RenderWidgetHostViewAndroid::OnCompositingDidCommit() {
1260 RunAckCallbacks();
1263 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
1264 DCHECK(content_view_core_);
1265 DCHECK(!using_synchronous_compositor_);
1266 RunAckCallbacks();
1269 void RenderWidgetHostViewAndroid::OnWillDestroyWindow() {
1270 root_window_destroyed_ = true;
1273 void RenderWidgetHostViewAndroid::OnLostResources() {
1274 ReleaseLocksOnSurface();
1275 if (layer_.get())
1276 DestroyDelegatedContent();
1277 DCHECK(ack_callbacks_.empty());
1280 // static
1281 void
1282 RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResultForDelegatedReadback(
1283 const gfx::Size& dst_size_in_pixel,
1284 const SkBitmap::Config config,
1285 const base::TimeTicks& start_time,
1286 scoped_refptr<cc::Layer> readback_layer,
1287 const base::Callback<void(bool, const SkBitmap&)>& callback,
1288 scoped_ptr<cc::CopyOutputResult> result) {
1289 readback_layer->RemoveFromParent();
1290 PrepareTextureCopyOutputResult(
1291 dst_size_in_pixel, config, start_time, callback, result.Pass());
1294 // static
1295 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
1296 const gfx::Size& dst_size_in_pixel,
1297 const SkBitmap::Config bitmap_config,
1298 const base::TimeTicks& start_time,
1299 const base::Callback<void(bool, const SkBitmap&)>& callback,
1300 scoped_ptr<cc::CopyOutputResult> result) {
1301 base::ScopedClosureRunner scoped_callback_runner(
1302 base::Bind(callback, false, SkBitmap()));
1304 if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty())
1305 return;
1307 scoped_ptr<SkBitmap> bitmap(new SkBitmap);
1308 bitmap->setConfig(bitmap_config,
1309 dst_size_in_pixel.width(),
1310 dst_size_in_pixel.height(),
1311 0, kOpaque_SkAlphaType);
1312 if (!bitmap->allocPixels())
1313 return;
1315 ImageTransportFactoryAndroid* factory =
1316 ImageTransportFactoryAndroid::GetInstance();
1317 GLHelper* gl_helper = factory->GetGLHelper();
1319 if (!gl_helper)
1320 return;
1322 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
1323 new SkAutoLockPixels(*bitmap));
1324 uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
1326 cc::TextureMailbox texture_mailbox;
1327 scoped_ptr<cc::SingleReleaseCallback> release_callback;
1328 result->TakeTexture(&texture_mailbox, &release_callback);
1329 DCHECK(texture_mailbox.IsTexture());
1330 if (!texture_mailbox.IsTexture())
1331 return;
1333 ignore_result(scoped_callback_runner.Release());
1335 gl_helper->CropScaleReadbackAndCleanMailbox(
1336 texture_mailbox.mailbox(),
1337 texture_mailbox.sync_point(),
1338 result->size(),
1339 gfx::Rect(result->size()),
1340 dst_size_in_pixel,
1341 pixels,
1342 bitmap_config,
1343 base::Bind(&CopyFromCompositingSurfaceFinished,
1344 callback,
1345 base::Passed(&release_callback),
1346 base::Passed(&bitmap),
1347 start_time,
1348 base::Passed(&bitmap_pixels_lock)));
1351 bool RenderWidgetHostViewAndroid::IsReadbackConfigSupported(
1352 SkBitmap::Config bitmap_config) {
1353 ImageTransportFactoryAndroid* factory =
1354 ImageTransportFactoryAndroid::GetInstance();
1355 GLHelper* gl_helper = factory->GetGLHelper();
1356 if (!gl_helper)
1357 return false;
1358 return gl_helper->IsReadbackConfigSupported(bitmap_config);
1361 SkBitmap::Config RenderWidgetHostViewAndroid::PreferredReadbackFormat() {
1362 // Define the criteria here. If say the 16 texture readback is
1363 // supported we should go with that (this degrades quality)
1364 // or stick back to the default format.
1365 if (base::android::SysUtils::IsLowEndDevice()) {
1366 if (IsReadbackConfigSupported(SkBitmap::kRGB_565_Config))
1367 return SkBitmap::kRGB_565_Config;
1369 return SkBitmap::kARGB_8888_Config;
1372 // static
1373 void RenderWidgetHostViewPort::GetDefaultScreenInfo(
1374 blink::WebScreenInfo* results) {
1375 const gfx::Display& display =
1376 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
1377 results->rect = display.bounds();
1378 // TODO(husky): Remove any system controls from availableRect.
1379 results->availableRect = display.work_area();
1380 results->deviceScaleFactor = display.device_scale_factor();
1381 gfx::DeviceDisplayInfo info;
1382 results->depth = info.GetBitsPerPixel();
1383 results->depthPerComponent = info.GetBitsPerComponent();
1384 results->isMonochrome = (results->depthPerComponent == 0);
1387 ////////////////////////////////////////////////////////////////////////////////
1388 // RenderWidgetHostView, public:
1390 // static
1391 RenderWidgetHostView*
1392 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost* widget) {
1393 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget);
1394 return new RenderWidgetHostViewAndroid(rwhi, NULL);
1397 } // namespace content