Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(905)

Side by Side Diff: android_webview/browser/browser_view_renderer.cc

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

Powered by Google App Engine
This is Rietveld 408576698