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"
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
,
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
),
107 } // anonymous namespace
109 RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo(
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
) {
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()
170 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view
) {
174 void RenderWidgetHostViewAndroid::InitAsPopup(
175 RenderWidgetHostView
* parent_host_view
, const gfx::Rect
& pos
) {
179 void RenderWidgetHostViewAndroid::InitAsFullscreen(
180 RenderWidgetHostView
* reference_host_view
) {
185 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
189 void RenderWidgetHostViewAndroid::WasShown() {
190 if (!host_
|| !host_
->is_hidden())
195 if (content_view_core_
&& !using_synchronous_compositor_
)
196 content_view_core_
->GetWindowAndroid()->AddObserver(this);
199 void RenderWidgetHostViewAndroid::WasHidden() {
202 if (!host_
|| host_
->is_hidden())
205 // Inform the renderer that we are being hidden so it can reduce its resource
209 if (content_view_core_
&& !using_synchronous_compositor_
)
210 content_view_core_
->GetWindowAndroid()->RemoveObserver(this);
213 void RenderWidgetHostViewAndroid::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
;
224 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect
& rect
) {
225 SetSize(rect
.size());
228 void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
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());
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);
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_
)
259 if (texture_size_in_layer_
.IsEmpty())
262 if (!frame_evictor_
->HasFrame())
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() {
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() {
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);
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() {
322 layer_
->SetHideLayerAndSubtree(false);
324 frame_evictor_
->SetVisible(true);
328 void RenderWidgetHostViewAndroid::Hide() {
333 if (layer_
&& locks_on_frame_count_
== 0)
334 layer_
->SetHideLayerAndSubtree(true);
336 frame_evictor_
->SetVisible(false);
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());
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)
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);
380 while (locks_on_frame_count_
> 0) {
381 UnlockCompositingSurface();
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_
)
401 return content_view_core_
->GetPhysicalBackingSize();
404 float RenderWidgetHostViewAndroid::GetOverdrawBottomHeight() const {
405 if (!content_view_core_
)
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
436 base::ScopedClosureRunner ack_caller
;
437 if (params
.is_non_ime_change
)
438 ack_caller
.Reset(base::Bind(&SendImeEventAck
, host_
));
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(
453 if (cached_background_color_
== color
)
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");
467 if (flush_input_requested_
) {
468 flush_input_requested_
= false;
470 content_view_core_
->RemoveBeginFrameSubscriber();
473 host_
->Send(new ViewMsg_BeginFrame(host_
->GetRoutingID(), args
));
476 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame(
478 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame",
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
) {
486 content_view_core_
->AddBeginFrameSubscriber();
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
) {
525 void RenderWidgetHostViewAndroid::RenderProcessGone(
526 base::TerminationStatus status
, int error_code
) {
530 void RenderWidgetHostViewAndroid::Destroy() {
532 SetContentViewCore(NULL
);
534 // The RenderWidgetHost's destruction led here, so don't call it.
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
,
547 const gfx::Range
& range
) {
548 RenderWidgetHostViewBase::SelectionChanged(text
, offset
, range
);
550 if (text
.empty() || range
.is_empty() || !content_view_core_
)
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.";
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
) {
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());
603 base::TimeTicks start_time
= base::TimeTicks::Now();
604 if (!using_synchronous_compositor_
&& !IsSurfaceAvailableForCopy()) {
605 callback
.Run(false, SkBitmap());
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
,
619 UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous",
620 base::TimeTicks::Now() - start_time
);
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();
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
,
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
) {
662 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
666 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
667 const gfx::Rect
& target_rect
, const SkBitmap
& zoomed_bitmap
) {
668 if (!content_view_core_
)
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
) {
686 cc::CompositorFrameAck ack
;
687 if (resource_collection_
.get())
688 resource_collection_
->TakeUnusedResourcesForChildCompositor(&ack
.resources
);
689 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_
->GetRoutingID(),
691 host_
->GetProcess()->GetID(),
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(),
706 host_
->GetProcess()->GetID(),
710 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
711 if (ack_callbacks_
.size())
713 SendReturnedDelegatedResources(last_output_surface_id_
);
716 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
718 frame_provider_
= 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
;
743 DestroyDelegatedContent();
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()) {
752 frame_provider_
= new cc::DelegatedFrameProvider(
753 resource_collection_
.get(), frame_data
.Pass());
754 layer_
= cc::DelegatedRendererLayer::Create(frame_provider_
);
757 frame_provider_
->SetFrameData(frame_data
.Pass());
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(),
774 ack_callbacks_
.push(ack_callback
);
775 if (host_
->is_hidden())
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";
802 if (locks_on_frame_count_
> 0) {
803 DCHECK(HasValidFrame());
804 RetainFrame(output_surface_id
, frame
.Pass());
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
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()),
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());
892 callback
.Run(false, SkBitmap());
897 bitmap
.setConfig(config
,
898 dst_size_in_pixel
.width(),
899 dst_size_in_pixel
.height());
900 bitmap
.allocPixels();
901 SkCanvas
canvas(bitmap
);
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
,
928 accelerated_surface_route_id_
= route_id
;
931 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
932 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params
& params
,
934 NOTREACHED() << "Need --composite-to-mailbox or --enable-delegated-renderer";
937 void RenderWidgetHostViewAndroid::AttachLayers() {
938 if (!content_view_core_
)
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_
)
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
,
981 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() {
985 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
989 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
991 DestroyDelegatedContent();
992 frame_evictor_
->DiscardedFrame();
995 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
996 const gfx::Size
& desired_size
) {
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();
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
;
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
))
1061 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_
));
1064 SynchronousCompositorImpl
* compositor
=
1065 SynchronousCompositorImpl::FromID(host_
->GetProcess()->GetID(),
1066 host_
->GetRoutingID());
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_
)
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
)
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
) {
1098 host_
->AccessibilitySetFocus(acc_obj_id
);
1101 void RenderWidgetHostViewAndroid::AccessibilityDoDefaultAction(int acc_obj_id
) {
1105 host_
->AccessibilityDoDefaultAction(acc_obj_id
);
1108 void RenderWidgetHostViewAndroid::AccessibilityScrollToMakeVisible(
1109 int acc_obj_id
, gfx::Rect subfocus
) {
1113 host_
->AccessibilityScrollToMakeVisible(acc_obj_id
, subfocus
);
1116 void RenderWidgetHostViewAndroid::AccessibilityScrollToPoint(
1117 int acc_obj_id
, gfx::Point point
) {
1121 host_
->AccessibilityScrollToPoint(acc_obj_id
, point
);
1124 void RenderWidgetHostViewAndroid::AccessibilitySetTextSelection(
1125 int acc_obj_id
, int start_offset
, int end_offset
) {
1129 host_
->AccessibilitySetTextSelection(
1130 acc_obj_id
, start_offset
, end_offset
);
1133 gfx::Point
RenderWidgetHostViewAndroid::GetLastTouchEventLocation() const {
1135 // Only used on Win8
1136 return gfx::Point();
1139 void RenderWidgetHostViewAndroid::FatalAccessibilityTreeError() {
1143 host_
->FatalAccessibilityTreeError();
1144 SetBrowserAccessibilityManager(NULL
);
1147 bool RenderWidgetHostViewAndroid::LockMouse() {
1152 void RenderWidgetHostViewAndroid::UnlockMouse() {
1156 // Methods called from the host to the render
1158 void RenderWidgetHostViewAndroid::SendKeyEvent(
1159 const NativeWebKeyboardEvent
& event
) {
1161 host_
->ForwardKeyboardEvent(event
);
1164 void RenderWidgetHostViewAndroid::SendTouchEvent(
1165 const blink::WebTouchEvent
& event
) {
1167 host_
->ForwardTouchEventWithLatencyInfo(event
, CreateLatencyInfo(event
));
1170 void RenderWidgetHostViewAndroid::SendMouseEvent(
1171 const blink::WebMouseEvent
& event
) {
1173 host_
->ForwardMouseEvent(event
);
1176 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
1177 const blink::WebMouseWheelEvent
& event
) {
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();
1189 host_
->ForwardGestureEventWithLatencyInfo(event
, CreateLatencyInfo(event
));
1192 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point
& point
) {
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_
)
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
) {
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
);
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() {
1263 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
1264 DCHECK(content_view_core_
);
1265 DCHECK(!using_synchronous_compositor_
);
1269 void RenderWidgetHostViewAndroid::OnWillDestroyWindow() {
1270 root_window_destroyed_
= true;
1273 void RenderWidgetHostViewAndroid::OnLostResources() {
1274 ReleaseLocksOnSurface();
1276 DestroyDelegatedContent();
1277 DCHECK(ack_callbacks_
.empty());
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());
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())
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())
1315 ImageTransportFactoryAndroid
* factory
=
1316 ImageTransportFactoryAndroid::GetInstance();
1317 GLHelper
* gl_helper
= factory
->GetGLHelper();
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())
1333 ignore_result(scoped_callback_runner
.Release());
1335 gl_helper
->CropScaleReadbackAndCleanMailbox(
1336 texture_mailbox
.mailbox(),
1337 texture_mailbox
.sync_point(),
1339 gfx::Rect(result
->size()),
1343 base::Bind(&CopyFromCompositingSurfaceFinished
,
1345 base::Passed(&release_callback
),
1346 base::Passed(&bitmap
),
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();
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
;
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:
1391 RenderWidgetHostView
*
1392 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost
* widget
) {
1393 RenderWidgetHostImpl
* rwhi
= RenderWidgetHostImpl::From(widget
);
1394 return new RenderWidgetHostViewAndroid(rwhi
, NULL
);
1397 } // namespace content