[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 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 |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "android_webview/browser/browser_view_renderer.h" |
| 6 | |
[email protected] | e4a0b19 | 2014-02-27 01:47:05 | [diff] [blame] | 7 | #include "android_webview/browser/browser_view_renderer_client.h" |
boliu | b887d327 | 2015-03-19 00:29:26 | [diff] [blame] | 8 | #include "android_webview/browser/child_frame.h" |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 9 | #include "base/auto_reset.h" |
[email protected] | 7d67302a | 2014-05-03 02:17:07 | [diff] [blame] | 10 | #include "base/command_line.h" |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 11 | #include "base/logging.h" |
[email protected] | 7d67302a | 2014-05-03 02:17:07 | [diff] [blame] | 12 | #include "base/strings/string_number_conversions.h" |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 13 | #include "base/strings/stringprintf.h" |
hush | 7d13f84 | 2015-02-26 18:32:07 | [diff] [blame] | 14 | #include "base/supports_user_data.h" |
ssid | 3bc4c0ee | 2015-01-27 14:21:26 | [diff] [blame] | 15 | #include "base/trace_event/trace_event_argument.h" |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 16 | #include "cc/output/compositor_frame.h" |
hush | 7d13f84 | 2015-02-26 18:32:07 | [diff] [blame] | 17 | #include "content/public/browser/web_contents.h" |
[email protected] | 7d67302a | 2014-05-03 02:17:07 | [diff] [blame] | 18 | #include "content/public/common/content_switches.h" |
boliu | 6be0a912 | 2014-08-29 18:59:10 | [diff] [blame] | 19 | #include "gpu/command_buffer/service/gpu_switches.h" |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 20 | #include "third_party/skia/include/core/SkBitmap.h" |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 21 | #include "third_party/skia/include/core/SkCanvas.h" |
| 22 | #include "third_party/skia/include/core/SkPicture.h" |
[email protected] | 1dfaaff | 2014-04-30 14:54:59 | [diff] [blame] | 23 | #include "third_party/skia/include/core/SkPictureRecorder.h" |
tfarina | 6d5dba56 | 2014-10-24 03:48:14 | [diff] [blame] | 24 | #include "ui/gfx/geometry/vector2d_conversions.h" |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 25 | |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 26 | namespace android_webview { |
| 27 | |
| 28 | namespace { |
| 29 | |
boliu | d9d957b | 2014-12-17 17:24:03 | [diff] [blame] | 30 | const double kEpsilon = 1e-8; |
| 31 | |
[email protected] | 691ac7a | 2014-06-27 19:09:49 | [diff] [blame] | 32 | const int64 kFallbackTickTimeoutInMilliseconds = 100; |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 33 | |
[email protected] | 7d67302a | 2014-05-03 02:17:07 | [diff] [blame] | 34 | // Used to calculate memory allocation. Determined experimentally. |
[email protected] | 14f7a8b | 2014-07-03 03:44:51 | [diff] [blame] | 35 | const size_t kMemoryMultiplier = 20; |
[email protected] | 7d67302a | 2014-05-03 02:17:07 | [diff] [blame] | 36 | const size_t kBytesPerPixel = 4; |
| 37 | const size_t kMemoryAllocationStep = 5 * 1024 * 1024; |
boliu | 6be0a912 | 2014-08-29 18:59:10 | [diff] [blame] | 38 | uint64 g_memory_override_in_bytes = 0u; |
[email protected] | 7d67302a | 2014-05-03 02:17:07 | [diff] [blame] | 39 | |
hush | 7d13f84 | 2015-02-26 18:32:07 | [diff] [blame] | 40 | const void* kBrowserViewRendererUserDataKey = &kBrowserViewRendererUserDataKey; |
| 41 | |
| 42 | class BrowserViewRendererUserData : public base::SupportsUserData::Data { |
| 43 | public: |
| 44 | BrowserViewRendererUserData(BrowserViewRenderer* ptr) : bvr_(ptr) {} |
| 45 | |
| 46 | static BrowserViewRenderer* GetBrowserViewRenderer( |
| 47 | content::WebContents* web_contents) { |
| 48 | if (!web_contents) |
| 49 | return NULL; |
| 50 | BrowserViewRendererUserData* data = |
| 51 | static_cast<BrowserViewRendererUserData*>( |
| 52 | web_contents->GetUserData(kBrowserViewRendererUserDataKey)); |
| 53 | return data ? data->bvr_ : NULL; |
| 54 | } |
| 55 | |
| 56 | private: |
| 57 | BrowserViewRenderer* bvr_; |
| 58 | }; |
| 59 | |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 60 | } // namespace |
| 61 | |
[email protected] | 7d67302a | 2014-05-03 02:17:07 | [diff] [blame] | 62 | // static |
reveman | ec103f0 | 2014-09-29 19:12:31 | [diff] [blame] | 63 | void BrowserViewRenderer::CalculateTileMemoryPolicy() { |
pgal.u-szeged | 929d45a9 | 2014-10-28 11:50:41 | [diff] [blame] | 64 | base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); |
boliu | 6be0a912 | 2014-08-29 18:59:10 | [diff] [blame] | 65 | |
| 66 | // If the value was overridden on the command line, use the specified value. |
| 67 | bool client_hard_limit_bytes_overridden = |
| 68 | cl->HasSwitch(switches::kForceGpuMemAvailableMb); |
| 69 | if (client_hard_limit_bytes_overridden) { |
| 70 | base::StringToUint64( |
| 71 | base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 72 | switches::kForceGpuMemAvailableMb), |
| 73 | &g_memory_override_in_bytes); |
| 74 | g_memory_override_in_bytes *= 1024 * 1024; |
| 75 | } |
[email protected] | 7d67302a | 2014-05-03 02:17:07 | [diff] [blame] | 76 | } |
| 77 | |
hush | 7d13f84 | 2015-02-26 18:32:07 | [diff] [blame] | 78 | // static |
| 79 | BrowserViewRenderer* BrowserViewRenderer::FromWebContents( |
| 80 | content::WebContents* web_contents) { |
| 81 | return BrowserViewRendererUserData::GetBrowserViewRenderer(web_contents); |
| 82 | } |
| 83 | |
[email protected] | e4a0b19 | 2014-02-27 01:47:05 | [diff] [blame] | 84 | BrowserViewRenderer::BrowserViewRenderer( |
| 85 | BrowserViewRendererClient* client, |
[email protected] | 596f7e7 | 2014-03-21 20:03:26 | [diff] [blame] | 86 | const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 87 | : client_(client), |
hush | 619ac5b4a | 2014-10-24 23:51:27 | [diff] [blame] | 88 | shared_renderer_state_(ui_task_runner, this), |
[email protected] | 596f7e7 | 2014-03-21 20:03:26 | [diff] [blame] | 89 | ui_task_runner_(ui_task_runner), |
[email protected] | 7a46143 | 2014-06-17 23:50:12 | [diff] [blame] | 90 | compositor_(NULL), |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 91 | is_paused_(false), |
| 92 | view_visible_(false), |
| 93 | window_visible_(false), |
| 94 | attached_to_window_(false), |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 95 | hardware_enabled_(false), |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 96 | dip_scale_(0.0), |
| 97 | page_scale_factor_(1.0), |
| 98 | on_new_picture_enable_(false), |
| 99 | clear_view_(false), |
hush | d00f1045 | 2015-02-25 22:11:10 | [diff] [blame] | 100 | offscreen_pre_raster_(false), |
boliu | 04aa64d | 2014-11-12 00:31:08 | [diff] [blame] | 101 | fallback_tick_pending_(false) { |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 102 | } |
| 103 | |
| 104 | BrowserViewRenderer::~BrowserViewRenderer() { |
[email protected] | 7d67302a | 2014-05-03 02:17:07 | [diff] [blame] | 105 | } |
| 106 | |
hush | 7d13f84 | 2015-02-26 18:32:07 | [diff] [blame] | 107 | void BrowserViewRenderer::RegisterWithWebContents( |
| 108 | content::WebContents* web_contents) { |
| 109 | web_contents->SetUserData(kBrowserViewRendererUserDataKey, |
| 110 | new BrowserViewRendererUserData(this)); |
| 111 | } |
| 112 | |
boliu | 6a7f826 | 2014-12-09 00:31:28 | [diff] [blame] | 113 | SharedRendererState* BrowserViewRenderer::GetAwDrawGLViewContext() { |
| 114 | return &shared_renderer_state_; |
hush | 619ac5b4a | 2014-10-24 23:51:27 | [diff] [blame] | 115 | } |
| 116 | |
boliu | 22c7532 | 2014-10-25 02:06:47 | [diff] [blame] | 117 | bool BrowserViewRenderer::RequestDrawGL(bool wait_for_completion) { |
| 118 | return client_->RequestDrawGL(wait_for_completion); |
hush | 619ac5b4a | 2014-10-24 23:51:27 | [diff] [blame] | 119 | } |
| 120 | |
[email protected] | 7d67302a | 2014-05-03 02:17:07 | [diff] [blame] | 121 | void BrowserViewRenderer::TrimMemory(const int level, const bool visible) { |
boliu | a3434da | 2014-10-14 01:31:15 | [diff] [blame] | 122 | DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
[email protected] | 7d67302a | 2014-05-03 02:17:07 | [diff] [blame] | 123 | // Constants from Android ComponentCallbacks2. |
| 124 | enum { |
| 125 | TRIM_MEMORY_RUNNING_LOW = 10, |
| 126 | TRIM_MEMORY_UI_HIDDEN = 20, |
| 127 | TRIM_MEMORY_BACKGROUND = 40, |
boliu | a3d41bdc | 2014-11-07 22:34:49 | [diff] [blame] | 128 | TRIM_MEMORY_MODERATE = 60, |
[email protected] | 7d67302a | 2014-05-03 02:17:07 | [diff] [blame] | 129 | }; |
| 130 | |
| 131 | // Not urgent enough. TRIM_MEMORY_UI_HIDDEN is treated specially because |
| 132 | // it does not indicate memory pressure, but merely that the app is |
| 133 | // backgrounded. |
| 134 | if (level < TRIM_MEMORY_RUNNING_LOW || level == TRIM_MEMORY_UI_HIDDEN) |
| 135 | return; |
| 136 | |
| 137 | // Do not release resources on view we expect to get DrawGL soon. |
| 138 | if (level < TRIM_MEMORY_BACKGROUND && visible) |
| 139 | return; |
| 140 | |
boliu | 77de021 | 2014-10-28 04:06:33 | [diff] [blame] | 141 | // Nothing to drop. |
| 142 | if (!compositor_ || !hardware_enabled_) |
[email protected] | 7d67302a | 2014-05-03 02:17:07 | [diff] [blame] | 143 | return; |
| 144 | |
| 145 | TRACE_EVENT0("android_webview", "BrowserViewRenderer::TrimMemory"); |
| 146 | |
hush | 6ef6205 | 2015-04-16 04:46:35 | [diff] [blame] | 147 | // If offscreen pre-raster is disabled, drop everything in hardware. Otherwise |
| 148 | // keep the tiles and just delete the HardwareRenderer. |
boliu | a3d41bdc | 2014-11-07 22:34:49 | [diff] [blame] | 149 | if (level >= TRIM_MEMORY_MODERATE) { |
hush | 6ef6205 | 2015-04-16 04:46:35 | [diff] [blame] | 150 | if (offscreen_pre_raster_) |
| 151 | shared_renderer_state_.DeleteHardwareRendererOnUI(); |
| 152 | else |
| 153 | shared_renderer_state_.ReleaseHardwareDrawIfNeededOnUI(); |
boliu | a3d41bdc | 2014-11-07 22:34:49 | [diff] [blame] | 154 | return; |
| 155 | } |
| 156 | |
boliu | 77de021 | 2014-10-28 04:06:33 | [diff] [blame] | 157 | // Just set the memory limit to 0 and drop all tiles. This will be reset to |
| 158 | // normal levels in the next DrawGL call. |
hush | 6ef6205 | 2015-04-16 04:46:35 | [diff] [blame] | 159 | if (!offscreen_pre_raster_) |
| 160 | compositor_->SetMemoryPolicy(0u); |
[email protected] | 7d67302a | 2014-05-03 02:17:07 | [diff] [blame] | 161 | } |
| 162 | |
hush | 6ef6205 | 2015-04-16 04:46:35 | [diff] [blame] | 163 | void BrowserViewRenderer::UpdateMemoryPolicy() { |
| 164 | if (!hardware_enabled_) { |
| 165 | compositor_->SetMemoryPolicy(0u); |
| 166 | return; |
| 167 | } |
boliu | 77de021 | 2014-10-28 04:06:33 | [diff] [blame] | 168 | |
hush | 6ef6205 | 2015-04-16 04:46:35 | [diff] [blame] | 169 | size_t bytes_limit = 0u; |
| 170 | if (g_memory_override_in_bytes) { |
| 171 | bytes_limit = static_cast<size_t>(g_memory_override_in_bytes); |
| 172 | } else { |
| 173 | gfx::Rect interest_rect = offscreen_pre_raster_ |
| 174 | ? gfx::Rect(size_) |
| 175 | : last_on_draw_global_visible_rect_; |
| 176 | size_t width = interest_rect.width(); |
| 177 | size_t height = interest_rect.height(); |
| 178 | bytes_limit = kMemoryMultiplier * kBytesPerPixel * width * height; |
| 179 | // Round up to a multiple of kMemoryAllocationStep. |
| 180 | bytes_limit = |
| 181 | (bytes_limit / kMemoryAllocationStep + 1) * kMemoryAllocationStep; |
| 182 | } |
| 183 | |
| 184 | compositor_->SetMemoryPolicy(bytes_limit); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 185 | } |
| 186 | |
boliu | 04aa64d | 2014-11-12 00:31:08 | [diff] [blame] | 187 | void BrowserViewRenderer::PrepareToDraw(const gfx::Vector2d& scroll, |
| 188 | const gfx::Rect& global_visible_rect) { |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 189 | last_on_draw_scroll_offset_ = scroll; |
| 190 | last_on_draw_global_visible_rect_ = global_visible_rect; |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 191 | } |
| 192 | |
boliu | 83cbc841 | 2015-01-14 03:16:59 | [diff] [blame] | 193 | bool BrowserViewRenderer::CanOnDraw() { |
boliu | e2f86986 | 2014-12-03 21:13:48 | [diff] [blame] | 194 | if (!compositor_) { |
| 195 | TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_NoCompositor", |
| 196 | TRACE_EVENT_SCOPE_THREAD); |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 197 | return false; |
boliu | e2f86986 | 2014-12-03 21:13:48 | [diff] [blame] | 198 | } |
boliu | 83cbc841 | 2015-01-14 03:16:59 | [diff] [blame] | 199 | if (clear_view_) { |
| 200 | TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_ClearView", |
| 201 | TRACE_EVENT_SCOPE_THREAD); |
| 202 | return false; |
| 203 | } |
| 204 | |
| 205 | return true; |
| 206 | } |
| 207 | |
| 208 | bool BrowserViewRenderer::OnDrawHardware() { |
| 209 | TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDrawHardware"); |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 210 | |
boliu | 83cbc841 | 2015-01-14 03:16:59 | [diff] [blame] | 211 | shared_renderer_state_.InitializeHardwareDrawIfNeededOnUI(); |
| 212 | |
| 213 | if (!CanOnDraw()) { |
| 214 | return false; |
| 215 | } |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 216 | |
hush | 619ac5b4a | 2014-10-24 23:51:27 | [diff] [blame] | 217 | shared_renderer_state_.SetScrollOffsetOnUI(last_on_draw_scroll_offset_); |
boliu | 4d7902e | 2015-04-10 20:36:59 | [diff] [blame] | 218 | hardware_enabled_ = true; |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 219 | |
boliu | b887d327 | 2015-03-19 00:29:26 | [diff] [blame] | 220 | return CompositeHw(); |
boliu | 96ba1a6 | 2014-10-16 02:29:52 | [diff] [blame] | 221 | } |
| 222 | |
boliu | b887d327 | 2015-03-19 00:29:26 | [diff] [blame] | 223 | bool BrowserViewRenderer::CompositeHw() { |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 224 | CancelFallbackTick(); |
| 225 | |
boliu | b887d327 | 2015-03-19 00:29:26 | [diff] [blame] | 226 | ReturnResourceFromParent(); |
hush | 6ef6205 | 2015-04-16 04:46:35 | [diff] [blame] | 227 | UpdateMemoryPolicy(); |
boliu | 96ba1a6 | 2014-10-16 02:29:52 | [diff] [blame] | 228 | |
boliu | b887d327 | 2015-03-19 00:29:26 | [diff] [blame] | 229 | ParentCompositorDrawConstraints parent_draw_constraints = |
hush | 619ac5b4a | 2014-10-24 23:51:27 | [diff] [blame] | 230 | shared_renderer_state_.GetParentDrawConstraintsOnUI(); |
boliu | 04aa64d | 2014-11-12 00:31:08 | [diff] [blame] | 231 | gfx::Size surface_size(size_); |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 232 | gfx::Rect viewport(surface_size); |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 233 | gfx::Rect clip = viewport; |
[email protected] | bd532459 | 2014-07-31 09:09:33 | [diff] [blame] | 234 | gfx::Transform transform_for_tile_priority = |
boliu | b887d327 | 2015-03-19 00:29:26 | [diff] [blame] | 235 | parent_draw_constraints.transform; |
[email protected] | bd532459 | 2014-07-31 09:09:33 | [diff] [blame] | 236 | |
| 237 | // If the WebView is on a layer, WebView does not know what transform is |
| 238 | // applied onto the layer so global visible rect does not make sense here. |
| 239 | // In this case, just use the surface rect for tiling. |
| 240 | gfx::Rect viewport_rect_for_tile_priority; |
hush | d00f1045 | 2015-02-25 22:11:10 | [diff] [blame] | 241 | |
| 242 | // Leave viewport_rect_for_tile_priority empty if offscreen_pre_raster_ is on. |
| 243 | if (!offscreen_pre_raster_) { |
boliu | b887d327 | 2015-03-19 00:29:26 | [diff] [blame] | 244 | if (parent_draw_constraints.is_layer) { |
| 245 | viewport_rect_for_tile_priority = parent_draw_constraints.surface_rect; |
hush | d00f1045 | 2015-02-25 22:11:10 | [diff] [blame] | 246 | } else { |
| 247 | viewport_rect_for_tile_priority = last_on_draw_global_visible_rect_; |
| 248 | } |
boliu | 6b96a04 | 2014-10-21 23:23:57 | [diff] [blame] | 249 | } |
[email protected] | bd532459 | 2014-07-31 09:09:33 | [diff] [blame] | 250 | |
| 251 | scoped_ptr<cc::CompositorFrame> frame = |
| 252 | compositor_->DemandDrawHw(surface_size, |
| 253 | gfx::Transform(), |
| 254 | viewport, |
| 255 | clip, |
| 256 | viewport_rect_for_tile_priority, |
| 257 | transform_for_tile_priority); |
boliu | b887d327 | 2015-03-19 00:29:26 | [diff] [blame] | 258 | if (!frame.get()) { |
| 259 | TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", |
| 260 | TRACE_EVENT_SCOPE_THREAD); |
| 261 | return false; |
| 262 | } |
| 263 | |
| 264 | scoped_ptr<ChildFrame> child_frame = make_scoped_ptr( |
| 265 | new ChildFrame(frame.Pass(), viewport_rect_for_tile_priority, |
| 266 | transform_for_tile_priority, offscreen_pre_raster_, |
| 267 | parent_draw_constraints.is_layer)); |
| 268 | |
boliu | b887d327 | 2015-03-19 00:29:26 | [diff] [blame] | 269 | // Uncommitted frame can happen with consecutive fallback ticks. |
| 270 | ReturnUnusedResource(shared_renderer_state_.PassUncommittedFrameOnUI()); |
| 271 | shared_renderer_state_.SetCompositorFrameOnUI(child_frame.Pass()); |
| 272 | return true; |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 273 | } |
| 274 | |
[email protected] | bd532459 | 2014-07-31 09:09:33 | [diff] [blame] | 275 | void BrowserViewRenderer::UpdateParentDrawConstraints() { |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 276 | PostInvalidateWithFallback(); |
hush | abaade8 | 2015-03-20 02:09:29 | [diff] [blame] | 277 | ParentCompositorDrawConstraints parent_draw_constraints = |
| 278 | shared_renderer_state_.GetParentDrawConstraintsOnUI(); |
| 279 | client_->ParentDrawConstraintsUpdated(parent_draw_constraints); |
[email protected] | bd532459 | 2014-07-31 09:09:33 | [diff] [blame] | 280 | } |
| 281 | |
boliu | 6439a53 | 2014-10-07 06:00:01 | [diff] [blame] | 282 | void BrowserViewRenderer::ReturnUnusedResource( |
boliu | b887d327 | 2015-03-19 00:29:26 | [diff] [blame] | 283 | scoped_ptr<ChildFrame> child_frame) { |
| 284 | if (!child_frame.get() || !child_frame->frame.get()) |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 285 | return; |
[email protected] | c62fc98 | 2014-06-27 04:49:02 | [diff] [blame] | 286 | |
| 287 | cc::CompositorFrameAck frame_ack; |
| 288 | cc::TransferableResource::ReturnResources( |
boliu | b887d327 | 2015-03-19 00:29:26 | [diff] [blame] | 289 | child_frame->frame->delegated_frame_data->resource_list, |
| 290 | &frame_ack.resources); |
boliu | 105144f | 2014-10-20 17:54:36 | [diff] [blame] | 291 | if (compositor_ && !frame_ack.resources.empty()) |
[email protected] | c62fc98 | 2014-06-27 04:49:02 | [diff] [blame] | 292 | compositor_->ReturnResources(frame_ack); |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 293 | } |
| 294 | |
[email protected] | c62fc98 | 2014-06-27 04:49:02 | [diff] [blame] | 295 | void BrowserViewRenderer::ReturnResourceFromParent() { |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 296 | cc::CompositorFrameAck frame_ack; |
hush | 619ac5b4a | 2014-10-24 23:51:27 | [diff] [blame] | 297 | shared_renderer_state_.SwapReturnedResourcesOnUI(&frame_ack.resources); |
boliu | 105144f | 2014-10-20 17:54:36 | [diff] [blame] | 298 | if (compositor_ && !frame_ack.resources.empty()) { |
[email protected] | 7a46143 | 2014-06-17 23:50:12 | [diff] [blame] | 299 | compositor_->ReturnResources(frame_ack); |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 300 | } |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 301 | } |
| 302 | |
tobiasjs | 125f6e7 | 2015-02-18 17:34:28 | [diff] [blame] | 303 | void BrowserViewRenderer::DetachFunctorFromView() { |
| 304 | client_->DetachFunctorFromView(); |
hush | c4a6fc02 | 2014-10-30 01:34:14 | [diff] [blame] | 305 | } |
| 306 | |
boliu | 04aa64d | 2014-11-12 00:31:08 | [diff] [blame] | 307 | bool BrowserViewRenderer::OnDrawSoftware(SkCanvas* canvas) { |
boliu | 83cbc841 | 2015-01-14 03:16:59 | [diff] [blame] | 308 | return CanOnDraw() && CompositeSW(canvas); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 309 | } |
| 310 | |
| 311 | skia::RefPtr<SkPicture> BrowserViewRenderer::CapturePicture(int width, |
| 312 | int height) { |
| 313 | TRACE_EVENT0("android_webview", "BrowserViewRenderer::CapturePicture"); |
| 314 | |
| 315 | // Return empty Picture objects for empty SkPictures. |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 316 | if (width <= 0 || height <= 0) { |
[email protected] | c7bd054 | 2014-07-14 18:22:04 | [diff] [blame] | 317 | SkPictureRecorder emptyRecorder; |
| 318 | emptyRecorder.beginRecording(0, 0); |
| 319 | return skia::AdoptRef(emptyRecorder.endRecording()); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 320 | } |
| 321 | |
| 322 | // Reset scroll back to the origin, will go back to the old |
| 323 | // value when scroll_reset is out of scope. |
[email protected] | 7a46143 | 2014-06-17 23:50:12 | [diff] [blame] | 324 | base::AutoReset<gfx::Vector2dF> scroll_reset(&scroll_offset_dip_, |
| 325 | gfx::Vector2dF()); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 326 | |
[email protected] | 1dfaaff | 2014-04-30 14:54:59 | [diff] [blame] | 327 | SkPictureRecorder recorder; |
| 328 | SkCanvas* rec_canvas = recorder.beginRecording(width, height, NULL, 0); |
[email protected] | 7a46143 | 2014-06-17 23:50:12 | [diff] [blame] | 329 | if (compositor_) |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 330 | CompositeSW(rec_canvas); |
[email protected] | 1dfaaff | 2014-04-30 14:54:59 | [diff] [blame] | 331 | return skia::AdoptRef(recorder.endRecording()); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 332 | } |
| 333 | |
| 334 | void BrowserViewRenderer::EnableOnNewPicture(bool enabled) { |
| 335 | on_new_picture_enable_ = enabled; |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 336 | } |
| 337 | |
| 338 | void BrowserViewRenderer::ClearView() { |
| 339 | TRACE_EVENT_INSTANT0("android_webview", |
| 340 | "BrowserViewRenderer::ClearView", |
| 341 | TRACE_EVENT_SCOPE_THREAD); |
| 342 | if (clear_view_) |
| 343 | return; |
| 344 | |
| 345 | clear_view_ = true; |
| 346 | // Always invalidate ignoring the compositor to actually clear the webview. |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 347 | PostInvalidateWithFallback(); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 348 | } |
| 349 | |
hush | d00f1045 | 2015-02-25 22:11:10 | [diff] [blame] | 350 | void BrowserViewRenderer::SetOffscreenPreRaster(bool enable) { |
hush | 6ef6205 | 2015-04-16 04:46:35 | [diff] [blame] | 351 | if (offscreen_pre_raster_ != enable && compositor_) |
| 352 | UpdateMemoryPolicy(); |
| 353 | |
hush | d00f1045 | 2015-02-25 22:11:10 | [diff] [blame] | 354 | offscreen_pre_raster_ = enable; |
| 355 | } |
| 356 | |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 357 | void BrowserViewRenderer::SetIsPaused(bool paused) { |
| 358 | TRACE_EVENT_INSTANT1("android_webview", |
| 359 | "BrowserViewRenderer::SetIsPaused", |
| 360 | TRACE_EVENT_SCOPE_THREAD, |
| 361 | "paused", |
| 362 | paused); |
| 363 | is_paused_ = paused; |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 364 | UpdateCompositorIsActive(); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 365 | } |
| 366 | |
| 367 | void BrowserViewRenderer::SetViewVisibility(bool view_visible) { |
| 368 | TRACE_EVENT_INSTANT1("android_webview", |
| 369 | "BrowserViewRenderer::SetViewVisibility", |
| 370 | TRACE_EVENT_SCOPE_THREAD, |
| 371 | "view_visible", |
| 372 | view_visible); |
| 373 | view_visible_ = view_visible; |
| 374 | } |
| 375 | |
| 376 | void BrowserViewRenderer::SetWindowVisibility(bool window_visible) { |
| 377 | TRACE_EVENT_INSTANT1("android_webview", |
| 378 | "BrowserViewRenderer::SetWindowVisibility", |
| 379 | TRACE_EVENT_SCOPE_THREAD, |
| 380 | "window_visible", |
| 381 | window_visible); |
| 382 | window_visible_ = window_visible; |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 383 | UpdateCompositorIsActive(); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 384 | } |
| 385 | |
| 386 | void BrowserViewRenderer::OnSizeChanged(int width, int height) { |
| 387 | TRACE_EVENT_INSTANT2("android_webview", |
| 388 | "BrowserViewRenderer::OnSizeChanged", |
| 389 | TRACE_EVENT_SCOPE_THREAD, |
| 390 | "width", |
| 391 | width, |
| 392 | "height", |
| 393 | height); |
boliu | 04aa64d | 2014-11-12 00:31:08 | [diff] [blame] | 394 | size_.SetSize(width, height); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 395 | } |
| 396 | |
| 397 | void BrowserViewRenderer::OnAttachedToWindow(int width, int height) { |
| 398 | TRACE_EVENT2("android_webview", |
| 399 | "BrowserViewRenderer::OnAttachedToWindow", |
| 400 | "width", |
| 401 | width, |
| 402 | "height", |
| 403 | height); |
| 404 | attached_to_window_ = true; |
boliu | 04aa64d | 2014-11-12 00:31:08 | [diff] [blame] | 405 | size_.SetSize(width, height); |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 406 | UpdateCompositorIsActive(); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 407 | } |
| 408 | |
| 409 | void BrowserViewRenderer::OnDetachedFromWindow() { |
| 410 | TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow"); |
boliu | a3d41bdc | 2014-11-07 22:34:49 | [diff] [blame] | 411 | shared_renderer_state_.ReleaseHardwareDrawIfNeededOnUI(); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 412 | attached_to_window_ = false; |
[email protected] | 686474c7 | 2014-07-22 02:09:50 | [diff] [blame] | 413 | DCHECK(!hardware_enabled_); |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 414 | UpdateCompositorIsActive(); |
[email protected] | 686474c7 | 2014-07-22 02:09:50 | [diff] [blame] | 415 | } |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 416 | |
[email protected] | 686474c7 | 2014-07-22 02:09:50 | [diff] [blame] | 417 | void BrowserViewRenderer::ReleaseHardware() { |
| 418 | DCHECK(hardware_enabled_); |
hush | c4a6fc02 | 2014-10-30 01:34:14 | [diff] [blame] | 419 | ReturnUnusedResource(shared_renderer_state_.PassUncommittedFrameOnUI()); |
[email protected] | 686474c7 | 2014-07-22 02:09:50 | [diff] [blame] | 420 | ReturnResourceFromParent(); |
hush | c4a6fc02 | 2014-10-30 01:34:14 | [diff] [blame] | 421 | DCHECK(shared_renderer_state_.ReturnedResourcesEmptyOnUI()); |
[email protected] | 686474c7 | 2014-07-22 02:09:50 | [diff] [blame] | 422 | |
boliu | 105144f | 2014-10-20 17:54:36 | [diff] [blame] | 423 | if (compositor_) { |
boliu | 4d7902e | 2015-04-10 20:36:59 | [diff] [blame] | 424 | compositor_->SetMemoryPolicy(0u); |
boliu | 105144f | 2014-10-20 17:54:36 | [diff] [blame] | 425 | } |
[email protected] | 686474c7 | 2014-07-22 02:09:50 | [diff] [blame] | 426 | |
boliu | 105144f | 2014-10-20 17:54:36 | [diff] [blame] | 427 | hardware_enabled_ = false; |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 428 | } |
| 429 | |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 430 | bool BrowserViewRenderer::IsVisible() const { |
| 431 | // Ignore |window_visible_| if |attached_to_window_| is false. |
| 432 | return view_visible_ && (!attached_to_window_ || window_visible_); |
| 433 | } |
| 434 | |
| 435 | gfx::Rect BrowserViewRenderer::GetScreenRect() const { |
boliu | 04aa64d | 2014-11-12 00:31:08 | [diff] [blame] | 436 | return gfx::Rect(client_->GetLocationOnScreen(), size_); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 437 | } |
| 438 | |
| 439 | void BrowserViewRenderer::DidInitializeCompositor( |
| 440 | content::SynchronousCompositor* compositor) { |
| 441 | TRACE_EVENT0("android_webview", |
| 442 | "BrowserViewRenderer::DidInitializeCompositor"); |
[email protected] | e4a0b19 | 2014-02-27 01:47:05 | [diff] [blame] | 443 | DCHECK(compositor); |
[email protected] | 7a46143 | 2014-06-17 23:50:12 | [diff] [blame] | 444 | DCHECK(!compositor_); |
| 445 | compositor_ = compositor; |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 446 | UpdateCompositorIsActive(); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 447 | } |
| 448 | |
| 449 | void BrowserViewRenderer::DidDestroyCompositor( |
| 450 | content::SynchronousCompositor* compositor) { |
| 451 | TRACE_EVENT0("android_webview", "BrowserViewRenderer::DidDestroyCompositor"); |
[email protected] | 7a46143 | 2014-06-17 23:50:12 | [diff] [blame] | 452 | DCHECK(compositor_); |
sunnyps | 0e3d721 | 2015-06-02 03:09:22 | [diff] [blame] | 453 | compositor_->SetIsActive(false); |
boliu | 105144f | 2014-10-20 17:54:36 | [diff] [blame] | 454 | compositor_ = NULL; |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 455 | } |
| 456 | |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 457 | void BrowserViewRenderer::SetDipScale(float dip_scale) { |
| 458 | dip_scale_ = dip_scale; |
boliu | d9d957b | 2014-12-17 17:24:03 | [diff] [blame] | 459 | CHECK_GT(dip_scale_, 0.f); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 460 | } |
| 461 | |
| 462 | gfx::Vector2d BrowserViewRenderer::max_scroll_offset() const { |
boliu | d9d957b | 2014-12-17 17:24:03 | [diff] [blame] | 463 | DCHECK_GT(dip_scale_, 0.f); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 464 | return gfx::ToCeiledVector2d(gfx::ScaleVector2d( |
| 465 | max_scroll_offset_dip_, dip_scale_ * page_scale_factor_)); |
| 466 | } |
| 467 | |
| 468 | void BrowserViewRenderer::ScrollTo(gfx::Vector2d scroll_offset) { |
| 469 | gfx::Vector2d max_offset = max_scroll_offset(); |
| 470 | gfx::Vector2dF scroll_offset_dip; |
| 471 | // To preserve the invariant that scrolling to the maximum physical pixel |
| 472 | // value also scrolls to the maximum dip pixel value we transform the physical |
| 473 | // offset into the dip offset by using a proportion (instead of dividing by |
| 474 | // dip_scale * page_scale_factor). |
| 475 | if (max_offset.x()) { |
| 476 | scroll_offset_dip.set_x((scroll_offset.x() * max_scroll_offset_dip_.x()) / |
| 477 | max_offset.x()); |
| 478 | } |
| 479 | if (max_offset.y()) { |
| 480 | scroll_offset_dip.set_y((scroll_offset.y() * max_scroll_offset_dip_.y()) / |
| 481 | max_offset.y()); |
| 482 | } |
| 483 | |
boliu | d9d957b | 2014-12-17 17:24:03 | [diff] [blame] | 484 | DCHECK_LE(0.f, scroll_offset_dip.x()); |
| 485 | DCHECK_LE(0.f, scroll_offset_dip.y()); |
| 486 | DCHECK(scroll_offset_dip.x() < max_scroll_offset_dip_.x() || |
| 487 | scroll_offset_dip.x() - max_scroll_offset_dip_.x() < kEpsilon) |
| 488 | << scroll_offset_dip.x() << " " << max_scroll_offset_dip_.x(); |
| 489 | DCHECK(scroll_offset_dip.y() < max_scroll_offset_dip_.y() || |
| 490 | scroll_offset_dip.y() - max_scroll_offset_dip_.y() < kEpsilon) |
| 491 | << scroll_offset_dip.y() << " " << max_scroll_offset_dip_.y(); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 492 | |
[email protected] | 7a46143 | 2014-06-17 23:50:12 | [diff] [blame] | 493 | if (scroll_offset_dip_ == scroll_offset_dip) |
| 494 | return; |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 495 | |
[email protected] | 7a46143 | 2014-06-17 23:50:12 | [diff] [blame] | 496 | scroll_offset_dip_ = scroll_offset_dip; |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 497 | |
[email protected] | ec2322e | 2014-05-15 16:32:00 | [diff] [blame] | 498 | TRACE_EVENT_INSTANT2("android_webview", |
| 499 | "BrowserViewRenderer::ScrollTo", |
| 500 | TRACE_EVENT_SCOPE_THREAD, |
| 501 | "x", |
| 502 | scroll_offset_dip.x(), |
| 503 | "y", |
| 504 | scroll_offset_dip.y()); |
| 505 | |
[email protected] | 7a46143 | 2014-06-17 23:50:12 | [diff] [blame] | 506 | if (compositor_) |
| 507 | compositor_->DidChangeRootLayerScrollOffset(); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 508 | } |
| 509 | |
| 510 | void BrowserViewRenderer::DidUpdateContent() { |
| 511 | TRACE_EVENT_INSTANT0("android_webview", |
| 512 | "BrowserViewRenderer::DidUpdateContent", |
| 513 | TRACE_EVENT_SCOPE_THREAD); |
| 514 | clear_view_ = false; |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 515 | if (on_new_picture_enable_) |
| 516 | client_->OnNewPicture(); |
| 517 | } |
| 518 | |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 519 | void BrowserViewRenderer::SetTotalRootLayerScrollOffset( |
| 520 | gfx::Vector2dF scroll_offset_dip) { |
[email protected] | 7a46143 | 2014-06-17 23:50:12 | [diff] [blame] | 521 | // TOOD(mkosiba): Add a DCHECK to say that this does _not_ get called during |
| 522 | // DrawGl when http://crbug.com/249972 is fixed. |
| 523 | if (scroll_offset_dip_ == scroll_offset_dip) |
| 524 | return; |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 525 | |
[email protected] | 7a46143 | 2014-06-17 23:50:12 | [diff] [blame] | 526 | scroll_offset_dip_ = scroll_offset_dip; |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 527 | |
| 528 | gfx::Vector2d max_offset = max_scroll_offset(); |
| 529 | gfx::Vector2d scroll_offset; |
| 530 | // For an explanation as to why this is done this way see the comment in |
| 531 | // BrowserViewRenderer::ScrollTo. |
| 532 | if (max_scroll_offset_dip_.x()) { |
| 533 | scroll_offset.set_x((scroll_offset_dip.x() * max_offset.x()) / |
| 534 | max_scroll_offset_dip_.x()); |
| 535 | } |
| 536 | |
| 537 | if (max_scroll_offset_dip_.y()) { |
| 538 | scroll_offset.set_y((scroll_offset_dip.y() * max_offset.y()) / |
| 539 | max_scroll_offset_dip_.y()); |
| 540 | } |
| 541 | |
boliu | 2d46b52 | 2014-08-29 22:33:44 | [diff] [blame] | 542 | DCHECK_LE(0, scroll_offset.x()); |
| 543 | DCHECK_LE(0, scroll_offset.y()); |
| 544 | DCHECK_LE(scroll_offset.x(), max_offset.x()); |
| 545 | DCHECK_LE(scroll_offset.y(), max_offset.y()); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 546 | |
| 547 | client_->ScrollContainerViewTo(scroll_offset); |
| 548 | } |
| 549 | |
| 550 | gfx::Vector2dF BrowserViewRenderer::GetTotalRootLayerScrollOffset() { |
| 551 | return scroll_offset_dip_; |
| 552 | } |
| 553 | |
| 554 | bool BrowserViewRenderer::IsExternalFlingActive() const { |
| 555 | return client_->IsFlingActive(); |
| 556 | } |
| 557 | |
[email protected] | ec2322e | 2014-05-15 16:32:00 | [diff] [blame] | 558 | void BrowserViewRenderer::UpdateRootLayerState( |
| 559 | const gfx::Vector2dF& total_scroll_offset_dip, |
| 560 | const gfx::Vector2dF& max_scroll_offset_dip, |
| 561 | const gfx::SizeF& scrollable_size_dip, |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 562 | float page_scale_factor, |
| 563 | float min_page_scale_factor, |
| 564 | float max_page_scale_factor) { |
[email protected] | ec2322e | 2014-05-15 16:32:00 | [diff] [blame] | 565 | TRACE_EVENT_INSTANT1( |
| 566 | "android_webview", |
| 567 | "BrowserViewRenderer::UpdateRootLayerState", |
| 568 | TRACE_EVENT_SCOPE_THREAD, |
| 569 | "state", |
boliu | a3434da | 2014-10-14 01:31:15 | [diff] [blame] | 570 | RootLayerStateAsValue(total_scroll_offset_dip, scrollable_size_dip)); |
[email protected] | ec2322e | 2014-05-15 16:32:00 | [diff] [blame] | 571 | |
boliu | d9d957b | 2014-12-17 17:24:03 | [diff] [blame] | 572 | DCHECK_GT(dip_scale_, 0.f); |
[email protected] | ec2322e | 2014-05-15 16:32:00 | [diff] [blame] | 573 | |
| 574 | max_scroll_offset_dip_ = max_scroll_offset_dip; |
boliu | d9d957b | 2014-12-17 17:24:03 | [diff] [blame] | 575 | DCHECK_LE(0.f, max_scroll_offset_dip_.x()); |
| 576 | DCHECK_LE(0.f, max_scroll_offset_dip_.y()); |
[email protected] | ec2322e | 2014-05-15 16:32:00 | [diff] [blame] | 577 | |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 578 | page_scale_factor_ = page_scale_factor; |
boliu | d9d957b | 2014-12-17 17:24:03 | [diff] [blame] | 579 | DCHECK_GT(page_scale_factor_, 0.f); |
[email protected] | ec2322e | 2014-05-15 16:32:00 | [diff] [blame] | 580 | |
| 581 | client_->UpdateScrollState(max_scroll_offset(), |
| 582 | scrollable_size_dip, |
| 583 | page_scale_factor, |
| 584 | min_page_scale_factor, |
| 585 | max_page_scale_factor); |
| 586 | SetTotalRootLayerScrollOffset(total_scroll_offset_dip); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 587 | } |
| 588 | |
ssid | 759dd8c | 2015-02-09 21:25:39 | [diff] [blame] | 589 | scoped_refptr<base::trace_event::ConvertableToTraceFormat> |
boliu | a3434da | 2014-10-14 01:31:15 | [diff] [blame] | 590 | BrowserViewRenderer::RootLayerStateAsValue( |
[email protected] | ec2322e | 2014-05-15 16:32:00 | [diff] [blame] | 591 | const gfx::Vector2dF& total_scroll_offset_dip, |
| 592 | const gfx::SizeF& scrollable_size_dip) { |
ssid | 759dd8c | 2015-02-09 21:25:39 | [diff] [blame] | 593 | scoped_refptr<base::trace_event::TracedValue> state = |
| 594 | new base::trace_event::TracedValue(); |
[email protected] | ec2322e | 2014-05-15 16:32:00 | [diff] [blame] | 595 | |
| 596 | state->SetDouble("total_scroll_offset_dip.x", total_scroll_offset_dip.x()); |
| 597 | state->SetDouble("total_scroll_offset_dip.y", total_scroll_offset_dip.y()); |
| 598 | |
| 599 | state->SetDouble("max_scroll_offset_dip.x", max_scroll_offset_dip_.x()); |
| 600 | state->SetDouble("max_scroll_offset_dip.y", max_scroll_offset_dip_.y()); |
| 601 | |
| 602 | state->SetDouble("scrollable_size_dip.width", scrollable_size_dip.width()); |
| 603 | state->SetDouble("scrollable_size_dip.height", scrollable_size_dip.height()); |
| 604 | |
| 605 | state->SetDouble("page_scale_factor", page_scale_factor_); |
boliu | a3434da | 2014-10-14 01:31:15 | [diff] [blame] | 606 | return state; |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 607 | } |
| 608 | |
| 609 | void BrowserViewRenderer::DidOverscroll(gfx::Vector2dF accumulated_overscroll, |
| 610 | gfx::Vector2dF latest_overscroll_delta, |
| 611 | gfx::Vector2dF current_fling_velocity) { |
| 612 | const float physical_pixel_scale = dip_scale_ * page_scale_factor_; |
| 613 | if (accumulated_overscroll == latest_overscroll_delta) |
| 614 | overscroll_rounding_error_ = gfx::Vector2dF(); |
| 615 | gfx::Vector2dF scaled_overscroll_delta = |
| 616 | gfx::ScaleVector2d(latest_overscroll_delta, physical_pixel_scale); |
| 617 | gfx::Vector2d rounded_overscroll_delta = gfx::ToRoundedVector2d( |
| 618 | scaled_overscroll_delta + overscroll_rounding_error_); |
| 619 | overscroll_rounding_error_ = |
| 620 | scaled_overscroll_delta - rounded_overscroll_delta; |
| 621 | client_->DidOverscroll(rounded_overscroll_delta); |
| 622 | } |
| 623 | |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 624 | void BrowserViewRenderer::PostInvalidate() { |
| 625 | TRACE_EVENT_INSTANT0("android_webview", "BrowserViewRenderer::PostInvalidate", |
| 626 | TRACE_EVENT_SCOPE_THREAD); |
| 627 | PostInvalidateWithFallback(); |
| 628 | } |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 629 | |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 630 | void BrowserViewRenderer::PostInvalidateWithFallback() { |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 631 | // Always call view invalidate. We rely the Android framework to ignore the |
| 632 | // invalidate when it's not needed such as when view is not visible. |
[email protected] | e4a0b19 | 2014-02-27 01:47:05 | [diff] [blame] | 633 | client_->PostInvalidate(); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 634 | |
| 635 | // Stop fallback ticks when one of these is true. |
| 636 | // 1) Webview is paused. Also need to check we are not in clear view since |
| 637 | // paused, offscreen still expect clear view to recover. |
| 638 | // 2) If we are attached to window and the window is not visible (eg when |
| 639 | // app is in the background). We are sure in this case the webview is used |
| 640 | // "on-screen" but that updates are not needed when in the background. |
| 641 | bool throttle_fallback_tick = |
| 642 | (is_paused_ && !clear_view_) || (attached_to_window_ && !window_visible_); |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 643 | |
| 644 | if (throttle_fallback_tick || fallback_tick_pending_) |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 645 | return; |
| 646 | |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 647 | DCHECK(post_fallback_tick_.IsCancelled()); |
| 648 | DCHECK(fallback_tick_fired_.IsCancelled()); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 649 | |
[email protected] | 691ac7a | 2014-06-27 19:09:49 | [diff] [blame] | 650 | post_fallback_tick_.Reset(base::Bind(&BrowserViewRenderer::PostFallbackTick, |
| 651 | base::Unretained(this))); |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 652 | ui_task_runner_->PostTask(FROM_HERE, post_fallback_tick_.callback()); |
| 653 | fallback_tick_pending_ = true; |
| 654 | } |
| 655 | |
| 656 | void BrowserViewRenderer::CancelFallbackTick() { |
| 657 | post_fallback_tick_.Cancel(); |
[email protected] | 691ac7a | 2014-06-27 19:09:49 | [diff] [blame] | 658 | fallback_tick_fired_.Cancel(); |
boliu | 4aa98dc6 | 2014-10-07 04:35:38 | [diff] [blame] | 659 | fallback_tick_pending_ = false; |
[email protected] | 691ac7a | 2014-06-27 19:09:49 | [diff] [blame] | 660 | } |
| 661 | |
| 662 | void BrowserViewRenderer::PostFallbackTick() { |
| 663 | DCHECK(fallback_tick_fired_.IsCancelled()); |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 664 | TRACE_EVENT0("android_webview", "BrowserViewRenderer::PostFallbackTick"); |
| 665 | post_fallback_tick_.Cancel(); |
[email protected] | 691ac7a | 2014-06-27 19:09:49 | [diff] [blame] | 666 | fallback_tick_fired_.Reset(base::Bind(&BrowserViewRenderer::FallbackTickFired, |
| 667 | base::Unretained(this))); |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 668 | ui_task_runner_->PostDelayedTask( |
| 669 | FROM_HERE, fallback_tick_fired_.callback(), |
| 670 | base::TimeDelta::FromMilliseconds(kFallbackTickTimeoutInMilliseconds)); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 671 | } |
| 672 | |
| 673 | void BrowserViewRenderer::FallbackTickFired() { |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 674 | TRACE_EVENT0("android_webview", "BrowserViewRenderer::FallbackTickFired"); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 675 | // This should only be called if OnDraw or DrawGL did not come in time, which |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 676 | // means fallback_tick_pending_ must still be true. |
| 677 | DCHECK(fallback_tick_pending_); |
| 678 | fallback_tick_fired_.Cancel(); |
boliu | 4aa98dc6 | 2014-10-07 04:35:38 | [diff] [blame] | 679 | fallback_tick_pending_ = false; |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 680 | if (compositor_) { |
boliu | 96ba1a6 | 2014-10-16 02:29:52 | [diff] [blame] | 681 | if (hardware_enabled_) { |
boliu | b887d327 | 2015-03-19 00:29:26 | [diff] [blame] | 682 | CompositeHw(); |
boliu | 96ba1a6 | 2014-10-16 02:29:52 | [diff] [blame] | 683 | } else { |
| 684 | ForceFakeCompositeSW(); |
| 685 | } |
boliu | d3ba720 | 2014-08-29 00:00:38 | [diff] [blame] | 686 | } |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 687 | } |
| 688 | |
| 689 | void BrowserViewRenderer::ForceFakeCompositeSW() { |
[email protected] | 7a46143 | 2014-06-17 23:50:12 | [diff] [blame] | 690 | DCHECK(compositor_); |
[email protected] | e758a237 | 2014-03-05 20:21:52 | [diff] [blame] | 691 | SkBitmap bitmap; |
| 692 | bitmap.allocN32Pixels(1, 1); |
| 693 | bitmap.eraseColor(0); |
| 694 | SkCanvas canvas(bitmap); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 695 | CompositeSW(&canvas); |
| 696 | } |
| 697 | |
| 698 | bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas) { |
[email protected] | 7a46143 | 2014-06-17 23:50:12 | [diff] [blame] | 699 | DCHECK(compositor_); |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 700 | CancelFallbackTick(); |
[email protected] | c62fc98 | 2014-06-27 04:49:02 | [diff] [blame] | 701 | ReturnResourceFromParent(); |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 702 | return compositor_->DemandDrawSw(canvas); |
[email protected] | 220e908a | 2014-03-05 06:23:04 | [diff] [blame] | 703 | } |
| 704 | |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 705 | void BrowserViewRenderer::UpdateCompositorIsActive() { |
| 706 | if (compositor_) |
| 707 | compositor_->SetIsActive(!is_paused_ && |
| 708 | (!attached_to_window_ || window_visible_)); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 709 | } |
| 710 | |
boliu | a3434da | 2014-10-14 01:31:15 | [diff] [blame] | 711 | std::string BrowserViewRenderer::ToString() const { |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 712 | std::string str; |
| 713 | base::StringAppendF(&str, "is_paused: %d ", is_paused_); |
| 714 | base::StringAppendF(&str, "view_visible: %d ", view_visible_); |
| 715 | base::StringAppendF(&str, "window_visible: %d ", window_visible_); |
| 716 | base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); |
| 717 | base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); |
sunnyps | eab5ac9 | 2015-04-02 20:26:13 | [diff] [blame] | 718 | base::StringAppendF(&str, "fallback_tick_pending: %d ", |
| 719 | fallback_tick_pending_); |
boliu | 04aa64d | 2014-11-12 00:31:08 | [diff] [blame] | 720 | base::StringAppendF(&str, "view size: %s ", size_.ToString().c_str()); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 721 | base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_); |
| 722 | base::StringAppendF(&str, |
| 723 | "global visible rect: %s ", |
[email protected] | 8705654b | 2014-05-24 01:16:19 | [diff] [blame] | 724 | last_on_draw_global_visible_rect_.ToString().c_str()); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 725 | base::StringAppendF( |
| 726 | &str, "scroll_offset_dip: %s ", scroll_offset_dip_.ToString().c_str()); |
| 727 | base::StringAppendF(&str, |
| 728 | "overscroll_rounding_error_: %s ", |
| 729 | overscroll_rounding_error_.ToString().c_str()); |
| 730 | base::StringAppendF( |
| 731 | &str, "on_new_picture_enable: %d ", on_new_picture_enable_); |
| 732 | base::StringAppendF(&str, "clear_view: %d ", clear_view_); |
[email protected] | 2306376 | 2014-02-26 01:01:56 | [diff] [blame] | 733 | return str; |
| 734 | } |
| 735 | |
| 736 | } // namespace android_webview |