Chromium Code Reviews| 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/common/aw_switches.h" |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/debug/trace_event_argument.h" | 12 #include "base/debug/trace_event_argument.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 16 #include "cc/output/compositor_frame.h" | 16 #include "cc/output/compositor_frame.h" |
| 17 #include "content/public/browser/web_contents.h" | 17 #include "content/public/browser/web_contents.h" |
| 18 #include "content/public/common/content_switches.h" | 18 #include "content/public/common/content_switches.h" |
| 19 #include "gpu/command_buffer/service/gpu_switches.h" | 19 #include "gpu/command_buffer/service/gpu_switches.h" |
| 20 #include "third_party/skia/include/core/SkBitmap.h" | 20 #include "third_party/skia/include/core/SkBitmap.h" |
| 21 #include "third_party/skia/include/core/SkCanvas.h" | 21 #include "third_party/skia/include/core/SkCanvas.h" |
| 22 #include "third_party/skia/include/core/SkPicture.h" | 22 #include "third_party/skia/include/core/SkPicture.h" |
| 23 #include "third_party/skia/include/core/SkPictureRecorder.h" | 23 #include "third_party/skia/include/core/SkPictureRecorder.h" |
| 24 #include "ui/gfx/geometry/vector2d_conversions.h" | 24 #include "ui/gfx/geometry/vector2d_conversions.h" |
| 25 | 25 |
| 26 using content::SynchronousCompositorMemoryPolicy; | |
| 27 | |
| 28 namespace android_webview { | 26 namespace android_webview { |
| 29 | 27 |
| 30 namespace { | 28 namespace { |
| 31 | 29 |
| 32 const int64 kFallbackTickTimeoutInMilliseconds = 100; | 30 const int64 kFallbackTickTimeoutInMilliseconds = 100; |
| 33 | 31 |
| 34 // Used to calculate memory allocation. Determined experimentally. | 32 // Used to calculate memory allocation. Determined experimentally. |
| 35 const size_t kMemoryMultiplier = 20; | 33 const size_t kMemoryMultiplier = 20; |
| 36 const size_t kBytesPerPixel = 4; | 34 const size_t kBytesPerPixel = 4; |
| 37 const size_t kMemoryAllocationStep = 5 * 1024 * 1024; | 35 const size_t kMemoryAllocationStep = 5 * 1024 * 1024; |
| 38 uint64 g_memory_override_in_bytes = 0u; | 36 uint64 g_memory_override_in_bytes = 0u; |
| 39 | 37 |
| 40 // Used to calculate tile allocation. Determined experimentally. | |
| 41 const size_t kTileMultiplier = 12; | |
| 42 const size_t kTileAllocationStep = 20; | |
| 43 // Use chrome's default tile size, which varies from 256 to 512. | |
| 44 // Be conservative here and use the smallest tile size possible. | |
| 45 const size_t kTileArea = 256 * 256; | |
| 46 | |
| 47 } // namespace | 38 } // namespace |
| 48 | 39 |
| 49 // static | 40 // static |
| 50 void BrowserViewRenderer::CalculateTileMemoryPolicy() { | 41 void BrowserViewRenderer::CalculateTileMemoryPolicy() { |
| 51 CommandLine* cl = CommandLine::ForCurrentProcess(); | 42 CommandLine* cl = CommandLine::ForCurrentProcess(); |
| 52 | 43 |
| 53 // If the value was overridden on the command line, use the specified value. | 44 // If the value was overridden on the command line, use the specified value. |
| 54 bool client_hard_limit_bytes_overridden = | 45 bool client_hard_limit_bytes_overridden = |
| 55 cl->HasSwitch(switches::kForceGpuMemAvailableMb); | 46 cl->HasSwitch(switches::kForceGpuMemAvailableMb); |
| 56 if (client_hard_limit_bytes_overridden) { | 47 if (client_hard_limit_bytes_overridden) { |
| 57 base::StringToUint64( | 48 base::StringToUint64( |
| 58 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 49 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 59 switches::kForceGpuMemAvailableMb), | 50 switches::kForceGpuMemAvailableMb), |
| 60 &g_memory_override_in_bytes); | 51 &g_memory_override_in_bytes); |
| 61 g_memory_override_in_bytes *= 1024 * 1024; | 52 g_memory_override_in_bytes *= 1024 * 1024; |
| 62 } | 53 } |
| 63 | |
| 64 // There is no need to limit number of tiles, so use an effectively unlimited | |
| 65 // value as the limit. | |
| 66 GlobalTileManager::GetInstance()->SetTileLimit(10 * 1000 * 1000); | |
| 67 } | 54 } |
| 68 | 55 |
| 69 BrowserViewRenderer::BrowserViewRenderer( | 56 BrowserViewRenderer::BrowserViewRenderer( |
| 70 BrowserViewRendererClient* client, | 57 BrowserViewRendererClient* client, |
| 71 SharedRendererState* shared_renderer_state, | 58 SharedRendererState* shared_renderer_state, |
| 72 content::WebContents* web_contents, | 59 content::WebContents* web_contents, |
| 73 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) | 60 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) |
| 74 : client_(client), | 61 : client_(client), |
| 75 shared_renderer_state_(shared_renderer_state), | 62 shared_renderer_state_(shared_renderer_state), |
| 76 web_contents_(web_contents), | 63 web_contents_(web_contents), |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 117 // Not urgent enough. TRIM_MEMORY_UI_HIDDEN is treated specially because | 104 // Not urgent enough. TRIM_MEMORY_UI_HIDDEN is treated specially because |
| 118 // it does not indicate memory pressure, but merely that the app is | 105 // it does not indicate memory pressure, but merely that the app is |
| 119 // backgrounded. | 106 // backgrounded. |
| 120 if (level < TRIM_MEMORY_RUNNING_LOW || level == TRIM_MEMORY_UI_HIDDEN) | 107 if (level < TRIM_MEMORY_RUNNING_LOW || level == TRIM_MEMORY_UI_HIDDEN) |
| 121 return; | 108 return; |
| 122 | 109 |
| 123 // Do not release resources on view we expect to get DrawGL soon. | 110 // Do not release resources on view we expect to get DrawGL soon. |
| 124 if (level < TRIM_MEMORY_BACKGROUND && visible) | 111 if (level < TRIM_MEMORY_BACKGROUND && visible) |
| 125 return; | 112 return; |
| 126 | 113 |
| 127 // Just set the memory limit to 0 and drop all tiles. This will be reset to | 114 // Nothing to drop. |
| 128 // normal levels in the next DrawGL call. | 115 if (!compositor_ || !hardware_enabled_) |
| 129 SynchronousCompositorMemoryPolicy zero_policy; | |
| 130 if (memory_policy_ == zero_policy) | |
| 131 return; | 116 return; |
| 132 | 117 |
| 133 TRACE_EVENT0("android_webview", "BrowserViewRenderer::TrimMemory"); | 118 TRACE_EVENT0("android_webview", "BrowserViewRenderer::TrimMemory"); |
| 134 DCHECK(hardware_enabled_); | |
| 135 DCHECK(compositor_); | |
| 136 | 119 |
| 137 RequestMemoryPolicy(zero_policy); | 120 // Just set the memory limit to 0 and drop all tiles. This will be reset to |
| 138 EnforceMemoryPolicyImmediately(zero_policy); | 121 // normal levels in the next DrawGL call. |
| 139 } | 122 compositor_->SetMemoryPolicy(0u); |
|
hush (inactive)
2014/10/24 23:36:37
do you need to enforce it immediately right here?
boliu
2014/10/24 23:37:53
It is enforce it once line below. There's just a h
hush (inactive)
2014/10/24 23:49:59
oops. Yes. Thanks!
| |
| 140 | |
| 141 SynchronousCompositorMemoryPolicy | |
| 142 BrowserViewRenderer::CalculateDesiredMemoryPolicy() { | |
| 143 SynchronousCompositorMemoryPolicy policy; | |
| 144 size_t width = last_on_draw_global_visible_rect_.width(); | |
| 145 size_t height = last_on_draw_global_visible_rect_.height(); | |
| 146 policy.bytes_limit = kMemoryMultiplier * kBytesPerPixel * width * height; | |
| 147 // Round up to a multiple of kMemoryAllocationStep. | |
| 148 policy.bytes_limit = | |
| 149 (policy.bytes_limit / kMemoryAllocationStep + 1) * kMemoryAllocationStep; | |
| 150 | |
| 151 if (g_memory_override_in_bytes) | |
| 152 policy.bytes_limit = static_cast<size_t>(g_memory_override_in_bytes); | |
| 153 | |
| 154 size_t tiles = width * height * kTileMultiplier / kTileArea; | |
| 155 // Round up to a multiple of kTileAllocationStep. The minimum number of tiles | |
| 156 // is also kTileAllocationStep. | |
| 157 tiles = (tiles / kTileAllocationStep + 1) * kTileAllocationStep; | |
| 158 policy.num_resources_limit = tiles; | |
| 159 return policy; | |
| 160 } | |
| 161 | |
| 162 // This function updates the cached memory policy in shared renderer state, as | |
| 163 // well as the tile resource allocation in GlobalTileManager. | |
| 164 void BrowserViewRenderer::RequestMemoryPolicy( | |
| 165 SynchronousCompositorMemoryPolicy& new_policy) { | |
| 166 DCHECK(compositor_); | |
| 167 GlobalTileManager* manager = GlobalTileManager::GetInstance(); | |
| 168 | |
| 169 // The following line will call BrowserViewRenderer::SetMemoryPolicy(). | |
| 170 manager->RequestTiles(new_policy, tile_manager_key_); | |
| 171 } | |
| 172 | |
| 173 void BrowserViewRenderer::SetMemoryPolicy( | |
| 174 SynchronousCompositorMemoryPolicy new_policy, | |
| 175 bool effective_immediately) { | |
| 176 memory_policy_ = new_policy; | |
| 177 if (effective_immediately) | |
| 178 EnforceMemoryPolicyImmediately(memory_policy_); | |
| 179 } | |
| 180 | |
| 181 void BrowserViewRenderer::EnforceMemoryPolicyImmediately( | |
| 182 SynchronousCompositorMemoryPolicy new_policy) { | |
| 183 compositor_->SetMemoryPolicy(new_policy); | |
| 184 ForceFakeCompositeSW(); | 123 ForceFakeCompositeSW(); |
| 185 } | 124 } |
| 186 | 125 |
| 187 SynchronousCompositorMemoryPolicy BrowserViewRenderer::GetMemoryPolicy() const { | 126 size_t BrowserViewRenderer::CalculateDesiredMemoryPolicy() { |
| 188 return memory_policy_; | 127 if (g_memory_override_in_bytes) |
| 128 return static_cast<size_t>(g_memory_override_in_bytes); | |
| 129 | |
| 130 size_t width = last_on_draw_global_visible_rect_.width(); | |
| 131 size_t height = last_on_draw_global_visible_rect_.height(); | |
| 132 size_t bytes_limit = kMemoryMultiplier * kBytesPerPixel * width * height; | |
| 133 // Round up to a multiple of kMemoryAllocationStep. | |
| 134 bytes_limit = | |
| 135 (bytes_limit / kMemoryAllocationStep + 1) * kMemoryAllocationStep; | |
| 136 return bytes_limit; | |
| 189 } | 137 } |
| 190 | 138 |
| 191 bool BrowserViewRenderer::OnDraw(jobject java_canvas, | 139 bool BrowserViewRenderer::OnDraw(jobject java_canvas, |
| 192 bool is_hardware_canvas, | 140 bool is_hardware_canvas, |
| 193 const gfx::Vector2d& scroll, | 141 const gfx::Vector2d& scroll, |
| 194 const gfx::Rect& global_visible_rect) { | 142 const gfx::Rect& global_visible_rect) { |
| 195 last_on_draw_scroll_offset_ = scroll; | 143 last_on_draw_scroll_offset_ = scroll; |
| 196 last_on_draw_global_visible_rect_ = global_visible_rect; | 144 last_on_draw_global_visible_rect_ = global_visible_rect; |
| 197 | 145 |
| 198 if (clear_view_) | 146 if (clear_view_) |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 209 | 157 |
| 210 bool BrowserViewRenderer::OnDrawHardware(jobject java_canvas) { | 158 bool BrowserViewRenderer::OnDrawHardware(jobject java_canvas) { |
| 211 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDrawHardware"); | 159 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDrawHardware"); |
| 212 if (!compositor_) | 160 if (!compositor_) |
| 213 return false; | 161 return false; |
| 214 | 162 |
| 215 shared_renderer_state_->SetScrollOffset(last_on_draw_scroll_offset_); | 163 shared_renderer_state_->SetScrollOffset(last_on_draw_scroll_offset_); |
| 216 | 164 |
| 217 if (!hardware_enabled_) { | 165 if (!hardware_enabled_) { |
| 218 hardware_enabled_ = compositor_->InitializeHwDraw(); | 166 hardware_enabled_ = compositor_->InitializeHwDraw(); |
| 219 if (hardware_enabled_) { | |
| 220 tile_manager_key_ = GlobalTileManager::GetInstance()->PushBack(this); | |
| 221 } | |
| 222 } | 167 } |
| 223 if (!hardware_enabled_) | 168 if (!hardware_enabled_) |
| 224 return false; | 169 return false; |
| 225 | 170 |
| 226 if (last_on_draw_global_visible_rect_.IsEmpty() && | 171 if (last_on_draw_global_visible_rect_.IsEmpty() && |
| 227 parent_draw_constraints_.surface_rect.IsEmpty()) { | 172 parent_draw_constraints_.surface_rect.IsEmpty()) { |
| 228 TRACE_EVENT_INSTANT0("android_webview", | 173 TRACE_EVENT_INSTANT0("android_webview", |
| 229 "EarlyOut_EmptyVisibleRect", | 174 "EarlyOut_EmptyVisibleRect", |
| 230 TRACE_EVENT_SCOPE_THREAD); | 175 TRACE_EVENT_SCOPE_THREAD); |
| 231 shared_renderer_state_->SetForceInvalidateOnNextDrawGL(true); | 176 shared_renderer_state_->SetForceInvalidateOnNextDrawGL(true); |
| 232 return client_->RequestDrawGL(java_canvas, false); | 177 return client_->RequestDrawGL(java_canvas, false); |
| 233 } | 178 } |
| 234 | 179 |
| 235 ReturnResourceFromParent(); | 180 ReturnResourceFromParent(); |
| 236 if (shared_renderer_state_->HasCompositorFrame()) { | 181 if (shared_renderer_state_->HasCompositorFrame()) { |
| 237 TRACE_EVENT_INSTANT0("android_webview", | 182 TRACE_EVENT_INSTANT0("android_webview", |
| 238 "EarlyOut_PreviousFrameUnconsumed", | 183 "EarlyOut_PreviousFrameUnconsumed", |
| 239 TRACE_EVENT_SCOPE_THREAD); | 184 TRACE_EVENT_SCOPE_THREAD); |
| 240 DidSkipCompositeInDraw(); | 185 DidSkipCompositeInDraw(); |
| 241 return client_->RequestDrawGL(java_canvas, false); | 186 return client_->RequestDrawGL(java_canvas, false); |
| 242 } | 187 } |
| 243 | 188 |
| 244 scoped_ptr<cc::CompositorFrame> frame = CompositeHw(); | 189 scoped_ptr<cc::CompositorFrame> frame = CompositeHw(); |
| 245 if (!frame.get()) | 190 if (!frame.get()) |
| 246 return false; | 191 return false; |
| 247 | 192 |
| 248 shared_renderer_state_->SetCompositorFrame(frame.Pass(), false); | 193 shared_renderer_state_->SetCompositorFrame(frame.Pass(), false); |
| 249 GlobalTileManager::GetInstance()->DidUse(tile_manager_key_); | |
| 250 return client_->RequestDrawGL(java_canvas, false); | 194 return client_->RequestDrawGL(java_canvas, false); |
| 251 } | 195 } |
| 252 | 196 |
| 253 scoped_ptr<cc::CompositorFrame> BrowserViewRenderer::CompositeHw() { | 197 scoped_ptr<cc::CompositorFrame> BrowserViewRenderer::CompositeHw() { |
| 254 SynchronousCompositorMemoryPolicy new_policy = CalculateDesiredMemoryPolicy(); | 198 compositor_->SetMemoryPolicy(CalculateDesiredMemoryPolicy()); |
| 255 RequestMemoryPolicy(new_policy); | |
| 256 compositor_->SetMemoryPolicy(memory_policy_); | |
| 257 | 199 |
| 258 parent_draw_constraints_ = shared_renderer_state_->ParentDrawConstraints(); | 200 parent_draw_constraints_ = shared_renderer_state_->ParentDrawConstraints(); |
| 259 gfx::Size surface_size(width_, height_); | 201 gfx::Size surface_size(width_, height_); |
| 260 gfx::Rect viewport(surface_size); | 202 gfx::Rect viewport(surface_size); |
| 261 gfx::Rect clip = viewport; | 203 gfx::Rect clip = viewport; |
| 262 gfx::Transform transform_for_tile_priority = | 204 gfx::Transform transform_for_tile_priority = |
| 263 parent_draw_constraints_.transform; | 205 parent_draw_constraints_.transform; |
| 264 | 206 |
| 265 // If the WebView is on a layer, WebView does not know what transform is | 207 // If the WebView is on a layer, WebView does not know what transform is |
| 266 // applied onto the layer so global visible rect does not make sense here. | 208 // applied onto the layer so global visible rect does not make sense here. |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 444 } | 386 } |
| 445 | 387 |
| 446 void BrowserViewRenderer::ReleaseHardware() { | 388 void BrowserViewRenderer::ReleaseHardware() { |
| 447 DCHECK(hardware_enabled_); | 389 DCHECK(hardware_enabled_); |
| 448 ReturnUnusedResource(shared_renderer_state_->PassCompositorFrame()); | 390 ReturnUnusedResource(shared_renderer_state_->PassCompositorFrame()); |
| 449 ReturnResourceFromParent(); | 391 ReturnResourceFromParent(); |
| 450 DCHECK(shared_renderer_state_->ReturnedResourcesEmpty()); | 392 DCHECK(shared_renderer_state_->ReturnedResourcesEmpty()); |
| 451 | 393 |
| 452 if (compositor_) { | 394 if (compositor_) { |
| 453 compositor_->ReleaseHwDraw(); | 395 compositor_->ReleaseHwDraw(); |
| 454 SynchronousCompositorMemoryPolicy zero_policy; | |
| 455 RequestMemoryPolicy(zero_policy); | |
| 456 } | 396 } |
| 457 | 397 |
| 458 hardware_enabled_ = false; | 398 hardware_enabled_ = false; |
| 459 GlobalTileManager::GetInstance()->Remove(tile_manager_key_); | |
| 460 } | 399 } |
| 461 | 400 |
| 462 bool BrowserViewRenderer::IsVisible() const { | 401 bool BrowserViewRenderer::IsVisible() const { |
| 463 // Ignore |window_visible_| if |attached_to_window_| is false. | 402 // Ignore |window_visible_| if |attached_to_window_| is false. |
| 464 return view_visible_ && (!attached_to_window_ || window_visible_); | 403 return view_visible_ && (!attached_to_window_ || window_visible_); |
| 465 } | 404 } |
| 466 | 405 |
| 467 gfx::Rect BrowserViewRenderer::GetScreenRect() const { | 406 gfx::Rect BrowserViewRenderer::GetScreenRect() const { |
| 468 return gfx::Rect(client_->GetLocationOnScreen(), gfx::Size(width_, height_)); | 407 return gfx::Rect(client_->GetLocationOnScreen(), gfx::Size(width_, height_)); |
| 469 } | 408 } |
| 470 | 409 |
| 471 void BrowserViewRenderer::DidInitializeCompositor( | 410 void BrowserViewRenderer::DidInitializeCompositor( |
| 472 content::SynchronousCompositor* compositor) { | 411 content::SynchronousCompositor* compositor) { |
| 473 TRACE_EVENT0("android_webview", | 412 TRACE_EVENT0("android_webview", |
| 474 "BrowserViewRenderer::DidInitializeCompositor"); | 413 "BrowserViewRenderer::DidInitializeCompositor"); |
| 475 DCHECK(compositor); | 414 DCHECK(compositor); |
| 476 DCHECK(!compositor_); | 415 DCHECK(!compositor_); |
| 477 compositor_ = compositor; | 416 compositor_ = compositor; |
| 478 } | 417 } |
| 479 | 418 |
| 480 void BrowserViewRenderer::DidDestroyCompositor( | 419 void BrowserViewRenderer::DidDestroyCompositor( |
| 481 content::SynchronousCompositor* compositor) { | 420 content::SynchronousCompositor* compositor) { |
| 482 TRACE_EVENT0("android_webview", "BrowserViewRenderer::DidDestroyCompositor"); | 421 TRACE_EVENT0("android_webview", "BrowserViewRenderer::DidDestroyCompositor"); |
| 483 DCHECK(compositor_); | 422 DCHECK(compositor_); |
| 484 SynchronousCompositorMemoryPolicy zero_policy; | |
| 485 if (hardware_enabled_) { | |
| 486 RequestMemoryPolicy(zero_policy); | |
| 487 } | |
| 488 DCHECK(memory_policy_ == zero_policy); | |
| 489 compositor_ = NULL; | 423 compositor_ = NULL; |
| 490 } | 424 } |
| 491 | 425 |
| 492 void BrowserViewRenderer::SetContinuousInvalidate(bool invalidate) { | 426 void BrowserViewRenderer::SetContinuousInvalidate(bool invalidate) { |
| 493 if (compositor_needs_continuous_invalidate_ == invalidate) | 427 if (compositor_needs_continuous_invalidate_ == invalidate) |
| 494 return; | 428 return; |
| 495 | 429 |
| 496 TRACE_EVENT_INSTANT1("android_webview", | 430 TRACE_EVENT_INSTANT1("android_webview", |
| 497 "BrowserViewRenderer::SetContinuousInvalidate", | 431 "BrowserViewRenderer::SetContinuousInvalidate", |
| 498 TRACE_EVENT_SCOPE_THREAD, | 432 TRACE_EVENT_SCOPE_THREAD, |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 809 base::StringAppendF(&str, | 743 base::StringAppendF(&str, |
| 810 "overscroll_rounding_error_: %s ", | 744 "overscroll_rounding_error_: %s ", |
| 811 overscroll_rounding_error_.ToString().c_str()); | 745 overscroll_rounding_error_.ToString().c_str()); |
| 812 base::StringAppendF( | 746 base::StringAppendF( |
| 813 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); | 747 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); |
| 814 base::StringAppendF(&str, "clear_view: %d ", clear_view_); | 748 base::StringAppendF(&str, "clear_view: %d ", clear_view_); |
| 815 return str; | 749 return str; |
| 816 } | 750 } |
| 817 | 751 |
| 818 } // namespace android_webview | 752 } // namespace android_webview |
| OLD | NEW |