OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "android_webview/browser/browser_view_renderer.h" | 5 #include "android_webview/browser/browser_view_renderer.h" |
6 | 6 |
7 #include "android_webview/browser/browser_view_renderer_client.h" | 7 #include "android_webview/browser/browser_view_renderer_client.h" |
8 #include "android_webview/browser/shared_renderer_state.h" | 8 #include "android_webview/browser/shared_renderer_state.h" |
| 9 #include "android_webview/common/aw_switches.h" |
9 #include "android_webview/public/browser/draw_gl.h" | 10 #include "android_webview/public/browser/draw_gl.h" |
10 #include "base/android/jni_android.h" | 11 #include "base/android/jni_android.h" |
11 #include "base/auto_reset.h" | 12 #include "base/auto_reset.h" |
12 #include "base/command_line.h" | 13 #include "base/command_line.h" |
13 #include "base/debug/trace_event.h" | 14 #include "base/debug/trace_event.h" |
14 #include "base/json/json_writer.h" | 15 #include "base/json/json_writer.h" |
15 #include "base/logging.h" | 16 #include "base/logging.h" |
16 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
17 #include "base/strings/stringprintf.h" | 18 #include "base/strings/stringprintf.h" |
| 19 #include "cc/output/compositor_frame.h" |
18 #include "content/public/browser/android/synchronous_compositor.h" | 20 #include "content/public/browser/android/synchronous_compositor.h" |
19 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
20 #include "content/public/browser/web_contents.h" | 22 #include "content/public/browser/web_contents.h" |
21 #include "content/public/common/content_switches.h" | 23 #include "content/public/common/content_switches.h" |
22 #include "third_party/skia/include/core/SkBitmap.h" | 24 #include "third_party/skia/include/core/SkBitmap.h" |
23 #include "third_party/skia/include/core/SkCanvas.h" | 25 #include "third_party/skia/include/core/SkCanvas.h" |
24 #include "third_party/skia/include/core/SkPicture.h" | 26 #include "third_party/skia/include/core/SkPicture.h" |
25 #include "third_party/skia/include/core/SkPictureRecorder.h" | 27 #include "third_party/skia/include/core/SkPictureRecorder.h" |
26 #include "ui/gfx/vector2d_conversions.h" | 28 #include "ui/gfx/vector2d_conversions.h" |
27 | 29 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 shared_renderer_state_(shared_renderer_state), | 124 shared_renderer_state_(shared_renderer_state), |
123 web_contents_(web_contents), | 125 web_contents_(web_contents), |
124 weak_factory_on_ui_thread_(this), | 126 weak_factory_on_ui_thread_(this), |
125 ui_thread_weak_ptr_(weak_factory_on_ui_thread_.GetWeakPtr()), | 127 ui_thread_weak_ptr_(weak_factory_on_ui_thread_.GetWeakPtr()), |
126 ui_task_runner_(ui_task_runner), | 128 ui_task_runner_(ui_task_runner), |
127 has_compositor_(false), | 129 has_compositor_(false), |
128 is_paused_(false), | 130 is_paused_(false), |
129 view_visible_(false), | 131 view_visible_(false), |
130 window_visible_(false), | 132 window_visible_(false), |
131 attached_to_window_(false), | 133 attached_to_window_(false), |
| 134 hardware_enabled_(false), |
132 dip_scale_(0.0), | 135 dip_scale_(0.0), |
133 page_scale_factor_(1.0), | 136 page_scale_factor_(1.0), |
134 on_new_picture_enable_(false), | 137 on_new_picture_enable_(false), |
135 clear_view_(false), | 138 clear_view_(false), |
136 compositor_needs_continuous_invalidate_(false), | 139 compositor_needs_continuous_invalidate_(false), |
137 block_invalidates_(false), | 140 block_invalidates_(false), |
138 width_(0), | 141 width_(0), |
139 height_(0), | 142 height_(0), |
140 num_tiles_(0u), | 143 num_tiles_(0u), |
141 num_bytes_(0u) { | 144 num_bytes_(0u) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 | 184 |
182 TRACE_EVENT0("android_webview", "BrowserViewRenderer::TrimMemory"); | 185 TRACE_EVENT0("android_webview", "BrowserViewRenderer::TrimMemory"); |
183 | 186 |
184 RequestMemoryPolicy(zero_policy); | 187 RequestMemoryPolicy(zero_policy); |
185 EnforceMemoryPolicyImmediately(zero_policy); | 188 EnforceMemoryPolicyImmediately(zero_policy); |
186 } | 189 } |
187 | 190 |
188 SynchronousCompositorMemoryPolicy | 191 SynchronousCompositorMemoryPolicy |
189 BrowserViewRenderer::CalculateDesiredMemoryPolicy() { | 192 BrowserViewRenderer::CalculateDesiredMemoryPolicy() { |
190 SynchronousCompositorMemoryPolicy policy; | 193 SynchronousCompositorMemoryPolicy policy; |
191 size_t width = draw_gl_input_.global_visible_rect.width(); | 194 size_t width = last_on_draw_global_visible_rect_.width(); |
192 size_t height = draw_gl_input_.global_visible_rect.height(); | 195 size_t height = last_on_draw_global_visible_rect_.height(); |
193 policy.bytes_limit = kMemoryMultiplier * kBytesPerPixel * width * height; | 196 policy.bytes_limit = kMemoryMultiplier * kBytesPerPixel * width * height; |
194 // Round up to a multiple of kMemoryAllocationStep. | 197 // Round up to a multiple of kMemoryAllocationStep. |
195 policy.bytes_limit = | 198 policy.bytes_limit = |
196 (policy.bytes_limit / kMemoryAllocationStep + 1) * kMemoryAllocationStep; | 199 (policy.bytes_limit / kMemoryAllocationStep + 1) * kMemoryAllocationStep; |
197 | 200 |
198 size_t tiles = width * height * kTileMultiplier / g_tile_area; | 201 size_t tiles = width * height * kTileMultiplier / g_tile_area; |
199 // Round up to a multiple of kTileAllocationStep. The minimum number of tiles | 202 // Round up to a multiple of kTileAllocationStep. The minimum number of tiles |
200 // is also kTileAllocationStep. | 203 // is also kTileAllocationStep. |
201 tiles = (tiles / kTileAllocationStep + 1) * kTileAllocationStep; | 204 tiles = (tiles / kTileAllocationStep + 1) * kTileAllocationStep; |
202 policy.num_resources_limit = tiles; | 205 policy.num_resources_limit = tiles; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 | 243 |
241 size_t BrowserViewRenderer::GetNumTiles() const { | 244 size_t BrowserViewRenderer::GetNumTiles() const { |
242 return shared_renderer_state_->GetMemoryPolicy().num_resources_limit; | 245 return shared_renderer_state_->GetMemoryPolicy().num_resources_limit; |
243 } | 246 } |
244 | 247 |
245 bool BrowserViewRenderer::OnDraw(jobject java_canvas, | 248 bool BrowserViewRenderer::OnDraw(jobject java_canvas, |
246 bool is_hardware_canvas, | 249 bool is_hardware_canvas, |
247 const gfx::Vector2d& scroll, | 250 const gfx::Vector2d& scroll, |
248 const gfx::Rect& global_visible_rect, | 251 const gfx::Rect& global_visible_rect, |
249 const gfx::Rect& clip) { | 252 const gfx::Rect& clip) { |
250 draw_gl_input_.frame_id++; | 253 last_on_draw_scroll_offset_ = scroll; |
251 draw_gl_input_.scroll_offset = scroll; | 254 last_on_draw_global_visible_rect_ = global_visible_rect; |
252 draw_gl_input_.global_visible_rect = global_visible_rect; | 255 |
253 draw_gl_input_.width = width_; | |
254 draw_gl_input_.height = height_; | |
255 if (clear_view_) | 256 if (clear_view_) |
256 return false; | 257 return false; |
| 258 |
257 if (is_hardware_canvas && attached_to_window_) { | 259 if (is_hardware_canvas && attached_to_window_) { |
258 shared_renderer_state_->SetDrawGLInput(draw_gl_input_); | 260 if (switches::UbercompEnabled()) { |
259 | 261 return OnDrawHardware(java_canvas); |
260 SynchronousCompositorMemoryPolicy old_policy = | 262 } else { |
261 shared_renderer_state_->GetMemoryPolicy(); | 263 return OnDrawHardwareLegacy(java_canvas); |
262 SynchronousCompositorMemoryPolicy new_policy = | 264 } |
263 CalculateDesiredMemoryPolicy(); | |
264 RequestMemoryPolicy(new_policy); | |
265 // We should be performing a hardware draw here. If we don't have the | |
266 // compositor yet or if RequestDrawGL fails, it means we failed this draw | |
267 // and thus return false here to clear to background color for this draw. | |
268 bool did_draw_gl = | |
269 has_compositor_ && client_->RequestDrawGL(java_canvas, false); | |
270 if (did_draw_gl) | |
271 GlobalTileManager::GetInstance()->DidUse(tile_manager_key_); | |
272 else | |
273 RequestMemoryPolicy(old_policy); | |
274 | |
275 return did_draw_gl; | |
276 } | 265 } |
277 // Perform a software draw | 266 // Perform a software draw |
278 return DrawSWInternal(java_canvas, clip); | 267 return DrawSWInternal(java_canvas, clip); |
279 } | 268 } |
280 | 269 |
281 void BrowserViewRenderer::DidDrawGL(const DrawGLResult& result) { | 270 bool BrowserViewRenderer::OnDrawHardwareLegacy(jobject java_canvas) { |
282 DidComposite(!result.clip_contains_visible_rect); | 271 scoped_ptr<DrawGLInput> draw_gl_input(new DrawGLInput); |
| 272 draw_gl_input->scroll_offset = last_on_draw_scroll_offset_; |
| 273 draw_gl_input->global_visible_rect = last_on_draw_global_visible_rect_; |
| 274 draw_gl_input->width = width_; |
| 275 draw_gl_input->height = height_; |
| 276 |
| 277 SynchronousCompositorMemoryPolicy old_policy = |
| 278 shared_renderer_state_->GetMemoryPolicy(); |
| 279 SynchronousCompositorMemoryPolicy new_policy = CalculateDesiredMemoryPolicy(); |
| 280 RequestMemoryPolicy(new_policy); |
| 281 // We should be performing a hardware draw here. If we don't have the |
| 282 // compositor yet or if RequestDrawGL fails, it means we failed this draw |
| 283 // and thus return false here to clear to background color for this draw. |
| 284 bool did_draw_gl = |
| 285 has_compositor_ && client_->RequestDrawGL(java_canvas, false); |
| 286 if (did_draw_gl) { |
| 287 GlobalTileManager::GetInstance()->DidUse(tile_manager_key_); |
| 288 shared_renderer_state_->SetDrawGLInput(draw_gl_input.Pass()); |
| 289 } else { |
| 290 RequestMemoryPolicy(old_policy); |
| 291 } |
| 292 |
| 293 return did_draw_gl; |
| 294 } |
| 295 |
| 296 void BrowserViewRenderer::DidDrawGL(scoped_ptr<DrawGLResult> result) { |
| 297 DidComposite(!result->clip_contains_visible_rect); |
| 298 } |
| 299 |
| 300 bool BrowserViewRenderer::OnDrawHardware(jobject java_canvas) { |
| 301 if (!has_compositor_) |
| 302 return false; |
| 303 |
| 304 if (!hardware_enabled_) { |
| 305 hardware_enabled_ = |
| 306 shared_renderer_state_->GetCompositor()->InitializeHwDraw(NULL); |
| 307 if (hardware_enabled_) { |
| 308 gpu::GLInProcessContext* share_context = |
| 309 shared_renderer_state_->GetCompositor()->GetShareContext(); |
| 310 DCHECK(share_context); |
| 311 shared_renderer_state_->SetSharedContext(share_context); |
| 312 } |
| 313 } |
| 314 if (!hardware_enabled_) |
| 315 return false; |
| 316 |
| 317 ReturnResources(); |
| 318 SynchronousCompositorMemoryPolicy new_policy = CalculateDesiredMemoryPolicy(); |
| 319 RequestMemoryPolicy(new_policy); |
| 320 shared_renderer_state_->GetCompositor()->SetMemoryPolicy( |
| 321 shared_renderer_state_->GetMemoryPolicy()); |
| 322 |
| 323 scoped_ptr<DrawGLInput> draw_gl_input(new DrawGLInput); |
| 324 draw_gl_input->scroll_offset = last_on_draw_scroll_offset_; |
| 325 draw_gl_input->global_visible_rect = last_on_draw_global_visible_rect_; |
| 326 draw_gl_input->width = width_; |
| 327 draw_gl_input->height = height_; |
| 328 |
| 329 gfx::Transform transform; |
| 330 gfx::Size surface_size(width_, height_); |
| 331 gfx::Rect viewport(surface_size); |
| 332 // TODO(boliu): Should really be |last_on_draw_global_visible_rect_|. |
| 333 // See crbug.com/372073. |
| 334 gfx::Rect clip = viewport; |
| 335 bool stencil_enabled = false; |
| 336 bool drew_delegated = shared_renderer_state_->GetCompositor()->DemandDrawHw( |
| 337 surface_size, |
| 338 transform, |
| 339 viewport, |
| 340 clip, |
| 341 stencil_enabled, |
| 342 &draw_gl_input->frame); |
| 343 if (!drew_delegated) |
| 344 return false; |
| 345 |
| 346 GlobalTileManager::GetInstance()->DidUse(tile_manager_key_); |
| 347 |
| 348 scoped_ptr<DrawGLInput> old_input = shared_renderer_state_->PassDrawGLInput(); |
| 349 if (old_input.get()) { |
| 350 shared_renderer_state_->ReturnResources( |
| 351 old_input->frame.delegated_frame_data->resource_list); |
| 352 } |
| 353 shared_renderer_state_->SetDrawGLInput(draw_gl_input.Pass()); |
| 354 |
| 355 DidComposite(false); |
| 356 bool did_request = client_->RequestDrawGL(java_canvas, false); |
| 357 if (did_request) |
| 358 return true; |
| 359 |
| 360 ReturnResources(); |
| 361 return false; |
| 362 } |
| 363 |
| 364 void BrowserViewRenderer::DidDrawDelegated(scoped_ptr<DrawGLResult> result) { |
| 365 if (!ui_task_runner_->BelongsToCurrentThread()) { |
| 366 // TODO(boliu): This should be a cancelable callback. |
| 367 ui_task_runner_->PostTask(FROM_HERE, |
| 368 base::Bind(&BrowserViewRenderer::DidDrawDelegated, |
| 369 ui_thread_weak_ptr_, |
| 370 base::Passed(&result))); |
| 371 return; |
| 372 } |
| 373 ReturnResources(); |
| 374 } |
| 375 |
| 376 void BrowserViewRenderer::ReturnResources() { |
| 377 cc::CompositorFrameAck frame_ack; |
| 378 shared_renderer_state_->SwapReturnedResources(&frame_ack.resources); |
| 379 if (!frame_ack.resources.empty()) { |
| 380 shared_renderer_state_->GetCompositor()->ReturnResources(frame_ack); |
| 381 } |
283 } | 382 } |
284 | 383 |
285 bool BrowserViewRenderer::DrawSWInternal(jobject java_canvas, | 384 bool BrowserViewRenderer::DrawSWInternal(jobject java_canvas, |
286 const gfx::Rect& clip) { | 385 const gfx::Rect& clip) { |
287 if (clip.IsEmpty()) { | 386 if (clip.IsEmpty()) { |
288 TRACE_EVENT_INSTANT0( | 387 TRACE_EVENT_INSTANT0( |
289 "android_webview", "EarlyOut_EmptyClip", TRACE_EVENT_SCOPE_THREAD); | 388 "android_webview", "EarlyOut_EmptyClip", TRACE_EVENT_SCOPE_THREAD); |
290 return true; | 389 return true; |
291 } | 390 } |
292 | 391 |
293 if (!has_compositor_) { | 392 if (!has_compositor_) { |
294 TRACE_EVENT_INSTANT0( | 393 TRACE_EVENT_INSTANT0( |
295 "android_webview", "EarlyOut_NoCompositor", TRACE_EVENT_SCOPE_THREAD); | 394 "android_webview", "EarlyOut_NoCompositor", TRACE_EVENT_SCOPE_THREAD); |
296 return false; | 395 return false; |
297 } | 396 } |
298 | 397 |
299 return BrowserViewRendererJavaHelper::GetInstance() | 398 return BrowserViewRendererJavaHelper::GetInstance() |
300 ->RenderViaAuxilaryBitmapIfNeeded( | 399 ->RenderViaAuxilaryBitmapIfNeeded( |
301 java_canvas, | 400 java_canvas, |
302 draw_gl_input_.scroll_offset, | 401 last_on_draw_scroll_offset_, |
303 clip, | 402 clip, |
304 base::Bind(&BrowserViewRenderer::CompositeSW, | 403 base::Bind(&BrowserViewRenderer::CompositeSW, |
305 base::Unretained(this))); | 404 base::Unretained(this))); |
306 } | 405 } |
307 | 406 |
308 skia::RefPtr<SkPicture> BrowserViewRenderer::CapturePicture(int width, | 407 skia::RefPtr<SkPicture> BrowserViewRenderer::CapturePicture(int width, |
309 int height) { | 408 int height) { |
310 TRACE_EVENT0("android_webview", "BrowserViewRenderer::CapturePicture"); | 409 TRACE_EVENT0("android_webview", "BrowserViewRenderer::CapturePicture"); |
311 | 410 |
312 // Return empty Picture objects for empty SkPictures. | 411 // Return empty Picture objects for empty SkPictures. |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 height); | 491 height); |
393 attached_to_window_ = true; | 492 attached_to_window_ = true; |
394 width_ = width; | 493 width_ = width; |
395 height_ = height; | 494 height_ = height; |
396 tile_manager_key_ = GlobalTileManager::GetInstance()->PushBack(this); | 495 tile_manager_key_ = GlobalTileManager::GetInstance()->PushBack(this); |
397 } | 496 } |
398 | 497 |
399 void BrowserViewRenderer::OnDetachedFromWindow() { | 498 void BrowserViewRenderer::OnDetachedFromWindow() { |
400 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow"); | 499 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow"); |
401 attached_to_window_ = false; | 500 attached_to_window_ = false; |
| 501 if (hardware_enabled_) { |
| 502 scoped_ptr<DrawGLInput> input = shared_renderer_state_->PassDrawGLInput(); |
| 503 if (input.get()) { |
| 504 shared_renderer_state_->ReturnResources( |
| 505 input->frame.delegated_frame_data->resource_list); |
| 506 } |
| 507 ReturnResources(); |
| 508 DCHECK(shared_renderer_state_->ReturnedResourcesEmpty()); |
| 509 |
| 510 if (switches::UbercompEnabled()) |
| 511 shared_renderer_state_->GetCompositor()->ReleaseHwDraw(); |
| 512 shared_renderer_state_->SetSharedContext(NULL); |
| 513 hardware_enabled_ = false; |
| 514 } |
402 SynchronousCompositorMemoryPolicy zero_policy; | 515 SynchronousCompositorMemoryPolicy zero_policy; |
403 RequestMemoryPolicy(zero_policy); | 516 RequestMemoryPolicy(zero_policy); |
404 GlobalTileManager::GetInstance()->Remove(tile_manager_key_); | 517 GlobalTileManager::GetInstance()->Remove(tile_manager_key_); |
405 // The hardware resources are released in the destructor of hardware renderer, | 518 // The hardware resources are released in the destructor of hardware renderer, |
406 // so we don't need to do it here. | 519 // so we don't need to do it here. |
407 // See AwContents::ReleaseHardwareDrawOnRenderThread(JNIEnv*, jobject). | 520 // See AwContents::ReleaseHardwareDrawOnRenderThread(JNIEnv*, jobject). |
408 } | 521 } |
409 | 522 |
410 bool BrowserViewRenderer::IsAttachedToWindow() const { | 523 bool BrowserViewRenderer::IsAttachedToWindow() const { |
411 return attached_to_window_; | 524 return attached_to_window_; |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); | 886 base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); |
774 base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); | 887 base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); |
775 base::StringAppendF(&str, | 888 base::StringAppendF(&str, |
776 "compositor_needs_continuous_invalidate: %d ", | 889 "compositor_needs_continuous_invalidate: %d ", |
777 compositor_needs_continuous_invalidate_); | 890 compositor_needs_continuous_invalidate_); |
778 base::StringAppendF(&str, "block_invalidates: %d ", block_invalidates_); | 891 base::StringAppendF(&str, "block_invalidates: %d ", block_invalidates_); |
779 base::StringAppendF(&str, "view width height: [%d %d] ", width_, height_); | 892 base::StringAppendF(&str, "view width height: [%d %d] ", width_, height_); |
780 base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_); | 893 base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_); |
781 base::StringAppendF(&str, | 894 base::StringAppendF(&str, |
782 "global visible rect: %s ", | 895 "global visible rect: %s ", |
783 draw_gl_input_.global_visible_rect.ToString().c_str()); | 896 last_on_draw_global_visible_rect_.ToString().c_str()); |
784 base::StringAppendF( | 897 base::StringAppendF( |
785 &str, "scroll_offset_dip: %s ", scroll_offset_dip_.ToString().c_str()); | 898 &str, "scroll_offset_dip: %s ", scroll_offset_dip_.ToString().c_str()); |
786 base::StringAppendF(&str, | 899 base::StringAppendF(&str, |
787 "overscroll_rounding_error_: %s ", | 900 "overscroll_rounding_error_: %s ", |
788 overscroll_rounding_error_.ToString().c_str()); | 901 overscroll_rounding_error_.ToString().c_str()); |
789 base::StringAppendF( | 902 base::StringAppendF( |
790 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); | 903 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); |
791 base::StringAppendF(&str, "clear_view: %d ", clear_view_); | 904 base::StringAppendF(&str, "clear_view: %d ", clear_view_); |
792 if (draw_info) { | 905 if (draw_info) { |
793 base::StringAppendF(&str, | 906 base::StringAppendF(&str, |
794 "clip left top right bottom: [%d %d %d %d] ", | 907 "clip left top right bottom: [%d %d %d %d] ", |
795 draw_info->clip_left, | 908 draw_info->clip_left, |
796 draw_info->clip_top, | 909 draw_info->clip_top, |
797 draw_info->clip_right, | 910 draw_info->clip_right, |
798 draw_info->clip_bottom); | 911 draw_info->clip_bottom); |
799 base::StringAppendF(&str, | 912 base::StringAppendF(&str, |
800 "surface width height: [%d %d] ", | 913 "surface width height: [%d %d] ", |
801 draw_info->width, | 914 draw_info->width, |
802 draw_info->height); | 915 draw_info->height); |
803 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); | 916 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); |
804 } | 917 } |
805 return str; | 918 return str; |
806 } | 919 } |
807 | 920 |
808 } // namespace android_webview | 921 } // namespace android_webview |
OLD | NEW |