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. 4 5 #include "content/browser/renderer_host/render_widget_host_view_android.h" 6 7 #include <android/bitmap.h> 8 9 #include "base/bind.h" 10 #include "base/bind_helpers.h" 11 #include "base/command_line.h" 12 #include "base/logging.h" 13 #include "base/message_loop/message_loop.h" 14 #include "base/strings/utf_string_conversions.h" 15 #include "base/threading/worker_pool.h" 16 #include "cc/layers/delegated_renderer_layer.h" 17 #include "cc/layers/layer.h" 18 #include "cc/layers/texture_layer.h" 19 #include "cc/output/compositor_frame.h" 20 #include "cc/output/compositor_frame_ack.h" 21 #include "cc/output/copy_output_request.h" 22 #include "cc/output/copy_output_result.h" 23 #include "cc/trees/layer_tree_host.h" 24 #include "content/browser/accessibility/browser_accessibility_manager_android.h" 25 #include "content/browser/android/content_view_core_impl.h" 26 #include "content/browser/android/in_process/synchronous_compositor_impl.h" 27 #include "content/browser/android/overscroll_glow.h" 28 #include "content/browser/gpu/gpu_surface_tracker.h" 29 #include "content/browser/renderer_host/compositor_impl_android.h" 30 #include "content/browser/renderer_host/dip_util.h" 31 #include "content/browser/renderer_host/image_transport_factory_android.h" 32 #include "content/browser/renderer_host/render_widget_host_impl.h" 33 #include "content/browser/renderer_host/surface_texture_transport_client_android.h" 34 #include "content/browser/renderer_host/touch_smooth_scroll_gesture_android.h" 35 #include "content/common/gpu/client/gl_helper.h" 36 #include "content/common/gpu/gpu_messages.h" 37 #include "content/common/input_messages.h" 38 #include "content/common/view_messages.h" 39 #include "content/public/common/content_switches.h" 40 #include "skia/ext/image_operations.h" 41 #include "third_party/khronos/GLES2/gl2.h" 42 #include "third_party/khronos/GLES2/gl2ext.h" 43 #include "ui/gfx/android/device_display_info.h" 44 #include "ui/gfx/android/java_bitmap.h" 45 #include "ui/gfx/display.h" 46 #include "ui/gfx/screen.h" 47 #include "ui/gfx/size_conversions.h" 48 49 namespace content { 50 51 namespace { 52 53 const int kUndefinedOutputSurfaceId = -1; 54 55 void InsertSyncPointAndAckForGpu( 56 int gpu_host_id, int route_id, const std::string& return_mailbox) { 57 uint32 sync_point = 58 ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint(); 59 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; 60 ack_params.mailbox_name = return_mailbox; 61 ack_params.sync_point = sync_point; 62 RenderWidgetHostImpl::AcknowledgeBufferPresent( 63 route_id, gpu_host_id, ack_params); 64 } 65 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(); 79 } 80 RenderWidgetHostImpl::SendSwapCompositorFrameAck( 81 route_id, output_surface_id, renderer_host_id, ack); 82 } 83 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())); 87 } 88 89 void CopyFromCompositingSurfaceFinished( 90 const base::Callback<void(bool, const SkBitmap&)>& callback, 91 const cc::TextureMailbox::ReleaseCallback& 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); 98 } 99 100 } // anonymous namespace 101 102 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid( 103 RenderWidgetHostImpl* widget_host, 104 ContentViewCoreImpl* content_view_core) 105 : host_(widget_host), 106 needs_begin_frame_(false), 107 are_layers_attached_(true), 108 content_view_core_(NULL), 109 ime_adapter_android_(this), 110 cached_background_color_(SK_ColorWHITE), 111 texture_id_in_layer_(0), 112 current_mailbox_output_surface_id_(kUndefinedOutputSurfaceId), 113 weak_ptr_factory_(this), 114 overscroll_effect_enabled_(true) { 115 if (CompositorImpl::UsesDirectGL()) { 116 surface_texture_transport_.reset(new SurfaceTextureTransportClient()); 117 layer_ = surface_texture_transport_->Initialize(); 118 layer_->SetIsDrawable(true); 119 } else { 120 if (CommandLine::ForCurrentProcess()->HasSwitch( 121 switches::kEnableDelegatedRenderer)) { 122 delegated_renderer_layer_ = cc::DelegatedRendererLayer::Create(this); 123 layer_ = delegated_renderer_layer_; 124 } else { 125 texture_layer_ = cc::TextureLayer::Create(this); 126 layer_ = texture_layer_; 127 } 128 } 129 130 layer_->SetContentsOpaque(true); 131 132 overscroll_effect_enabled_ = !CommandLine::ForCurrentProcess()-> 133 HasSwitch(switches::kDisableOverscrollEdgeEffect); 134 // Don't block the main thread with effect resource loading. 135 // Actual effect creation is deferred until an overscroll event is received. 136 if (overscroll_effect_enabled_) { 137 base::WorkerPool::PostTask(FROM_HERE, 138 base::Bind(&OverscrollGlow::EnsureResources), 139 true); 140 } 141 142 host_->SetView(this); 143 SetContentViewCore(content_view_core); 144 ImageTransportFactoryAndroid::AddObserver(this); 145 } 146 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_); 154 } 155 156 if (texture_layer_.get()) 157 texture_layer_->ClearClient(); 158 } 159 160 161 bool RenderWidgetHostViewAndroid::OnMessageReceived( 162 const IPC::Message& message) { 163 bool handled = true; 164 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message) 165 IPC_MESSAGE_HANDLER(ViewHostMsg_ImeBatchStateChanged_ACK, 166 OnProcessImeBatchStateAck) 167 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent) 168 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor, 169 OnDidChangeBodyBackgroundColor) 170 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame, 171 OnSetNeedsBeginFrame) 172 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged, 173 OnTextInputStateChanged) 174 IPC_MESSAGE_UNHANDLED(handled = false) 175 IPC_END_MESSAGE_MAP() 176 return handled; 177 } 178 179 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) { 180 NOTIMPLEMENTED(); 181 } 182 183 void RenderWidgetHostViewAndroid::InitAsPopup( 184 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) { 185 NOTIMPLEMENTED(); 186 } 187 188 void RenderWidgetHostViewAndroid::InitAsFullscreen( 189 RenderWidgetHostView* reference_host_view) { 190 NOTIMPLEMENTED(); 191 } 192 193 RenderWidgetHost* 194 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const { 195 return host_; 196 } 197 198 void RenderWidgetHostViewAndroid::WasShown() { 199 if (!host_->is_hidden()) 200 return; 201 202 host_->WasShown(); 203 } 204 205 void RenderWidgetHostViewAndroid::WasHidden() { 206 RunAckCallbacks(); 207 208 if (host_->is_hidden()) 209 return; 210 211 // Inform the renderer that we are being hidden so it can reduce its resource 212 // utilization. 213 host_->WasHidden(); 214 } 215 216 void RenderWidgetHostViewAndroid::WasResized() { 217 if (surface_texture_transport_.get() && content_view_core_) 218 surface_texture_transport_->SetSize( 219 content_view_core_->GetPhysicalBackingSize()); 220 221 host_->WasResized(); 222 } 223 224 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) { 225 // Ignore the given size as only the Java code has the power to 226 // resize the view on Android. 227 WasResized(); 228 } 229 230 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) { 231 SetSize(rect.size()); 232 } 233 234 WebKit::WebGLId RenderWidgetHostViewAndroid::GetScaledContentTexture( 235 float scale, 236 gfx::Size* out_size) { 237 gfx::Size size(gfx::ToCeiledSize( 238 gfx::ScaleSize(texture_size_in_layer_, scale))); 239 240 if (!CompositorImpl::IsInitialized() || 241 texture_id_in_layer_ == 0 || 242 texture_size_in_layer_.IsEmpty() || 243 size.IsEmpty()) { 244 if (out_size) 245 out_size->SetSize(0, 0); 246 247 return 0; 248 } 249 250 if (out_size) 251 *out_size = size; 252 253 GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper(); 254 return helper->CopyAndScaleTexture(texture_id_in_layer_, 255 texture_size_in_layer_, 256 size, 257 true, 258 GLHelper::SCALER_QUALITY_FAST); 259 } 260 261 bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(jobject jbitmap) { 262 if (!CompositorImpl::IsInitialized() || 263 texture_id_in_layer_ == 0 || 264 texture_size_in_layer_.IsEmpty()) 265 return false; 266 267 gfx::JavaBitmap bitmap(jbitmap); 268 269 // TODO(dtrainor): Eventually add support for multiple formats here. 270 DCHECK(bitmap.format() == ANDROID_BITMAP_FORMAT_RGBA_8888); 271 272 GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper(); 273 274 WebKit::WebGLId texture = helper->CopyAndScaleTexture( 275 texture_id_in_layer_, 276 texture_size_in_layer_, 277 bitmap.size(), 278 true, 279 GLHelper::SCALER_QUALITY_FAST); 280 if (texture == 0) 281 return false; 282 283 helper->ReadbackTextureSync(texture, 284 gfx::Rect(bitmap.size()), 285 static_cast<unsigned char*> (bitmap.pixels())); 286 287 WebKit::WebGraphicsContext3D* context = 288 ImageTransportFactoryAndroid::GetInstance()->GetContext3D(); 289 context->deleteTexture(texture); 290 291 return true; 292 } 293 294 bool RenderWidgetHostViewAndroid::HasValidFrame() const { 295 return texture_id_in_layer_ != 0 && 296 content_view_core_ && 297 !texture_size_in_layer_.IsEmpty(); 298 } 299 300 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const { 301 return content_view_core_->GetViewAndroid(); 302 } 303 304 gfx::NativeViewId RenderWidgetHostViewAndroid::GetNativeViewId() const { 305 return reinterpret_cast<gfx::NativeViewId>( 306 const_cast<RenderWidgetHostViewAndroid*>(this)); 307 } 308 309 gfx::NativeViewAccessible 310 RenderWidgetHostViewAndroid::GetNativeViewAccessible() { 311 NOTIMPLEMENTED(); 312 return NULL; 313 } 314 315 void RenderWidgetHostViewAndroid::MovePluginWindows( 316 const gfx::Vector2d& scroll_offset, 317 const std::vector<WebPluginGeometry>& moves) { 318 // We don't have plugin windows on Android. Do nothing. Note: this is called 319 // from RenderWidgetHost::OnUpdateRect which is itself invoked while 320 // processing the corresponding message from Renderer. 321 } 322 323 void RenderWidgetHostViewAndroid::Focus() { 324 host_->Focus(); 325 host_->SetInputMethodActive(true); 326 ResetClipping(); 327 if (overscroll_effect_) 328 overscroll_effect_->SetEnabled(true); 329 } 330 331 void RenderWidgetHostViewAndroid::Blur() { 332 host_->ExecuteEditCommand("Unselect", ""); 333 host_->SetInputMethodActive(false); 334 host_->Blur(); 335 if (overscroll_effect_) 336 overscroll_effect_->SetEnabled(false); 337 } 338 339 bool RenderWidgetHostViewAndroid::HasFocus() const { 340 if (!content_view_core_) 341 return false; // ContentViewCore not created yet. 342 343 return content_view_core_->HasFocus(); 344 } 345 346 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const { 347 return HasValidFrame(); 348 } 349 350 void RenderWidgetHostViewAndroid::Show() { 351 if (are_layers_attached_) 352 return; 353 354 are_layers_attached_ = true; 355 AttachLayers(); 356 } 357 358 void RenderWidgetHostViewAndroid::Hide() { 359 if (!are_layers_attached_) 360 return; 361 362 are_layers_attached_ = false; 363 RemoveLayers(); 364 } 365 366 bool RenderWidgetHostViewAndroid::IsShowing() { 367 // ContentViewCoreImpl represents the native side of the Java 368 // ContentViewCore. It being NULL means that it is not attached 369 // to the View system yet, so we treat this RWHVA as hidden. 370 return are_layers_attached_ && content_view_core_; 371 } 372 373 gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const { 374 if (!content_view_core_) 375 return gfx::Rect(); 376 377 gfx::Size size = content_view_core_->GetViewportSizeDip(); 378 gfx::Size offset = content_view_core_->GetViewportSizeOffsetDip(); 379 size.Enlarge(-offset.width(), -offset.height()); 380 381 return gfx::Rect(size); 382 } 383 384 gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const { 385 if (!content_view_core_) 386 return gfx::Size(); 387 388 return content_view_core_->GetPhysicalBackingSize(); 389 } 390 391 float RenderWidgetHostViewAndroid::GetOverdrawBottomHeight() const { 392 if (!content_view_core_) 393 return 0.f; 394 395 return content_view_core_->GetOverdrawBottomHeightDip(); 396 } 397 398 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& cursor) { 399 // There are no cursors on Android. 400 } 401 402 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading) { 403 // Do nothing. The UI notification is handled through ContentViewClient which 404 // is TabContentsDelegate. 405 } 406 407 void RenderWidgetHostViewAndroid::TextInputTypeChanged( 408 ui::TextInputType type, 409 bool can_compose_inline, 410 ui::TextInputMode input_mode) { 411 // Unused on Android, which uses OnTextInputChanged instead. 412 } 413 414 int RenderWidgetHostViewAndroid::GetNativeImeAdapter() { 415 return reinterpret_cast<int>(&ime_adapter_android_); 416 } 417 418 void RenderWidgetHostViewAndroid::OnTextInputStateChanged( 419 const ViewHostMsg_TextInputState_Params& params) { 420 // If an acknowledgement is required for this event, regardless of how we exit 421 // from this method, we must acknowledge that we processed the input state 422 // change. 423 base::ScopedClosureRunner ack_caller(base::Bind(&SendImeEventAck, host_)); 424 if (!params.require_ack) 425 ack_caller.Release(); 426 427 if (!IsShowing()) 428 return; 429 430 content_view_core_->UpdateImeAdapter( 431 GetNativeImeAdapter(), 432 static_cast<int>(params.type), 433 params.value, params.selection_start, params.selection_end, 434 params.composition_start, params.composition_end, 435 params.show_ime_if_needed); 436 } 437 438 void RenderWidgetHostViewAndroid::OnProcessImeBatchStateAck(bool is_begin) { 439 if (content_view_core_) 440 content_view_core_->ProcessImeBatchStateAck(is_begin); 441 } 442 443 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor( 444 SkColor color) { 445 if (cached_background_color_ == color) 446 return; 447 448 cached_background_color_ = color; 449 if (content_view_core_) 450 content_view_core_->OnBackgroundColorChanged(color); 451 } 452 453 void RenderWidgetHostViewAndroid::SendBeginFrame( 454 const cc::BeginFrameArgs& args) { 455 TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::SendBeginFrame"); 456 if (host_) 457 host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), args)); 458 } 459 460 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame( 461 bool enabled) { 462 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame", 463 "enabled", enabled); 464 // ContentViewCoreImpl handles multiple subscribers to the BeginFrame, so 465 // we have to make sure calls to ContentViewCoreImpl's SetNeedsBeginFrame 466 // are balanced, even if RenderWidgetHostViewAndroid's may not be. 467 if (content_view_core_ && needs_begin_frame_ != enabled) { 468 content_view_core_->SetNeedsBeginFrame(enabled); 469 needs_begin_frame_ = enabled; 470 } 471 } 472 473 void RenderWidgetHostViewAndroid::OnStartContentIntent( 474 const GURL& content_url) { 475 if (content_view_core_) 476 content_view_core_->StartContentIntent(content_url); 477 } 478 479 void RenderWidgetHostViewAndroid::ImeCancelComposition() { 480 ime_adapter_android_.CancelComposition(); 481 } 482 483 void RenderWidgetHostViewAndroid::DidUpdateBackingStore( 484 const gfx::Rect& scroll_rect, 485 const gfx::Vector2d& scroll_delta, 486 const std::vector<gfx::Rect>& copy_rects, 487 const ui::LatencyInfo& latency_info) { 488 NOTIMPLEMENTED(); 489 } 490 491 void RenderWidgetHostViewAndroid::RenderProcessGone( 492 base::TerminationStatus status, int error_code) { 493 Destroy(); 494 } 495 496 void RenderWidgetHostViewAndroid::Destroy() { 497 RemoveLayers(); 498 content_view_core_ = NULL; 499 500 // The RenderWidgetHost's destruction led here, so don't call it. 501 host_ = NULL; 502 503 delete this; 504 } 505 506 void RenderWidgetHostViewAndroid::SetTooltipText( 507 const string16& tooltip_text) { 508 // Tooltips don't makes sense on Android. 509 } 510 511 void RenderWidgetHostViewAndroid::SelectionChanged(const string16& text, 512 size_t offset, 513 const ui::Range& range) { 514 RenderWidgetHostViewBase::SelectionChanged(text, offset, range); 515 516 if (text.empty() || range.is_empty() || !content_view_core_) 517 return; 518 size_t pos = range.GetMin() - offset; 519 size_t n = range.length(); 520 521 DCHECK(pos + n <= text.length()) << "The text can not fully cover range."; 522 if (pos >= text.length()) { 523 NOTREACHED() << "The text can not cover range."; 524 return; 525 } 526 527 std::string utf8_selection = UTF16ToUTF8(text.substr(pos, n)); 528 529 content_view_core_->OnSelectionChanged(utf8_selection); 530 } 531 532 void RenderWidgetHostViewAndroid::SelectionBoundsChanged( 533 const ViewHostMsg_SelectionBounds_Params& params) { 534 if (content_view_core_) { 535 content_view_core_->OnSelectionBoundsChanged(params); 536 } 537 } 538 539 void RenderWidgetHostViewAndroid::ScrollOffsetChanged() { 540 } 541 542 BackingStore* RenderWidgetHostViewAndroid::AllocBackingStore( 543 const gfx::Size& size) { 544 NOTIMPLEMENTED(); 545 return NULL; 546 } 547 548 void RenderWidgetHostViewAndroid::SetBackground(const SkBitmap& background) { 549 RenderWidgetHostViewBase::SetBackground(background); 550 host_->Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background)); 551 } 552 553 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface( 554 const gfx::Rect& src_subrect, 555 const gfx::Size& dst_size, 556 const base::Callback<void(bool, const SkBitmap&)>& callback) { 557 if (!IsSurfaceAvailableForCopy()) { 558 callback.Run(false, SkBitmap()); 559 return; 560 } 561 562 const gfx::Display& display = 563 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); 564 float device_scale_factor = display.device_scale_factor(); 565 566 DCHECK_EQ(device_scale_factor, 567 ui::GetScaleFactorScale(GetScaleFactorForView(this))); 568 569 const gfx::Size& dst_size_in_pixel = ConvertViewSizeToPixel(this, dst_size); 570 gfx::Rect src_subrect_in_pixel = 571 ConvertRectToPixel(device_scale_factor, src_subrect); 572 573 scoped_ptr<cc::CopyOutputRequest> request; 574 if (src_subrect_in_pixel.size() == dst_size_in_pixel) { 575 request = cc::CopyOutputRequest::CreateBitmapRequest(base::Bind( 576 &RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult, 577 dst_size_in_pixel, 578 callback)); 579 } else { 580 request = cc::CopyOutputRequest::CreateRequest(base::Bind( 581 &RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult, 582 dst_size_in_pixel, 583 callback)); 584 } 585 request->set_area(src_subrect_in_pixel); 586 layer_->RequestCopyOfOutput(request.Pass()); 587 } 588 589 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame( 590 const gfx::Rect& src_subrect, 591 const scoped_refptr<media::VideoFrame>& target, 592 const base::Callback<void(bool)>& callback) { 593 NOTIMPLEMENTED(); 594 callback.Run(false); 595 } 596 597 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const { 598 return false; 599 } 600 601 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup( 602 const gfx::Rect& target_rect, const SkBitmap& zoomed_bitmap) { 603 if (!content_view_core_) 604 return; 605 606 content_view_core_->ShowDisambiguationPopup(target_rect, zoomed_bitmap); 607 } 608 609 SmoothScrollGesture* RenderWidgetHostViewAndroid::CreateSmoothScrollGesture( 610 bool scroll_down, int pixels_to_scroll, int mouse_event_x, 611 int mouse_event_y) { 612 return new TouchSmoothScrollGestureAndroid( 613 pixels_to_scroll, 614 GetRenderWidgetHost(), 615 content_view_core_->CreateSmoothScroller( 616 scroll_down, mouse_event_x, mouse_event_y)); 617 } 618 619 void RenderWidgetHostViewAndroid::OnAcceleratedCompositingStateChange() { 620 } 621 622 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck( 623 uint32 output_surface_id) { 624 cc::CompositorFrameAck ack; 625 delegated_renderer_layer_->TakeUnusedResourcesForChildCompositor( 626 &ack.resources); 627 RenderWidgetHostImpl::SendSwapCompositorFrameAck( 628 host_->GetRoutingID(), output_surface_id, 629 host_->GetProcess()->GetID(), ack); 630 } 631 632 void RenderWidgetHostViewAndroid::SwapDelegatedFrame( 633 uint32 output_surface_id, 634 scoped_ptr<cc::DelegatedFrameData> frame_data) { 635 bool has_frame = frame_data.get() && !frame_data->render_pass_list.empty(); 636 637 if (has_frame) { 638 delegated_renderer_layer_->SetFrameData(frame_data.Pass()); 639 delegated_renderer_layer_->SetDisplaySize(texture_size_in_layer_); 640 layer_->SetIsDrawable(true); 641 } 642 layer_->SetBounds(content_size_in_layer_); 643 layer_->SetNeedsDisplay(); 644 645 base::Closure ack_callback = 646 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck, 647 weak_ptr_factory_.GetWeakPtr(), 648 output_surface_id); 649 650 if (host_->is_hidden()) 651 ack_callback.Run(); 652 else 653 ack_callbacks_.push(ack_callback); 654 } 655 656 void RenderWidgetHostViewAndroid::ComputeContentsSize( 657 const cc::CompositorFrameMetadata& frame_metadata) { 658 // Calculate the content size. This should be 0 if the texture_size is 0. 659 gfx::Vector2dF offset; 660 if (texture_size_in_layer_.GetArea() > 0) 661 offset = frame_metadata.location_bar_content_translation; 662 offset.set_y(offset.y() + frame_metadata.overdraw_bottom_height); 663 offset.Scale(frame_metadata.device_scale_factor); 664 content_size_in_layer_ = 665 gfx::Size(texture_size_in_layer_.width() - offset.x(), 666 texture_size_in_layer_.height() - offset.y()); 667 // Content size changes should be reflected in associated animation effects. 668 UpdateAnimationSize(frame_metadata); 669 } 670 671 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame( 672 uint32 output_surface_id, 673 scoped_ptr<cc::CompositorFrame> frame) { 674 // Always let ContentViewCore know about the new frame first, so it can decide 675 // to schedule a Draw immediately when it sees the texture layer invalidation. 676 UpdateContentViewCoreFrameMetadata(frame->metadata); 677 678 if (frame->delegated_frame_data) { 679 if (!frame->delegated_frame_data->render_pass_list.empty()) { 680 texture_size_in_layer_ = frame->delegated_frame_data->render_pass_list 681 .back()->output_rect.size(); 682 } 683 ComputeContentsSize(frame->metadata); 684 685 SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass()); 686 return; 687 } 688 689 if (!frame->gl_frame_data || frame->gl_frame_data->mailbox.IsZero()) 690 return; 691 692 if (output_surface_id != current_mailbox_output_surface_id_) { 693 current_mailbox_ = gpu::Mailbox(); 694 current_mailbox_output_surface_id_ = kUndefinedOutputSurfaceId; 695 } 696 697 base::Closure callback = base::Bind(&InsertSyncPointAndAckForCompositor, 698 host_->GetProcess()->GetID(), 699 output_surface_id, 700 host_->GetRoutingID(), 701 current_mailbox_, 702 texture_size_in_layer_); 703 ImageTransportFactoryAndroid::GetInstance()->WaitSyncPoint( 704 frame->gl_frame_data->sync_point); 705 706 texture_size_in_layer_ = frame->gl_frame_data->size; 707 ComputeContentsSize(frame->metadata); 708 709 if (layer_->layer_tree_host()) 710 layer_->layer_tree_host()->SetLatencyInfo(frame->metadata.latency_info); 711 712 BuffersSwapped(frame->gl_frame_data->mailbox, output_surface_id, callback); 713 } 714 715 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata( 716 const cc::CompositorFrameMetadata& frame_metadata) { 717 // This is a subset of OnSwapCompositorFrame() used in the synchronous 718 // compositor flow. 719 UpdateContentViewCoreFrameMetadata(frame_metadata); 720 ComputeContentsSize(frame_metadata); 721 } 722 723 void RenderWidgetHostViewAndroid::UpdateContentViewCoreFrameMetadata( 724 const cc::CompositorFrameMetadata& frame_metadata) { 725 if (content_view_core_) { 726 // All offsets and sizes are in CSS pixels. 727 content_view_core_->UpdateFrameInfo( 728 frame_metadata.root_scroll_offset, 729 frame_metadata.page_scale_factor, 730 gfx::Vector2dF(frame_metadata.min_page_scale_factor, 731 frame_metadata.max_page_scale_factor), 732 frame_metadata.root_layer_size, 733 frame_metadata.viewport_size, 734 frame_metadata.location_bar_offset, 735 frame_metadata.location_bar_content_translation, 736 frame_metadata.overdraw_bottom_height); 737 } 738 } 739 740 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped( 741 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, 742 int gpu_host_id) { 743 NOTREACHED() << "Deprecated. Use --composite-to-mailbox."; 744 745 if (params.mailbox_name.empty()) 746 return; 747 748 std::string return_mailbox; 749 if (!current_mailbox_.IsZero()) { 750 return_mailbox.assign( 751 reinterpret_cast<const char*>(current_mailbox_.name), 752 sizeof(current_mailbox_.name)); 753 } 754 755 base::Closure callback = base::Bind(&InsertSyncPointAndAckForGpu, 756 gpu_host_id, params.route_id, 757 return_mailbox); 758 759 gpu::Mailbox mailbox; 760 std::copy(params.mailbox_name.data(), 761 params.mailbox_name.data() + params.mailbox_name.length(), 762 reinterpret_cast<char*>(mailbox.name)); 763 764 texture_size_in_layer_ = params.size; 765 content_size_in_layer_ = params.size; 766 767 BuffersSwapped(mailbox, kUndefinedOutputSurfaceId, callback); 768 } 769 770 void RenderWidgetHostViewAndroid::BuffersSwapped( 771 const gpu::Mailbox& mailbox, 772 uint32_t output_surface_id, 773 const base::Closure& ack_callback) { 774 ImageTransportFactoryAndroid* factory = 775 ImageTransportFactoryAndroid::GetInstance(); 776 777 // TODO(sievers): When running the impl thread in the browser we 778 // need to delay the ACK until after commit and use more than a single 779 // texture. 780 DCHECK(!CompositorImpl::IsThreadingEnabled()); 781 782 if (!texture_id_in_layer_) { 783 texture_id_in_layer_ = factory->CreateTexture(); 784 texture_layer_->SetIsDrawable(true); 785 } 786 787 ImageTransportFactoryAndroid::GetInstance()->AcquireTexture( 788 texture_id_in_layer_, mailbox.name); 789 790 ResetClipping(); 791 792 current_mailbox_ = mailbox; 793 current_mailbox_output_surface_id_ = output_surface_id; 794 795 if (host_->is_hidden()) 796 ack_callback.Run(); 797 else 798 ack_callbacks_.push(ack_callback); 799 } 800 801 void RenderWidgetHostViewAndroid::AttachLayers() { 802 if (!content_view_core_) 803 return; 804 805 content_view_core_->AttachLayer(layer_); 806 807 if (overscroll_effect_) 808 content_view_core_->AttachLayer(overscroll_effect_->root_layer()); 809 } 810 811 void RenderWidgetHostViewAndroid::RemoveLayers() { 812 if (!content_view_core_) 813 return; 814 815 if (overscroll_effect_) 816 content_view_core_->RemoveLayer(overscroll_effect_->root_layer()); 817 818 content_view_core_->RemoveLayer(layer_); 819 } 820 821 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) { 822 if (!overscroll_effect_) 823 return false; 824 return overscroll_effect_->Animate(frame_time); 825 } 826 827 void RenderWidgetHostViewAndroid::CreateOverscrollEffectIfNecessary() { 828 if (!overscroll_effect_enabled_ || overscroll_effect_) 829 return; 830 831 overscroll_effect_ = OverscrollGlow::Create(true); 832 833 // Prevent future creation attempts on failure. 834 if (!overscroll_effect_) 835 overscroll_effect_enabled_ = false; 836 837 if (overscroll_effect_ && content_view_core_ && are_layers_attached_) 838 content_view_core_->AttachLayer(overscroll_effect_->root_layer()); 839 } 840 841 void RenderWidgetHostViewAndroid::UpdateAnimationSize( 842 const cc::CompositorFrameMetadata& frame_metadata) { 843 if (!overscroll_effect_) 844 return; 845 // Disable edge effects for axes on which scrolling is impossible. 846 gfx::SizeF ceiled_viewport_size = 847 gfx::ToCeiledSize(frame_metadata.viewport_size); 848 overscroll_effect_->set_horizontal_overscroll_enabled( 849 ceiled_viewport_size.width() < frame_metadata.root_layer_size.width()); 850 overscroll_effect_->set_vertical_overscroll_enabled( 851 ceiled_viewport_size.height() < frame_metadata.root_layer_size.height()); 852 overscroll_effect_->set_size(content_size_in_layer_); 853 } 854 855 void RenderWidgetHostViewAndroid::ScheduleAnimationIfNecessary() { 856 if (!content_view_core_) 857 return; 858 if (overscroll_effect_ && overscroll_effect_->NeedsAnimate()) 859 content_view_core_->SetNeedsAnimate(); 860 } 861 862 void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer( 863 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, 864 int gpu_host_id) { 865 NOTREACHED(); 866 } 867 868 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() { 869 NOTREACHED(); 870 } 871 872 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() { 873 // This tells us we should free the frontbuffer. 874 if (texture_id_in_layer_) { 875 texture_layer_->SetTextureId(0); 876 texture_layer_->SetIsDrawable(false); 877 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture( 878 texture_id_in_layer_); 879 texture_id_in_layer_ = 0; 880 current_mailbox_ = gpu::Mailbox(); 881 current_mailbox_output_surface_id_ = kUndefinedOutputSurfaceId; 882 } 883 } 884 885 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface( 886 const gfx::Size& desired_size) { 887 NOTREACHED(); 888 return false; 889 } 890 891 void RenderWidgetHostViewAndroid::GetScreenInfo(WebKit::WebScreenInfo* result) { 892 // ScreenInfo isn't tied to the widget on Android. Always return the default. 893 RenderWidgetHostViewBase::GetDefaultScreenInfo(result); 894 } 895 896 // TODO(jrg): Find out the implications and answer correctly here, 897 // as we are returning the WebView and not root window bounds. 898 gfx::Rect RenderWidgetHostViewAndroid::GetBoundsInRootWindow() { 899 return GetViewBounds(); 900 } 901 902 gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() { 903 if (surface_texture_transport_) { 904 return surface_texture_transport_->GetCompositingSurface( 905 host_->surface_id()); 906 } else { 907 return gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::TEXTURE_TRANSPORT); 908 } 909 } 910 911 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent( 912 const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) { 913 if (content_view_core_) 914 content_view_core_->ConfirmTouchEvent(ack_result); 915 } 916 917 void RenderWidgetHostViewAndroid::SetHasHorizontalScrollbar( 918 bool has_horizontal_scrollbar) { 919 // intentionally empty, like RenderWidgetHostViewViews 920 } 921 922 void RenderWidgetHostViewAndroid::SetScrollOffsetPinning( 923 bool is_pinned_to_left, bool is_pinned_to_right) { 924 // intentionally empty, like RenderWidgetHostViewViews 925 } 926 927 void RenderWidgetHostViewAndroid::UnhandledWheelEvent( 928 const WebKit::WebMouseWheelEvent& event) { 929 // intentionally empty, like RenderWidgetHostViewViews 930 } 931 932 void RenderWidgetHostViewAndroid::GestureEventAck( 933 int gesture_event_type, 934 InputEventAckState ack_result) { 935 if (gesture_event_type == WebKit::WebInputEvent::GestureScrollUpdate && 936 ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) { 937 content_view_core_->OnScrollUpdateGestureConsumed(); 938 } 939 if (gesture_event_type == WebKit::WebInputEvent::GestureFlingStart && 940 ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) { 941 content_view_core_->UnhandledFlingStartEvent(); 942 } 943 } 944 945 InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent( 946 const WebKit::WebInputEvent& input_event) { 947 if (host_) { 948 SynchronousCompositorImpl* compositor = 949 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(), 950 host_->GetRoutingID()); 951 if (compositor) 952 return compositor->HandleInputEvent(input_event); 953 } 954 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED; 955 } 956 957 void RenderWidgetHostViewAndroid::OnAccessibilityNotifications( 958 const std::vector<AccessibilityHostMsg_NotificationParams>& params) { 959 if (!host_ || 960 host_->accessibility_mode() != AccessibilityModeComplete || 961 !content_view_core_) { 962 return; 963 } 964 965 if (!GetBrowserAccessibilityManager()) { 966 SetBrowserAccessibilityManager( 967 new BrowserAccessibilityManagerAndroid( 968 content_view_core_->GetJavaObject(), 969 BrowserAccessibilityManagerAndroid::GetEmptyDocument(), 970 this)); 971 } 972 GetBrowserAccessibilityManager()->OnAccessibilityNotifications(params); 973 } 974 975 void RenderWidgetHostViewAndroid::SetAccessibilityFocus(int acc_obj_id) { 976 if (!host_) 977 return; 978 979 host_->AccessibilitySetFocus(acc_obj_id); 980 } 981 982 void RenderWidgetHostViewAndroid::AccessibilityDoDefaultAction(int acc_obj_id) { 983 if (!host_) 984 return; 985 986 host_->AccessibilityDoDefaultAction(acc_obj_id); 987 } 988 989 void RenderWidgetHostViewAndroid::AccessibilityScrollToMakeVisible( 990 int acc_obj_id, gfx::Rect subfocus) { 991 if (!host_) 992 return; 993 994 host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus); 995 } 996 997 void RenderWidgetHostViewAndroid::AccessibilityScrollToPoint( 998 int acc_obj_id, gfx::Point point) { 999 if (!host_) 1000 return; 1001 1002 host_->AccessibilityScrollToPoint(acc_obj_id, point); 1003 } 1004 1005 void RenderWidgetHostViewAndroid::AccessibilitySetTextSelection( 1006 int acc_obj_id, int start_offset, int end_offset) { 1007 if (!host_) 1008 return; 1009 1010 host_->AccessibilitySetTextSelection( 1011 acc_obj_id, start_offset, end_offset); 1012 } 1013 1014 gfx::Point RenderWidgetHostViewAndroid::GetLastTouchEventLocation() const { 1015 NOTIMPLEMENTED(); 1016 // Only used on Win8 1017 return gfx::Point(); 1018 } 1019 1020 void RenderWidgetHostViewAndroid::FatalAccessibilityTreeError() { 1021 if (!host_) 1022 return; 1023 1024 host_->FatalAccessibilityTreeError(); 1025 SetBrowserAccessibilityManager(NULL); 1026 } 1027 1028 bool RenderWidgetHostViewAndroid::LockMouse() { 1029 NOTIMPLEMENTED(); 1030 return false; 1031 } 1032 1033 void RenderWidgetHostViewAndroid::UnlockMouse() { 1034 NOTIMPLEMENTED(); 1035 } 1036 1037 // Methods called from the host to the render 1038 1039 void RenderWidgetHostViewAndroid::SendKeyEvent( 1040 const NativeWebKeyboardEvent& event) { 1041 if (host_) 1042 host_->ForwardKeyboardEvent(event); 1043 } 1044 1045 void RenderWidgetHostViewAndroid::SendTouchEvent( 1046 const WebKit::WebTouchEvent& event) { 1047 if (host_) 1048 host_->ForwardTouchEventWithLatencyInfo(event, ui::LatencyInfo()); 1049 } 1050 1051 1052 void RenderWidgetHostViewAndroid::SendMouseEvent( 1053 const WebKit::WebMouseEvent& event) { 1054 if (host_) 1055 host_->ForwardMouseEvent(event); 1056 } 1057 1058 void RenderWidgetHostViewAndroid::SendMouseWheelEvent( 1059 const WebKit::WebMouseWheelEvent& event) { 1060 if (host_) 1061 host_->ForwardWheelEvent(event); 1062 } 1063 1064 void RenderWidgetHostViewAndroid::SendGestureEvent( 1065 const WebKit::WebGestureEvent& event) { 1066 // Sending a gesture that may trigger overscroll should resume the effect. 1067 if (overscroll_effect_) { 1068 overscroll_effect_->SetEnabled(true); 1069 if (event.type == WebKit::WebInputEvent::GestureScrollEnd) 1070 overscroll_effect_->Release(base::TimeTicks::Now()); 1071 } 1072 1073 if (host_) 1074 host_->ForwardGestureEvent(event); 1075 } 1076 1077 void RenderWidgetHostViewAndroid::SelectRange(const gfx::Point& start, 1078 const gfx::Point& end) { 1079 if (host_) 1080 host_->SelectRange(start, end); 1081 } 1082 1083 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) { 1084 if (host_) 1085 host_->MoveCaret(point); 1086 } 1087 1088 void RenderWidgetHostViewAndroid::RequestContentClipping( 1089 const gfx::Rect& clipping, 1090 const gfx::Size& content_size) { 1091 // A focused view provides its own clipping. 1092 if (HasFocus()) 1093 return; 1094 1095 ClipContents(clipping, content_size); 1096 } 1097 1098 void RenderWidgetHostViewAndroid::ResetClipping() { 1099 ClipContents(gfx::Rect(gfx::Point(), content_size_in_layer_), 1100 content_size_in_layer_); 1101 } 1102 1103 void RenderWidgetHostViewAndroid::ClipContents(const gfx::Rect& clipping, 1104 const gfx::Size& content_size) { 1105 if (!texture_id_in_layer_ || content_size_in_layer_.IsEmpty()) 1106 return; 1107 1108 gfx::Size clipped_content(content_size_in_layer_); 1109 clipped_content.SetToMin(clipping.size()); 1110 texture_layer_->SetBounds(clipped_content); 1111 texture_layer_->SetNeedsDisplay(); 1112 1113 if (texture_size_in_layer_.IsEmpty()) { 1114 texture_layer_->SetUV(gfx::PointF(), gfx::PointF()); 1115 return; 1116 } 1117 1118 gfx::PointF offset( 1119 clipping.x() + content_size_in_layer_.width() - content_size.width(), 1120 clipping.y() + content_size_in_layer_.height() - content_size.height()); 1121 offset.SetToMax(gfx::PointF()); 1122 1123 gfx::Vector2dF uv_scale(1.f / texture_size_in_layer_.width(), 1124 1.f / texture_size_in_layer_.height()); 1125 texture_layer_->SetUV( 1126 gfx::PointF(offset.x() * uv_scale.x(), 1127 offset.y() * uv_scale.y()), 1128 gfx::PointF((offset.x() + clipped_content.width()) * uv_scale.x(), 1129 (offset.y() + clipped_content.height()) * uv_scale.y())); 1130 } 1131 1132 SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const { 1133 return cached_background_color_; 1134 } 1135 1136 void RenderWidgetHostViewAndroid::OnOverscrolled( 1137 gfx::Vector2dF accumulated_overscroll, 1138 gfx::Vector2dF current_fling_velocity) { 1139 CreateOverscrollEffectIfNecessary(); 1140 if (!overscroll_effect_) 1141 return; 1142 1143 overscroll_effect_->OnOverscrolled(base::TimeTicks::Now(), 1144 accumulated_overscroll, 1145 current_fling_velocity); 1146 ScheduleAnimationIfNecessary(); 1147 } 1148 1149 void RenderWidgetHostViewAndroid::SetContentViewCore( 1150 ContentViewCoreImpl* content_view_core) { 1151 RunAckCallbacks(); 1152 1153 if (are_layers_attached_) 1154 RemoveLayers(); 1155 1156 content_view_core_ = content_view_core; 1157 1158 if (are_layers_attached_) 1159 AttachLayers(); 1160 } 1161 1162 void RenderWidgetHostViewAndroid::RunAckCallbacks() { 1163 while (!ack_callbacks_.empty()) { 1164 ack_callbacks_.front().Run(); 1165 ack_callbacks_.pop(); 1166 } 1167 } 1168 1169 void RenderWidgetHostViewAndroid::HasTouchEventHandlers( 1170 bool need_touch_events) { 1171 if (content_view_core_) 1172 content_view_core_->HasTouchEventHandlers(need_touch_events); 1173 } 1174 1175 unsigned RenderWidgetHostViewAndroid::PrepareTexture() { 1176 RunAckCallbacks(); 1177 return texture_id_in_layer_; 1178 } 1179 1180 void RenderWidgetHostViewAndroid::DidCommitFrameData() { 1181 RunAckCallbacks(); 1182 } 1183 1184 WebKit::WebGraphicsContext3D* RenderWidgetHostViewAndroid::Context3d() { 1185 return ImageTransportFactoryAndroid::GetInstance()->GetContext3D(); 1186 } 1187 1188 bool RenderWidgetHostViewAndroid::PrepareTextureMailbox( 1189 cc::TextureMailbox* mailbox, 1190 bool use_shared_memory) { 1191 return false; 1192 } 1193 1194 void RenderWidgetHostViewAndroid::OnLostResources() { 1195 if (texture_layer_) 1196 texture_layer_->SetIsDrawable(false); 1197 texture_id_in_layer_ = 0; 1198 RunAckCallbacks(); 1199 } 1200 1201 // static 1202 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult( 1203 const gfx::Size& dst_size_in_pixel, 1204 const base::Callback<void(bool, const SkBitmap&)>& callback, 1205 scoped_ptr<cc::CopyOutputResult> result) { 1206 DCHECK(result->HasTexture()); 1207 base::ScopedClosureRunner scoped_callback_runner( 1208 base::Bind(callback, false, SkBitmap())); 1209 1210 if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty()) 1211 return; 1212 1213 scoped_ptr<SkBitmap> bitmap(new SkBitmap); 1214 bitmap->setConfig(SkBitmap::kARGB_8888_Config, 1215 dst_size_in_pixel.width(), dst_size_in_pixel.height()); 1216 if (!bitmap->allocPixels()) 1217 return; 1218 bitmap->setIsOpaque(true); 1219 1220 ImageTransportFactoryAndroid* factory = 1221 ImageTransportFactoryAndroid::GetInstance(); 1222 GLHelper* gl_helper = factory->GetGLHelper(); 1223 if (!gl_helper) 1224 return; 1225 1226 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock( 1227 new SkAutoLockPixels(*bitmap)); 1228 uint8* pixels = static_cast<uint8*>(bitmap->getPixels()); 1229 1230 scoped_ptr<cc::TextureMailbox> texture_mailbox = result->TakeTexture(); 1231 DCHECK(texture_mailbox->IsTexture()); 1232 if (!texture_mailbox->IsTexture()) 1233 return; 1234 1235 scoped_callback_runner.Release(); 1236 1237 gl_helper->CropScaleReadbackAndCleanMailbox( 1238 texture_mailbox->name(), 1239 texture_mailbox->sync_point(), 1240 result->size(), 1241 gfx::Rect(result->size()), 1242 dst_size_in_pixel, 1243 pixels, 1244 base::Bind(&CopyFromCompositingSurfaceFinished, 1245 callback, 1246 texture_mailbox->callback(), 1247 base::Passed(&bitmap), 1248 base::Passed(&bitmap_pixels_lock))); 1249 } 1250 1251 // static 1252 void RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult( 1253 const gfx::Size& dst_size_in_pixel, 1254 const base::Callback<void(bool, const SkBitmap&)>& callback, 1255 scoped_ptr<cc::CopyOutputResult> result) { 1256 DCHECK(result->HasBitmap()); 1257 base::ScopedClosureRunner scoped_callback_runner( 1258 base::Bind(callback, false, SkBitmap())); 1259 1260 if (!result->HasBitmap() || result->IsEmpty() || result->size().IsEmpty()) 1261 return; 1262 1263 scoped_ptr<SkBitmap> source = result->TakeBitmap(); 1264 DCHECK(source); 1265 if (!source) 1266 return; 1267 1268 DCHECK_EQ(source->width(), dst_size_in_pixel.width()); 1269 DCHECK_EQ(source->height(), dst_size_in_pixel.height()); 1270 1271 scoped_callback_runner.Release(); 1272 callback.Run(true, *source); 1273 } 1274 1275 // static 1276 void RenderWidgetHostViewPort::GetDefaultScreenInfo( 1277 WebKit::WebScreenInfo* results) { 1278 const gfx::Display& display = 1279 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); 1280 results->rect = display.bounds(); 1281 // TODO(husky): Remove any system controls from availableRect. 1282 results->availableRect = display.work_area(); 1283 results->deviceScaleFactor = display.device_scale_factor(); 1284 gfx::DeviceDisplayInfo info; 1285 results->depth = info.GetBitsPerPixel(); 1286 results->depthPerComponent = info.GetBitsPerComponent(); 1287 results->isMonochrome = (results->depthPerComponent == 0); 1288 } 1289 1290 //////////////////////////////////////////////////////////////////////////////// 1291 // RenderWidgetHostView, public: 1292 1293 // static 1294 RenderWidgetHostView* 1295 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost* widget) { 1296 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget); 1297 return new RenderWidgetHostViewAndroid(rwhi, NULL); 1298 } 1299 1300 } // namespace content 1301