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/strings/utf_string_conversions.h"
16 #include "base/threading/worker_pool.h"
17 #include "cc/base/latency_info_swap_promise.h"
18 #include "cc/layers/delegated_frame_provider.h"
19 #include "cc/layers/delegated_renderer_layer.h"
20 #include "cc/layers/layer.h"
21 #include "cc/layers/texture_layer.h"
22 #include "cc/output/compositor_frame.h"
23 #include "cc/output/compositor_frame_ack.h"
24 #include "cc/output/copy_output_request.h"
25 #include "cc/output/copy_output_result.h"
26 #include "cc/resources/single_release_callback.h"
27 #include "cc/trees/layer_tree_host.h"
28 #include "content/browser/accessibility/browser_accessibility_manager_android.h"
29 #include "content/browser/android/content_view_core_impl.h"
30 #include "content/browser/android/in_process/synchronous_compositor_impl.h"
31 #include "content/browser/android/overscroll_glow.h"
32 #include "content/browser/devtools/render_view_devtools_agent_host.h"
33 #include "content/browser/gpu/gpu_data_manager_impl.h"
34 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
35 #include "content/browser/gpu/gpu_surface_tracker.h"
36 #include "content/browser/renderer_host/compositor_impl_android.h"
37 #include "content/browser/renderer_host/dip_util.h"
38 #include "content/browser/renderer_host/image_transport_factory_android.h"
39 #include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
40 #include "content/browser/renderer_host/render_process_host_impl.h"
41 #include "content/browser/renderer_host/render_widget_host_impl.h"
42 #include "content/common/gpu/client/gl_helper.h"
43 #include "content/common/gpu/gpu_messages.h"
44 #include "content/common/input_messages.h"
45 #include "content/common/view_messages.h"
46 #include "content/public/browser/devtools_agent_host.h"
47 #include "content/public/browser/render_view_host.h"
48 #include "content/public/common/content_switches.h"
49 #include "gpu/config/gpu_driver_bug_workaround_type.h"
50 #include "skia/ext/image_operations.h"
51 #include "third_party/khronos/GLES2/gl2.h"
52 #include "third_party/khronos/GLES2/gl2ext.h"
53 #include "third_party/skia/include/core/SkCanvas.h"
54 #include "ui/base/android/window_android.h"
55 #include "ui/gfx/android/device_display_info.h"
56 #include "ui/gfx/android/java_bitmap.h"
57 #include "ui/gfx/display.h"
58 #include "ui/gfx/screen.h"
59 #include "ui/gfx/size_conversions.h"
65 const int kUndefinedOutputSurfaceId
= -1;
67 void InsertSyncPointAndAckForCompositor(
69 uint32 output_surface_id
,
71 const gpu::Mailbox
& return_mailbox
,
72 const gfx::Size return_size
) {
73 cc::CompositorFrameAck ack
;
74 ack
.gl_frame_data
.reset(new cc::GLFrameData());
75 if (!return_mailbox
.IsZero()) {
76 ack
.gl_frame_data
->mailbox
= return_mailbox
;
77 ack
.gl_frame_data
->size
= return_size
;
78 ack
.gl_frame_data
->sync_point
=
79 ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint();
81 RenderWidgetHostImpl::SendSwapCompositorFrameAck(
82 route_id
, output_surface_id
, renderer_host_id
, ack
);
85 // Sends an acknowledgement to the renderer of a processed IME event.
86 void SendImeEventAck(RenderWidgetHostImpl
* host
) {
87 host
->Send(new ViewMsg_ImeEventAck(host
->GetRoutingID()));
90 void CopyFromCompositingSurfaceFinished(
91 const base::Callback
<void(bool, const SkBitmap
&)>& callback
,
92 scoped_ptr
<cc::SingleReleaseCallback
> release_callback
,
93 scoped_ptr
<SkBitmap
> bitmap
,
94 scoped_ptr
<SkAutoLockPixels
> bitmap_pixels_lock
,
96 bitmap_pixels_lock
.reset();
97 release_callback
->Run(0, false);
98 callback
.Run(result
, *bitmap
);
101 bool UsingDelegatedRenderer() {
102 bool using_delegated_renderer
= false;
104 using_delegated_renderer
|= CommandLine::ForCurrentProcess()->HasSwitch(
105 switches::kEnableDelegatedRenderer
);
107 using_delegated_renderer
&= !CommandLine::ForCurrentProcess()->HasSwitch(
108 switches::kDisableDelegatedRenderer
);
110 return using_delegated_renderer
;
113 } // anonymous namespace
115 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
116 RenderWidgetHostImpl
* widget_host
,
117 ContentViewCoreImpl
* content_view_core
)
118 : host_(widget_host
),
119 needs_begin_frame_(false),
120 are_layers_attached_(!widget_host
->is_hidden()),
121 content_view_core_(NULL
),
122 ime_adapter_android_(this),
123 cached_background_color_(SK_ColorWHITE
),
124 texture_id_in_layer_(0),
125 last_output_surface_id_(kUndefinedOutputSurfaceId
),
126 weak_ptr_factory_(this),
127 overscroll_effect_enabled_(
128 !CommandLine::ForCurrentProcess()->
129 HasSwitch(switches::kDisableOverscrollEdgeEffect
)),
130 overscroll_effect_(OverscrollGlow::Create(overscroll_effect_enabled_
)),
131 flush_input_requested_(false),
132 accelerated_surface_route_id_(0),
133 using_synchronous_compositor_(SynchronousCompositorImpl::FromID(
134 widget_host
->GetProcess()->GetID(),
135 widget_host
->GetRoutingID()) != NULL
),
136 frame_evictor_(new DelegatedFrameEvictor(this)) {
137 if (!UsingDelegatedRenderer()) {
138 texture_layer_
= cc::TextureLayer::Create(NULL
);
139 layer_
= texture_layer_
;
142 host_
->SetView(this);
143 SetContentViewCore(content_view_core
);
144 ImageTransportFactoryAndroid::AddObserver(this);
147 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
148 ImageTransportFactoryAndroid::RemoveObserver(this);
149 SetContentViewCore(NULL
);
150 DCHECK(ack_callbacks_
.empty());
151 if (texture_id_in_layer_
) {
152 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
153 texture_id_in_layer_
);
156 if (texture_layer_
.get())
157 texture_layer_
->ClearClient();
159 if (resource_collection_
.get())
160 resource_collection_
->SetClient(NULL
);
164 bool RenderWidgetHostViewAndroid::OnMessageReceived(
165 const IPC::Message
& message
) {
167 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid
, message
)
168 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent
, OnStartContentIntent
)
169 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor
,
170 OnDidChangeBodyBackgroundColor
)
171 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame
,
172 OnSetNeedsBeginFrame
)
173 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged
,
174 OnTextInputStateChanged
)
175 IPC_MESSAGE_HANDLER(ViewHostMsg_SmartClipDataExtracted
,
176 OnSmartClipDataExtracted
)
177 IPC_MESSAGE_UNHANDLED(handled
= false)
178 IPC_END_MESSAGE_MAP()
182 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view
) {
186 void RenderWidgetHostViewAndroid::InitAsPopup(
187 RenderWidgetHostView
* parent_host_view
, const gfx::Rect
& pos
) {
191 void RenderWidgetHostViewAndroid::InitAsFullscreen(
192 RenderWidgetHostView
* reference_host_view
) {
197 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
201 void RenderWidgetHostViewAndroid::WasShown() {
202 if (!host_
|| !host_
->is_hidden())
207 if (content_view_core_
&& !using_synchronous_compositor_
)
208 content_view_core_
->GetWindowAndroid()->AddObserver(this);
211 void RenderWidgetHostViewAndroid::WasHidden() {
214 if (!host_
|| host_
->is_hidden())
217 // Inform the renderer that we are being hidden so it can reduce its resource
221 if (content_view_core_
&& !using_synchronous_compositor_
)
222 content_view_core_
->GetWindowAndroid()->RemoveObserver(this);
225 void RenderWidgetHostViewAndroid::WasResized() {
229 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size
& size
) {
230 // Ignore the given size as only the Java code has the power to
231 // resize the view on Android.
232 default_size_
= size
;
236 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect
& rect
) {
237 SetSize(rect
.size());
240 blink::WebGLId
RenderWidgetHostViewAndroid::GetScaledContentTexture(
242 gfx::Size
* out_size
) {
243 gfx::Size
size(gfx::ToCeiledSize(
244 gfx::ScaleSize(texture_size_in_layer_
, scale
)));
246 if (!CompositorImpl::IsInitialized() ||
247 texture_id_in_layer_
== 0 ||
248 texture_size_in_layer_
.IsEmpty() ||
251 out_size
->SetSize(0, 0);
259 GLHelper
* helper
= ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
260 return helper
->CopyAndScaleTexture(texture_id_in_layer_
,
261 texture_size_in_layer_
,
264 GLHelper::SCALER_QUALITY_FAST
);
267 bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(jobject jbitmap
) {
268 if (!CompositorImpl::IsInitialized() ||
269 texture_id_in_layer_
== 0 ||
270 texture_size_in_layer_
.IsEmpty())
273 gfx::JavaBitmap
bitmap(jbitmap
);
275 // TODO(dtrainor): Eventually add support for multiple formats here.
276 DCHECK(bitmap
.format() == ANDROID_BITMAP_FORMAT_RGBA_8888
);
278 GLHelper
* helper
= ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
280 blink::WebGLId texture
= helper
->CopyAndScaleTexture(
281 texture_id_in_layer_
,
282 texture_size_in_layer_
,
285 GLHelper::SCALER_QUALITY_FAST
);
289 helper
->ReadbackTextureSync(texture
,
290 gfx::Rect(bitmap
.size()),
291 static_cast<unsigned char*> (bitmap
.pixels()));
293 blink::WebGraphicsContext3D
* context
=
294 ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
295 context
->deleteTexture(texture
);
300 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
301 if (!content_view_core_
)
303 if (texture_size_in_layer_
.IsEmpty())
306 if (UsingDelegatedRenderer()) {
307 if (!delegated_renderer_layer_
.get())
310 if (texture_id_in_layer_
== 0)
317 gfx::NativeView
RenderWidgetHostViewAndroid::GetNativeView() const {
318 return content_view_core_
->GetViewAndroid();
321 gfx::NativeViewId
RenderWidgetHostViewAndroid::GetNativeViewId() const {
322 return reinterpret_cast<gfx::NativeViewId
>(
323 const_cast<RenderWidgetHostViewAndroid
*>(this));
326 gfx::NativeViewAccessible
327 RenderWidgetHostViewAndroid::GetNativeViewAccessible() {
332 void RenderWidgetHostViewAndroid::MovePluginWindows(
333 const gfx::Vector2d
& scroll_offset
,
334 const std::vector
<WebPluginGeometry
>& moves
) {
335 // We don't have plugin windows on Android. Do nothing. Note: this is called
336 // from RenderWidgetHost::OnUpdateRect which is itself invoked while
337 // processing the corresponding message from Renderer.
340 void RenderWidgetHostViewAndroid::Focus() {
342 host_
->SetInputMethodActive(true);
344 if (overscroll_effect_enabled_
)
345 overscroll_effect_
->Enable();
348 void RenderWidgetHostViewAndroid::Blur() {
349 host_
->ExecuteEditCommand("Unselect", "");
350 host_
->SetInputMethodActive(false);
352 overscroll_effect_
->Disable();
355 bool RenderWidgetHostViewAndroid::HasFocus() const {
356 if (!content_view_core_
)
357 return false; // ContentViewCore not created yet.
359 return content_view_core_
->HasFocus();
362 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
363 return HasValidFrame();
366 void RenderWidgetHostViewAndroid::Show() {
367 if (are_layers_attached_
)
370 are_layers_attached_
= true;
373 frame_evictor_
->SetVisible(true);
377 void RenderWidgetHostViewAndroid::Hide() {
378 if (!are_layers_attached_
)
381 are_layers_attached_
= false;
384 frame_evictor_
->SetVisible(false);
388 bool RenderWidgetHostViewAndroid::IsShowing() {
389 // ContentViewCoreImpl represents the native side of the Java
390 // ContentViewCore. It being NULL means that it is not attached
391 // to the View system yet, so we treat this RWHVA as hidden.
392 return are_layers_attached_
&& content_view_core_
;
395 void RenderWidgetHostViewAndroid::LockResources() {
396 DCHECK(HasValidFrame());
398 DCHECK(!host_
->is_hidden());
399 frame_evictor_
->LockFrame();
402 void RenderWidgetHostViewAndroid::UnlockResources() {
403 DCHECK(HasValidFrame());
404 frame_evictor_
->UnlockFrame();
407 gfx::Rect
RenderWidgetHostViewAndroid::GetViewBounds() const {
408 if (!content_view_core_
)
409 return gfx::Rect(default_size_
);
411 gfx::Size size
= content_view_core_
->GetViewportSizeDip();
412 gfx::Size offset
= content_view_core_
->GetViewportSizeOffsetDip();
413 size
.Enlarge(-offset
.width(), -offset
.height());
415 return gfx::Rect(size
);
418 gfx::Size
RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
419 if (!content_view_core_
)
422 return content_view_core_
->GetPhysicalBackingSize();
425 float RenderWidgetHostViewAndroid::GetOverdrawBottomHeight() const {
426 if (!content_view_core_
)
429 return content_view_core_
->GetOverdrawBottomHeightDip();
432 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor
& cursor
) {
433 // There are no cursors on Android.
436 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading
) {
437 // Do nothing. The UI notification is handled through ContentViewClient which
438 // is TabContentsDelegate.
441 void RenderWidgetHostViewAndroid::TextInputTypeChanged(
442 ui::TextInputType type
,
443 ui::TextInputMode input_mode
,
444 bool can_compose_inline
) {
445 // Unused on Android, which uses OnTextInputChanged instead.
448 int RenderWidgetHostViewAndroid::GetNativeImeAdapter() {
449 return reinterpret_cast<int>(&ime_adapter_android_
);
452 void RenderWidgetHostViewAndroid::OnTextInputStateChanged(
453 const ViewHostMsg_TextInputState_Params
& params
) {
454 // If an acknowledgement is required for this event, regardless of how we exit
455 // from this method, we must acknowledge that we processed the input state
457 base::ScopedClosureRunner ack_caller
;
458 if (params
.require_ack
)
459 ack_caller
.Reset(base::Bind(&SendImeEventAck
, host_
));
464 content_view_core_
->UpdateImeAdapter(
465 GetNativeImeAdapter(),
466 static_cast<int>(params
.type
),
467 params
.value
, params
.selection_start
, params
.selection_end
,
468 params
.composition_start
, params
.composition_end
,
469 params
.show_ime_if_needed
, params
.require_ack
);
472 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor(
474 if (cached_background_color_
== color
)
477 cached_background_color_
= color
;
478 if (content_view_core_
)
479 content_view_core_
->OnBackgroundColorChanged(color
);
482 void RenderWidgetHostViewAndroid::SendBeginFrame(
483 const cc::BeginFrameArgs
& args
) {
484 TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::SendBeginFrame");
488 if (flush_input_requested_
) {
489 flush_input_requested_
= false;
491 content_view_core_
->RemoveBeginFrameSubscriber();
494 host_
->Send(new ViewMsg_BeginFrame(host_
->GetRoutingID(), args
));
497 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame(
499 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame",
501 // ContentViewCoreImpl handles multiple subscribers to the BeginFrame, so
502 // we have to make sure calls to ContentViewCoreImpl's
503 // {Add,Remove}BeginFrameSubscriber are balanced, even if
504 // RenderWidgetHostViewAndroid's may not be.
505 if (content_view_core_
&& needs_begin_frame_
!= enabled
) {
507 content_view_core_
->AddBeginFrameSubscriber();
509 content_view_core_
->RemoveBeginFrameSubscriber();
510 needs_begin_frame_
= enabled
;
514 void RenderWidgetHostViewAndroid::OnStartContentIntent(
515 const GURL
& content_url
) {
516 if (content_view_core_
)
517 content_view_core_
->StartContentIntent(content_url
);
520 void RenderWidgetHostViewAndroid::OnSmartClipDataExtracted(
521 const base::string16
& result
) {
522 // Custom serialization over IPC isn't allowed normally for security reasons.
523 // Since this feature is only used in (single-process) WebView, there are no
524 // security issues. Enforce that it's only called in single process mode.
525 CHECK(RenderProcessHost::run_renderer_in_process());
526 if (content_view_core_
)
527 content_view_core_
->OnSmartClipDataExtracted(result
);
530 void RenderWidgetHostViewAndroid::ImeCancelComposition() {
531 ime_adapter_android_
.CancelComposition();
534 void RenderWidgetHostViewAndroid::DidUpdateBackingStore(
535 const gfx::Rect
& scroll_rect
,
536 const gfx::Vector2d
& scroll_delta
,
537 const std::vector
<gfx::Rect
>& copy_rects
,
538 const std::vector
<ui::LatencyInfo
>& latency_info
) {
542 void RenderWidgetHostViewAndroid::RenderProcessGone(
543 base::TerminationStatus status
, int error_code
) {
547 void RenderWidgetHostViewAndroid::Destroy() {
549 SetContentViewCore(NULL
);
551 // The RenderWidgetHost's destruction led here, so don't call it.
557 void RenderWidgetHostViewAndroid::SetTooltipText(
558 const base::string16
& tooltip_text
) {
559 // Tooltips don't makes sense on Android.
562 void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16
& text
,
564 const gfx::Range
& range
) {
565 RenderWidgetHostViewBase::SelectionChanged(text
, offset
, range
);
567 if (text
.empty() || range
.is_empty() || !content_view_core_
)
569 size_t pos
= range
.GetMin() - offset
;
570 size_t n
= range
.length();
572 DCHECK(pos
+ n
<= text
.length()) << "The text can not fully cover range.";
573 if (pos
>= text
.length()) {
574 NOTREACHED() << "The text can not cover range.";
578 std::string utf8_selection
= base::UTF16ToUTF8(text
.substr(pos
, n
));
580 content_view_core_
->OnSelectionChanged(utf8_selection
);
583 void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
584 const ViewHostMsg_SelectionBounds_Params
& params
) {
585 if (content_view_core_
) {
586 content_view_core_
->OnSelectionBoundsChanged(params
);
590 void RenderWidgetHostViewAndroid::ScrollOffsetChanged() {
593 BackingStore
* RenderWidgetHostViewAndroid::AllocBackingStore(
594 const gfx::Size
& size
) {
599 void RenderWidgetHostViewAndroid::SetBackground(const SkBitmap
& background
) {
600 RenderWidgetHostViewBase::SetBackground(background
);
601 host_
->Send(new ViewMsg_SetBackground(host_
->GetRoutingID(), background
));
604 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
605 const gfx::Rect
& src_subrect
,
606 const gfx::Size
& dst_size
,
607 const base::Callback
<void(bool, const SkBitmap
&)>& callback
) {
608 if (!using_synchronous_compositor_
&& !IsSurfaceAvailableForCopy()) {
609 callback
.Run(false, SkBitmap());
613 const gfx::Display
& display
=
614 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
615 float device_scale_factor
= display
.device_scale_factor();
617 DCHECK_EQ(device_scale_factor
,
618 ui::GetImageScale(GetScaleFactorForView(this)));
620 const gfx::Size
& dst_size_in_pixel
= ConvertViewSizeToPixel(this, dst_size
);
621 gfx::Rect src_subrect_in_pixel
=
622 ConvertRectToPixel(device_scale_factor
, src_subrect
);
624 if (using_synchronous_compositor_
) {
625 SynchronousCopyContents(src_subrect_in_pixel
, dst_size_in_pixel
, callback
);
629 scoped_ptr
<cc::CopyOutputRequest
> request
;
630 if (src_subrect_in_pixel
.size() == dst_size_in_pixel
) {
631 request
= cc::CopyOutputRequest::CreateBitmapRequest(base::Bind(
632 &RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult
,
636 request
= cc::CopyOutputRequest::CreateRequest(base::Bind(
637 &RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult
,
641 request
->set_area(src_subrect_in_pixel
);
642 layer_
->RequestCopyOfOutput(request
.Pass());
645 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
646 const gfx::Rect
& src_subrect
,
647 const scoped_refptr
<media::VideoFrame
>& target
,
648 const base::Callback
<void(bool)>& callback
) {
653 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
657 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
658 const gfx::Rect
& target_rect
, const SkBitmap
& zoomed_bitmap
) {
659 if (!content_view_core_
)
662 content_view_core_
->ShowDisambiguationPopup(target_rect
, zoomed_bitmap
);
665 scoped_ptr
<SyntheticGestureTarget
>
666 RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
667 return scoped_ptr
<SyntheticGestureTarget
>(new SyntheticGestureTargetAndroid(
668 host_
, content_view_core_
->CreateTouchEventSynthesizer()));
671 void RenderWidgetHostViewAndroid::OnAcceleratedCompositingStateChange() {
674 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
675 uint32 output_surface_id
) {
676 cc::CompositorFrameAck ack
;
677 if (resource_collection_
.get())
678 resource_collection_
->TakeUnusedResourcesForChildCompositor(&ack
.resources
);
679 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_
->GetRoutingID(),
681 host_
->GetProcess()->GetID(),
685 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
686 // TODO(danakj): If no ack is pending, collect and send resources now.
689 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
690 if (are_layers_attached_
)
692 frame_provider_
= NULL
;
693 delegated_renderer_layer_
= NULL
;
697 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
698 uint32 output_surface_id
,
699 scoped_ptr
<cc::DelegatedFrameData
> frame_data
) {
700 bool has_content
= !texture_size_in_layer_
.IsEmpty();
702 if (output_surface_id
!= last_output_surface_id_
) {
703 // TODO(danakj): Lose all resources and send them back here, such as:
704 // resource_collection_->LoseAllResources();
705 // SendReturnedDelegatedResources(last_output_surface_id_);
707 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
708 // any resources from the old output surface with the new output surface id.
709 if (resource_collection_
.get()) {
710 resource_collection_
->SetClient(NULL
);
711 resource_collection_
= NULL
;
713 DestroyDelegatedContent();
715 last_output_surface_id_
= output_surface_id
;
719 DestroyDelegatedContent();
721 if (!resource_collection_
.get()) {
722 resource_collection_
= new cc::DelegatedFrameResourceCollection
;
723 resource_collection_
->SetClient(this);
725 if (!frame_provider_
||
726 texture_size_in_layer_
!= frame_provider_
->frame_size()) {
727 if (are_layers_attached_
)
729 frame_provider_
= new cc::DelegatedFrameProvider(
730 resource_collection_
.get(), frame_data
.Pass());
731 delegated_renderer_layer_
=
732 cc::DelegatedRendererLayer::Create(frame_provider_
);
733 layer_
= delegated_renderer_layer_
;
734 if (are_layers_attached_
)
737 frame_provider_
->SetFrameData(frame_data
.Pass());
741 if (delegated_renderer_layer_
.get()) {
742 delegated_renderer_layer_
->SetDisplaySize(texture_size_in_layer_
);
743 delegated_renderer_layer_
->SetIsDrawable(true);
744 delegated_renderer_layer_
->SetContentsOpaque(true);
745 delegated_renderer_layer_
->SetBounds(content_size_in_layer_
);
746 delegated_renderer_layer_
->SetNeedsDisplay();
749 base::Closure ack_callback
=
750 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck
,
751 weak_ptr_factory_
.GetWeakPtr(),
754 if (host_
->is_hidden())
757 ack_callbacks_
.push(ack_callback
);
760 void RenderWidgetHostViewAndroid::ComputeContentsSize(
761 const cc::CompositorFrameMetadata
& frame_metadata
) {
762 // Calculate the content size. This should be 0 if the texture_size is 0.
763 gfx::Vector2dF offset
;
764 if (texture_size_in_layer_
.GetArea() > 0)
765 offset
= frame_metadata
.location_bar_content_translation
;
766 offset
.set_y(offset
.y() + frame_metadata
.overdraw_bottom_height
);
767 offset
.Scale(frame_metadata
.device_scale_factor
);
768 content_size_in_layer_
=
769 gfx::Size(texture_size_in_layer_
.width() - offset
.x(),
770 texture_size_in_layer_
.height() - offset
.y());
771 // Content size changes should be reflected in associated animation effects.
772 UpdateAnimationSize(frame_metadata
);
775 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
776 uint32 output_surface_id
,
777 scoped_ptr
<cc::CompositorFrame
> frame
) {
778 // Always let ContentViewCore know about the new frame first, so it can decide
779 // to schedule a Draw immediately when it sees the texture layer invalidation.
780 UpdateContentViewCoreFrameMetadata(frame
->metadata
);
782 if (frame
->delegated_frame_data
) {
783 DCHECK(UsingDelegatedRenderer());
785 DCHECK(frame
->delegated_frame_data
);
786 DCHECK(!frame
->delegated_frame_data
->render_pass_list
.empty());
788 cc::RenderPass
* root_pass
=
789 frame
->delegated_frame_data
->render_pass_list
.back();
790 texture_size_in_layer_
= root_pass
->output_rect
.size();
791 ComputeContentsSize(frame
->metadata
);
793 SwapDelegatedFrame(output_surface_id
, frame
->delegated_frame_data
.Pass());
797 DCHECK(!UsingDelegatedRenderer());
799 if (!frame
->gl_frame_data
|| frame
->gl_frame_data
->mailbox
.IsZero())
802 if (output_surface_id
!= last_output_surface_id_
) {
803 current_mailbox_
= gpu::Mailbox();
804 last_output_surface_id_
= kUndefinedOutputSurfaceId
;
807 base::Closure callback
= base::Bind(&InsertSyncPointAndAckForCompositor
,
808 host_
->GetProcess()->GetID(),
810 host_
->GetRoutingID(),
812 texture_size_in_layer_
);
813 ImageTransportFactoryAndroid::GetInstance()->WaitSyncPoint(
814 frame
->gl_frame_data
->sync_point
);
816 texture_size_in_layer_
= frame
->gl_frame_data
->size
;
817 ComputeContentsSize(frame
->metadata
);
819 if (layer_
->layer_tree_host()) {
820 for (size_t i
= 0; i
< frame
->metadata
.latency_info
.size(); i
++) {
821 scoped_ptr
<cc::SwapPromise
> swap_promise(
822 new cc::LatencyInfoSwapPromise(frame
->metadata
.latency_info
[i
]));
823 layer_
->layer_tree_host()->QueueSwapPromise(swap_promise
.Pass());
827 BuffersSwapped(frame
->gl_frame_data
->mailbox
, output_surface_id
, callback
);
828 frame_evictor_
->SwappedFrame(!host_
->is_hidden());
831 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
832 const cc::CompositorFrameMetadata
& frame_metadata
) {
833 // This is a subset of OnSwapCompositorFrame() used in the synchronous
835 UpdateContentViewCoreFrameMetadata(frame_metadata
);
836 ComputeContentsSize(frame_metadata
);
838 // DevTools ScreenCast support for Android WebView.
839 if (DevToolsAgentHost::HasFor(RenderViewHost::From(GetRenderWidgetHost()))) {
840 scoped_refptr
<DevToolsAgentHost
> dtah
=
841 DevToolsAgentHost::GetOrCreateFor(
842 RenderViewHost::From(GetRenderWidgetHost()));
843 // Unblock the compositor.
844 BrowserThread::PostTask(
845 BrowserThread::UI
, FROM_HERE
,
846 base::Bind(&RenderViewDevToolsAgentHost::SynchronousSwapCompositorFrame
,
847 static_cast<RenderViewDevToolsAgentHost
*>(dtah
.get()),
852 void RenderWidgetHostViewAndroid::SetOverlayVideoMode(bool enabled
) {
853 layer_
->SetContentsOpaque(!enabled
);
856 void RenderWidgetHostViewAndroid::SynchronousCopyContents(
857 const gfx::Rect
& src_subrect_in_pixel
,
858 const gfx::Size
& dst_size_in_pixel
,
859 const base::Callback
<void(bool, const SkBitmap
&)>& callback
) {
860 SynchronousCompositor
* compositor
=
861 SynchronousCompositorImpl::FromID(host_
->GetProcess()->GetID(),
862 host_
->GetRoutingID());
864 callback
.Run(false, SkBitmap());
869 bitmap
.setConfig(SkBitmap::kARGB_8888_Config
,
870 dst_size_in_pixel
.width(),
871 dst_size_in_pixel
.height());
872 bitmap
.allocPixels();
873 SkCanvas
canvas(bitmap
);
875 (float)dst_size_in_pixel
.width() / (float)src_subrect_in_pixel
.width(),
876 (float)dst_size_in_pixel
.height() / (float)src_subrect_in_pixel
.height());
877 compositor
->DemandDrawSw(&canvas
);
878 callback
.Run(true, bitmap
);
881 void RenderWidgetHostViewAndroid::UpdateContentViewCoreFrameMetadata(
882 const cc::CompositorFrameMetadata
& frame_metadata
) {
883 if (content_view_core_
) {
884 // All offsets and sizes are in CSS pixels.
885 content_view_core_
->UpdateFrameInfo(
886 frame_metadata
.root_scroll_offset
,
887 frame_metadata
.page_scale_factor
,
888 gfx::Vector2dF(frame_metadata
.min_page_scale_factor
,
889 frame_metadata
.max_page_scale_factor
),
890 frame_metadata
.root_layer_size
,
891 frame_metadata
.viewport_size
,
892 frame_metadata
.location_bar_offset
,
893 frame_metadata
.location_bar_content_translation
,
894 frame_metadata
.overdraw_bottom_height
);
898 void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int host_id
,
900 accelerated_surface_route_id_
= route_id
;
903 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
904 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params
& params
,
906 NOTREACHED() << "Need --composite-to-mailbox or --enable-delegated-renderer";
909 void RenderWidgetHostViewAndroid::BuffersSwapped(
910 const gpu::Mailbox
& mailbox
,
911 uint32_t output_surface_id
,
912 const base::Closure
& ack_callback
) {
913 ImageTransportFactoryAndroid
* factory
=
914 ImageTransportFactoryAndroid::GetInstance();
916 if (!texture_id_in_layer_
) {
917 texture_id_in_layer_
= factory
->CreateTexture();
918 texture_layer_
->SetTextureId(texture_id_in_layer_
);
919 texture_layer_
->SetIsDrawable(true);
920 texture_layer_
->SetContentsOpaque(true);
923 ImageTransportFactoryAndroid::GetInstance()->AcquireTexture(
924 texture_id_in_layer_
, mailbox
.name
);
928 current_mailbox_
= mailbox
;
929 last_output_surface_id_
= output_surface_id
;
931 if (host_
->is_hidden())
934 ack_callbacks_
.push(ack_callback
);
937 void RenderWidgetHostViewAndroid::AttachLayers() {
938 if (!content_view_core_
)
943 content_view_core_
->AttachLayer(layer_
);
944 if (overscroll_effect_enabled_
)
945 overscroll_effect_
->Enable();
948 void RenderWidgetHostViewAndroid::RemoveLayers() {
949 if (!content_view_core_
)
954 content_view_core_
->RemoveLayer(layer_
);
955 overscroll_effect_
->Disable();
958 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time
) {
959 return overscroll_effect_
->Animate(frame_time
);
962 void RenderWidgetHostViewAndroid::UpdateAnimationSize(
963 const cc::CompositorFrameMetadata
& frame_metadata
) {
964 // Disable edge effects for axes on which scrolling is impossible.
965 gfx::SizeF ceiled_viewport_size
=
966 gfx::ToCeiledSize(frame_metadata
.viewport_size
);
967 overscroll_effect_
->set_horizontal_overscroll_enabled(
968 ceiled_viewport_size
.width() < frame_metadata
.root_layer_size
.width());
969 overscroll_effect_
->set_vertical_overscroll_enabled(
970 ceiled_viewport_size
.height() < frame_metadata
.root_layer_size
.height());
971 overscroll_effect_
->set_size(content_size_in_layer_
);
974 void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
975 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params
& params
,
980 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() {
984 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
988 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
989 if (texture_id_in_layer_
) {
990 texture_layer_
->SetTextureId(0);
991 texture_layer_
->SetIsDrawable(false);
992 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
993 texture_id_in_layer_
);
994 texture_id_in_layer_
= 0;
995 current_mailbox_
= gpu::Mailbox();
996 last_output_surface_id_
= kUndefinedOutputSurfaceId
;
998 if (delegated_renderer_layer_
.get())
999 DestroyDelegatedContent();
1000 frame_evictor_
->DiscardedFrame();
1003 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
1004 const gfx::Size
& desired_size
) {
1009 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo
* result
) {
1010 // ScreenInfo isn't tied to the widget on Android. Always return the default.
1011 RenderWidgetHostViewBase::GetDefaultScreenInfo(result
);
1014 // TODO(jrg): Find out the implications and answer correctly here,
1015 // as we are returning the WebView and not root window bounds.
1016 gfx::Rect
RenderWidgetHostViewAndroid::GetBoundsInRootWindow() {
1017 return GetViewBounds();
1020 gfx::GLSurfaceHandle
RenderWidgetHostViewAndroid::GetCompositingSurface() {
1021 gfx::GLSurfaceHandle handle
=
1022 gfx::GLSurfaceHandle(gfx::kNullPluginWindow
, gfx::NATIVE_TRANSPORT
);
1023 if (CompositorImpl::IsInitialized()) {
1024 handle
.parent_client_id
=
1025 ImageTransportFactoryAndroid::GetInstance()->GetChannelID();
1030 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
1031 const TouchEventWithLatencyInfo
& touch
, InputEventAckState ack_result
) {
1032 if (content_view_core_
)
1033 content_view_core_
->ConfirmTouchEvent(ack_result
);
1036 void RenderWidgetHostViewAndroid::SetHasHorizontalScrollbar(
1037 bool has_horizontal_scrollbar
) {
1038 // intentionally empty, like RenderWidgetHostViewViews
1041 void RenderWidgetHostViewAndroid::SetScrollOffsetPinning(
1042 bool is_pinned_to_left
, bool is_pinned_to_right
) {
1043 // intentionally empty, like RenderWidgetHostViewViews
1046 void RenderWidgetHostViewAndroid::UnhandledWheelEvent(
1047 const blink::WebMouseWheelEvent
& event
) {
1048 // intentionally empty, like RenderWidgetHostViewViews
1051 void RenderWidgetHostViewAndroid::GestureEventAck(
1052 int gesture_event_type
,
1053 InputEventAckState ack_result
) {
1054 if (gesture_event_type
== blink::WebInputEvent::GestureScrollUpdate
&&
1055 ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
) {
1056 content_view_core_
->OnScrollUpdateGestureConsumed();
1058 if (gesture_event_type
== blink::WebInputEvent::GestureFlingStart
&&
1059 ack_result
== INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS
) {
1060 content_view_core_
->UnhandledFlingStartEvent();
1064 InputEventAckState
RenderWidgetHostViewAndroid::FilterInputEvent(
1065 const blink::WebInputEvent
& input_event
) {
1067 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED
;
1069 if (input_event
.type
== blink::WebInputEvent::GestureTapDown
||
1070 input_event
.type
== blink::WebInputEvent::TouchStart
) {
1071 GpuDataManagerImpl
* gpu_data
= GpuDataManagerImpl::GetInstance();
1072 GpuProcessHostUIShim
* shim
= GpuProcessHostUIShim::GetOneInstance();
1073 if (shim
&& gpu_data
&& accelerated_surface_route_id_
&&
1074 gpu_data
->IsDriverBugWorkaroundActive(gpu::WAKE_UP_GPU_BEFORE_DRAWING
))
1076 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_
));
1079 SynchronousCompositorImpl
* compositor
=
1080 SynchronousCompositorImpl::FromID(host_
->GetProcess()->GetID(),
1081 host_
->GetRoutingID());
1083 return compositor
->HandleInputEvent(input_event
);
1084 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED
;
1087 void RenderWidgetHostViewAndroid::OnSetNeedsFlushInput() {
1088 if (flush_input_requested_
|| !content_view_core_
)
1090 flush_input_requested_
= true;
1091 content_view_core_
->AddBeginFrameSubscriber();
1094 void RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManagerIfNeeded() {
1095 if (!host_
|| host_
->accessibility_mode() != AccessibilityModeComplete
)
1098 if (!GetBrowserAccessibilityManager()) {
1099 base::android::ScopedJavaLocalRef
<jobject
> obj
;
1100 if (content_view_core_
)
1101 obj
= content_view_core_
->GetJavaObject();
1102 SetBrowserAccessibilityManager(
1103 new BrowserAccessibilityManagerAndroid(
1104 obj
, BrowserAccessibilityManagerAndroid::GetEmptyDocument(), this));
1108 void RenderWidgetHostViewAndroid::SetAccessibilityFocus(int acc_obj_id
) {
1112 host_
->AccessibilitySetFocus(acc_obj_id
);
1115 void RenderWidgetHostViewAndroid::AccessibilityDoDefaultAction(int acc_obj_id
) {
1119 host_
->AccessibilityDoDefaultAction(acc_obj_id
);
1122 void RenderWidgetHostViewAndroid::AccessibilityScrollToMakeVisible(
1123 int acc_obj_id
, gfx::Rect subfocus
) {
1127 host_
->AccessibilityScrollToMakeVisible(acc_obj_id
, subfocus
);
1130 void RenderWidgetHostViewAndroid::AccessibilityScrollToPoint(
1131 int acc_obj_id
, gfx::Point point
) {
1135 host_
->AccessibilityScrollToPoint(acc_obj_id
, point
);
1138 void RenderWidgetHostViewAndroid::AccessibilitySetTextSelection(
1139 int acc_obj_id
, int start_offset
, int end_offset
) {
1143 host_
->AccessibilitySetTextSelection(
1144 acc_obj_id
, start_offset
, end_offset
);
1147 gfx::Point
RenderWidgetHostViewAndroid::GetLastTouchEventLocation() const {
1149 // Only used on Win8
1150 return gfx::Point();
1153 void RenderWidgetHostViewAndroid::FatalAccessibilityTreeError() {
1157 host_
->FatalAccessibilityTreeError();
1158 SetBrowserAccessibilityManager(NULL
);
1161 bool RenderWidgetHostViewAndroid::LockMouse() {
1166 void RenderWidgetHostViewAndroid::UnlockMouse() {
1170 // Methods called from the host to the render
1172 void RenderWidgetHostViewAndroid::SendKeyEvent(
1173 const NativeWebKeyboardEvent
& event
) {
1175 host_
->ForwardKeyboardEvent(event
);
1178 void RenderWidgetHostViewAndroid::SendTouchEvent(
1179 const blink::WebTouchEvent
& event
) {
1181 host_
->ForwardTouchEventWithLatencyInfo(event
, ui::LatencyInfo());
1185 void RenderWidgetHostViewAndroid::SendMouseEvent(
1186 const blink::WebMouseEvent
& event
) {
1188 host_
->ForwardMouseEvent(event
);
1191 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
1192 const blink::WebMouseWheelEvent
& event
) {
1194 host_
->ForwardWheelEvent(event
);
1197 void RenderWidgetHostViewAndroid::SendGestureEvent(
1198 const blink::WebGestureEvent
& event
) {
1199 // Sending a gesture that may trigger overscroll should resume the effect.
1200 if (overscroll_effect_enabled_
)
1201 overscroll_effect_
->Enable();
1204 host_
->ForwardGestureEvent(event
);
1207 void RenderWidgetHostViewAndroid::SelectRange(const gfx::Point
& start
,
1208 const gfx::Point
& end
) {
1210 host_
->SelectRange(start
, end
);
1213 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point
& point
) {
1215 host_
->MoveCaret(point
);
1218 void RenderWidgetHostViewAndroid::RequestContentClipping(
1219 const gfx::Rect
& clipping
,
1220 const gfx::Size
& content_size
) {
1221 // A focused view provides its own clipping.
1225 ClipContents(clipping
, content_size
);
1228 void RenderWidgetHostViewAndroid::ResetClipping() {
1229 ClipContents(gfx::Rect(gfx::Point(), content_size_in_layer_
),
1230 content_size_in_layer_
);
1233 void RenderWidgetHostViewAndroid::ClipContents(const gfx::Rect
& clipping
,
1234 const gfx::Size
& content_size
) {
1235 if (!texture_id_in_layer_
|| content_size_in_layer_
.IsEmpty())
1238 gfx::Size
clipped_content(content_size_in_layer_
);
1239 clipped_content
.SetToMin(clipping
.size());
1240 texture_layer_
->SetBounds(clipped_content
);
1241 texture_layer_
->SetNeedsDisplay();
1243 if (texture_size_in_layer_
.IsEmpty()) {
1244 texture_layer_
->SetUV(gfx::PointF(), gfx::PointF());
1249 clipping
.x() + content_size_in_layer_
.width() - content_size
.width(),
1250 clipping
.y() + content_size_in_layer_
.height() - content_size
.height());
1251 offset
.SetToMax(gfx::PointF());
1253 gfx::Vector2dF
uv_scale(1.f
/ texture_size_in_layer_
.width(),
1254 1.f
/ texture_size_in_layer_
.height());
1255 texture_layer_
->SetUV(
1256 gfx::PointF(offset
.x() * uv_scale
.x(),
1257 offset
.y() * uv_scale
.y()),
1258 gfx::PointF((offset
.x() + clipped_content
.width()) * uv_scale
.x(),
1259 (offset
.y() + clipped_content
.height()) * uv_scale
.y()));
1262 SkColor
RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
1263 return cached_background_color_
;
1266 void RenderWidgetHostViewAndroid::OnOverscrolled(
1267 gfx::Vector2dF accumulated_overscroll
,
1268 gfx::Vector2dF current_fling_velocity
) {
1269 if (!content_view_core_
|| !are_layers_attached_
)
1272 if (overscroll_effect_
->OnOverscrolled(content_view_core_
->GetLayer(),
1273 base::TimeTicks::Now(),
1274 accumulated_overscroll
,
1275 current_fling_velocity
)) {
1276 content_view_core_
->SetNeedsAnimate();
1280 void RenderWidgetHostViewAndroid::SetContentViewCore(
1281 ContentViewCoreImpl
* content_view_core
) {
1284 if (are_layers_attached_
)
1287 if (content_view_core_
&& !using_synchronous_compositor_
)
1288 content_view_core_
->GetWindowAndroid()->RemoveObserver(this);
1290 content_view_core_
= content_view_core
;
1292 if (GetBrowserAccessibilityManager()) {
1293 base::android::ScopedJavaLocalRef
<jobject
> obj
;
1294 if (content_view_core_
)
1295 obj
= content_view_core_
->GetJavaObject();
1296 GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerAndroid()->
1297 SetContentViewCore(obj
);
1300 if (are_layers_attached_
) {
1302 if (content_view_core_
&& !using_synchronous_compositor_
)
1303 content_view_core_
->GetWindowAndroid()->AddObserver(this);
1307 void RenderWidgetHostViewAndroid::RunAckCallbacks() {
1308 while (!ack_callbacks_
.empty()) {
1309 ack_callbacks_
.front().Run();
1310 ack_callbacks_
.pop();
1314 void RenderWidgetHostViewAndroid::HasTouchEventHandlers(
1315 bool need_touch_events
) {
1316 if (content_view_core_
)
1317 content_view_core_
->HasTouchEventHandlers(need_touch_events
);
1320 void RenderWidgetHostViewAndroid::OnCompositingDidCommit() {
1324 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
1325 DCHECK(content_view_core_
);
1326 DCHECK(!using_synchronous_compositor_
);
1330 void RenderWidgetHostViewAndroid::OnLostResources() {
1331 if (texture_layer_
.get())
1332 texture_layer_
->SetIsDrawable(false);
1333 if (delegated_renderer_layer_
.get())
1334 DestroyDelegatedContent();
1335 texture_id_in_layer_
= 0;
1340 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
1341 const gfx::Size
& dst_size_in_pixel
,
1342 const base::Callback
<void(bool, const SkBitmap
&)>& callback
,
1343 scoped_ptr
<cc::CopyOutputResult
> result
) {
1344 DCHECK(result
->HasTexture());
1345 base::ScopedClosureRunner
scoped_callback_runner(
1346 base::Bind(callback
, false, SkBitmap()));
1348 if (!result
->HasTexture() || result
->IsEmpty() || result
->size().IsEmpty())
1351 scoped_ptr
<SkBitmap
> bitmap(new SkBitmap
);
1352 bitmap
->setConfig(SkBitmap::kARGB_8888_Config
,
1353 dst_size_in_pixel
.width(), dst_size_in_pixel
.height(),
1354 0, kOpaque_SkAlphaType
);
1355 if (!bitmap
->allocPixels())
1358 ImageTransportFactoryAndroid
* factory
=
1359 ImageTransportFactoryAndroid::GetInstance();
1360 GLHelper
* gl_helper
= factory
->GetGLHelper();
1364 scoped_ptr
<SkAutoLockPixels
> bitmap_pixels_lock(
1365 new SkAutoLockPixels(*bitmap
));
1366 uint8
* pixels
= static_cast<uint8
*>(bitmap
->getPixels());
1368 cc::TextureMailbox texture_mailbox
;
1369 scoped_ptr
<cc::SingleReleaseCallback
> release_callback
;
1370 result
->TakeTexture(&texture_mailbox
, &release_callback
);
1371 DCHECK(texture_mailbox
.IsTexture());
1372 if (!texture_mailbox
.IsTexture())
1375 ignore_result(scoped_callback_runner
.Release());
1377 gl_helper
->CropScaleReadbackAndCleanMailbox(
1378 texture_mailbox
.name(),
1379 texture_mailbox
.sync_point(),
1381 gfx::Rect(result
->size()),
1384 base::Bind(&CopyFromCompositingSurfaceFinished
,
1386 base::Passed(&release_callback
),
1387 base::Passed(&bitmap
),
1388 base::Passed(&bitmap_pixels_lock
)));
1392 void RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult(
1393 const gfx::Size
& dst_size_in_pixel
,
1394 const base::Callback
<void(bool, const SkBitmap
&)>& callback
,
1395 scoped_ptr
<cc::CopyOutputResult
> result
) {
1396 DCHECK(result
->HasBitmap());
1397 base::ScopedClosureRunner
scoped_callback_runner(
1398 base::Bind(callback
, false, SkBitmap()));
1400 if (!result
->HasBitmap() || result
->IsEmpty() || result
->size().IsEmpty())
1403 scoped_ptr
<SkBitmap
> source
= result
->TakeBitmap();
1408 DCHECK_EQ(source
->width(), dst_size_in_pixel
.width());
1409 DCHECK_EQ(source
->height(), dst_size_in_pixel
.height());
1411 ignore_result(scoped_callback_runner
.Release());
1412 callback
.Run(true, *source
);
1416 void RenderWidgetHostViewPort::GetDefaultScreenInfo(
1417 blink::WebScreenInfo
* results
) {
1418 const gfx::Display
& display
=
1419 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
1420 results
->rect
= display
.bounds();
1421 // TODO(husky): Remove any system controls from availableRect.
1422 results
->availableRect
= display
.work_area();
1423 results
->deviceScaleFactor
= display
.device_scale_factor();
1424 gfx::DeviceDisplayInfo info
;
1425 results
->depth
= info
.GetBitsPerPixel();
1426 results
->depthPerComponent
= info
.GetBitsPerComponent();
1427 results
->isMonochrome
= (results
->depthPerComponent
== 0);
1430 ////////////////////////////////////////////////////////////////////////////////
1431 // RenderWidgetHostView, public:
1434 RenderWidgetHostView
*
1435 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost
* widget
) {
1436 RenderWidgetHostImpl
* rwhi
= RenderWidgetHostImpl::From(widget
);
1437 return new RenderWidgetHostViewAndroid(rwhi
, NULL
);
1440 } // namespace content