OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/native/aw_contents.h" | 5 #include "android_webview/native/aw_contents.h" |
6 | 6 |
7 #include <sys/system_properties.h> | 7 #include <sys/system_properties.h> |
8 | 8 |
9 #include "android_webview/browser/aw_browser_main_parts.h" | 9 #include "android_webview/browser/aw_browser_main_parts.h" |
10 #include "android_webview/browser/net_disk_cache_remover.h" | 10 #include "android_webview/browser/net_disk_cache_remover.h" |
11 #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h" | 11 #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h" |
12 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_dele gate.h" | 12 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_dele gate.h" |
13 #include "android_webview/common/aw_hit_test_data.h" | 13 #include "android_webview/common/aw_hit_test_data.h" |
14 #include "android_webview/common/renderer_picture_map.h" | 14 #include "android_webview/common/renderer_picture_map.h" |
15 #include "android_webview/native/aw_browser_dependency_factory.h" | 15 #include "android_webview/native/aw_browser_dependency_factory.h" |
16 #include "android_webview/native/aw_contents_io_thread_client_impl.h" | 16 #include "android_webview/native/aw_contents_io_thread_client_impl.h" |
17 #include "android_webview/native/aw_web_contents_delegate.h" | 17 #include "android_webview/native/aw_web_contents_delegate.h" |
18 #include "android_webview/native/state_serializer.h" | 18 #include "android_webview/native/state_serializer.h" |
19 #include "android_webview/public/browser/draw_sw.h" | 19 #include "android_webview/public/browser/draw_sw.h" |
20 #include "base/android/jni_android.h" | 20 #include "base/android/jni_android.h" |
21 #include "base/android/jni_array.h" | 21 #include "base/android/jni_array.h" |
22 #include "base/android/jni_string.h" | 22 #include "base/android/jni_string.h" |
23 #include "base/bind.h" | 23 #include "base/bind.h" |
24 #include "base/callback.h" | 24 #include "base/callback.h" |
25 #include "base/debug/trace_event.h" | 25 #include "base/debug/trace_event.h" |
26 #include "base/message_loop.h" | 26 #include "base/message_loop.h" |
27 #include "base/pickle.h" | 27 #include "base/pickle.h" |
28 #include "base/supports_user_data.h" | 28 #include "base/supports_user_data.h" |
29 #include "cc/layer.h" | 29 #include "cc/layer.h" |
30 #include "cc/picture_pile_impl.h" | |
31 #include "cc/rendering_stats.h" | |
32 #include "content/components/navigation_interception/intercept_navigation_delega te.h" | 30 #include "content/components/navigation_interception/intercept_navigation_delega te.h" |
33 #include "content/public/browser/android/content_view_core.h" | 31 #include "content/public/browser/android/content_view_core.h" |
34 #include "content/public/browser/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
35 #include "content/public/browser/cert_store.h" | 33 #include "content/public/browser/cert_store.h" |
36 #include "content/public/browser/navigation_entry.h" | 34 #include "content/public/browser/navigation_entry.h" |
37 #include "content/public/browser/render_process_host.h" | 35 #include "content/public/browser/render_process_host.h" |
38 #include "content/public/browser/web_contents.h" | 36 #include "content/public/browser/web_contents.h" |
39 #include "content/public/common/ssl_status.h" | 37 #include "content/public/common/ssl_status.h" |
40 #include "jni/AwContents_jni.h" | 38 #include "jni/AwContents_jni.h" |
41 #include "net/base/x509_certificate.h" | 39 #include "net/base/x509_certificate.h" |
40 #include "skia/ext/refptr.h" | |
42 #include "third_party/skia/include/core/SkBitmap.h" | 41 #include "third_party/skia/include/core/SkBitmap.h" |
43 #include "third_party/skia/include/core/SkCanvas.h" | 42 #include "third_party/skia/include/core/SkCanvas.h" |
44 #include "third_party/skia/include/core/SkDevice.h" | 43 #include "third_party/skia/include/core/SkDevice.h" |
44 #include "third_party/skia/include/core/SkPicture.h" | |
45 #include "ui/gfx/transform.h" | 45 #include "ui/gfx/transform.h" |
46 #include "ui/gl/gl_bindings.h" | 46 #include "ui/gl/gl_bindings.h" |
47 | 47 |
48 // TODO(leandrogracia): remove when crbug.com/164140 is closed. | 48 // TODO(leandrogracia): remove when crbug.com/164140 is closed. |
49 // Borrowed from gl2ext.h. Cannot be included due to conflicts with | 49 // Borrowed from gl2ext.h. Cannot be included due to conflicts with |
50 // gl_bindings.h and the EGL library methods (eglGetCurrentContext). | 50 // gl_bindings.h and the EGL library methods (eglGetCurrentContext). |
51 #ifndef GL_TEXTURE_EXTERNAL_OES | 51 #ifndef GL_TEXTURE_EXTERNAL_OES |
52 #define GL_TEXTURE_EXTERNAL_OES 0x8D65 | 52 #define GL_TEXTURE_EXTERNAL_OES 0x8D65 |
53 #endif | 53 #endif |
54 | 54 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
115 AwContents::AwContents(JNIEnv* env, | 115 AwContents::AwContents(JNIEnv* env, |
116 jobject obj, | 116 jobject obj, |
117 jobject web_contents_delegate, | 117 jobject web_contents_delegate, |
118 bool private_browsing) | 118 bool private_browsing) |
119 : java_ref_(env, obj), | 119 : java_ref_(env, obj), |
120 web_contents_delegate_( | 120 web_contents_delegate_( |
121 new AwWebContentsDelegate(env, web_contents_delegate)), | 121 new AwWebContentsDelegate(env, web_contents_delegate)), |
122 view_visible_(false), | 122 view_visible_(false), |
123 compositor_visible_(false), | 123 compositor_visible_(false), |
124 is_composite_pending_(false), | 124 is_composite_pending_(false), |
125 last_scroll_x_(0), last_scroll_y_(0), | |
126 last_frame_context_(NULL) { | 125 last_frame_context_(NULL) { |
127 RendererPictureMap::CreateInstance(); | 126 RendererPictureMap::CreateInstance(); |
128 android_webview::AwBrowserDependencyFactory* dependency_factory = | 127 android_webview::AwBrowserDependencyFactory* dependency_factory = |
129 android_webview::AwBrowserDependencyFactory::GetInstance(); | 128 android_webview::AwBrowserDependencyFactory::GetInstance(); |
130 | 129 |
131 // TODO(joth): rather than create and set the WebContents here, expose the | 130 // TODO(joth): rather than create and set the WebContents here, expose the |
132 // factory method to java side and have that orchestrate the construction | 131 // factory method to java side and have that orchestrate the construction |
133 // order. | 132 // order. |
134 SetWebContents(dependency_factory->CreateWebContents(private_browsing)); | 133 SetWebContents(dependency_factory->CreateWebContents(private_browsing)); |
135 } | 134 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 LOG(WARNING) << "No current context attached. Skipping composite."; | 262 LOG(WARNING) << "No current context attached. Skipping composite."; |
264 return; | 263 return; |
265 } | 264 } |
266 | 265 |
267 if (last_frame_context_ != current_context) { | 266 if (last_frame_context_ != current_context) { |
268 if (last_frame_context_) | 267 if (last_frame_context_) |
269 ResetCompositor(); | 268 ResetCompositor(); |
270 last_frame_context_ = current_context; | 269 last_frame_context_ = current_context; |
271 } | 270 } |
272 | 271 |
273 gfx::Transform transform; | |
274 compositor_->SetWindowBounds(gfx::Size(draw_info->width, draw_info->height)); | 272 compositor_->SetWindowBounds(gfx::Size(draw_info->width, draw_info->height)); |
275 | 273 |
276 if (draw_info->is_layer) { | 274 if (draw_info->is_layer) { |
277 // When rendering into a separate layer no view clipping, transform, | 275 // When rendering into a separate layer no view clipping, transform, |
278 // scissoring or background transparency need to be handled. | 276 // scissoring or background transparency need to be handled. |
279 // The Android framework will composite us afterwards. | 277 // The Android framework will composite us afterwards. |
280 compositor_->SetHasTransparentBackground(false); | 278 compositor_->SetHasTransparentBackground(false); |
281 view_clip_layer_->setMasksToBounds(false); | 279 view_clip_layer_->setMasksToBounds(false); |
280 transform_layer_->setTransform(gfx::Transform()); | |
282 scissor_clip_layer_->setMasksToBounds(false); | 281 scissor_clip_layer_->setMasksToBounds(false); |
283 scissor_clip_layer_->setPosition(gfx::PointF()); | 282 scissor_clip_layer_->setPosition(gfx::PointF()); |
284 scissor_clip_layer_->setBounds(gfx::Size()); | 283 scissor_clip_layer_->setBounds(gfx::Size()); |
285 scissor_clip_layer_->setSublayerTransform(gfx::Transform()); | 284 scissor_clip_layer_->setSublayerTransform(gfx::Transform()); |
286 | 285 |
287 } else { | 286 } else { |
288 compositor_->SetHasTransparentBackground(true); | 287 compositor_->SetHasTransparentBackground(true); |
289 | 288 |
290 gfx::Rect clip_rect(draw_info->clip_left, draw_info->clip_top, | 289 gfx::Rect clip_rect(draw_info->clip_left, draw_info->clip_top, |
291 draw_info->clip_right - draw_info->clip_left, | 290 draw_info->clip_right - draw_info->clip_left, |
292 draw_info->clip_bottom - draw_info->clip_top); | 291 draw_info->clip_bottom - draw_info->clip_top); |
293 | 292 |
294 scissor_clip_layer_->setPosition(clip_rect.origin()); | 293 scissor_clip_layer_->setPosition(clip_rect.origin()); |
295 scissor_clip_layer_->setBounds(clip_rect.size()); | 294 scissor_clip_layer_->setBounds(clip_rect.size()); |
296 scissor_clip_layer_->setMasksToBounds(true); | 295 scissor_clip_layer_->setMasksToBounds(true); |
297 | 296 |
298 // The compositor clipping architecture enforces us to have the clip layer | 297 // The compositor clipping architecture enforces us to have the clip layer |
299 // as an ancestor of the area we want to clip, but this makes the transform | 298 // as an ancestor of the area we want to clip, but this makes the transform |
300 // become relative to the clip area rather than the full surface. The clip | 299 // become relative to the clip area rather than the full surface. The clip |
301 // position offset needs to be undone before applying the transform. | 300 // position offset needs to be undone before applying the transform. |
302 gfx::Transform undo_clip_position; | 301 gfx::Transform undo_clip_position; |
303 undo_clip_position.Translate(-clip_rect.x(), -clip_rect.y()); | 302 undo_clip_position.Translate(-clip_rect.x(), -clip_rect.y()); |
304 scissor_clip_layer_->setSublayerTransform(undo_clip_position); | 303 scissor_clip_layer_->setSublayerTransform(undo_clip_position); |
305 | 304 |
305 gfx::Transform transform; | |
306 transform.matrix().setColMajorf(draw_info->transform); | 306 transform.matrix().setColMajorf(draw_info->transform); |
307 | |
308 // The scrolling values of the Android Framework affect the transformation | |
309 // matrix. This needs to be undone to let the compositor handle scrolling. | |
310 transform.Translate(hw_rendering_scroll_.x(), hw_rendering_scroll_.y()); | |
311 transform_layer_->setTransform(transform); | |
312 | |
joth
2013/01/08 20:48:23
should we land this bit separately to the SkPictur
Leandro GraciĆ” Gil
2013/01/08 21:52:44
I'll do if you prefer so, although that will simpl
| |
307 view_clip_layer_->setMasksToBounds(true); | 313 view_clip_layer_->setMasksToBounds(true); |
308 } | 314 } |
309 | 315 |
310 // The scrolling values of the Android Framework affect the transformation | |
311 // matrix. This needs to be undone to let the compositor handle scrolling. | |
312 transform.Translate(last_scroll_x_, last_scroll_y_); | |
313 transform_layer_->setTransform(transform); | |
314 | |
315 compositor_->Composite(); | 316 compositor_->Composite(); |
316 is_composite_pending_ = false; | 317 is_composite_pending_ = false; |
317 | 318 |
318 // TODO(leandrogracia): remove when crbug.com/164140 is closed. | 319 // TODO(leandrogracia): remove when crbug.com/164140 is closed. |
319 // --------------------------------------------------------------------------- | 320 // --------------------------------------------------------------------------- |
320 char no_gl_restore_prop[PROP_VALUE_MAX]; | 321 char no_gl_restore_prop[PROP_VALUE_MAX]; |
321 __system_property_get("webview.chromium_no_gl_restore", no_gl_restore_prop); | 322 __system_property_get("webview.chromium_no_gl_restore", no_gl_restore_prop); |
322 if (!strcmp(no_gl_restore_prop, "true")) { | 323 if (!strcmp(no_gl_restore_prop, "true")) { |
323 LOG(WARNING) << "Android GL functor not restoring the previous GL state."; | 324 LOG(WARNING) << "Android GL functor not restoring the previous GL state."; |
324 } else { | 325 } else { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
372 | 373 |
373 glScissor(scissor_box[0], scissor_box[1], scissor_box[2], | 374 glScissor(scissor_box[0], scissor_box[1], scissor_box[2], |
374 scissor_box[3]); | 375 scissor_box[3]); |
375 | 376 |
376 glUseProgram(current_program); | 377 glUseProgram(current_program); |
377 } | 378 } |
378 // --------------------------------------------------------------------------- | 379 // --------------------------------------------------------------------------- |
379 } | 380 } |
380 | 381 |
381 bool AwContents::DrawSW(JNIEnv* env, jobject obj, jobject java_canvas) { | 382 bool AwContents::DrawSW(JNIEnv* env, jobject obj, jobject java_canvas) { |
382 scoped_refptr<cc::PicturePileImpl> picture = | 383 skia::RefPtr<SkPicture> picture = |
383 RendererPictureMap::GetInstance()->GetRendererPicture( | 384 RendererPictureMap::GetInstance()->GetRendererPicture( |
384 web_contents_->GetRoutingID()); | 385 web_contents_->GetRoutingID()); |
385 if (!picture) | 386 if (!picture) |
386 return false; | 387 return false; |
387 | 388 |
388 AwPixelInfo* pixels; | 389 AwPixelInfo* pixels; |
389 if (!g_draw_sw_functions || | 390 if (!g_draw_sw_functions || |
390 (pixels = g_draw_sw_functions->access_pixels(env, java_canvas)) == NULL) { | 391 (pixels = g_draw_sw_functions->access_pixels(env, java_canvas)) == NULL) { |
391 // TODO(joth): Fall back to slow path rendering via temporary bitmap. | 392 // TODO(joth): Fall back to slow path rendering via temporary bitmap. |
392 return false; | 393 return false; |
393 } | 394 } |
394 | 395 |
395 { | 396 { |
396 SkBitmap bitmap; | 397 SkBitmap bitmap; |
397 bitmap.setConfig(static_cast<SkBitmap::Config>(pixels->config), | 398 bitmap.setConfig(static_cast<SkBitmap::Config>(pixels->config), |
398 pixels->width, | 399 pixels->width, |
399 pixels->height, | 400 pixels->height, |
400 pixels->row_bytes); | 401 pixels->row_bytes); |
401 bitmap.setPixels(pixels->pixels); | 402 bitmap.setPixels(pixels->pixels); |
402 SkDevice device(bitmap); | 403 SkDevice device(bitmap); |
403 SkCanvas canvas(&device); | 404 SkCanvas canvas(&device); |
404 SkMatrix matrix; | 405 SkMatrix matrix; |
405 for (int i = 0; i < 9; i++) { | 406 for (int i = 0; i < 9; i++) |
406 matrix.set(i, pixels->matrix[i]); | 407 matrix.set(i, pixels->matrix[i]); |
407 } | |
408 canvas.setMatrix(matrix); | 408 canvas.setMatrix(matrix); |
409 | 409 |
410 SkRegion clip; | 410 SkRegion clip; |
411 if (pixels->clip_region_size) { | 411 if (pixels->clip_region_size) { |
412 size_t bytes_read = clip.readFromMemory(pixels->clip_region); | 412 size_t bytes_read = clip.readFromMemory(pixels->clip_region); |
413 DCHECK_EQ(pixels->clip_region_size, bytes_read); | 413 DCHECK_EQ(pixels->clip_region_size, bytes_read); |
414 canvas.setClipRegion(clip); | 414 canvas.setClipRegion(clip); |
415 } else { | 415 } else { |
416 clip.setRect(SkIRect::MakeWH(pixels->width, pixels->height)); | 416 clip.setRect(SkIRect::MakeWH(pixels->width, pixels->height)); |
417 } | 417 } |
418 | 418 |
419 SkIRect sk_clip_rect = clip.getBounds(); | 419 picture->draw(&canvas); |
420 gfx::Rect clip_rect(sk_clip_rect.x(), sk_clip_rect.y(), | |
421 sk_clip_rect.width(), sk_clip_rect.height()); | |
422 | |
423 cc::RenderingStats stats; | |
424 picture->Raster(&canvas, clip_rect, 1.0, &stats); | |
425 } | 420 } |
426 | 421 |
427 g_draw_sw_functions->release_pixels(pixels); | 422 g_draw_sw_functions->release_pixels(pixels); |
428 return true; | 423 return true; |
429 } | 424 } |
430 | 425 |
431 jint AwContents::GetWebContents(JNIEnv* env, jobject obj) { | 426 jint AwContents::GetWebContents(JNIEnv* env, jobject obj) { |
432 return reinterpret_cast<jint>(web_contents_.get()); | 427 return reinterpret_cast<jint>(web_contents_.get()); |
433 } | 428 } |
434 | 429 |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
810 | 805 |
811 Pickle pickle(reinterpret_cast<const char*>(state_vector.begin()), | 806 Pickle pickle(reinterpret_cast<const char*>(state_vector.begin()), |
812 state_vector.size()); | 807 state_vector.size()); |
813 PickleIterator iterator(pickle); | 808 PickleIterator iterator(pickle); |
814 | 809 |
815 return RestoreFromPickle(&iterator, web_contents_.get()); | 810 return RestoreFromPickle(&iterator, web_contents_.get()); |
816 } | 811 } |
817 | 812 |
818 void AwContents::SetScrollForHWFrame(JNIEnv* env, jobject obj, | 813 void AwContents::SetScrollForHWFrame(JNIEnv* env, jobject obj, |
819 int scroll_x, int scroll_y) { | 814 int scroll_x, int scroll_y) { |
820 last_scroll_x_ = scroll_x; | 815 hw_rendering_scroll_ = gfx::Point(scroll_x, scroll_y); |
821 last_scroll_y_ = scroll_y; | |
822 } | 816 } |
823 | 817 |
824 void AwContents::SetPendingWebContentsForPopup( | 818 void AwContents::SetPendingWebContentsForPopup( |
825 scoped_ptr<content::WebContents> pending) { | 819 scoped_ptr<content::WebContents> pending) { |
826 if (pending_contents_.get()) { | 820 if (pending_contents_.get()) { |
827 // TODO(benm): Support holding multiple pop up window requests. | 821 // TODO(benm): Support holding multiple pop up window requests. |
828 LOG(WARNING) << "Blocking popup window creation as an outstanding " | 822 LOG(WARNING) << "Blocking popup window creation as an outstanding " |
829 << "popup window is still pending."; | 823 << "popup window is still pending."; |
830 MessageLoop::current()->DeleteSoon(FROM_HERE, pending.release()); | 824 MessageLoop::current()->DeleteSoon(FROM_HERE, pending.release()); |
831 return; | 825 return; |
832 } | 826 } |
833 pending_contents_ = pending.Pass(); | 827 pending_contents_ = pending.Pass(); |
834 } | 828 } |
835 | 829 |
836 void AwContents::FocusFirstNode(JNIEnv* env, jobject obj) { | 830 void AwContents::FocusFirstNode(JNIEnv* env, jobject obj) { |
837 web_contents_->FocusThroughTabTraversal(false); | 831 web_contents_->FocusThroughTabTraversal(false); |
838 } | 832 } |
839 | 833 |
840 jint AwContents::ReleasePopupWebContents(JNIEnv* env, jobject obj) { | 834 jint AwContents::ReleasePopupWebContents(JNIEnv* env, jobject obj) { |
841 return reinterpret_cast<jint>(pending_contents_.release()); | 835 return reinterpret_cast<jint>(pending_contents_.release()); |
842 } | 836 } |
843 | 837 |
844 void AwContents::OnPictureUpdated(int process_id, int render_view_id) { | 838 void AwContents::OnPictureUpdated(int process_id, int render_view_id) { |
845 CHECK_EQ(web_contents_->GetRenderProcessHost()->GetID(), process_id); | 839 CHECK_EQ(web_contents_->GetRenderProcessHost()->GetID(), process_id); |
846 if (render_view_id != web_contents_->GetRoutingID()) | 840 if (render_view_id != web_contents_->GetRoutingID()) |
847 return; | 841 return; |
848 | 842 |
843 // TODO(leandrogracia): delete when sw rendering uses Ubercompositor. | |
844 // Invalidation should be provided by the compositor only. | |
849 Invalidate(); | 845 Invalidate(); |
850 } | 846 } |
851 | 847 |
852 } // namespace android_webview | 848 } // namespace android_webview |
OLD | NEW |