1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/render_widget_host_view_android.h"
7 #include <android/bitmap.h>
9 #include "base/basictypes.h"
10 #include "base/bind.h"
11 #include "base/callback_helpers.h"
12 #include "base/command_line.h"
13 #include "base/logging.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/metrics/histogram.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/threading/worker_pool.h"
18 #include "cc/base/latency_info_swap_promise.h"
19 #include "cc/layers/delegated_frame_provider.h"
20 #include "cc/layers/delegated_renderer_layer.h"
21 #include "cc/layers/layer.h"
22 #include "cc/layers/texture_layer.h"
23 #include "cc/output/compositor_frame.h"
24 #include "cc/output/compositor_frame_ack.h"
25 #include "cc/output/copy_output_request.h"
26 #include "cc/output/copy_output_result.h"
27 #include "cc/resources/single_release_callback.h"
28 #include "cc/trees/layer_tree_host.h"
29 #include "content/browser/accessibility/browser_accessibility_manager_android.h"
30 #include "content/browser/android/content_view_core_impl.h"
31 #include "content/browser/android/in_process/synchronous_compositor_impl.h"
32 #include "content/browser/android/overscroll_glow.h"
33 #include "content/browser/devtools/render_view_devtools_agent_host.h"
34 #include "content/browser/gpu/gpu_data_manager_impl.h"
35 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
36 #include "content/browser/gpu/gpu_surface_tracker.h"
37 #include "content/browser/renderer_host/compositor_impl_android.h"
38 #include "content/browser/renderer_host/dip_util.h"
39 #include "content/browser/renderer_host/image_transport_factory_android.h"
40 #include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
41 #include "content/browser/renderer_host/render_process_host_impl.h"
42 #include "content/browser/renderer_host/render_widget_host_impl.h"
43 #include "content/common/gpu/client/gl_helper.h"
44 #include "content/common/gpu/gpu_messages.h"
45 #include "content/common/input_messages.h"
46 #include "content/common/view_messages.h"
47 #include "content/public/browser/devtools_agent_host.h"
48 #include "content/public/browser/render_view_host.h"
49 #include "content/public/common/content_switches.h"
50 #include "gpu/command_buffer/client/gles2_interface.h"
51 #include "gpu/config/gpu_driver_bug_workaround_type.h"
52 #include "skia/ext/image_operations.h"
53 #include "third_party/khronos/GLES2/gl2.h"
54 #include "third_party/khronos/GLES2/gl2ext.h"
55 #include "third_party/skia/include/core/SkCanvas.h"
56 #include "ui/base/android/window_android.h"
57 #include "ui/gfx/android/device_display_info.h"
58 #include "ui/gfx/android/java_bitmap.h"
59 #include "ui/gfx/display.h"
60 #include "ui/gfx/screen.h"
61 #include "ui/gfx/size_conversions.h"
67 const int kUndefinedOutputSurfaceId
= -1;
68 static const char kAsyncReadBackString
[] = "Compositing.CopyFromSurfaceTime";
70 void InsertSyncPointAndAckForCompositor(
72 uint32 output_surface_id
,
74 const gpu::Mailbox
& return_mailbox
,
75 const gfx::Size return_size
) {
76 cc::CompositorFrameAck ack
;
77 ack
.gl_frame_data
.reset(new cc::GLFrameData());
78 if (!return_mailbox
.IsZero()) {
79 ack
.gl_frame_data
->mailbox
= return_mailbox
;
80 ack
.gl_frame_data
->size
= return_size
;
81 ack
.gl_frame_data
->sync_point
=
82 ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint();
84 RenderWidgetHostImpl::SendSwapCompositorFrameAck(
85 route_id
, output_surface_id
, renderer_host_id
, ack
);
88 // Sends an acknowledgement to the renderer of a processed IME event.
89 void SendImeEventAck(RenderWidgetHostImpl
* host
) {
90 host
->Send(new ViewMsg_ImeEventAck(host
->GetRoutingID()));
93 void CopyFromCompositingSurfaceFinished(
94 const base::Callback
<void(bool, const SkBitmap
&)>& callback
,
95 scoped_ptr
<cc::SingleReleaseCallback
> release_callback
,
96 scoped_ptr
<SkBitmap
> bitmap
,
97 const base::TimeTicks
& start_time
,
98 scoped_ptr
<SkAutoLockPixels
> bitmap_pixels_lock
,
100 bitmap_pixels_lock
.reset();
101 release_callback
->Run(0, false);
102 UMA_HISTOGRAM_TIMES(kAsyncReadBackString
,
103 base::TimeTicks::Now() - start_time
);
104 callback
.Run(result
, *bitmap
);
107 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
),
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
) {
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()
204 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view
) {
208 void RenderWidgetHostViewAndroid::InitAsPopup(
209 RenderWidgetHostView
* parent_host_view
, const gfx::Rect
& pos
) {
213 void RenderWidgetHostViewAndroid::InitAsFullscreen(
214 RenderWidgetHostView
* reference_host_view
) {
219 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
223 void RenderWidgetHostViewAndroid::WasShown() {
224 if (!host_
|| !host_
->is_hidden())
229 if (content_view_core_
&& !using_synchronous_compositor_
)
230 content_view_core_
->GetWindowAndroid()->AddObserver(this);
233 void RenderWidgetHostViewAndroid::WasHidden() {
236 if (!host_
|| host_
->is_hidden())
239 // Inform the renderer that we are being hidden so it can reduce its resource
243 if (content_view_core_
&& !using_synchronous_compositor_
)
244 content_view_core_
->GetWindowAndroid()->RemoveObserver(this);
247 void RenderWidgetHostViewAndroid::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
;
258 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect
& rect
) {
259 SetSize(rect
.size());
262 void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
265 const base::Callback
<void(bool, const SkBitmap
&)>& result_callback
) {
266 if (!IsSurfaceAvailableForCopy()) {
267 result_callback
.Run(false, SkBitmap());
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);
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())
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_
,
302 GLHelper::SCALER_QUALITY_FAST
);
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
);
318 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
319 if (!content_view_core_
)
324 if (texture_size_in_layer_
.IsEmpty())
327 if (UsingDelegatedRenderer()) {
328 if (!delegated_renderer_layer_
.get())
331 if (texture_id_in_layer_
== 0)
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() {
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() {
363 host_
->SetInputMethodActive(true);
365 if (overscroll_effect_enabled_
)
366 overscroll_effect_
->Enable();
369 void RenderWidgetHostViewAndroid::Blur() {
370 host_
->ExecuteEditCommand("Unselect", "");
371 host_
->SetInputMethodActive(false);
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() {
393 layer_
->SetHideLayerAndSubtree(false);
395 frame_evictor_
->SetVisible(true);
399 void RenderWidgetHostViewAndroid::Hide() {
405 layer_
->SetHideLayerAndSubtree(true);
407 frame_evictor_
->SetVisible(false);
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());
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_
)
445 return content_view_core_
->GetPhysicalBackingSize();
448 float RenderWidgetHostViewAndroid::GetOverdrawBottomHeight() const {
449 if (!content_view_core_
)
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
480 base::ScopedClosureRunner ack_caller
;
481 if (params
.require_ack
)
482 ack_caller
.Reset(base::Bind(&SendImeEventAck
, host_
));
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(
497 if (cached_background_color_
== color
)
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");
511 if (flush_input_requested_
) {
512 flush_input_requested_
= false;
514 content_view_core_
->RemoveBeginFrameSubscriber();
517 host_
->Send(new ViewMsg_BeginFrame(host_
->GetRoutingID(), args
));
520 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame(
522 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame",
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
) {
530 content_view_core_
->AddBeginFrameSubscriber();
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
) {
569 void RenderWidgetHostViewAndroid::RenderProcessGone(
570 base::TerminationStatus status
, int error_code
) {
574 void RenderWidgetHostViewAndroid::Destroy() {
576 SetContentViewCore(NULL
);
578 // The RenderWidgetHost's destruction led here, so don't call it.
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
,
591 const gfx::Range
& range
) {
592 RenderWidgetHostViewBase::SelectionChanged(text
, offset
, range
);
594 if (text
.empty() || range
.is_empty() || !content_view_core_
)
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.";
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
) {
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());
644 base::TimeTicks start_time
= base::TimeTicks::Now();
645 if (!using_synchronous_compositor_
&& !IsSurfaceAvailableForCopy()) {
646 callback
.Run(false, SkBitmap());
649 ImageTransportFactoryAndroid
* factory
=
650 ImageTransportFactoryAndroid::GetInstance();
651 GLHelper
* gl_helper
= factory
->GetGLHelper();
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());
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
);
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
,
686 request
= cc::CopyOutputRequest::CreateRequest(base::Bind(
687 &RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult
,
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
) {
705 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
709 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
710 const gfx::Rect
& target_rect
, const SkBitmap
& zoomed_bitmap
) {
711 if (!content_view_core_
)
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(),
733 host_
->GetProcess()->GetID(),
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(),
748 host_
->GetProcess()->GetID(),
752 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
753 if (ack_callbacks_
.size())
755 SendReturnedDelegatedResources(last_output_surface_id_
);
758 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
760 frame_provider_
= NULL
;
761 delegated_renderer_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
;
786 DestroyDelegatedContent();
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()) {
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_
;
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(),
819 if (host_
->is_hidden())
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());
863 DCHECK(!UsingDelegatedRenderer());
865 if (!frame
->gl_frame_data
|| frame
->gl_frame_data
->mailbox
.IsZero())
868 if (output_surface_id
!= last_output_surface_id_
) {
869 current_mailbox_
= gpu::Mailbox();
870 last_output_surface_id_
= kUndefinedOutputSurfaceId
;
873 base::Closure callback
= base::Bind(&InsertSyncPointAndAckForCompositor
,
874 host_
->GetProcess()->GetID(),
876 host_
->GetRoutingID(),
878 texture_size_in_layer_
);
879 ImageTransportFactoryAndroid::GetInstance()->WaitSyncPoint(
880 frame
->gl_frame_data
->sync_point
);
882 texture_size_in_layer_
= frame
->gl_frame_data
->size
;
883 ComputeContentsSize(frame
->metadata
);
885 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
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()),
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());
930 callback
.Run(false, SkBitmap());
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
);
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
,
966 accelerated_surface_route_id_
= route_id
;
969 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
970 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params
& params
,
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
);
994 current_mailbox_
= mailbox
;
995 last_output_surface_id_
= output_surface_id
;
997 if (host_
->is_hidden())
1000 ack_callbacks_
.push(ack_callback
);
1003 void RenderWidgetHostViewAndroid::AttachLayers() {
1004 if (!content_view_core_
)
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_
)
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
,
1047 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() {
1051 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
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
) {
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();
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
;
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
))
1141 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_
));
1144 SynchronousCompositorImpl
* compositor
=
1145 SynchronousCompositorImpl::FromID(host_
->GetProcess()->GetID(),
1146 host_
->GetRoutingID());
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_
)
1155 flush_input_requested_
= true;
1156 content_view_core_
->AddBeginFrameSubscriber();
1159 void RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManagerIfNeeded() {
1160 if (!host_
|| host_
->accessibility_mode() != AccessibilityModeComplete
)
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
) {
1177 host_
->AccessibilitySetFocus(acc_obj_id
);
1180 void RenderWidgetHostViewAndroid::AccessibilityDoDefaultAction(int acc_obj_id
) {
1184 host_
->AccessibilityDoDefaultAction(acc_obj_id
);
1187 void RenderWidgetHostViewAndroid::AccessibilityScrollToMakeVisible(
1188 int acc_obj_id
, gfx::Rect subfocus
) {
1192 host_
->AccessibilityScrollToMakeVisible(acc_obj_id
, subfocus
);
1195 void RenderWidgetHostViewAndroid::AccessibilityScrollToPoint(
1196 int acc_obj_id
, gfx::Point point
) {
1200 host_
->AccessibilityScrollToPoint(acc_obj_id
, point
);
1203 void RenderWidgetHostViewAndroid::AccessibilitySetTextSelection(
1204 int acc_obj_id
, int start_offset
, int end_offset
) {
1208 host_
->AccessibilitySetTextSelection(
1209 acc_obj_id
, start_offset
, end_offset
);
1212 gfx::Point
RenderWidgetHostViewAndroid::GetLastTouchEventLocation() const {
1214 // Only used on Win8
1215 return gfx::Point();
1218 void RenderWidgetHostViewAndroid::FatalAccessibilityTreeError() {
1222 host_
->FatalAccessibilityTreeError();
1223 SetBrowserAccessibilityManager(NULL
);
1226 bool RenderWidgetHostViewAndroid::LockMouse() {
1231 void RenderWidgetHostViewAndroid::UnlockMouse() {
1235 // Methods called from the host to the render
1237 void RenderWidgetHostViewAndroid::SendKeyEvent(
1238 const NativeWebKeyboardEvent
& event
) {
1240 host_
->ForwardKeyboardEvent(event
);
1243 void RenderWidgetHostViewAndroid::SendTouchEvent(
1244 const blink::WebTouchEvent
& event
) {
1246 host_
->ForwardTouchEventWithLatencyInfo(event
, CreateLatencyInfo(event
));
1249 void RenderWidgetHostViewAndroid::SendMouseEvent(
1250 const blink::WebMouseEvent
& event
) {
1252 host_
->ForwardMouseEvent(event
);
1255 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
1256 const blink::WebMouseWheelEvent
& event
) {
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();
1268 host_
->ForwardGestureEventWithLatencyInfo(event
, CreateLatencyInfo(event
));
1271 void RenderWidgetHostViewAndroid::SelectRange(const gfx::Point
& start
,
1272 const gfx::Point
& end
) {
1274 host_
->SelectRange(start
, end
);
1277 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point
& point
) {
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.
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())
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());
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_
)
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
) {
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
);
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() {
1387 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
1388 DCHECK(content_view_core_
);
1389 DCHECK(!using_synchronous_compositor_
);
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;
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())
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())
1423 ImageTransportFactoryAndroid
* factory
=
1424 ImageTransportFactoryAndroid::GetInstance();
1425 GLHelper
* gl_helper
= factory
->GetGLHelper();
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())
1440 ignore_result(scoped_callback_runner
.Release());
1442 gl_helper
->CropScaleReadbackAndCleanMailbox(
1443 texture_mailbox
.mailbox(),
1444 texture_mailbox
.sync_point(),
1446 gfx::Rect(result
->size()),
1450 base::Bind(&CopyFromCompositingSurfaceFinished
,
1452 base::Passed(&release_callback
),
1453 base::Passed(&bitmap
),
1455 base::Passed(&bitmap_pixels_lock
)));
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())
1471 scoped_ptr
<SkBitmap
> source
= result
->TakeBitmap();
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
);
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:
1505 RenderWidgetHostView
*
1506 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost
* widget
) {
1507 RenderWidgetHostImpl
* rwhi
= RenderWidgetHostImpl::From(widget
);
1508 return new RenderWidgetHostViewAndroid(rwhi
, NULL
);
1511 } // namespace content