Ignore non-active fullscreen windows for shelf state.
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_host_view_android.cc
blob171bacf9b494b6f4397377283a68be1a016dbb04
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_widget_host_impl.h"
41 #include "content/common/gpu/client/gl_helper.h"
42 #include "content/common/gpu/gpu_messages.h"
43 #include "content/common/input_messages.h"
44 #include "content/common/view_messages.h"
45 #include "content/public/browser/devtools_agent_host.h"
46 #include "content/public/browser/render_view_host.h"
47 #include "content/public/common/content_switches.h"
48 #include "gpu/config/gpu_driver_bug_workaround_type.h"
49 #include "skia/ext/image_operations.h"
50 #include "third_party/khronos/GLES2/gl2.h"
51 #include "third_party/khronos/GLES2/gl2ext.h"
52 #include "third_party/skia/include/core/SkCanvas.h"
53 #include "ui/base/android/window_android.h"
54 #include "ui/gfx/android/device_display_info.h"
55 #include "ui/gfx/android/java_bitmap.h"
56 #include "ui/gfx/display.h"
57 #include "ui/gfx/screen.h"
58 #include "ui/gfx/size_conversions.h"
60 namespace content {
62 namespace {
64 const int kUndefinedOutputSurfaceId = -1;
66 void InsertSyncPointAndAckForCompositor(
67 int renderer_host_id,
68 uint32 output_surface_id,
69 int route_id,
70 const gpu::Mailbox& return_mailbox,
71 const gfx::Size return_size) {
72 cc::CompositorFrameAck ack;
73 ack.gl_frame_data.reset(new cc::GLFrameData());
74 if (!return_mailbox.IsZero()) {
75 ack.gl_frame_data->mailbox = return_mailbox;
76 ack.gl_frame_data->size = return_size;
77 ack.gl_frame_data->sync_point =
78 ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint();
80 RenderWidgetHostImpl::SendSwapCompositorFrameAck(
81 route_id, output_surface_id, renderer_host_id, ack);
84 // Sends an acknowledgement to the renderer of a processed IME event.
85 void SendImeEventAck(RenderWidgetHostImpl* host) {
86 host->Send(new ViewMsg_ImeEventAck(host->GetRoutingID()));
89 void CopyFromCompositingSurfaceFinished(
90 const base::Callback<void(bool, const SkBitmap&)>& callback,
91 scoped_ptr<cc::SingleReleaseCallback> release_callback,
92 scoped_ptr<SkBitmap> bitmap,
93 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
94 bool result) {
95 bitmap_pixels_lock.reset();
96 release_callback->Run(0, false);
97 callback.Run(result, *bitmap);
100 bool UsingDelegatedRenderer() {
101 return CommandLine::ForCurrentProcess()->HasSwitch(
102 switches::kEnableDelegatedRenderer);
105 } // anonymous namespace
107 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
108 RenderWidgetHostImpl* widget_host,
109 ContentViewCoreImpl* content_view_core)
110 : host_(widget_host),
111 needs_begin_frame_(false),
112 are_layers_attached_(true),
113 content_view_core_(NULL),
114 ime_adapter_android_(this),
115 cached_background_color_(SK_ColorWHITE),
116 texture_id_in_layer_(0),
117 last_output_surface_id_(kUndefinedOutputSurfaceId),
118 weak_ptr_factory_(this),
119 overscroll_effect_enabled_(
120 !CommandLine::ForCurrentProcess()->
121 HasSwitch(switches::kDisableOverscrollEdgeEffect)),
122 overscroll_effect_(OverscrollGlow::Create(overscroll_effect_enabled_)),
123 flush_input_requested_(false),
124 accelerated_surface_route_id_(0),
125 using_synchronous_compositor_(SynchronousCompositorImpl::FromID(
126 widget_host->GetProcess()->GetID(),
127 widget_host->GetRoutingID()) != NULL) {
128 if (!UsingDelegatedRenderer()) {
129 texture_layer_ = cc::TextureLayer::Create(NULL);
130 layer_ = texture_layer_;
133 host_->SetView(this);
134 SetContentViewCore(content_view_core);
135 ImageTransportFactoryAndroid::AddObserver(this);
138 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
139 ImageTransportFactoryAndroid::RemoveObserver(this);
140 SetContentViewCore(NULL);
141 DCHECK(ack_callbacks_.empty());
142 if (texture_id_in_layer_) {
143 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
144 texture_id_in_layer_);
147 if (texture_layer_.get())
148 texture_layer_->ClearClient();
150 if (resource_collection_.get())
151 resource_collection_->SetClient(NULL);
155 bool RenderWidgetHostViewAndroid::OnMessageReceived(
156 const IPC::Message& message) {
157 bool handled = true;
158 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
159 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
160 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor,
161 OnDidChangeBodyBackgroundColor)
162 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame,
163 OnSetNeedsBeginFrame)
164 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
165 OnTextInputStateChanged)
166 IPC_MESSAGE_UNHANDLED(handled = false)
167 IPC_END_MESSAGE_MAP()
168 return handled;
171 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
172 NOTIMPLEMENTED();
175 void RenderWidgetHostViewAndroid::InitAsPopup(
176 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
177 NOTIMPLEMENTED();
180 void RenderWidgetHostViewAndroid::InitAsFullscreen(
181 RenderWidgetHostView* reference_host_view) {
182 NOTIMPLEMENTED();
185 RenderWidgetHost*
186 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
187 return host_;
190 void RenderWidgetHostViewAndroid::WasShown() {
191 if (!host_ || !host_->is_hidden())
192 return;
194 host_->WasShown();
196 if (content_view_core_ && !using_synchronous_compositor_)
197 content_view_core_->GetWindowAndroid()->AddObserver(this);
200 void RenderWidgetHostViewAndroid::WasHidden() {
201 RunAckCallbacks();
203 if (!host_ || host_->is_hidden())
204 return;
206 // Inform the renderer that we are being hidden so it can reduce its resource
207 // utilization.
208 host_->WasHidden();
210 if (content_view_core_ && !using_synchronous_compositor_)
211 content_view_core_->GetWindowAndroid()->RemoveObserver(this);
214 void RenderWidgetHostViewAndroid::WasResized() {
215 host_->WasResized();
218 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) {
219 // Ignore the given size as only the Java code has the power to
220 // resize the view on Android.
221 default_size_ = size;
222 WasResized();
225 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
226 SetSize(rect.size());
229 blink::WebGLId RenderWidgetHostViewAndroid::GetScaledContentTexture(
230 float scale,
231 gfx::Size* out_size) {
232 gfx::Size size(gfx::ToCeiledSize(
233 gfx::ScaleSize(texture_size_in_layer_, scale)));
235 if (!CompositorImpl::IsInitialized() ||
236 texture_id_in_layer_ == 0 ||
237 texture_size_in_layer_.IsEmpty() ||
238 size.IsEmpty()) {
239 if (out_size)
240 out_size->SetSize(0, 0);
242 return 0;
245 if (out_size)
246 *out_size = size;
248 GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
249 return helper->CopyAndScaleTexture(texture_id_in_layer_,
250 texture_size_in_layer_,
251 size,
252 true,
253 GLHelper::SCALER_QUALITY_FAST);
256 bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(jobject jbitmap) {
257 if (!CompositorImpl::IsInitialized() ||
258 texture_id_in_layer_ == 0 ||
259 texture_size_in_layer_.IsEmpty())
260 return false;
262 gfx::JavaBitmap bitmap(jbitmap);
264 // TODO(dtrainor): Eventually add support for multiple formats here.
265 DCHECK(bitmap.format() == ANDROID_BITMAP_FORMAT_RGBA_8888);
267 GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
269 blink::WebGLId texture = helper->CopyAndScaleTexture(
270 texture_id_in_layer_,
271 texture_size_in_layer_,
272 bitmap.size(),
273 true,
274 GLHelper::SCALER_QUALITY_FAST);
275 if (texture == 0)
276 return false;
278 helper->ReadbackTextureSync(texture,
279 gfx::Rect(bitmap.size()),
280 static_cast<unsigned char*> (bitmap.pixels()));
282 blink::WebGraphicsContext3D* context =
283 ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
284 context->deleteTexture(texture);
286 return true;
289 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
290 if (!content_view_core_)
291 return false;
292 if (texture_size_in_layer_.IsEmpty())
293 return false;
295 if (UsingDelegatedRenderer()) {
296 if (!delegated_renderer_layer_.get())
297 return false;
298 } else {
299 if (texture_id_in_layer_ == 0)
300 return false;
303 return true;
306 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
307 return content_view_core_->GetViewAndroid();
310 gfx::NativeViewId RenderWidgetHostViewAndroid::GetNativeViewId() const {
311 return reinterpret_cast<gfx::NativeViewId>(
312 const_cast<RenderWidgetHostViewAndroid*>(this));
315 gfx::NativeViewAccessible
316 RenderWidgetHostViewAndroid::GetNativeViewAccessible() {
317 NOTIMPLEMENTED();
318 return NULL;
321 void RenderWidgetHostViewAndroid::MovePluginWindows(
322 const gfx::Vector2d& scroll_offset,
323 const std::vector<WebPluginGeometry>& moves) {
324 // We don't have plugin windows on Android. Do nothing. Note: this is called
325 // from RenderWidgetHost::OnUpdateRect which is itself invoked while
326 // processing the corresponding message from Renderer.
329 void RenderWidgetHostViewAndroid::Focus() {
330 host_->Focus();
331 host_->SetInputMethodActive(true);
332 ResetClipping();
333 if (overscroll_effect_enabled_)
334 overscroll_effect_->Enable();
337 void RenderWidgetHostViewAndroid::Blur() {
338 host_->ExecuteEditCommand("Unselect", "");
339 host_->SetInputMethodActive(false);
340 host_->Blur();
341 overscroll_effect_->Disable();
344 bool RenderWidgetHostViewAndroid::HasFocus() const {
345 if (!content_view_core_)
346 return false; // ContentViewCore not created yet.
348 return content_view_core_->HasFocus();
351 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
352 return HasValidFrame();
355 void RenderWidgetHostViewAndroid::Show() {
356 if (are_layers_attached_)
357 return;
359 are_layers_attached_ = true;
360 AttachLayers();
362 WasShown();
365 void RenderWidgetHostViewAndroid::Hide() {
366 if (!are_layers_attached_)
367 return;
369 are_layers_attached_ = false;
370 RemoveLayers();
372 WasHidden();
375 bool RenderWidgetHostViewAndroid::IsShowing() {
376 // ContentViewCoreImpl represents the native side of the Java
377 // ContentViewCore. It being NULL means that it is not attached
378 // to the View system yet, so we treat this RWHVA as hidden.
379 return are_layers_attached_ && content_view_core_;
382 gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const {
383 if (!content_view_core_)
384 return gfx::Rect(default_size_);
386 gfx::Size size = content_view_core_->GetViewportSizeDip();
387 gfx::Size offset = content_view_core_->GetViewportSizeOffsetDip();
388 size.Enlarge(-offset.width(), -offset.height());
390 return gfx::Rect(size);
393 gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
394 if (!content_view_core_)
395 return gfx::Size();
397 return content_view_core_->GetPhysicalBackingSize();
400 float RenderWidgetHostViewAndroid::GetOverdrawBottomHeight() const {
401 if (!content_view_core_)
402 return 0.f;
404 return content_view_core_->GetOverdrawBottomHeightDip();
407 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& cursor) {
408 // There are no cursors on Android.
411 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading) {
412 // Do nothing. The UI notification is handled through ContentViewClient which
413 // is TabContentsDelegate.
416 void RenderWidgetHostViewAndroid::TextInputTypeChanged(
417 ui::TextInputType type,
418 ui::TextInputMode input_mode,
419 bool can_compose_inline) {
420 // Unused on Android, which uses OnTextInputChanged instead.
423 int RenderWidgetHostViewAndroid::GetNativeImeAdapter() {
424 return reinterpret_cast<int>(&ime_adapter_android_);
427 void RenderWidgetHostViewAndroid::OnTextInputStateChanged(
428 const ViewHostMsg_TextInputState_Params& params) {
429 // If an acknowledgement is required for this event, regardless of how we exit
430 // from this method, we must acknowledge that we processed the input state
431 // change.
432 base::ScopedClosureRunner ack_caller;
433 if (params.require_ack)
434 ack_caller.Reset(base::Bind(&SendImeEventAck, host_));
436 if (!IsShowing())
437 return;
439 content_view_core_->UpdateImeAdapter(
440 GetNativeImeAdapter(),
441 static_cast<int>(params.type),
442 params.value, params.selection_start, params.selection_end,
443 params.composition_start, params.composition_end,
444 params.show_ime_if_needed, params.require_ack);
447 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor(
448 SkColor color) {
449 if (cached_background_color_ == color)
450 return;
452 cached_background_color_ = color;
453 if (content_view_core_)
454 content_view_core_->OnBackgroundColorChanged(color);
457 void RenderWidgetHostViewAndroid::SendBeginFrame(
458 const cc::BeginFrameArgs& args) {
459 TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::SendBeginFrame");
460 if (!host_)
461 return;
463 if (flush_input_requested_) {
464 flush_input_requested_ = false;
465 host_->FlushInput();
466 content_view_core_->RemoveBeginFrameSubscriber();
469 host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), args));
472 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame(
473 bool enabled) {
474 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame",
475 "enabled", enabled);
476 // ContentViewCoreImpl handles multiple subscribers to the BeginFrame, so
477 // we have to make sure calls to ContentViewCoreImpl's
478 // {Add,Remove}BeginFrameSubscriber are balanced, even if
479 // RenderWidgetHostViewAndroid's may not be.
480 if (content_view_core_ && needs_begin_frame_ != enabled) {
481 if (enabled)
482 content_view_core_->AddBeginFrameSubscriber();
483 else
484 content_view_core_->RemoveBeginFrameSubscriber();
485 needs_begin_frame_ = enabled;
489 void RenderWidgetHostViewAndroid::OnStartContentIntent(
490 const GURL& content_url) {
491 if (content_view_core_)
492 content_view_core_->StartContentIntent(content_url);
495 void RenderWidgetHostViewAndroid::ImeCancelComposition() {
496 ime_adapter_android_.CancelComposition();
499 void RenderWidgetHostViewAndroid::DidUpdateBackingStore(
500 const gfx::Rect& scroll_rect,
501 const gfx::Vector2d& scroll_delta,
502 const std::vector<gfx::Rect>& copy_rects,
503 const ui::LatencyInfo& latency_info) {
504 NOTIMPLEMENTED();
507 void RenderWidgetHostViewAndroid::RenderProcessGone(
508 base::TerminationStatus status, int error_code) {
509 Destroy();
512 void RenderWidgetHostViewAndroid::Destroy() {
513 RemoveLayers();
514 SetContentViewCore(NULL);
516 // The RenderWidgetHost's destruction led here, so don't call it.
517 host_ = NULL;
519 delete this;
522 void RenderWidgetHostViewAndroid::SetTooltipText(
523 const base::string16& tooltip_text) {
524 // Tooltips don't makes sense on Android.
527 void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16& text,
528 size_t offset,
529 const gfx::Range& range) {
530 RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
532 if (text.empty() || range.is_empty() || !content_view_core_)
533 return;
534 size_t pos = range.GetMin() - offset;
535 size_t n = range.length();
537 DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
538 if (pos >= text.length()) {
539 NOTREACHED() << "The text can not cover range.";
540 return;
543 std::string utf8_selection = UTF16ToUTF8(text.substr(pos, n));
545 content_view_core_->OnSelectionChanged(utf8_selection);
548 void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
549 const ViewHostMsg_SelectionBounds_Params& params) {
550 if (content_view_core_) {
551 content_view_core_->OnSelectionBoundsChanged(params);
555 void RenderWidgetHostViewAndroid::ScrollOffsetChanged() {
558 BackingStore* RenderWidgetHostViewAndroid::AllocBackingStore(
559 const gfx::Size& size) {
560 NOTIMPLEMENTED();
561 return NULL;
564 void RenderWidgetHostViewAndroid::SetBackground(const SkBitmap& background) {
565 RenderWidgetHostViewBase::SetBackground(background);
566 host_->Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background));
569 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
570 const gfx::Rect& src_subrect,
571 const gfx::Size& dst_size,
572 const base::Callback<void(bool, const SkBitmap&)>& callback) {
573 if (!using_synchronous_compositor_ && !IsSurfaceAvailableForCopy()) {
574 callback.Run(false, SkBitmap());
575 return;
578 const gfx::Display& display =
579 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
580 float device_scale_factor = display.device_scale_factor();
582 DCHECK_EQ(device_scale_factor,
583 ui::GetImageScale(GetScaleFactorForView(this)));
585 const gfx::Size& dst_size_in_pixel = ConvertViewSizeToPixel(this, dst_size);
586 gfx::Rect src_subrect_in_pixel =
587 ConvertRectToPixel(device_scale_factor, src_subrect);
589 if (using_synchronous_compositor_) {
590 SynchronousCopyContents(src_subrect_in_pixel, dst_size_in_pixel, callback);
591 return;
594 scoped_ptr<cc::CopyOutputRequest> request;
595 if (src_subrect_in_pixel.size() == dst_size_in_pixel) {
596 request = cc::CopyOutputRequest::CreateBitmapRequest(base::Bind(
597 &RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult,
598 dst_size_in_pixel,
599 callback));
600 } else {
601 request = cc::CopyOutputRequest::CreateRequest(base::Bind(
602 &RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult,
603 dst_size_in_pixel,
604 callback));
606 request->set_area(src_subrect_in_pixel);
607 layer_->RequestCopyOfOutput(request.Pass());
610 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
611 const gfx::Rect& src_subrect,
612 const scoped_refptr<media::VideoFrame>& target,
613 const base::Callback<void(bool)>& callback) {
614 NOTIMPLEMENTED();
615 callback.Run(false);
618 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
619 return false;
622 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
623 const gfx::Rect& target_rect, const SkBitmap& zoomed_bitmap) {
624 if (!content_view_core_)
625 return;
627 content_view_core_->ShowDisambiguationPopup(target_rect, zoomed_bitmap);
630 scoped_ptr<SyntheticGestureTarget>
631 RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
632 return scoped_ptr<SyntheticGestureTarget>(new SyntheticGestureTargetAndroid(
633 host_, content_view_core_->CreateTouchEventSynthesizer()));
636 void RenderWidgetHostViewAndroid::OnAcceleratedCompositingStateChange() {
639 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
640 uint32 output_surface_id) {
641 cc::CompositorFrameAck ack;
642 if (resource_collection_.get())
643 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
644 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_->GetRoutingID(),
645 output_surface_id,
646 host_->GetProcess()->GetID(),
647 ack);
650 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
651 // TODO(danakj): If no ack is pending, collect and send resources now.
654 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
655 if (are_layers_attached_)
656 RemoveLayers();
657 frame_provider_ = NULL;
658 delegated_renderer_layer_ = NULL;
659 layer_ = NULL;
662 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
663 uint32 output_surface_id,
664 scoped_ptr<cc::DelegatedFrameData> frame_data) {
665 bool has_content = !texture_size_in_layer_.IsEmpty();
667 if (output_surface_id != last_output_surface_id_) {
668 // TODO(danakj): Lose all resources and send them back here, such as:
669 // resource_collection_->LoseAllResources();
670 // SendReturnedDelegatedResources(last_output_surface_id_);
672 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
673 // any resources from the old output surface with the new output surface id.
674 if (resource_collection_.get()) {
675 resource_collection_->SetClient(NULL);
676 resource_collection_ = NULL;
678 DestroyDelegatedContent();
680 last_output_surface_id_ = output_surface_id;
683 if (!has_content) {
684 DestroyDelegatedContent();
685 } else {
686 if (!resource_collection_.get()) {
687 resource_collection_ = new cc::DelegatedFrameResourceCollection;
688 resource_collection_->SetClient(this);
690 if (!frame_provider_ ||
691 texture_size_in_layer_ != frame_provider_->frame_size()) {
692 if (are_layers_attached_)
693 RemoveLayers();
694 frame_provider_ = new cc::DelegatedFrameProvider(
695 resource_collection_.get(), frame_data.Pass());
696 delegated_renderer_layer_ =
697 cc::DelegatedRendererLayer::Create(frame_provider_);
698 layer_ = delegated_renderer_layer_;
699 if (are_layers_attached_)
700 AttachLayers();
701 } else {
702 frame_provider_->SetFrameData(frame_data.Pass());
706 if (delegated_renderer_layer_.get()) {
707 delegated_renderer_layer_->SetDisplaySize(texture_size_in_layer_);
708 delegated_renderer_layer_->SetIsDrawable(true);
709 delegated_renderer_layer_->SetContentsOpaque(true);
710 delegated_renderer_layer_->SetBounds(content_size_in_layer_);
711 delegated_renderer_layer_->SetNeedsDisplay();
714 base::Closure ack_callback =
715 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
716 weak_ptr_factory_.GetWeakPtr(),
717 output_surface_id);
719 if (host_->is_hidden())
720 ack_callback.Run();
721 else
722 ack_callbacks_.push(ack_callback);
725 void RenderWidgetHostViewAndroid::ComputeContentsSize(
726 const cc::CompositorFrameMetadata& frame_metadata) {
727 // Calculate the content size. This should be 0 if the texture_size is 0.
728 gfx::Vector2dF offset;
729 if (texture_size_in_layer_.GetArea() > 0)
730 offset = frame_metadata.location_bar_content_translation;
731 offset.set_y(offset.y() + frame_metadata.overdraw_bottom_height);
732 offset.Scale(frame_metadata.device_scale_factor);
733 content_size_in_layer_ =
734 gfx::Size(texture_size_in_layer_.width() - offset.x(),
735 texture_size_in_layer_.height() - offset.y());
736 // Content size changes should be reflected in associated animation effects.
737 UpdateAnimationSize(frame_metadata);
740 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
741 uint32 output_surface_id,
742 scoped_ptr<cc::CompositorFrame> frame) {
743 // Always let ContentViewCore know about the new frame first, so it can decide
744 // to schedule a Draw immediately when it sees the texture layer invalidation.
745 UpdateContentViewCoreFrameMetadata(frame->metadata);
747 if (frame->delegated_frame_data) {
748 DCHECK(UsingDelegatedRenderer());
750 DCHECK(frame->delegated_frame_data);
751 DCHECK(!frame->delegated_frame_data->render_pass_list.empty());
753 cc::RenderPass* root_pass =
754 frame->delegated_frame_data->render_pass_list.back();
755 texture_size_in_layer_ = root_pass->output_rect.size();
756 ComputeContentsSize(frame->metadata);
758 SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass());
759 return;
762 DCHECK(!UsingDelegatedRenderer());
764 if (!frame->gl_frame_data || frame->gl_frame_data->mailbox.IsZero())
765 return;
767 if (output_surface_id != last_output_surface_id_) {
768 current_mailbox_ = gpu::Mailbox();
769 last_output_surface_id_ = kUndefinedOutputSurfaceId;
772 base::Closure callback = base::Bind(&InsertSyncPointAndAckForCompositor,
773 host_->GetProcess()->GetID(),
774 output_surface_id,
775 host_->GetRoutingID(),
776 current_mailbox_,
777 texture_size_in_layer_);
778 ImageTransportFactoryAndroid::GetInstance()->WaitSyncPoint(
779 frame->gl_frame_data->sync_point);
781 texture_size_in_layer_ = frame->gl_frame_data->size;
782 ComputeContentsSize(frame->metadata);
784 if (layer_->layer_tree_host()) {
785 scoped_ptr<cc::SwapPromise> swap_promise(
786 new cc::LatencyInfoSwapPromise(frame->metadata.latency_info));
787 layer_->layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
790 BuffersSwapped(frame->gl_frame_data->mailbox, output_surface_id, callback);
793 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
794 const cc::CompositorFrameMetadata& frame_metadata) {
795 // This is a subset of OnSwapCompositorFrame() used in the synchronous
796 // compositor flow.
797 UpdateContentViewCoreFrameMetadata(frame_metadata);
798 ComputeContentsSize(frame_metadata);
800 // DevTools ScreenCast support for Android WebView.
801 if (DevToolsAgentHost::HasFor(RenderViewHost::From(GetRenderWidgetHost()))) {
802 scoped_refptr<DevToolsAgentHost> dtah =
803 DevToolsAgentHost::GetOrCreateFor(
804 RenderViewHost::From(GetRenderWidgetHost()));
805 // Unblock the compositor.
806 BrowserThread::PostTask(
807 BrowserThread::UI, FROM_HERE,
808 base::Bind(&RenderViewDevToolsAgentHost::SynchronousSwapCompositorFrame,
809 static_cast<RenderViewDevToolsAgentHost*>(dtah.get()),
810 frame_metadata));
814 void RenderWidgetHostViewAndroid::SynchronousCopyContents(
815 const gfx::Rect& src_subrect_in_pixel,
816 const gfx::Size& dst_size_in_pixel,
817 const base::Callback<void(bool, const SkBitmap&)>& callback) {
818 SynchronousCompositor* compositor =
819 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
820 host_->GetRoutingID());
821 if (!compositor) {
822 callback.Run(false, SkBitmap());
823 return;
826 SkBitmap bitmap;
827 bitmap.setConfig(SkBitmap::kARGB_8888_Config,
828 dst_size_in_pixel.width(),
829 dst_size_in_pixel.height());
830 bitmap.allocPixels();
831 SkCanvas canvas(bitmap);
832 canvas.scale(
833 (float)dst_size_in_pixel.width() / (float)src_subrect_in_pixel.width(),
834 (float)dst_size_in_pixel.height() / (float)src_subrect_in_pixel.height());
835 compositor->DemandDrawSw(&canvas);
836 callback.Run(true, bitmap);
839 void RenderWidgetHostViewAndroid::UpdateContentViewCoreFrameMetadata(
840 const cc::CompositorFrameMetadata& frame_metadata) {
841 if (content_view_core_) {
842 // All offsets and sizes are in CSS pixels.
843 content_view_core_->UpdateFrameInfo(
844 frame_metadata.root_scroll_offset,
845 frame_metadata.page_scale_factor,
846 gfx::Vector2dF(frame_metadata.min_page_scale_factor,
847 frame_metadata.max_page_scale_factor),
848 frame_metadata.root_layer_size,
849 frame_metadata.viewport_size,
850 frame_metadata.location_bar_offset,
851 frame_metadata.location_bar_content_translation,
852 frame_metadata.overdraw_bottom_height);
856 void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int host_id,
857 int route_id) {
858 accelerated_surface_route_id_ = route_id;
861 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
862 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
863 int gpu_host_id) {
864 NOTREACHED() << "Need --composite-to-mailbox or --enable-delegated-renderer";
867 void RenderWidgetHostViewAndroid::BuffersSwapped(
868 const gpu::Mailbox& mailbox,
869 uint32_t output_surface_id,
870 const base::Closure& ack_callback) {
871 ImageTransportFactoryAndroid* factory =
872 ImageTransportFactoryAndroid::GetInstance();
874 if (!texture_id_in_layer_) {
875 texture_id_in_layer_ = factory->CreateTexture();
876 texture_layer_->SetTextureId(texture_id_in_layer_);
877 texture_layer_->SetIsDrawable(true);
878 texture_layer_->SetContentsOpaque(true);
881 ImageTransportFactoryAndroid::GetInstance()->AcquireTexture(
882 texture_id_in_layer_, mailbox.name);
884 ResetClipping();
886 current_mailbox_ = mailbox;
887 last_output_surface_id_ = output_surface_id;
889 if (host_->is_hidden())
890 ack_callback.Run();
891 else
892 ack_callbacks_.push(ack_callback);
895 void RenderWidgetHostViewAndroid::AttachLayers() {
896 if (!content_view_core_)
897 return;
898 if (!layer_.get())
899 return;
901 content_view_core_->AttachLayer(layer_);
902 if (overscroll_effect_enabled_)
903 overscroll_effect_->Enable();
906 void RenderWidgetHostViewAndroid::RemoveLayers() {
907 if (!content_view_core_)
908 return;
909 if (!layer_.get())
910 return;
912 content_view_core_->RemoveLayer(layer_);
913 overscroll_effect_->Disable();
916 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) {
917 return overscroll_effect_->Animate(frame_time);
920 void RenderWidgetHostViewAndroid::UpdateAnimationSize(
921 const cc::CompositorFrameMetadata& frame_metadata) {
922 // Disable edge effects for axes on which scrolling is impossible.
923 gfx::SizeF ceiled_viewport_size =
924 gfx::ToCeiledSize(frame_metadata.viewport_size);
925 overscroll_effect_->set_horizontal_overscroll_enabled(
926 ceiled_viewport_size.width() < frame_metadata.root_layer_size.width());
927 overscroll_effect_->set_vertical_overscroll_enabled(
928 ceiled_viewport_size.height() < frame_metadata.root_layer_size.height());
929 overscroll_effect_->set_size(content_size_in_layer_);
932 void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
933 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
934 int gpu_host_id) {
935 NOTREACHED();
938 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() {
939 NOTREACHED();
942 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
943 // This tells us we should free the frontbuffer.
944 if (texture_id_in_layer_) {
945 texture_layer_->SetTextureId(0);
946 texture_layer_->SetIsDrawable(false);
947 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
948 texture_id_in_layer_);
949 texture_id_in_layer_ = 0;
950 current_mailbox_ = gpu::Mailbox();
951 last_output_surface_id_ = kUndefinedOutputSurfaceId;
953 if (delegated_renderer_layer_.get())
954 DestroyDelegatedContent();
957 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
958 const gfx::Size& desired_size) {
959 NOTREACHED();
960 return false;
963 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) {
964 // ScreenInfo isn't tied to the widget on Android. Always return the default.
965 RenderWidgetHostViewBase::GetDefaultScreenInfo(result);
968 // TODO(jrg): Find out the implications and answer correctly here,
969 // as we are returning the WebView and not root window bounds.
970 gfx::Rect RenderWidgetHostViewAndroid::GetBoundsInRootWindow() {
971 return GetViewBounds();
974 gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() {
975 gfx::GLSurfaceHandle handle =
976 gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::NATIVE_TRANSPORT);
977 if (CompositorImpl::IsInitialized()) {
978 handle.parent_client_id =
979 ImageTransportFactoryAndroid::GetInstance()->GetChannelID();
981 return handle;
984 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
985 const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
986 if (content_view_core_)
987 content_view_core_->ConfirmTouchEvent(ack_result);
990 void RenderWidgetHostViewAndroid::SetHasHorizontalScrollbar(
991 bool has_horizontal_scrollbar) {
992 // intentionally empty, like RenderWidgetHostViewViews
995 void RenderWidgetHostViewAndroid::SetScrollOffsetPinning(
996 bool is_pinned_to_left, bool is_pinned_to_right) {
997 // intentionally empty, like RenderWidgetHostViewViews
1000 void RenderWidgetHostViewAndroid::UnhandledWheelEvent(
1001 const blink::WebMouseWheelEvent& event) {
1002 // intentionally empty, like RenderWidgetHostViewViews
1005 void RenderWidgetHostViewAndroid::GestureEventAck(
1006 int gesture_event_type,
1007 InputEventAckState ack_result) {
1008 if (gesture_event_type == blink::WebInputEvent::GestureScrollUpdate &&
1009 ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) {
1010 content_view_core_->OnScrollUpdateGestureConsumed();
1012 if (gesture_event_type == blink::WebInputEvent::GestureFlingStart &&
1013 ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) {
1014 content_view_core_->UnhandledFlingStartEvent();
1018 InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
1019 const blink::WebInputEvent& input_event) {
1020 if (!host_)
1021 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1023 if (input_event.type == blink::WebInputEvent::GestureTapDown ||
1024 input_event.type == blink::WebInputEvent::TouchStart) {
1025 GpuDataManagerImpl* gpu_data = GpuDataManagerImpl::GetInstance();
1026 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
1027 if (shim && gpu_data && accelerated_surface_route_id_ &&
1028 gpu_data->IsDriverBugWorkaroundActive(gpu::WAKE_UP_GPU_BEFORE_DRAWING))
1029 shim->Send(
1030 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_));
1033 SynchronousCompositorImpl* compositor =
1034 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
1035 host_->GetRoutingID());
1036 if (compositor)
1037 return compositor->HandleInputEvent(input_event);
1038 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1041 void RenderWidgetHostViewAndroid::OnSetNeedsFlushInput() {
1042 if (flush_input_requested_ || !content_view_core_)
1043 return;
1044 flush_input_requested_ = true;
1045 content_view_core_->AddBeginFrameSubscriber();
1048 void RenderWidgetHostViewAndroid::OnAccessibilityEvents(
1049 const std::vector<AccessibilityHostMsg_EventParams>& params) {
1050 if (!host_ || host_->accessibility_mode() != AccessibilityModeComplete)
1051 return;
1053 if (!GetBrowserAccessibilityManager()) {
1054 base::android::ScopedJavaLocalRef<jobject> obj;
1055 if (content_view_core_)
1056 obj = content_view_core_->GetJavaObject();
1057 SetBrowserAccessibilityManager(
1058 new BrowserAccessibilityManagerAndroid(
1059 obj, BrowserAccessibilityManagerAndroid::GetEmptyDocument(), this));
1061 GetBrowserAccessibilityManager()->OnAccessibilityEvents(params);
1064 void RenderWidgetHostViewAndroid::SetAccessibilityFocus(int acc_obj_id) {
1065 if (!host_)
1066 return;
1068 host_->AccessibilitySetFocus(acc_obj_id);
1071 void RenderWidgetHostViewAndroid::AccessibilityDoDefaultAction(int acc_obj_id) {
1072 if (!host_)
1073 return;
1075 host_->AccessibilityDoDefaultAction(acc_obj_id);
1078 void RenderWidgetHostViewAndroid::AccessibilityScrollToMakeVisible(
1079 int acc_obj_id, gfx::Rect subfocus) {
1080 if (!host_)
1081 return;
1083 host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus);
1086 void RenderWidgetHostViewAndroid::AccessibilityScrollToPoint(
1087 int acc_obj_id, gfx::Point point) {
1088 if (!host_)
1089 return;
1091 host_->AccessibilityScrollToPoint(acc_obj_id, point);
1094 void RenderWidgetHostViewAndroid::AccessibilitySetTextSelection(
1095 int acc_obj_id, int start_offset, int end_offset) {
1096 if (!host_)
1097 return;
1099 host_->AccessibilitySetTextSelection(
1100 acc_obj_id, start_offset, end_offset);
1103 gfx::Point RenderWidgetHostViewAndroid::GetLastTouchEventLocation() const {
1104 NOTIMPLEMENTED();
1105 // Only used on Win8
1106 return gfx::Point();
1109 void RenderWidgetHostViewAndroid::FatalAccessibilityTreeError() {
1110 if (!host_)
1111 return;
1113 host_->FatalAccessibilityTreeError();
1114 SetBrowserAccessibilityManager(NULL);
1117 bool RenderWidgetHostViewAndroid::LockMouse() {
1118 NOTIMPLEMENTED();
1119 return false;
1122 void RenderWidgetHostViewAndroid::UnlockMouse() {
1123 NOTIMPLEMENTED();
1126 // Methods called from the host to the render
1128 void RenderWidgetHostViewAndroid::SendKeyEvent(
1129 const NativeWebKeyboardEvent& event) {
1130 if (host_)
1131 host_->ForwardKeyboardEvent(event);
1134 void RenderWidgetHostViewAndroid::SendTouchEvent(
1135 const blink::WebTouchEvent& event) {
1136 if (host_)
1137 host_->ForwardTouchEventWithLatencyInfo(event, ui::LatencyInfo());
1141 void RenderWidgetHostViewAndroid::SendMouseEvent(
1142 const blink::WebMouseEvent& event) {
1143 if (host_)
1144 host_->ForwardMouseEvent(event);
1147 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
1148 const blink::WebMouseWheelEvent& event) {
1149 if (host_)
1150 host_->ForwardWheelEvent(event);
1153 void RenderWidgetHostViewAndroid::SendGestureEvent(
1154 const blink::WebGestureEvent& event) {
1155 // Sending a gesture that may trigger overscroll should resume the effect.
1156 if (overscroll_effect_enabled_)
1157 overscroll_effect_->Enable();
1159 if (host_)
1160 host_->ForwardGestureEvent(event);
1163 void RenderWidgetHostViewAndroid::SelectRange(const gfx::Point& start,
1164 const gfx::Point& end) {
1165 if (host_)
1166 host_->SelectRange(start, end);
1169 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) {
1170 if (host_)
1171 host_->MoveCaret(point);
1174 void RenderWidgetHostViewAndroid::RequestContentClipping(
1175 const gfx::Rect& clipping,
1176 const gfx::Size& content_size) {
1177 // A focused view provides its own clipping.
1178 if (HasFocus())
1179 return;
1181 ClipContents(clipping, content_size);
1184 void RenderWidgetHostViewAndroid::ResetClipping() {
1185 ClipContents(gfx::Rect(gfx::Point(), content_size_in_layer_),
1186 content_size_in_layer_);
1189 void RenderWidgetHostViewAndroid::ClipContents(const gfx::Rect& clipping,
1190 const gfx::Size& content_size) {
1191 if (!texture_id_in_layer_ || content_size_in_layer_.IsEmpty())
1192 return;
1194 gfx::Size clipped_content(content_size_in_layer_);
1195 clipped_content.SetToMin(clipping.size());
1196 texture_layer_->SetBounds(clipped_content);
1197 texture_layer_->SetNeedsDisplay();
1199 if (texture_size_in_layer_.IsEmpty()) {
1200 texture_layer_->SetUV(gfx::PointF(), gfx::PointF());
1201 return;
1204 gfx::PointF offset(
1205 clipping.x() + content_size_in_layer_.width() - content_size.width(),
1206 clipping.y() + content_size_in_layer_.height() - content_size.height());
1207 offset.SetToMax(gfx::PointF());
1209 gfx::Vector2dF uv_scale(1.f / texture_size_in_layer_.width(),
1210 1.f / texture_size_in_layer_.height());
1211 texture_layer_->SetUV(
1212 gfx::PointF(offset.x() * uv_scale.x(),
1213 offset.y() * uv_scale.y()),
1214 gfx::PointF((offset.x() + clipped_content.width()) * uv_scale.x(),
1215 (offset.y() + clipped_content.height()) * uv_scale.y()));
1218 SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
1219 return cached_background_color_;
1222 void RenderWidgetHostViewAndroid::OnOverscrolled(
1223 gfx::Vector2dF accumulated_overscroll,
1224 gfx::Vector2dF current_fling_velocity) {
1225 if (!content_view_core_ || !are_layers_attached_)
1226 return;
1228 if (overscroll_effect_->OnOverscrolled(content_view_core_->GetLayer(),
1229 base::TimeTicks::Now(),
1230 accumulated_overscroll,
1231 current_fling_velocity)) {
1232 content_view_core_->SetNeedsAnimate();
1236 void RenderWidgetHostViewAndroid::SetContentViewCore(
1237 ContentViewCoreImpl* content_view_core) {
1238 RunAckCallbacks();
1240 if (are_layers_attached_)
1241 RemoveLayers();
1243 if (content_view_core_ && !using_synchronous_compositor_)
1244 content_view_core_->GetWindowAndroid()->RemoveObserver(this);
1246 content_view_core_ = content_view_core;
1248 if (GetBrowserAccessibilityManager()) {
1249 base::android::ScopedJavaLocalRef<jobject> obj;
1250 if (content_view_core_)
1251 obj = content_view_core_->GetJavaObject();
1252 GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerAndroid()->
1253 SetContentViewCore(obj);
1256 if (are_layers_attached_) {
1257 AttachLayers();
1258 if (content_view_core_ && !using_synchronous_compositor_)
1259 content_view_core_->GetWindowAndroid()->AddObserver(this);
1263 void RenderWidgetHostViewAndroid::RunAckCallbacks() {
1264 while (!ack_callbacks_.empty()) {
1265 ack_callbacks_.front().Run();
1266 ack_callbacks_.pop();
1270 void RenderWidgetHostViewAndroid::HasTouchEventHandlers(
1271 bool need_touch_events) {
1272 if (content_view_core_)
1273 content_view_core_->HasTouchEventHandlers(need_touch_events);
1276 void RenderWidgetHostViewAndroid::OnCompositingDidCommit() {
1277 RunAckCallbacks();
1280 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
1281 DCHECK(content_view_core_);
1282 DCHECK(!using_synchronous_compositor_);
1283 RunAckCallbacks();
1286 void RenderWidgetHostViewAndroid::OnLostResources() {
1287 if (texture_layer_.get())
1288 texture_layer_->SetIsDrawable(false);
1289 if (delegated_renderer_layer_.get())
1290 DestroyDelegatedContent();
1291 texture_id_in_layer_ = 0;
1292 RunAckCallbacks();
1295 // static
1296 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
1297 const gfx::Size& dst_size_in_pixel,
1298 const base::Callback<void(bool, const SkBitmap&)>& callback,
1299 scoped_ptr<cc::CopyOutputResult> result) {
1300 DCHECK(result->HasTexture());
1301 base::ScopedClosureRunner scoped_callback_runner(
1302 base::Bind(callback, false, SkBitmap()));
1304 if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty())
1305 return;
1307 scoped_ptr<SkBitmap> bitmap(new SkBitmap);
1308 bitmap->setConfig(SkBitmap::kARGB_8888_Config,
1309 dst_size_in_pixel.width(), dst_size_in_pixel.height(),
1310 0, kOpaque_SkAlphaType);
1311 if (!bitmap->allocPixels())
1312 return;
1314 ImageTransportFactoryAndroid* factory =
1315 ImageTransportFactoryAndroid::GetInstance();
1316 GLHelper* gl_helper = factory->GetGLHelper();
1317 if (!gl_helper)
1318 return;
1320 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
1321 new SkAutoLockPixels(*bitmap));
1322 uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
1324 cc::TextureMailbox texture_mailbox;
1325 scoped_ptr<cc::SingleReleaseCallback> release_callback;
1326 result->TakeTexture(&texture_mailbox, &release_callback);
1327 DCHECK(texture_mailbox.IsTexture());
1328 if (!texture_mailbox.IsTexture())
1329 return;
1331 ignore_result(scoped_callback_runner.Release());
1333 gl_helper->CropScaleReadbackAndCleanMailbox(
1334 texture_mailbox.name(),
1335 texture_mailbox.sync_point(),
1336 result->size(),
1337 gfx::Rect(result->size()),
1338 dst_size_in_pixel,
1339 pixels,
1340 base::Bind(&CopyFromCompositingSurfaceFinished,
1341 callback,
1342 base::Passed(&release_callback),
1343 base::Passed(&bitmap),
1344 base::Passed(&bitmap_pixels_lock)));
1347 // static
1348 void RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult(
1349 const gfx::Size& dst_size_in_pixel,
1350 const base::Callback<void(bool, const SkBitmap&)>& callback,
1351 scoped_ptr<cc::CopyOutputResult> result) {
1352 DCHECK(result->HasBitmap());
1353 base::ScopedClosureRunner scoped_callback_runner(
1354 base::Bind(callback, false, SkBitmap()));
1356 if (!result->HasBitmap() || result->IsEmpty() || result->size().IsEmpty())
1357 return;
1359 scoped_ptr<SkBitmap> source = result->TakeBitmap();
1360 DCHECK(source);
1361 if (!source)
1362 return;
1364 DCHECK_EQ(source->width(), dst_size_in_pixel.width());
1365 DCHECK_EQ(source->height(), dst_size_in_pixel.height());
1367 ignore_result(scoped_callback_runner.Release());
1368 callback.Run(true, *source);
1371 // static
1372 void RenderWidgetHostViewPort::GetDefaultScreenInfo(
1373 blink::WebScreenInfo* results) {
1374 const gfx::Display& display =
1375 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
1376 results->rect = display.bounds();
1377 // TODO(husky): Remove any system controls from availableRect.
1378 results->availableRect = display.work_area();
1379 results->deviceScaleFactor = display.device_scale_factor();
1380 gfx::DeviceDisplayInfo info;
1381 results->depth = info.GetBitsPerPixel();
1382 results->depthPerComponent = info.GetBitsPerComponent();
1383 results->isMonochrome = (results->depthPerComponent == 0);
1386 ////////////////////////////////////////////////////////////////////////////////
1387 // RenderWidgetHostView, public:
1389 // static
1390 RenderWidgetHostView*
1391 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost* widget) {
1392 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget);
1393 return new RenderWidgetHostViewAndroid(rwhi, NULL);
1396 } // namespace content