OLD | NEW |
1 // Copyright 2013 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/in_process_view_renderer.h" | 5 #include "android_webview/browser/browser_view_renderer.h" |
6 | 6 |
7 #include "android_webview/browser/aw_gl_surface.h" | 7 #include "android_webview/browser/hardware_renderer.h" |
8 #include "android_webview/browser/scoped_app_gl_state_restore.h" | |
9 #include "android_webview/common/aw_switches.h" | |
10 #include "android_webview/public/browser/draw_gl.h" | 8 #include "android_webview/public/browser/draw_gl.h" |
11 #include "base/android/jni_android.h" | 9 #include "base/android/jni_android.h" |
12 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
13 #include "base/command_line.h" | |
14 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
15 #include "base/lazy_instance.h" | |
16 #include "base/logging.h" | 12 #include "base/logging.h" |
17 #include "base/strings/string_number_conversions.h" | |
18 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 14 #include "content/public/browser/android/synchronous_compositor.h" |
19 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
20 #include "content/public/browser/web_contents.h" | 16 #include "content/public/browser/web_contents.h" |
21 #include "content/public/common/content_switches.h" | |
22 #include "gpu/command_buffer/service/in_process_command_buffer.h" | |
23 #include "third_party/skia/include/core/SkBitmap.h" | 17 #include "third_party/skia/include/core/SkBitmap.h" |
24 #include "third_party/skia/include/core/SkBitmapDevice.h" | 18 #include "third_party/skia/include/core/SkBitmapDevice.h" |
25 #include "third_party/skia/include/core/SkCanvas.h" | 19 #include "third_party/skia/include/core/SkCanvas.h" |
26 #include "third_party/skia/include/core/SkPicture.h" | 20 #include "third_party/skia/include/core/SkPicture.h" |
27 #include "ui/gfx/transform.h" | |
28 #include "ui/gfx/vector2d_conversions.h" | 21 #include "ui/gfx/vector2d_conversions.h" |
29 | 22 |
30 using base::android::AttachCurrentThread; | 23 using base::android::AttachCurrentThread; |
31 using base::android::JavaRef; | 24 using base::android::JavaRef; |
32 using base::android::ScopedJavaLocalRef; | 25 using base::android::ScopedJavaLocalRef; |
33 using content::BrowserThread; | 26 using content::BrowserThread; |
34 | 27 |
35 namespace android_webview { | 28 namespace android_webview { |
36 | 29 |
37 namespace { | 30 namespace { |
38 | 31 |
39 const void* kUserDataKey = &kUserDataKey; | |
40 | |
41 class UserData : public content::WebContents::Data { | |
42 public: | |
43 UserData(InProcessViewRenderer* ptr) : instance_(ptr) {} | |
44 virtual ~UserData() { | |
45 instance_->WebContentsGone(); | |
46 } | |
47 | |
48 static InProcessViewRenderer* GetInstance(content::WebContents* contents) { | |
49 if (!contents) | |
50 return NULL; | |
51 UserData* data = reinterpret_cast<UserData*>( | |
52 contents->GetUserData(kUserDataKey)); | |
53 return data ? data->instance_ : NULL; | |
54 } | |
55 | |
56 private: | |
57 InProcessViewRenderer* instance_; | |
58 }; | |
59 | |
60 bool HardwareEnabled() { | |
61 static bool g_hw_enabled = !CommandLine::ForCurrentProcess()->HasSwitch( | |
62 switches::kDisableWebViewGLMode); | |
63 return g_hw_enabled; | |
64 } | |
65 | |
66 const int64 kFallbackTickTimeoutInMilliseconds = 20; | 32 const int64 kFallbackTickTimeoutInMilliseconds = 20; |
67 | 33 |
68 // Used to calculate memory and resource allocation. Determined experimentally. | |
69 size_t g_memory_multiplier = 10; | |
70 size_t g_num_gralloc_limit = 150; | |
71 const size_t kBytesPerPixel = 4; | |
72 const size_t kMemoryAllocationStep = 5 * 1024 * 1024; | |
73 | |
74 base::LazyInstance<GLViewRendererManager>::Leaky g_view_renderer_manager = | |
75 LAZY_INSTANCE_INITIALIZER; | |
76 | |
77 class ScopedAllowGL { | |
78 public: | |
79 ScopedAllowGL(); | |
80 ~ScopedAllowGL(); | |
81 | |
82 static bool IsAllowed() { | |
83 return g_view_renderer_manager.Get().OnRenderThread() && allow_gl; | |
84 } | |
85 | |
86 private: | |
87 static bool allow_gl; | |
88 | |
89 DISALLOW_COPY_AND_ASSIGN(ScopedAllowGL); | |
90 }; | |
91 | |
92 ScopedAllowGL::ScopedAllowGL() { | |
93 DCHECK(g_view_renderer_manager.Get().OnRenderThread()); | |
94 DCHECK(!allow_gl); | |
95 allow_gl = true; | |
96 } | |
97 | |
98 ScopedAllowGL::~ScopedAllowGL() { | |
99 allow_gl = false; | |
100 } | |
101 | |
102 bool ScopedAllowGL::allow_gl = false; | |
103 | |
104 void RequestProcessGLOnUIThread() { | |
105 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
106 BrowserThread::PostTask( | |
107 BrowserThread::UI, FROM_HERE, base::Bind(&RequestProcessGLOnUIThread)); | |
108 return; | |
109 } | |
110 | |
111 InProcessViewRenderer* renderer = static_cast<InProcessViewRenderer*>( | |
112 g_view_renderer_manager.Get().GetMostRecentlyDrawn()); | |
113 if (!renderer || !renderer->RequestProcessGL()) { | |
114 LOG(ERROR) << "Failed to request GL process. Deadlock likely: " | |
115 << !!renderer; | |
116 } | |
117 } | |
118 | |
119 class DeferredGpuCommandService | |
120 : public gpu::InProcessCommandBuffer::Service, | |
121 public base::RefCountedThreadSafe<DeferredGpuCommandService> { | |
122 public: | |
123 DeferredGpuCommandService(); | |
124 | |
125 virtual void ScheduleTask(const base::Closure& task) OVERRIDE; | |
126 virtual void ScheduleIdleWork(const base::Closure& task) OVERRIDE; | |
127 virtual bool UseVirtualizedGLContexts() OVERRIDE; | |
128 | |
129 void RunTasks(); | |
130 | |
131 virtual void AddRef() const OVERRIDE { | |
132 base::RefCountedThreadSafe<DeferredGpuCommandService>::AddRef(); | |
133 } | |
134 virtual void Release() const OVERRIDE { | |
135 base::RefCountedThreadSafe<DeferredGpuCommandService>::Release(); | |
136 } | |
137 | |
138 protected: | |
139 virtual ~DeferredGpuCommandService(); | |
140 friend class base::RefCountedThreadSafe<DeferredGpuCommandService>; | |
141 | |
142 private: | |
143 base::Lock tasks_lock_; | |
144 std::queue<base::Closure> tasks_; | |
145 DISALLOW_COPY_AND_ASSIGN(DeferredGpuCommandService); | |
146 }; | |
147 | |
148 DeferredGpuCommandService::DeferredGpuCommandService() {} | |
149 | |
150 DeferredGpuCommandService::~DeferredGpuCommandService() { | |
151 base::AutoLock lock(tasks_lock_); | |
152 DCHECK(tasks_.empty()); | |
153 } | |
154 | |
155 // Called from different threads! | |
156 void DeferredGpuCommandService::ScheduleTask(const base::Closure& task) { | |
157 { | |
158 base::AutoLock lock(tasks_lock_); | |
159 tasks_.push(task); | |
160 } | |
161 if (ScopedAllowGL::IsAllowed()) { | |
162 RunTasks(); | |
163 } else { | |
164 RequestProcessGLOnUIThread(); | |
165 } | |
166 } | |
167 | |
168 void DeferredGpuCommandService::ScheduleIdleWork( | |
169 const base::Closure& callback) { | |
170 // TODO(sievers): Should this do anything? | |
171 } | |
172 | |
173 bool DeferredGpuCommandService::UseVirtualizedGLContexts() { return true; } | |
174 | |
175 void DeferredGpuCommandService::RunTasks() { | |
176 bool has_more_tasks; | |
177 { | |
178 base::AutoLock lock(tasks_lock_); | |
179 has_more_tasks = tasks_.size() > 0; | |
180 } | |
181 | |
182 while (has_more_tasks) { | |
183 base::Closure task; | |
184 { | |
185 base::AutoLock lock(tasks_lock_); | |
186 task = tasks_.front(); | |
187 tasks_.pop(); | |
188 } | |
189 task.Run(); | |
190 { | |
191 base::AutoLock lock(tasks_lock_); | |
192 has_more_tasks = tasks_.size() > 0; | |
193 } | |
194 | |
195 } | |
196 } | |
197 | |
198 base::LazyInstance<scoped_refptr<DeferredGpuCommandService> > g_service = | |
199 LAZY_INSTANCE_INITIALIZER; | |
200 | |
201 } // namespace | 34 } // namespace |
202 | 35 |
203 InProcessViewRenderer::InProcessViewRenderer( | 36 BrowserViewRenderer::BrowserViewRenderer(BrowserViewRendererClient* client, |
204 BrowserViewRenderer::Client* client, | 37 content::WebContents* web_contents) |
205 content::WebContents* web_contents) | |
206 : client_(client), | 38 : client_(client), |
207 web_contents_(web_contents), | 39 web_contents_(web_contents), |
208 compositor_(NULL), | 40 compositor_(NULL), |
209 is_paused_(false), | 41 is_paused_(false), |
210 view_visible_(false), | 42 view_visible_(false), |
211 window_visible_(false), | 43 window_visible_(false), |
212 attached_to_window_(false), | 44 attached_to_window_(false), |
213 dip_scale_(0.0), | 45 dip_scale_(0.0), |
214 page_scale_factor_(1.0), | 46 page_scale_factor_(1.0), |
215 on_new_picture_enable_(false), | 47 on_new_picture_enable_(false), |
216 clear_view_(false), | 48 clear_view_(false), |
217 compositor_needs_continuous_invalidate_(false), | 49 compositor_needs_continuous_invalidate_(false), |
218 block_invalidates_(false), | 50 block_invalidates_(false), |
219 width_(0), | 51 width_(0), |
220 height_(0), | 52 height_(0) { |
221 hardware_initialized_(false), | |
222 hardware_failed_(false), | |
223 last_egl_context_(NULL), | |
224 manager_key_(g_view_renderer_manager.Get().NullKey()) { | |
225 CHECK(web_contents_); | 53 CHECK(web_contents_); |
226 web_contents_->SetUserData(kUserDataKey, new UserData(this)); | |
227 content::SynchronousCompositor::SetClientForWebContents(web_contents_, this); | 54 content::SynchronousCompositor::SetClientForWebContents(web_contents_, this); |
228 | 55 |
229 // Currently the logic in this class relies on |compositor_| remaining NULL | 56 // Currently the logic in this class relies on |compositor_| remaining NULL |
230 // until the DidInitializeCompositor() call, hence it is not set here. | 57 // until the DidInitializeCompositor() call, hence it is not set here. |
231 } | 58 } |
232 | 59 |
233 InProcessViewRenderer::~InProcessViewRenderer() { | 60 BrowserViewRenderer::~BrowserViewRenderer() { |
234 CHECK(web_contents_); | |
235 content::SynchronousCompositor::SetClientForWebContents(web_contents_, NULL); | 61 content::SynchronousCompositor::SetClientForWebContents(web_contents_, NULL); |
236 web_contents_->SetUserData(kUserDataKey, NULL); | |
237 NoLongerExpectsDrawGL(); | |
238 DCHECK(web_contents_ == NULL); // WebContentsGone should have been called. | |
239 } | 62 } |
240 | 63 |
241 void InProcessViewRenderer::NoLongerExpectsDrawGL() { | 64 void BrowserViewRenderer::TrimMemory(int level) { |
242 GLViewRendererManager& mru = g_view_renderer_manager.Get(); | 65 if (hardware_renderer_) { |
243 if (manager_key_ != mru.NullKey()) { | 66 client_->UpdateGlobalVisibleRect(); |
244 mru.NoLongerExpectsDrawGL(manager_key_); | 67 bool visible = view_visible_ && window_visible_ && |
245 manager_key_ = mru.NullKey(); | 68 !cached_global_visible_rect_.IsEmpty(); |
| 69 if (hardware_renderer_->TrimMemory(level, visible)) { |
| 70 // Force a draw for compositor to drop tiles synchronously. |
| 71 ForceFakeCompositeSW(); |
| 72 } |
246 } | 73 } |
247 } | 74 } |
248 | 75 |
249 // static | 76 bool BrowserViewRenderer::OnDraw(jobject java_canvas, |
250 InProcessViewRenderer* InProcessViewRenderer::FromWebContents( | 77 bool is_hardware_canvas, |
251 content::WebContents* contents) { | 78 const gfx::Vector2d& scroll, |
252 return UserData::GetInstance(contents); | 79 const gfx::Rect& clip) { |
253 } | 80 scroll_at_start_of_frame_ = scroll; |
254 | |
255 void InProcessViewRenderer::WebContentsGone() { | |
256 web_contents_ = NULL; | |
257 compositor_ = NULL; | |
258 } | |
259 | |
260 // static | |
261 void InProcessViewRenderer::CalculateTileMemoryPolicy() { | |
262 CommandLine* cl = CommandLine::ForCurrentProcess(); | |
263 if (cl->HasSwitch(switches::kTileMemoryMultiplier)) { | |
264 std::string string_value = | |
265 cl->GetSwitchValueASCII(switches::kTileMemoryMultiplier); | |
266 int int_value = 0; | |
267 if (base::StringToInt(string_value, &int_value) && | |
268 int_value >= 2 && int_value <= 50) { | |
269 g_memory_multiplier = int_value; | |
270 } | |
271 } | |
272 | |
273 if (cl->HasSwitch(switches::kNumGrallocBuffersPerWebview)) { | |
274 std::string string_value = | |
275 cl->GetSwitchValueASCII(switches::kNumGrallocBuffersPerWebview); | |
276 int int_value = 0; | |
277 if (base::StringToInt(string_value, &int_value) && | |
278 int_value >= 50 && int_value <= 500) { | |
279 g_num_gralloc_limit = int_value; | |
280 } | |
281 } | |
282 | |
283 const char kDefaultTileSize[] = "384"; | |
284 if (!cl->HasSwitch(switches::kDefaultTileWidth)) | |
285 cl->AppendSwitchASCII(switches::kDefaultTileWidth, kDefaultTileSize); | |
286 | |
287 if (!cl->HasSwitch(switches::kDefaultTileHeight)) | |
288 cl->AppendSwitchASCII(switches::kDefaultTileHeight, kDefaultTileSize); | |
289 } | |
290 | |
291 bool InProcessViewRenderer::RequestProcessGL() { | |
292 return client_->RequestDrawGL(NULL); | |
293 } | |
294 | |
295 void InProcessViewRenderer::TrimMemory(int level) { | |
296 // Constants from Android ComponentCallbacks2. | |
297 enum { | |
298 TRIM_MEMORY_RUNNING_LOW = 10, | |
299 TRIM_MEMORY_UI_HIDDEN = 20, | |
300 TRIM_MEMORY_BACKGROUND = 40, | |
301 }; | |
302 | |
303 // Not urgent enough. TRIM_MEMORY_UI_HIDDEN is treated specially because | |
304 // it does not indicate memory pressure, but merely that the app is | |
305 // backgrounded. | |
306 if (level < TRIM_MEMORY_RUNNING_LOW || level == TRIM_MEMORY_UI_HIDDEN) | |
307 return; | |
308 | |
309 // Nothing to drop. | |
310 if (!attached_to_window_ || !hardware_initialized_ || !compositor_) | |
311 return; | |
312 | |
313 // Do not release resources on view we expect to get DrawGL soon. | |
314 if (level < TRIM_MEMORY_BACKGROUND) { | |
315 client_->UpdateGlobalVisibleRect(); | |
316 if (view_visible_ && window_visible_ && | |
317 !cached_global_visible_rect_.IsEmpty()) { | |
318 return; | |
319 } | |
320 } | |
321 | |
322 if (!eglGetCurrentContext()) { | |
323 NOTREACHED(); | |
324 return; | |
325 } | |
326 | |
327 // Just set the memory limit to 0 and drop all tiles. This will be reset to | |
328 // normal levels in the next DrawGL call. | |
329 content::SynchronousCompositorMemoryPolicy policy; | |
330 policy.bytes_limit = 0; | |
331 policy.num_resources_limit = 0; | |
332 if (memory_policy_ == policy) | |
333 return; | |
334 | |
335 TRACE_EVENT0("android_webview", "InProcessViewRenderer::TrimMemory"); | |
336 ScopedAppGLStateRestore state_restore( | |
337 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); | |
338 g_service.Get()->RunTasks(); | |
339 ScopedAllowGL allow_gl; | |
340 | |
341 SetMemoryPolicy(policy); | |
342 ForceFakeCompositeSW(); | |
343 } | |
344 | |
345 void InProcessViewRenderer::SetMemoryPolicy( | |
346 content::SynchronousCompositorMemoryPolicy& new_policy) { | |
347 if (memory_policy_ == new_policy) | |
348 return; | |
349 | |
350 memory_policy_ = new_policy; | |
351 compositor_->SetMemoryPolicy(memory_policy_); | |
352 } | |
353 | |
354 void InProcessViewRenderer::UpdateCachedGlobalVisibleRect() { | |
355 client_->UpdateGlobalVisibleRect(); | |
356 } | |
357 | |
358 bool InProcessViewRenderer::OnDraw(jobject java_canvas, | |
359 bool is_hardware_canvas, | |
360 const gfx::Vector2d& scroll, | |
361 const gfx::Rect& clip) { | |
362 scroll_at_start_of_frame_ = scroll; | |
363 if (clear_view_) | 81 if (clear_view_) |
364 return false; | 82 return false; |
365 if (is_hardware_canvas && attached_to_window_ && HardwareEnabled()) { | 83 if (is_hardware_canvas && attached_to_window_) { |
366 // We should be performing a hardware draw here. If we don't have the | 84 // We should be performing a hardware draw here. If we don't have the |
367 // comositor yet or if RequestDrawGL fails, it means we failed this draw and | 85 // compositor yet or if RequestDrawGL fails, it means we failed this draw |
368 // thus return false here to clear to background color for this draw. | 86 // and thus return false here to clear to background color for this draw. |
369 return compositor_ && client_->RequestDrawGL(java_canvas); | 87 return compositor_ && client_->RequestDrawGL(java_canvas); |
370 } | 88 } |
371 // Perform a software draw | 89 // Perform a software draw |
372 return DrawSWInternal(java_canvas, clip); | 90 return DrawSWInternal(java_canvas, clip); |
373 } | 91 } |
374 | 92 |
375 bool InProcessViewRenderer::InitializeHwDraw() { | 93 void BrowserViewRenderer::DrawGL(AwDrawGLInfo* draw_info) { |
376 TRACE_EVENT0("android_webview", "InitializeHwDraw"); | 94 if (!attached_to_window_ || !compositor_) |
377 DCHECK(!gl_surface_); | 95 return; |
378 gl_surface_ = new AwGLSurface; | 96 |
379 if (!g_service.Get()) { | 97 client_->UpdateGlobalVisibleRect(); |
380 g_service.Get() = new DeferredGpuCommandService; | 98 if (cached_global_visible_rect_.IsEmpty()) |
381 content::SynchronousCompositor::SetGpuService(g_service.Get()); | 99 return; |
| 100 |
| 101 if (!hardware_renderer_) |
| 102 hardware_renderer_.reset(new HardwareRenderer(compositor_, client_)); |
| 103 |
| 104 DrawGLInput input; |
| 105 input.global_visible_rect = cached_global_visible_rect_; |
| 106 input.scroll = scroll_at_start_of_frame_; |
| 107 DrawGLResult result; |
| 108 { |
| 109 base::AutoReset<bool> auto_reset(&block_invalidates_, true); |
| 110 result = hardware_renderer_->DrawGL(draw_info, input); |
382 } | 111 } |
383 hardware_failed_ = !compositor_->InitializeHwDraw(gl_surface_); | |
384 hardware_initialized_ = true; | |
385 | 112 |
386 if (hardware_failed_) | 113 if (result.did_draw) { |
387 gl_surface_ = NULL; | 114 fallback_tick_.Cancel(); |
388 | 115 block_invalidates_ = false; |
389 return !hardware_failed_; | 116 EnsureContinuousInvalidation(draw_info, !result.clip_contains_visible_rect); |
| 117 } |
390 } | 118 } |
391 | 119 |
392 void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) { | 120 void BrowserViewRenderer::SetGlobalVisibleRect(const gfx::Rect& visible_rect) { |
393 TRACE_EVENT0("android_webview", "InProcessViewRenderer::DrawGL"); | |
394 | |
395 manager_key_ = g_view_renderer_manager.Get().DidDrawGL(manager_key_, this); | |
396 | |
397 // We need to watch if the current Android context has changed and enforce | |
398 // a clean-up in the compositor. | |
399 EGLContext current_context = eglGetCurrentContext(); | |
400 if (!current_context) { | |
401 TRACE_EVENT_INSTANT0( | |
402 "android_webview", "EarlyOut_NullEGLContext", TRACE_EVENT_SCOPE_THREAD); | |
403 return; | |
404 } | |
405 | |
406 ScopedAppGLStateRestore state_restore(ScopedAppGLStateRestore::MODE_DRAW); | |
407 if (g_service.Get()) | |
408 g_service.Get()->RunTasks(); | |
409 ScopedAllowGL allow_gl; | |
410 | |
411 if (!attached_to_window_) { | |
412 TRACE_EVENT_INSTANT0( | |
413 "android_webview", "EarlyOut_NotAttached", TRACE_EVENT_SCOPE_THREAD); | |
414 return; | |
415 } | |
416 | |
417 if (draw_info->mode == AwDrawGLInfo::kModeProcess) { | |
418 TRACE_EVENT_INSTANT0( | |
419 "android_webview", "EarlyOut_ModeProcess", TRACE_EVENT_SCOPE_THREAD); | |
420 return; | |
421 } | |
422 | |
423 if (compositor_ && !hardware_initialized_) { | |
424 if (InitializeHwDraw()) { | |
425 last_egl_context_ = current_context; | |
426 } else { | |
427 TRACE_EVENT_INSTANT0( | |
428 "android_webview", "EarlyOut_HwInitFail", TRACE_EVENT_SCOPE_THREAD); | |
429 LOG(ERROR) << "WebView hardware initialization failed"; | |
430 return; | |
431 } | |
432 } | |
433 | |
434 UpdateCachedGlobalVisibleRect(); | |
435 if (cached_global_visible_rect_.IsEmpty()) { | |
436 TRACE_EVENT_INSTANT0("android_webview", | |
437 "EarlyOut_EmptyVisibleRect", | |
438 TRACE_EVENT_SCOPE_THREAD); | |
439 return; | |
440 } | |
441 | |
442 if (last_egl_context_ != current_context) { | |
443 // TODO(boliu): Handle context lost | |
444 TRACE_EVENT_INSTANT0( | |
445 "android_webview", "EGLContextChanged", TRACE_EVENT_SCOPE_THREAD); | |
446 } | |
447 | |
448 if (!compositor_) { | |
449 TRACE_EVENT_INSTANT0( | |
450 "android_webview", "EarlyOut_NoCompositor", TRACE_EVENT_SCOPE_THREAD); | |
451 return; | |
452 } | |
453 | |
454 // DrawGL may be called without OnDraw, so cancel |fallback_tick_| here as | |
455 // well just to be safe. | |
456 fallback_tick_.Cancel(); | |
457 | |
458 // Update memory budget. This will no-op in compositor if the policy has not | |
459 // changed since last draw. | |
460 content::SynchronousCompositorMemoryPolicy policy; | |
461 policy.bytes_limit = g_memory_multiplier * kBytesPerPixel * | |
462 cached_global_visible_rect_.width() * | |
463 cached_global_visible_rect_.height(); | |
464 // Round up to a multiple of kMemoryAllocationStep. | |
465 policy.bytes_limit = | |
466 (policy.bytes_limit / kMemoryAllocationStep + 1) * kMemoryAllocationStep; | |
467 policy.num_resources_limit = g_num_gralloc_limit; | |
468 SetMemoryPolicy(policy); | |
469 | |
470 DCHECK(gl_surface_); | |
471 gl_surface_->SetBackingFrameBufferObject( | |
472 state_restore.framebuffer_binding_ext()); | |
473 | |
474 gfx::Transform transform; | |
475 transform.matrix().setColMajorf(draw_info->transform); | |
476 transform.Translate(scroll_at_start_of_frame_.x(), | |
477 scroll_at_start_of_frame_.y()); | |
478 gfx::Rect clip_rect(draw_info->clip_left, | |
479 draw_info->clip_top, | |
480 draw_info->clip_right - draw_info->clip_left, | |
481 draw_info->clip_bottom - draw_info->clip_top); | |
482 | |
483 // Assume we always draw the full visible rect if we are drawing into a layer. | |
484 bool drew_full_visible_rect = true; | |
485 | |
486 gfx::Rect viewport_rect; | |
487 if (!draw_info->is_layer) { | |
488 viewport_rect = cached_global_visible_rect_; | |
489 clip_rect.Intersect(viewport_rect); | |
490 drew_full_visible_rect = clip_rect.Contains(viewport_rect); | |
491 } else { | |
492 viewport_rect = clip_rect; | |
493 } | |
494 | |
495 block_invalidates_ = true; | |
496 // TODO(joth): Check return value. | |
497 compositor_->DemandDrawHw(gfx::Size(draw_info->width, draw_info->height), | |
498 transform, | |
499 viewport_rect, | |
500 clip_rect, | |
501 state_restore.stencil_enabled()); | |
502 block_invalidates_ = false; | |
503 gl_surface_->ResetBackingFrameBufferObject(); | |
504 | |
505 EnsureContinuousInvalidation(draw_info, !drew_full_visible_rect); | |
506 } | |
507 | |
508 void InProcessViewRenderer::SetGlobalVisibleRect( | |
509 const gfx::Rect& visible_rect) { | |
510 cached_global_visible_rect_ = visible_rect; | 121 cached_global_visible_rect_ = visible_rect; |
511 } | 122 } |
512 | 123 |
513 bool InProcessViewRenderer::DrawSWInternal(jobject java_canvas, | 124 bool BrowserViewRenderer::DrawSWInternal(jobject java_canvas, |
514 const gfx::Rect& clip) { | 125 const gfx::Rect& clip) { |
515 if (clip.IsEmpty()) { | 126 if (clip.IsEmpty()) { |
516 TRACE_EVENT_INSTANT0( | 127 TRACE_EVENT_INSTANT0( |
517 "android_webview", "EarlyOut_EmptyClip", TRACE_EVENT_SCOPE_THREAD); | 128 "android_webview", "EarlyOut_EmptyClip", TRACE_EVENT_SCOPE_THREAD); |
518 return true; | 129 return true; |
519 } | 130 } |
520 | 131 |
521 if (!compositor_) { | 132 if (!compositor_) { |
522 TRACE_EVENT_INSTANT0( | 133 TRACE_EVENT_INSTANT0( |
523 "android_webview", "EarlyOut_NoCompositor", TRACE_EVENT_SCOPE_THREAD); | 134 "android_webview", "EarlyOut_NoCompositor", TRACE_EVENT_SCOPE_THREAD); |
524 return false; | 135 return false; |
525 } | 136 } |
526 | 137 |
527 return JavaHelper::GetInstance()->RenderViaAuxilaryBitmapIfNeeded( | 138 return BrowserViewRendererJavaHelper::GetInstance() |
528 java_canvas, | 139 ->RenderViaAuxilaryBitmapIfNeeded( |
529 scroll_at_start_of_frame_, | 140 java_canvas, |
530 clip, | 141 scroll_at_start_of_frame_, |
531 base::Bind(&InProcessViewRenderer::CompositeSW, base::Unretained(this))); | 142 clip, |
| 143 base::Bind(&BrowserViewRenderer::CompositeSW, |
| 144 base::Unretained(this))); |
532 } | 145 } |
533 | 146 |
534 skia::RefPtr<SkPicture> InProcessViewRenderer::CapturePicture(int width, | 147 skia::RefPtr<SkPicture> BrowserViewRenderer::CapturePicture(int width, |
535 int height) { | 148 int height) { |
536 TRACE_EVENT0("android_webview", "InProcessViewRenderer::CapturePicture"); | 149 TRACE_EVENT0("android_webview", "BrowserViewRenderer::CapturePicture"); |
537 | 150 |
538 // Return empty Picture objects for empty SkPictures. | 151 // Return empty Picture objects for empty SkPictures. |
539 skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture); | 152 skia::RefPtr<SkPicture> picture = skia::AdoptRef(new SkPicture); |
540 if (width <= 0 || height <= 0) { | 153 if (width <= 0 || height <= 0) { |
541 return picture; | 154 return picture; |
542 } | 155 } |
543 | 156 |
544 // Reset scroll back to the origin, will go back to the old | 157 // Reset scroll back to the origin, will go back to the old |
545 // value when scroll_reset is out of scope. | 158 // value when scroll_reset is out of scope. |
546 base::AutoReset<gfx::Vector2dF> scroll_reset(&scroll_offset_dip_, | 159 base::AutoReset<gfx::Vector2dF> scroll_reset(&scroll_offset_dip_, |
547 gfx::Vector2d()); | 160 gfx::Vector2d()); |
548 | 161 |
549 SkCanvas* rec_canvas = picture->beginRecording(width, height, 0); | 162 SkCanvas* rec_canvas = picture->beginRecording(width, height, 0); |
550 if (compositor_) | 163 if (compositor_) |
551 CompositeSW(rec_canvas); | 164 CompositeSW(rec_canvas); |
552 picture->endRecording(); | 165 picture->endRecording(); |
553 return picture; | 166 return picture; |
554 } | 167 } |
555 | 168 |
556 void InProcessViewRenderer::EnableOnNewPicture(bool enabled) { | 169 void BrowserViewRenderer::EnableOnNewPicture(bool enabled) { |
557 on_new_picture_enable_ = enabled; | 170 on_new_picture_enable_ = enabled; |
558 EnsureContinuousInvalidation(NULL, false); | 171 EnsureContinuousInvalidation(NULL, false); |
559 } | 172 } |
560 | 173 |
561 void InProcessViewRenderer::ClearView() { | 174 void BrowserViewRenderer::ClearView() { |
562 TRACE_EVENT_INSTANT0("android_webview", | 175 TRACE_EVENT_INSTANT0("android_webview", |
563 "InProcessViewRenderer::ClearView", | 176 "BrowserViewRenderer::ClearView", |
564 TRACE_EVENT_SCOPE_THREAD); | 177 TRACE_EVENT_SCOPE_THREAD); |
565 if (clear_view_) | 178 if (clear_view_) |
566 return; | 179 return; |
567 | 180 |
568 clear_view_ = true; | 181 clear_view_ = true; |
569 // Always invalidate ignoring the compositor to actually clear the webview. | 182 // Always invalidate ignoring the compositor to actually clear the webview. |
570 EnsureContinuousInvalidation(NULL, true); | 183 EnsureContinuousInvalidation(NULL, true); |
571 } | 184 } |
572 | 185 |
573 void InProcessViewRenderer::SetIsPaused(bool paused) { | 186 void BrowserViewRenderer::SetIsPaused(bool paused) { |
574 TRACE_EVENT_INSTANT1("android_webview", | 187 TRACE_EVENT_INSTANT1("android_webview", |
575 "InProcessViewRenderer::SetIsPaused", | 188 "BrowserViewRenderer::SetIsPaused", |
576 TRACE_EVENT_SCOPE_THREAD, | 189 TRACE_EVENT_SCOPE_THREAD, |
577 "paused", | 190 "paused", |
578 paused); | 191 paused); |
579 is_paused_ = paused; | 192 is_paused_ = paused; |
580 EnsureContinuousInvalidation(NULL, false); | 193 EnsureContinuousInvalidation(NULL, false); |
581 } | 194 } |
582 | 195 |
583 void InProcessViewRenderer::SetViewVisibility(bool view_visible) { | 196 void BrowserViewRenderer::SetViewVisibility(bool view_visible) { |
584 TRACE_EVENT_INSTANT1("android_webview", | 197 TRACE_EVENT_INSTANT1("android_webview", |
585 "InProcessViewRenderer::SetViewVisibility", | 198 "BrowserViewRenderer::SetViewVisibility", |
586 TRACE_EVENT_SCOPE_THREAD, | 199 TRACE_EVENT_SCOPE_THREAD, |
587 "view_visible", | 200 "view_visible", |
588 view_visible); | 201 view_visible); |
589 view_visible_ = view_visible; | 202 view_visible_ = view_visible; |
590 } | 203 } |
591 | 204 |
592 void InProcessViewRenderer::SetWindowVisibility(bool window_visible) { | 205 void BrowserViewRenderer::SetWindowVisibility(bool window_visible) { |
593 TRACE_EVENT_INSTANT1("android_webview", | 206 TRACE_EVENT_INSTANT1("android_webview", |
594 "InProcessViewRenderer::SetWindowVisibility", | 207 "BrowserViewRenderer::SetWindowVisibility", |
595 TRACE_EVENT_SCOPE_THREAD, | 208 TRACE_EVENT_SCOPE_THREAD, |
596 "window_visible", | 209 "window_visible", |
597 window_visible); | 210 window_visible); |
598 window_visible_ = window_visible; | 211 window_visible_ = window_visible; |
599 EnsureContinuousInvalidation(NULL, false); | 212 EnsureContinuousInvalidation(NULL, false); |
600 } | 213 } |
601 | 214 |
602 void InProcessViewRenderer::OnSizeChanged(int width, int height) { | 215 void BrowserViewRenderer::OnSizeChanged(int width, int height) { |
603 TRACE_EVENT_INSTANT2("android_webview", | 216 TRACE_EVENT_INSTANT2("android_webview", |
604 "InProcessViewRenderer::OnSizeChanged", | 217 "BrowserViewRenderer::OnSizeChanged", |
605 TRACE_EVENT_SCOPE_THREAD, | 218 TRACE_EVENT_SCOPE_THREAD, |
606 "width", | 219 "width", |
607 width, | 220 width, |
608 "height", | 221 "height", |
609 height); | 222 height); |
610 width_ = width; | 223 width_ = width; |
611 height_ = height; | 224 height_ = height; |
612 } | 225 } |
613 | 226 |
614 void InProcessViewRenderer::OnAttachedToWindow(int width, int height) { | 227 void BrowserViewRenderer::OnAttachedToWindow(int width, int height) { |
615 TRACE_EVENT2("android_webview", | 228 TRACE_EVENT2("android_webview", |
616 "InProcessViewRenderer::OnAttachedToWindow", | 229 "BrowserViewRenderer::OnAttachedToWindow", |
617 "width", | 230 "width", |
618 width, | 231 width, |
619 "height", | 232 "height", |
620 height); | 233 height); |
621 attached_to_window_ = true; | 234 attached_to_window_ = true; |
622 width_ = width; | 235 width_ = width; |
623 height_ = height; | 236 height_ = height; |
624 } | 237 } |
625 | 238 |
626 void InProcessViewRenderer::OnDetachedFromWindow() { | 239 void BrowserViewRenderer::OnDetachedFromWindow() { |
627 TRACE_EVENT0("android_webview", | 240 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow"); |
628 "InProcessViewRenderer::OnDetachedFromWindow"); | |
629 | |
630 NoLongerExpectsDrawGL(); | |
631 if (hardware_initialized_) { | |
632 DCHECK(compositor_); | |
633 | |
634 ScopedAppGLStateRestore state_restore( | |
635 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); | |
636 g_service.Get()->RunTasks(); | |
637 ScopedAllowGL allow_gl; | |
638 compositor_->ReleaseHwDraw(); | |
639 hardware_initialized_ = false; | |
640 } | |
641 | |
642 gl_surface_ = NULL; | |
643 attached_to_window_ = false; | 241 attached_to_window_ = false; |
| 242 hardware_renderer_.reset(); |
644 } | 243 } |
645 | 244 |
646 bool InProcessViewRenderer::IsAttachedToWindow() { | 245 bool BrowserViewRenderer::IsAttachedToWindow() const { |
647 return attached_to_window_; | 246 return attached_to_window_; |
648 } | 247 } |
649 | 248 |
650 bool InProcessViewRenderer::IsVisible() { | 249 bool BrowserViewRenderer::IsVisible() const { |
651 // Ignore |window_visible_| if |attached_to_window_| is false. | 250 // Ignore |window_visible_| if |attached_to_window_| is false. |
652 return view_visible_ && (!attached_to_window_ || window_visible_); | 251 return view_visible_ && (!attached_to_window_ || window_visible_); |
653 } | 252 } |
654 | 253 |
655 gfx::Rect InProcessViewRenderer::GetScreenRect() { | 254 gfx::Rect BrowserViewRenderer::GetScreenRect() const { |
656 return gfx::Rect(client_->GetLocationOnScreen(), gfx::Size(width_, height_)); | 255 return gfx::Rect(client_->GetLocationOnScreen(), gfx::Size(width_, height_)); |
657 } | 256 } |
658 | 257 |
659 void InProcessViewRenderer::DidInitializeCompositor( | 258 void BrowserViewRenderer::DidInitializeCompositor( |
660 content::SynchronousCompositor* compositor) { | 259 content::SynchronousCompositor* compositor) { |
661 TRACE_EVENT0("android_webview", | 260 TRACE_EVENT0("android_webview", |
662 "InProcessViewRenderer::DidInitializeCompositor"); | 261 "BrowserViewRenderer::DidInitializeCompositor"); |
663 DCHECK(compositor && compositor_ == NULL); | 262 DCHECK(compositor && compositor_ == NULL); |
664 compositor_ = compositor; | 263 compositor_ = compositor; |
665 hardware_initialized_ = false; | |
666 hardware_failed_ = false; | |
667 } | 264 } |
668 | 265 |
669 void InProcessViewRenderer::DidDestroyCompositor( | 266 void BrowserViewRenderer::DidDestroyCompositor( |
670 content::SynchronousCompositor* compositor) { | 267 content::SynchronousCompositor* compositor) { |
671 TRACE_EVENT0("android_webview", | 268 TRACE_EVENT0("android_webview", "BrowserViewRenderer::DidDestroyCompositor"); |
672 "InProcessViewRenderer::DidDestroyCompositor"); | |
673 DCHECK(compositor_ == compositor); | 269 DCHECK(compositor_ == compositor); |
674 | 270 DCHECK(!hardware_renderer_.get()); |
675 // This can fail if Apps call destroy while the webview is still attached | |
676 // to the view tree. This is an illegal operation that will lead to leaks. | |
677 // Log for now. Consider a proper fix if this becomes a problem. | |
678 LOG_IF(ERROR, hardware_initialized_) | |
679 << "Destroy called before OnDetachedFromWindow. May Leak GL resources"; | |
680 compositor_ = NULL; | 271 compositor_ = NULL; |
681 } | 272 } |
682 | 273 |
683 void InProcessViewRenderer::SetContinuousInvalidate(bool invalidate) { | 274 void BrowserViewRenderer::SetContinuousInvalidate(bool invalidate) { |
684 if (compositor_needs_continuous_invalidate_ == invalidate) | 275 if (compositor_needs_continuous_invalidate_ == invalidate) |
685 return; | 276 return; |
686 | 277 |
687 TRACE_EVENT_INSTANT1("android_webview", | 278 TRACE_EVENT_INSTANT1("android_webview", |
688 "InProcessViewRenderer::SetContinuousInvalidate", | 279 "BrowserViewRenderer::SetContinuousInvalidate", |
689 TRACE_EVENT_SCOPE_THREAD, | 280 TRACE_EVENT_SCOPE_THREAD, |
690 "invalidate", | 281 "invalidate", |
691 invalidate); | 282 invalidate); |
692 compositor_needs_continuous_invalidate_ = invalidate; | 283 compositor_needs_continuous_invalidate_ = invalidate; |
693 EnsureContinuousInvalidation(NULL, false); | 284 EnsureContinuousInvalidation(NULL, false); |
694 } | 285 } |
695 | 286 |
696 void InProcessViewRenderer::SetDipScale(float dip_scale) { | 287 void BrowserViewRenderer::SetDipScale(float dip_scale) { |
697 dip_scale_ = dip_scale; | 288 dip_scale_ = dip_scale; |
698 CHECK(dip_scale_ > 0); | 289 CHECK(dip_scale_ > 0); |
699 } | 290 } |
700 | 291 |
701 gfx::Vector2d InProcessViewRenderer::max_scroll_offset() const { | 292 gfx::Vector2d BrowserViewRenderer::max_scroll_offset() const { |
702 DCHECK_GT(dip_scale_, 0); | 293 DCHECK_GT(dip_scale_, 0); |
703 return gfx::ToCeiledVector2d(gfx::ScaleVector2d( | 294 return gfx::ToCeiledVector2d(gfx::ScaleVector2d( |
704 max_scroll_offset_dip_, dip_scale_ * page_scale_factor_)); | 295 max_scroll_offset_dip_, dip_scale_ * page_scale_factor_)); |
705 } | 296 } |
706 | 297 |
707 void InProcessViewRenderer::ScrollTo(gfx::Vector2d scroll_offset) { | 298 void BrowserViewRenderer::ScrollTo(gfx::Vector2d scroll_offset) { |
708 gfx::Vector2d max_offset = max_scroll_offset(); | 299 gfx::Vector2d max_offset = max_scroll_offset(); |
709 gfx::Vector2dF scroll_offset_dip; | 300 gfx::Vector2dF scroll_offset_dip; |
710 // To preserve the invariant that scrolling to the maximum physical pixel | 301 // To preserve the invariant that scrolling to the maximum physical pixel |
711 // value also scrolls to the maximum dip pixel value we transform the physical | 302 // value also scrolls to the maximum dip pixel value we transform the physical |
712 // offset into the dip offset by using a proportion (instead of dividing by | 303 // offset into the dip offset by using a proportion (instead of dividing by |
713 // dip_scale * page_scale_factor). | 304 // dip_scale * page_scale_factor). |
714 if (max_offset.x()) { | 305 if (max_offset.x()) { |
715 scroll_offset_dip.set_x((scroll_offset.x() * max_scroll_offset_dip_.x()) / | 306 scroll_offset_dip.set_x((scroll_offset.x() * max_scroll_offset_dip_.x()) / |
716 max_offset.x()); | 307 max_offset.x()); |
717 } | 308 } |
718 if (max_offset.y()) { | 309 if (max_offset.y()) { |
719 scroll_offset_dip.set_y((scroll_offset.y() * max_scroll_offset_dip_.y()) / | 310 scroll_offset_dip.set_y((scroll_offset.y() * max_scroll_offset_dip_.y()) / |
720 max_offset.y()); | 311 max_offset.y()); |
721 } | 312 } |
722 | 313 |
723 DCHECK_LE(0, scroll_offset_dip.x()); | 314 DCHECK_LE(0, scroll_offset_dip.x()); |
724 DCHECK_LE(0, scroll_offset_dip.y()); | 315 DCHECK_LE(0, scroll_offset_dip.y()); |
725 DCHECK_LE(scroll_offset_dip.x(), max_scroll_offset_dip_.x()); | 316 DCHECK_LE(scroll_offset_dip.x(), max_scroll_offset_dip_.x()); |
726 DCHECK_LE(scroll_offset_dip.y(), max_scroll_offset_dip_.y()); | 317 DCHECK_LE(scroll_offset_dip.y(), max_scroll_offset_dip_.y()); |
727 | 318 |
728 if (scroll_offset_dip_ == scroll_offset_dip) | 319 if (scroll_offset_dip_ == scroll_offset_dip) |
729 return; | 320 return; |
730 | 321 |
731 scroll_offset_dip_ = scroll_offset_dip; | 322 scroll_offset_dip_ = scroll_offset_dip; |
732 | 323 |
733 if (compositor_) | 324 if (compositor_) |
734 compositor_->DidChangeRootLayerScrollOffset(); | 325 compositor_->DidChangeRootLayerScrollOffset(); |
735 } | 326 } |
736 | 327 |
737 void InProcessViewRenderer::DidUpdateContent() { | 328 void BrowserViewRenderer::DidUpdateContent() { |
738 TRACE_EVENT_INSTANT0("android_webview", | 329 TRACE_EVENT_INSTANT0("android_webview", |
739 "InProcessViewRenderer::DidUpdateContent", | 330 "BrowserViewRenderer::DidUpdateContent", |
740 TRACE_EVENT_SCOPE_THREAD); | 331 TRACE_EVENT_SCOPE_THREAD); |
741 clear_view_ = false; | 332 clear_view_ = false; |
742 EnsureContinuousInvalidation(NULL, false); | 333 EnsureContinuousInvalidation(NULL, false); |
743 if (on_new_picture_enable_) | 334 if (on_new_picture_enable_) |
744 client_->OnNewPicture(); | 335 client_->OnNewPicture(); |
745 } | 336 } |
746 | 337 |
747 void InProcessViewRenderer::SetMaxRootLayerScrollOffset( | 338 void BrowserViewRenderer::SetMaxRootLayerScrollOffset( |
748 gfx::Vector2dF new_value_dip) { | 339 gfx::Vector2dF new_value_dip) { |
749 DCHECK_GT(dip_scale_, 0); | 340 DCHECK_GT(dip_scale_, 0); |
750 | 341 |
751 max_scroll_offset_dip_ = new_value_dip; | 342 max_scroll_offset_dip_ = new_value_dip; |
752 DCHECK_LE(0, max_scroll_offset_dip_.x()); | 343 DCHECK_LE(0, max_scroll_offset_dip_.x()); |
753 DCHECK_LE(0, max_scroll_offset_dip_.y()); | 344 DCHECK_LE(0, max_scroll_offset_dip_.y()); |
754 | 345 |
755 client_->SetMaxContainerViewScrollOffset(max_scroll_offset()); | 346 client_->SetMaxContainerViewScrollOffset(max_scroll_offset()); |
756 } | 347 } |
757 | 348 |
758 void InProcessViewRenderer::SetTotalRootLayerScrollOffset( | 349 void BrowserViewRenderer::SetTotalRootLayerScrollOffset( |
759 gfx::Vector2dF scroll_offset_dip) { | 350 gfx::Vector2dF scroll_offset_dip) { |
760 // TOOD(mkosiba): Add a DCHECK to say that this does _not_ get called during | 351 // TOOD(mkosiba): Add a DCHECK to say that this does _not_ get called during |
761 // DrawGl when http://crbug.com/249972 is fixed. | 352 // DrawGl when http://crbug.com/249972 is fixed. |
762 if (scroll_offset_dip_ == scroll_offset_dip) | 353 if (scroll_offset_dip_ == scroll_offset_dip) |
763 return; | 354 return; |
764 | 355 |
765 scroll_offset_dip_ = scroll_offset_dip; | 356 scroll_offset_dip_ = scroll_offset_dip; |
766 | 357 |
767 gfx::Vector2d max_offset = max_scroll_offset(); | 358 gfx::Vector2d max_offset = max_scroll_offset(); |
768 gfx::Vector2d scroll_offset; | 359 gfx::Vector2d scroll_offset; |
769 // For an explanation as to why this is done this way see the comment in | 360 // For an explanation as to why this is done this way see the comment in |
770 // InProcessViewRenderer::ScrollTo. | 361 // BrowserViewRenderer::ScrollTo. |
771 if (max_scroll_offset_dip_.x()) { | 362 if (max_scroll_offset_dip_.x()) { |
772 scroll_offset.set_x((scroll_offset_dip.x() * max_offset.x()) / | 363 scroll_offset.set_x((scroll_offset_dip.x() * max_offset.x()) / |
773 max_scroll_offset_dip_.x()); | 364 max_scroll_offset_dip_.x()); |
774 } | 365 } |
775 | 366 |
776 if (max_scroll_offset_dip_.y()) { | 367 if (max_scroll_offset_dip_.y()) { |
777 scroll_offset.set_y((scroll_offset_dip.y() * max_offset.y()) / | 368 scroll_offset.set_y((scroll_offset_dip.y() * max_offset.y()) / |
778 max_scroll_offset_dip_.y()); | 369 max_scroll_offset_dip_.y()); |
779 } | 370 } |
780 | 371 |
781 DCHECK(0 <= scroll_offset.x()); | 372 DCHECK(0 <= scroll_offset.x()); |
782 DCHECK(0 <= scroll_offset.y()); | 373 DCHECK(0 <= scroll_offset.y()); |
783 // Disabled because the conditions are being violated while running | 374 // Disabled because the conditions are being violated while running |
784 // AwZoomTest.testMagnification, see http://crbug.com/340648 | 375 // AwZoomTest.testMagnification, see http://crbug.com/340648 |
785 // DCHECK(scroll_offset.x() <= max_offset.x()); | 376 // DCHECK(scroll_offset.x() <= max_offset.x()); |
786 // DCHECK(scroll_offset.y() <= max_offset.y()); | 377 // DCHECK(scroll_offset.y() <= max_offset.y()); |
787 | 378 |
788 client_->ScrollContainerViewTo(scroll_offset); | 379 client_->ScrollContainerViewTo(scroll_offset); |
789 } | 380 } |
790 | 381 |
791 gfx::Vector2dF InProcessViewRenderer::GetTotalRootLayerScrollOffset() { | 382 gfx::Vector2dF BrowserViewRenderer::GetTotalRootLayerScrollOffset() { |
792 return scroll_offset_dip_; | 383 return scroll_offset_dip_; |
793 } | 384 } |
794 | 385 |
795 bool InProcessViewRenderer::IsExternalFlingActive() const { | 386 bool BrowserViewRenderer::IsExternalFlingActive() const { |
796 return client_->IsFlingActive(); | 387 return client_->IsFlingActive(); |
797 } | 388 } |
798 | 389 |
799 void InProcessViewRenderer::SetRootLayerPageScaleFactorAndLimits( | 390 void BrowserViewRenderer::SetRootLayerPageScaleFactorAndLimits( |
800 float page_scale_factor, | 391 float page_scale_factor, |
801 float min_page_scale_factor, | 392 float min_page_scale_factor, |
802 float max_page_scale_factor) { | 393 float max_page_scale_factor) { |
803 page_scale_factor_ = page_scale_factor; | 394 page_scale_factor_ = page_scale_factor; |
804 DCHECK_GT(page_scale_factor_, 0); | 395 DCHECK_GT(page_scale_factor_, 0); |
805 client_->SetPageScaleFactorAndLimits( | 396 client_->SetPageScaleFactorAndLimits( |
806 page_scale_factor, min_page_scale_factor, max_page_scale_factor); | 397 page_scale_factor, min_page_scale_factor, max_page_scale_factor); |
807 } | 398 } |
808 | 399 |
809 void InProcessViewRenderer::SetRootLayerScrollableSize( | 400 void BrowserViewRenderer::SetRootLayerScrollableSize( |
810 gfx::SizeF scrollable_size) { | 401 gfx::SizeF scrollable_size) { |
811 client_->SetContentsSize(scrollable_size); | 402 client_->SetContentsSize(scrollable_size); |
812 } | 403 } |
813 | 404 |
814 void InProcessViewRenderer::DidOverscroll( | 405 void BrowserViewRenderer::DidOverscroll(gfx::Vector2dF accumulated_overscroll, |
815 gfx::Vector2dF accumulated_overscroll, | 406 gfx::Vector2dF latest_overscroll_delta, |
816 gfx::Vector2dF latest_overscroll_delta, | 407 gfx::Vector2dF current_fling_velocity) { |
817 gfx::Vector2dF current_fling_velocity) { | |
818 const float physical_pixel_scale = dip_scale_ * page_scale_factor_; | 408 const float physical_pixel_scale = dip_scale_ * page_scale_factor_; |
819 if (accumulated_overscroll == latest_overscroll_delta) | 409 if (accumulated_overscroll == latest_overscroll_delta) |
820 overscroll_rounding_error_ = gfx::Vector2dF(); | 410 overscroll_rounding_error_ = gfx::Vector2dF(); |
821 gfx::Vector2dF scaled_overscroll_delta = | 411 gfx::Vector2dF scaled_overscroll_delta = |
822 gfx::ScaleVector2d(latest_overscroll_delta, physical_pixel_scale); | 412 gfx::ScaleVector2d(latest_overscroll_delta, physical_pixel_scale); |
823 gfx::Vector2d rounded_overscroll_delta = gfx::ToRoundedVector2d( | 413 gfx::Vector2d rounded_overscroll_delta = gfx::ToRoundedVector2d( |
824 scaled_overscroll_delta + overscroll_rounding_error_); | 414 scaled_overscroll_delta + overscroll_rounding_error_); |
825 overscroll_rounding_error_ = | 415 overscroll_rounding_error_ = |
826 scaled_overscroll_delta - rounded_overscroll_delta; | 416 scaled_overscroll_delta - rounded_overscroll_delta; |
827 client_->DidOverscroll(rounded_overscroll_delta); | 417 client_->DidOverscroll(rounded_overscroll_delta); |
828 } | 418 } |
829 | 419 |
830 void InProcessViewRenderer::EnsureContinuousInvalidation( | 420 void BrowserViewRenderer::EnsureContinuousInvalidation( |
831 AwDrawGLInfo* draw_info, | 421 AwDrawGLInfo* draw_info, |
832 bool invalidate_ignore_compositor) { | 422 bool invalidate_ignore_compositor) { |
833 // This method should be called again when any of these conditions change. | 423 // This method should be called again when any of these conditions change. |
834 bool need_invalidate = | 424 bool need_invalidate = |
835 compositor_needs_continuous_invalidate_ || invalidate_ignore_compositor; | 425 compositor_needs_continuous_invalidate_ || invalidate_ignore_compositor; |
836 if (!need_invalidate || block_invalidates_) | 426 if (!need_invalidate || block_invalidates_) |
837 return; | 427 return; |
838 | 428 |
839 // Always call view invalidate. We rely the Android framework to ignore the | 429 // Always call view invalidate. We rely the Android framework to ignore the |
840 // invalidate when it's not needed such as when view is not visible. | 430 // invalidate when it's not needed such as when view is not visible. |
(...skipping 15 matching lines...) Expand all Loading... |
856 // "on-screen" but that updates are not needed when in the background. | 446 // "on-screen" but that updates are not needed when in the background. |
857 bool throttle_fallback_tick = | 447 bool throttle_fallback_tick = |
858 (is_paused_ && !clear_view_) || (attached_to_window_ && !window_visible_); | 448 (is_paused_ && !clear_view_) || (attached_to_window_ && !window_visible_); |
859 if (throttle_fallback_tick) | 449 if (throttle_fallback_tick) |
860 return; | 450 return; |
861 | 451 |
862 block_invalidates_ = compositor_needs_continuous_invalidate_; | 452 block_invalidates_ = compositor_needs_continuous_invalidate_; |
863 | 453 |
864 // Unretained here is safe because the callback is cancelled when | 454 // Unretained here is safe because the callback is cancelled when |
865 // |fallback_tick_| is destroyed. | 455 // |fallback_tick_| is destroyed. |
866 fallback_tick_.Reset(base::Bind(&InProcessViewRenderer::FallbackTickFired, | 456 fallback_tick_.Reset(base::Bind(&BrowserViewRenderer::FallbackTickFired, |
867 base::Unretained(this))); | 457 base::Unretained(this))); |
868 | 458 |
869 // No need to reschedule fallback tick if compositor does not need to be | 459 // No need to reschedule fallback tick if compositor does not need to be |
870 // ticked. This can happen if this is reached because | 460 // ticked. This can happen if this is reached because |
871 // invalidate_ignore_compositor is true. | 461 // invalidate_ignore_compositor is true. |
872 if (compositor_needs_continuous_invalidate_) { | 462 if (compositor_needs_continuous_invalidate_) { |
873 BrowserThread::PostDelayedTask( | 463 BrowserThread::PostDelayedTask( |
874 BrowserThread::UI, | 464 BrowserThread::UI, |
875 FROM_HERE, | 465 FROM_HERE, |
876 fallback_tick_.callback(), | 466 fallback_tick_.callback(), |
877 base::TimeDelta::FromMilliseconds( | 467 base::TimeDelta::FromMilliseconds(kFallbackTickTimeoutInMilliseconds)); |
878 kFallbackTickTimeoutInMilliseconds)); | |
879 } | 468 } |
880 } | 469 } |
881 | 470 |
882 void InProcessViewRenderer::FallbackTickFired() { | 471 void BrowserViewRenderer::FallbackTickFired() { |
883 TRACE_EVENT1("android_webview", | 472 TRACE_EVENT1("android_webview", |
884 "InProcessViewRenderer::FallbackTickFired", | 473 "BrowserViewRenderer::FallbackTickFired", |
885 "compositor_needs_continuous_invalidate_", | 474 "compositor_needs_continuous_invalidate_", |
886 compositor_needs_continuous_invalidate_); | 475 compositor_needs_continuous_invalidate_); |
887 | 476 |
888 // This should only be called if OnDraw or DrawGL did not come in time, which | 477 // This should only be called if OnDraw or DrawGL did not come in time, which |
889 // means block_invalidates_ must still be true. | 478 // means block_invalidates_ must still be true. |
890 DCHECK(block_invalidates_); | 479 DCHECK(block_invalidates_); |
891 if (compositor_needs_continuous_invalidate_ && compositor_) | 480 if (compositor_needs_continuous_invalidate_ && compositor_) |
892 ForceFakeCompositeSW(); | 481 ForceFakeCompositeSW(); |
893 } | 482 } |
894 | 483 |
895 void InProcessViewRenderer::ForceFakeCompositeSW() { | 484 void BrowserViewRenderer::ForceFakeCompositeSW() { |
896 DCHECK(compositor_); | 485 DCHECK(compositor_); |
897 SkBitmapDevice device(SkBitmap::kARGB_8888_Config, 1, 1); | 486 SkBitmapDevice device(SkBitmap::kARGB_8888_Config, 1, 1); |
898 SkCanvas canvas(&device); | 487 SkCanvas canvas(&device); |
899 CompositeSW(&canvas); | 488 CompositeSW(&canvas); |
900 } | 489 } |
901 | 490 |
902 bool InProcessViewRenderer::CompositeSW(SkCanvas* canvas) { | 491 bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas) { |
903 DCHECK(compositor_); | 492 DCHECK(compositor_); |
904 | 493 |
905 fallback_tick_.Cancel(); | 494 fallback_tick_.Cancel(); |
906 block_invalidates_ = true; | 495 block_invalidates_ = true; |
907 bool result = compositor_->DemandDrawSw(canvas); | 496 bool result = compositor_->DemandDrawSw(canvas); |
908 block_invalidates_ = false; | 497 block_invalidates_ = false; |
909 EnsureContinuousInvalidation(NULL, false); | 498 EnsureContinuousInvalidation(NULL, false); |
910 return result; | 499 return result; |
911 } | 500 } |
912 | 501 |
913 std::string InProcessViewRenderer::ToString(AwDrawGLInfo* draw_info) const { | 502 std::string BrowserViewRenderer::ToString(AwDrawGLInfo* draw_info) const { |
914 std::string str; | 503 std::string str; |
915 base::StringAppendF(&str, "is_paused: %d ", is_paused_); | 504 base::StringAppendF(&str, "is_paused: %d ", is_paused_); |
916 base::StringAppendF(&str, "view_visible: %d ", view_visible_); | 505 base::StringAppendF(&str, "view_visible: %d ", view_visible_); |
917 base::StringAppendF(&str, "window_visible: %d ", window_visible_); | 506 base::StringAppendF(&str, "window_visible: %d ", window_visible_); |
918 base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); | 507 base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); |
919 base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); | 508 base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); |
920 base::StringAppendF(&str, | 509 base::StringAppendF(&str, |
921 "compositor_needs_continuous_invalidate: %d ", | 510 "compositor_needs_continuous_invalidate: %d ", |
922 compositor_needs_continuous_invalidate_); | 511 compositor_needs_continuous_invalidate_); |
923 base::StringAppendF(&str, "block_invalidates: %d ", block_invalidates_); | 512 base::StringAppendF(&str, "block_invalidates: %d ", block_invalidates_); |
924 base::StringAppendF(&str, "view width height: [%d %d] ", width_, height_); | 513 base::StringAppendF(&str, "view width height: [%d %d] ", width_, height_); |
925 base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_); | 514 base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_); |
926 base::StringAppendF(&str, "hardware_initialized: %d ", hardware_initialized_); | |
927 base::StringAppendF(&str, "hardware_failed: %d ", hardware_failed_); | |
928 base::StringAppendF(&str, | 515 base::StringAppendF(&str, |
929 "global visible rect: %s ", | 516 "global visible rect: %s ", |
930 cached_global_visible_rect_.ToString().c_str()); | 517 cached_global_visible_rect_.ToString().c_str()); |
931 base::StringAppendF(&str, | 518 base::StringAppendF(&str, |
932 "scroll_at_start_of_frame: %s ", | 519 "scroll_at_start_of_frame: %s ", |
933 scroll_at_start_of_frame_.ToString().c_str()); | 520 scroll_at_start_of_frame_.ToString().c_str()); |
934 base::StringAppendF( | 521 base::StringAppendF( |
935 &str, "scroll_offset_dip: %s ", scroll_offset_dip_.ToString().c_str()); | 522 &str, "scroll_offset_dip: %s ", scroll_offset_dip_.ToString().c_str()); |
936 base::StringAppendF(&str, | 523 base::StringAppendF(&str, |
937 "overscroll_rounding_error_: %s ", | 524 "overscroll_rounding_error_: %s ", |
(...skipping 11 matching lines...) Expand all Loading... |
949 base::StringAppendF(&str, | 536 base::StringAppendF(&str, |
950 "surface width height: [%d %d] ", | 537 "surface width height: [%d %d] ", |
951 draw_info->width, | 538 draw_info->width, |
952 draw_info->height); | 539 draw_info->height); |
953 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); | 540 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); |
954 } | 541 } |
955 return str; | 542 return str; |
956 } | 543 } |
957 | 544 |
958 } // namespace android_webview | 545 } // namespace android_webview |
OLD | NEW |