| 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 <android/bitmap.h> | |
| 8 #include <sys/system_properties.h> | |
| 9 | |
| 10 #include "android_webview/browser/aw_browser_context.h" | 7 #include "android_webview/browser/aw_browser_context.h" |
| 11 #include "android_webview/browser/aw_browser_main_parts.h" | 8 #include "android_webview/browser/aw_browser_main_parts.h" |
| 9 #include "android_webview/browser/browser_view_renderer_impl.h" |
| 12 #include "android_webview/browser/net_disk_cache_remover.h" | 10 #include "android_webview/browser/net_disk_cache_remover.h" |
| 13 #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" |
| 14 #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" |
| 15 #include "android_webview/common/aw_hit_test_data.h" | 13 #include "android_webview/common/aw_hit_test_data.h" |
| 16 #include "android_webview/common/renderer_picture_map.h" | |
| 17 #include "android_webview/native/aw_browser_dependency_factory.h" | 14 #include "android_webview/native/aw_browser_dependency_factory.h" |
| 18 #include "android_webview/native/aw_contents_io_thread_client_impl.h" | 15 #include "android_webview/native/aw_contents_io_thread_client_impl.h" |
| 19 #include "android_webview/native/aw_web_contents_delegate.h" | 16 #include "android_webview/native/aw_web_contents_delegate.h" |
| 17 #include "android_webview/native/java_browser_view_renderer_helper.h" |
| 20 #include "android_webview/native/state_serializer.h" | 18 #include "android_webview/native/state_serializer.h" |
| 21 #include "android_webview/public/browser/draw_sw.h" | 19 #include "android_webview/public/browser/draw_gl.h" |
| 22 #include "base/android/jni_android.h" | 20 #include "base/android/jni_android.h" |
| 23 #include "base/android/jni_array.h" | 21 #include "base/android/jni_array.h" |
| 24 #include "base/android/jni_string.h" | 22 #include "base/android/jni_string.h" |
| 25 #include "base/bind.h" | 23 #include "base/bind.h" |
| 26 #include "base/callback.h" | 24 #include "base/callback.h" |
| 27 #include "base/debug/trace_event.h" | |
| 28 #include "base/message_loop.h" | 25 #include "base/message_loop.h" |
| 29 #include "base/pickle.h" | 26 #include "base/pickle.h" |
| 30 #include "base/string16.h" | 27 #include "base/string16.h" |
| 31 #include "base/supports_user_data.h" | 28 #include "base/supports_user_data.h" |
| 32 #include "cc/layer.h" | |
| 33 #include "components/navigation_interception/intercept_navigation_delegate.h" | 29 #include "components/navigation_interception/intercept_navigation_delegate.h" |
| 34 #include "content/public/browser/android/content_view_core.h" | 30 #include "content/public/browser/android/content_view_core.h" |
| 35 #include "content/public/browser/browser_thread.h" | 31 #include "content/public/browser/browser_thread.h" |
| 36 #include "content/public/browser/cert_store.h" | 32 #include "content/public/browser/cert_store.h" |
| 37 #include "content/public/browser/navigation_entry.h" | 33 #include "content/public/browser/navigation_entry.h" |
| 38 #include "content/public/browser/render_process_host.h" | 34 #include "content/public/browser/render_process_host.h" |
| 39 #include "content/public/browser/render_view_host.h" | 35 #include "content/public/browser/render_view_host.h" |
| 40 #include "content/public/browser/web_contents.h" | 36 #include "content/public/browser/web_contents.h" |
| 41 #include "content/public/common/ssl_status.h" | 37 #include "content/public/common/ssl_status.h" |
| 42 #include "jni/AwContents_jni.h" | 38 #include "jni/AwContents_jni.h" |
| 43 #include "net/base/x509_certificate.h" | 39 #include "net/base/x509_certificate.h" |
| 44 #include "third_party/skia/include/core/SkBitmap.h" | |
| 45 #include "third_party/skia/include/core/SkCanvas.h" | |
| 46 #include "third_party/skia/include/core/SkDevice.h" | |
| 47 #include "third_party/skia/include/core/SkGraphics.h" | |
| 48 #include "third_party/skia/include/core/SkPicture.h" | |
| 49 #include "ui/gfx/android/java_bitmap.h" | 40 #include "ui/gfx/android/java_bitmap.h" |
| 50 #include "ui/gfx/transform.h" | |
| 51 #include "ui/gl/gl_bindings.h" | |
| 52 | 41 |
| 53 // TODO(leandrogracia): remove when crbug.com/164140 is closed. | 42 struct AwDrawSWFunctionTable; |
| 54 // Borrowed from gl2ext.h. Cannot be included due to conflicts with | |
| 55 // gl_bindings.h and the EGL library methods (eglGetCurrentContext). | |
| 56 #ifndef GL_TEXTURE_EXTERNAL_OES | |
| 57 #define GL_TEXTURE_EXTERNAL_OES 0x8D65 | |
| 58 #endif | |
| 59 | |
| 60 #ifndef GL_TEXTURE_BINDING_EXTERNAL_OES | |
| 61 #define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 | |
| 62 #endif | |
| 63 | 43 |
| 64 using base::android::AttachCurrentThread; | 44 using base::android::AttachCurrentThread; |
| 65 using base::android::ConvertJavaStringToUTF16; | 45 using base::android::ConvertJavaStringToUTF16; |
| 66 using base::android::ConvertJavaStringToUTF8; | 46 using base::android::ConvertJavaStringToUTF8; |
| 67 using base::android::ConvertUTF16ToJavaString; | 47 using base::android::ConvertUTF16ToJavaString; |
| 68 using base::android::ConvertUTF8ToJavaString; | 48 using base::android::ConvertUTF8ToJavaString; |
| 69 using base::android::JavaRef; | 49 using base::android::JavaRef; |
| 70 using base::android::ScopedJavaGlobalRef; | 50 using base::android::ScopedJavaGlobalRef; |
| 71 using base::android::ScopedJavaLocalRef; | 51 using base::android::ScopedJavaLocalRef; |
| 72 using components::InterceptNavigationDelegate; | 52 using components::InterceptNavigationDelegate; |
| 73 using content::BrowserThread; | 53 using content::BrowserThread; |
| 74 using content::ContentViewCore; | 54 using content::ContentViewCore; |
| 75 using content::WebContents; | 55 using content::WebContents; |
| 76 | 56 |
| 77 extern "C" { | 57 extern "C" { |
| 78 static AwDrawGLFunction DrawGLFunction; | 58 static AwDrawGLFunction DrawGLFunction; |
| 79 static void DrawGLFunction(int view_context, | 59 static void DrawGLFunction(int view_context, |
| 80 AwDrawGLInfo* draw_info, | 60 AwDrawGLInfo* draw_info, |
| 81 void* spare) { | 61 void* spare) { |
| 82 // |view_context| is the value that was returned from the java | 62 // |view_context| is the value that was returned from the java |
| 83 // AwContents.onPrepareDrawGL; this cast must match the code there. | 63 // AwContents.onPrepareDrawGL; this cast must match the code there. |
| 84 reinterpret_cast<android_webview::AwContents*>(view_context)->DrawGL( | 64 reinterpret_cast<android_webview::BrowserViewRenderer*>(view_context)->DrawGL( |
| 85 draw_info); | 65 draw_info); |
| 86 } | 66 } |
| 87 | |
| 88 typedef base::Callback<bool(SkCanvas*)> RenderMethod; | |
| 89 | |
| 90 static bool RasterizeIntoBitmap(JNIEnv* env, | |
| 91 jobject jbitmap, | |
| 92 int scroll_x, | |
| 93 int scroll_y, | |
| 94 const RenderMethod& renderer) { | |
| 95 DCHECK(jbitmap); | |
| 96 | |
| 97 AndroidBitmapInfo bitmap_info; | |
| 98 if (AndroidBitmap_getInfo(env, jbitmap, &bitmap_info) < 0) { | |
| 99 LOG(WARNING) << "Error getting java bitmap info."; | |
| 100 return false; | |
| 101 } | |
| 102 | |
| 103 void* pixels = NULL; | |
| 104 if (AndroidBitmap_lockPixels(env, jbitmap, &pixels) < 0) { | |
| 105 LOG(WARNING) << "Error locking java bitmap pixels."; | |
| 106 return false; | |
| 107 } | |
| 108 | |
| 109 bool succeeded = false; | |
| 110 { | |
| 111 SkBitmap bitmap; | |
| 112 bitmap.setConfig(SkBitmap::kARGB_8888_Config, | |
| 113 bitmap_info.width, | |
| 114 bitmap_info.height, | |
| 115 bitmap_info.stride); | |
| 116 bitmap.setPixels(pixels); | |
| 117 | |
| 118 SkDevice device(bitmap); | |
| 119 SkCanvas canvas(&device); | |
| 120 canvas.translate(-scroll_x, -scroll_y); | |
| 121 succeeded = renderer.Run(&canvas); | |
| 122 } | |
| 123 | |
| 124 if (AndroidBitmap_unlockPixels(env, jbitmap) < 0) { | |
| 125 LOG(WARNING) << "Error unlocking java bitmap pixels."; | |
| 126 return false; | |
| 127 } | |
| 128 | |
| 129 return succeeded; | |
| 130 } | |
| 131 } | 67 } |
| 132 | 68 |
| 133 namespace android_webview { | 69 namespace android_webview { |
| 134 | 70 |
| 135 namespace { | 71 namespace { |
| 136 | 72 |
| 137 AwDrawSWFunctionTable* g_draw_sw_functions = NULL; | 73 static JavaBrowserViewRendererHelper java_renderer_helper; |
| 138 bool g_is_skia_version_compatible = false; | |
| 139 | 74 |
| 140 const void* kAwContentsUserDataKey = &kAwContentsUserDataKey; | 75 const void* kAwContentsUserDataKey = &kAwContentsUserDataKey; |
| 141 | 76 |
| 142 class AwContentsUserData : public base::SupportsUserData::Data { | 77 class AwContentsUserData : public base::SupportsUserData::Data { |
| 143 public: | 78 public: |
| 144 AwContentsUserData(AwContents* ptr) : contents_(ptr) {} | 79 AwContentsUserData(AwContents* ptr) : contents_(ptr) {} |
| 145 | 80 |
| 146 static AwContents* GetContents(WebContents* web_contents) { | 81 static AwContents* GetContents(WebContents* web_contents) { |
| 147 if (!web_contents) | 82 if (!web_contents) |
| 148 return NULL; | 83 return NULL; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 173 if (!web_contents) return NULL; | 108 if (!web_contents) return NULL; |
| 174 return FromWebContents(web_contents); | 109 return FromWebContents(web_contents); |
| 175 } | 110 } |
| 176 | 111 |
| 177 AwContents::AwContents(JNIEnv* env, | 112 AwContents::AwContents(JNIEnv* env, |
| 178 jobject obj, | 113 jobject obj, |
| 179 jobject web_contents_delegate) | 114 jobject web_contents_delegate) |
| 180 : java_ref_(env, obj), | 115 : java_ref_(env, obj), |
| 181 web_contents_delegate_( | 116 web_contents_delegate_( |
| 182 new AwWebContentsDelegate(env, web_contents_delegate)), | 117 new AwWebContentsDelegate(env, web_contents_delegate)), |
| 183 view_visible_(false), | 118 ALLOW_THIS_IN_INITIALIZER_LIST(browser_view_renderer_( |
| 184 compositor_visible_(false), | 119 BrowserViewRendererImpl::Create(this, &java_renderer_helper))) { |
| 185 is_composite_pending_(false), | |
| 186 dpi_scale_(1.0f), | |
| 187 on_new_picture_mode_(kOnNewPictureDisabled), | |
| 188 last_frame_context_(NULL) { | |
| 189 RendererPictureMap::CreateInstance(); | |
| 190 android_webview::AwBrowserDependencyFactory* dependency_factory = | 120 android_webview::AwBrowserDependencyFactory* dependency_factory = |
| 191 android_webview::AwBrowserDependencyFactory::GetInstance(); | 121 android_webview::AwBrowserDependencyFactory::GetInstance(); |
| 192 | 122 |
| 193 // TODO(joth): rather than create and set the WebContents here, expose the | 123 // TODO(joth): rather than create and set the WebContents here, expose the |
| 194 // factory method to java side and have that orchestrate the construction | 124 // factory method to java side and have that orchestrate the construction |
| 195 // order. | 125 // order. |
| 196 SetWebContents(dependency_factory->CreateWebContents()); | 126 SetWebContents(dependency_factory->CreateWebContents()); |
| 197 } | 127 } |
| 198 | 128 |
| 199 void AwContents::ResetCompositor() { | |
| 200 compositor_.reset(content::Compositor::Create(this)); | |
| 201 if (scissor_clip_layer_.get()) | |
| 202 AttachLayerTree(); | |
| 203 } | |
| 204 | |
| 205 void AwContents::SetWebContents(content::WebContents* web_contents) { | 129 void AwContents::SetWebContents(content::WebContents* web_contents) { |
| 206 web_contents_.reset(web_contents); | 130 web_contents_.reset(web_contents); |
| 207 if (find_helper_.get()) { | 131 if (find_helper_.get()) { |
| 208 find_helper_->SetListener(NULL); | 132 find_helper_->SetListener(NULL); |
| 209 } | 133 } |
| 210 icon_helper_.reset(new IconHelper(web_contents_.get())); | 134 icon_helper_.reset(new IconHelper(web_contents_.get())); |
| 211 icon_helper_->SetListener(this); | 135 icon_helper_->SetListener(this); |
| 212 web_contents_->SetUserData(kAwContentsUserDataKey, | 136 web_contents_->SetUserData(kAwContentsUserDataKey, |
| 213 new AwContentsUserData(this)); | 137 new AwContentsUserData(this)); |
| 214 | |
| 215 web_contents_->SetDelegate(web_contents_delegate_.get()); | 138 web_contents_->SetDelegate(web_contents_delegate_.get()); |
| 216 render_view_host_ext_.reset(new AwRenderViewHostExt(web_contents_.get(), | 139 render_view_host_ext_.reset(new AwRenderViewHostExt(web_contents_.get())); |
| 217 this)); | |
| 218 ResetCompositor(); | |
| 219 } | 140 } |
| 220 | 141 |
| 221 void AwContents::SetWebContents(JNIEnv* env, jobject obj, jint new_wc) { | 142 void AwContents::SetWebContents(JNIEnv* env, jobject obj, jint new_wc) { |
| 222 SetWebContents(reinterpret_cast<content::WebContents*>(new_wc)); | 143 SetWebContents(reinterpret_cast<content::WebContents*>(new_wc)); |
| 223 } | 144 } |
| 224 | 145 |
| 225 AwContents::~AwContents() { | 146 AwContents::~AwContents() { |
| 226 DCHECK(AwContents::FromWebContents(web_contents_.get()) == this); | 147 DCHECK(AwContents::FromWebContents(web_contents_.get()) == this); |
| 227 web_contents_->RemoveUserData(kAwContentsUserDataKey); | 148 web_contents_->RemoveUserData(kAwContentsUserDataKey); |
| 228 if (find_helper_.get()) | 149 if (find_helper_.get()) |
| 229 find_helper_->SetListener(NULL); | 150 find_helper_->SetListener(NULL); |
| 230 if (icon_helper_.get()) | 151 if (icon_helper_.get()) |
| 231 icon_helper_->SetListener(NULL); | 152 icon_helper_->SetListener(NULL); |
| 232 } | 153 } |
| 233 | 154 |
| 234 void AwContents::DrawGL(AwDrawGLInfo* draw_info) { | |
| 235 | |
| 236 TRACE_EVENT0("AwContents", "AwContents::DrawGL"); | |
| 237 | |
| 238 if (view_size_.IsEmpty() || !scissor_clip_layer_ || | |
| 239 draw_info->mode == AwDrawGLInfo::kModeProcess) | |
| 240 return; | |
| 241 | |
| 242 DCHECK_EQ(draw_info->mode, AwDrawGLInfo::kModeDraw); | |
| 243 | |
| 244 SetCompositorVisibility(view_visible_); | |
| 245 if (!compositor_visible_) | |
| 246 return; | |
| 247 | |
| 248 // TODO(leandrogracia): remove when crbug.com/164140 is closed. | |
| 249 // --------------------------------------------------------------------------- | |
| 250 GLint texture_external_oes_binding; | |
| 251 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texture_external_oes_binding); | |
| 252 | |
| 253 GLint vertex_array_buffer_binding; | |
| 254 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertex_array_buffer_binding); | |
| 255 | |
| 256 GLint index_array_buffer_binding; | |
| 257 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &index_array_buffer_binding); | |
| 258 | |
| 259 GLint pack_alignment; | |
| 260 glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment); | |
| 261 | |
| 262 GLint unpack_alignment; | |
| 263 glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment); | |
| 264 | |
| 265 struct { | |
| 266 GLint enabled; | |
| 267 GLint size; | |
| 268 GLint type; | |
| 269 GLint normalized; | |
| 270 GLint stride; | |
| 271 GLvoid* pointer; | |
| 272 } vertex_attrib[3]; | |
| 273 | |
| 274 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib); ++i) { | |
| 275 glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, | |
| 276 &vertex_attrib[i].enabled); | |
| 277 glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, | |
| 278 &vertex_attrib[i].size); | |
| 279 glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, | |
| 280 &vertex_attrib[i].type); | |
| 281 glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, | |
| 282 &vertex_attrib[i].normalized); | |
| 283 glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, | |
| 284 &vertex_attrib[i].stride); | |
| 285 glGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, | |
| 286 &vertex_attrib[i].pointer); | |
| 287 } | |
| 288 | |
| 289 GLboolean depth_test; | |
| 290 glGetBooleanv(GL_DEPTH_TEST, &depth_test); | |
| 291 | |
| 292 GLboolean cull_face; | |
| 293 glGetBooleanv(GL_CULL_FACE, &cull_face); | |
| 294 | |
| 295 GLboolean color_mask[4]; | |
| 296 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask); | |
| 297 | |
| 298 GLboolean blend_enabled; | |
| 299 glGetBooleanv(GL_BLEND, &blend_enabled); | |
| 300 | |
| 301 GLint blend_src_rgb; | |
| 302 glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb); | |
| 303 | |
| 304 GLint blend_src_alpha; | |
| 305 glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_alpha); | |
| 306 | |
| 307 GLint blend_dest_rgb; | |
| 308 glGetIntegerv(GL_BLEND_DST_RGB, &blend_dest_rgb); | |
| 309 | |
| 310 GLint blend_dest_alpha; | |
| 311 glGetIntegerv(GL_BLEND_DST_ALPHA, &blend_dest_alpha); | |
| 312 | |
| 313 GLint active_texture; | |
| 314 glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture); | |
| 315 | |
| 316 GLint viewport[4]; | |
| 317 glGetIntegerv(GL_VIEWPORT, viewport); | |
| 318 | |
| 319 GLboolean scissor_test; | |
| 320 glGetBooleanv(GL_SCISSOR_TEST, &scissor_test); | |
| 321 | |
| 322 GLint scissor_box[4]; | |
| 323 glGetIntegerv(GL_SCISSOR_BOX, scissor_box); | |
| 324 | |
| 325 GLint current_program; | |
| 326 glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program); | |
| 327 // --------------------------------------------------------------------------- | |
| 328 | |
| 329 // We need to watch if the current Android context has changed and enforce | |
| 330 // a clean-up in the compositor. | |
| 331 EGLContext current_context = eglGetCurrentContext(); | |
| 332 if (!current_context) { | |
| 333 LOG(WARNING) << "No current context attached. Skipping composite."; | |
| 334 return; | |
| 335 } | |
| 336 | |
| 337 if (last_frame_context_ != current_context) { | |
| 338 if (last_frame_context_) | |
| 339 ResetCompositor(); | |
| 340 last_frame_context_ = current_context; | |
| 341 } | |
| 342 | |
| 343 compositor_->SetWindowBounds(gfx::Size(draw_info->width, draw_info->height)); | |
| 344 | |
| 345 if (draw_info->is_layer) { | |
| 346 // When rendering into a separate layer no view clipping, transform, | |
| 347 // scissoring or background transparency need to be handled. | |
| 348 // The Android framework will composite us afterwards. | |
| 349 compositor_->SetHasTransparentBackground(false); | |
| 350 view_clip_layer_->setMasksToBounds(false); | |
| 351 transform_layer_->setTransform(gfx::Transform()); | |
| 352 scissor_clip_layer_->setMasksToBounds(false); | |
| 353 scissor_clip_layer_->setPosition(gfx::PointF()); | |
| 354 scissor_clip_layer_->setBounds(gfx::Size()); | |
| 355 scissor_clip_layer_->setSublayerTransform(gfx::Transform()); | |
| 356 | |
| 357 } else { | |
| 358 compositor_->SetHasTransparentBackground(true); | |
| 359 | |
| 360 gfx::Rect clip_rect(draw_info->clip_left, draw_info->clip_top, | |
| 361 draw_info->clip_right - draw_info->clip_left, | |
| 362 draw_info->clip_bottom - draw_info->clip_top); | |
| 363 | |
| 364 scissor_clip_layer_->setPosition(clip_rect.origin()); | |
| 365 scissor_clip_layer_->setBounds(clip_rect.size()); | |
| 366 scissor_clip_layer_->setMasksToBounds(true); | |
| 367 | |
| 368 // The compositor clipping architecture enforces us to have the clip layer | |
| 369 // as an ancestor of the area we want to clip, but this makes the transform | |
| 370 // become relative to the clip area rather than the full surface. The clip | |
| 371 // position offset needs to be undone before applying the transform. | |
| 372 gfx::Transform undo_clip_position; | |
| 373 undo_clip_position.Translate(-clip_rect.x(), -clip_rect.y()); | |
| 374 scissor_clip_layer_->setSublayerTransform(undo_clip_position); | |
| 375 | |
| 376 gfx::Transform transform; | |
| 377 transform.matrix().setColMajorf(draw_info->transform); | |
| 378 | |
| 379 // The scrolling values of the Android Framework affect the transformation | |
| 380 // matrix. This needs to be undone to let the compositor handle scrolling. | |
| 381 transform.Translate(hw_rendering_scroll_.x(), hw_rendering_scroll_.y()); | |
| 382 transform_layer_->setTransform(transform); | |
| 383 | |
| 384 view_clip_layer_->setMasksToBounds(true); | |
| 385 } | |
| 386 | |
| 387 compositor_->Composite(); | |
| 388 is_composite_pending_ = false; | |
| 389 | |
| 390 // TODO(leandrogracia): remove when crbug.com/164140 is closed. | |
| 391 // --------------------------------------------------------------------------- | |
| 392 char no_gl_restore_prop[PROP_VALUE_MAX]; | |
| 393 __system_property_get("webview.chromium_no_gl_restore", no_gl_restore_prop); | |
| 394 if (!strcmp(no_gl_restore_prop, "true")) { | |
| 395 LOG(WARNING) << "Android GL functor not restoring the previous GL state."; | |
| 396 } else { | |
| 397 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_external_oes_binding); | |
| 398 glBindBuffer(GL_ARRAY_BUFFER, vertex_array_buffer_binding); | |
| 399 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding); | |
| 400 | |
| 401 glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment); | |
| 402 glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment); | |
| 403 | |
| 404 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib); ++i) { | |
| 405 glVertexAttribPointer(i, vertex_attrib[i].size, | |
| 406 vertex_attrib[i].type, vertex_attrib[i].normalized, | |
| 407 vertex_attrib[i].stride, vertex_attrib[i].pointer); | |
| 408 | |
| 409 if (vertex_attrib[i].enabled) | |
| 410 glEnableVertexAttribArray(i); | |
| 411 else | |
| 412 glDisableVertexAttribArray(i); | |
| 413 } | |
| 414 | |
| 415 if (depth_test) | |
| 416 glEnable(GL_DEPTH_TEST); | |
| 417 else | |
| 418 glDisable(GL_DEPTH_TEST); | |
| 419 | |
| 420 if (cull_face) | |
| 421 glEnable(GL_CULL_FACE); | |
| 422 else | |
| 423 glDisable(GL_CULL_FACE); | |
| 424 | |
| 425 glColorMask(color_mask[0], color_mask[1], color_mask[2], | |
| 426 color_mask[3]); | |
| 427 | |
| 428 if (blend_enabled) | |
| 429 glEnable(GL_BLEND); | |
| 430 else | |
| 431 glDisable(GL_BLEND); | |
| 432 | |
| 433 glBlendFuncSeparate(blend_src_rgb, blend_dest_rgb, | |
| 434 blend_src_alpha, blend_dest_alpha); | |
| 435 | |
| 436 glActiveTexture(active_texture); | |
| 437 | |
| 438 glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); | |
| 439 | |
| 440 if (scissor_test) | |
| 441 glEnable(GL_SCISSOR_TEST); | |
| 442 else | |
| 443 glDisable(GL_SCISSOR_TEST); | |
| 444 | |
| 445 glScissor(scissor_box[0], scissor_box[1], scissor_box[2], | |
| 446 scissor_box[3]); | |
| 447 | |
| 448 glUseProgram(current_program); | |
| 449 } | |
| 450 // --------------------------------------------------------------------------- | |
| 451 } | |
| 452 | |
| 453 bool AwContents::DrawSW(JNIEnv* env, | |
| 454 jobject obj, | |
| 455 jobject java_canvas, | |
| 456 jint clip_x, | |
| 457 jint clip_y, | |
| 458 jint clip_w, | |
| 459 jint clip_h) { | |
| 460 TRACE_EVENT0("AwContents", "AwContents::DrawSW"); | |
| 461 | |
| 462 if (clip_w <= 0 || clip_h <= 0) | |
| 463 return true; | |
| 464 | |
| 465 AwPixelInfo* pixels; | |
| 466 | |
| 467 // Render into an auxiliary bitmap if pixel info is not available. | |
| 468 if (!g_draw_sw_functions || | |
| 469 (pixels = g_draw_sw_functions->access_pixels(env, java_canvas)) == NULL) { | |
| 470 ScopedJavaLocalRef<jobject> jbitmap(Java_AwContents_createBitmap( | |
| 471 env, clip_w, clip_h)); | |
| 472 if (!jbitmap.obj()) | |
| 473 return false; | |
| 474 | |
| 475 if (!RasterizeIntoBitmap(env, jbitmap.obj(), clip_x, clip_y, | |
| 476 base::Bind(&AwContents::RenderSW, base::Unretained(this)))) | |
| 477 return false; | |
| 478 | |
| 479 Java_AwContents_drawBitmapIntoCanvas(env, jbitmap.obj(), java_canvas); | |
| 480 return true; | |
| 481 } | |
| 482 | |
| 483 // Draw in a SkCanvas built over the pixel information. | |
| 484 bool succeeded = false; | |
| 485 { | |
| 486 SkBitmap bitmap; | |
| 487 bitmap.setConfig(static_cast<SkBitmap::Config>(pixels->config), | |
| 488 pixels->width, | |
| 489 pixels->height, | |
| 490 pixels->row_bytes); | |
| 491 bitmap.setPixels(pixels->pixels); | |
| 492 SkDevice device(bitmap); | |
| 493 SkCanvas canvas(&device); | |
| 494 SkMatrix matrix; | |
| 495 for (int i = 0; i < 9; i++) | |
| 496 matrix.set(i, pixels->matrix[i]); | |
| 497 canvas.setMatrix(matrix); | |
| 498 | |
| 499 SkRegion clip; | |
| 500 if (pixels->clip_region_size) { | |
| 501 size_t bytes_read = clip.readFromMemory(pixels->clip_region); | |
| 502 DCHECK_EQ(pixels->clip_region_size, bytes_read); | |
| 503 canvas.setClipRegion(clip); | |
| 504 } else { | |
| 505 clip.setRect(SkIRect::MakeWH(pixels->width, pixels->height)); | |
| 506 } | |
| 507 | |
| 508 succeeded = RenderSW(&canvas); | |
| 509 } | |
| 510 | |
| 511 g_draw_sw_functions->release_pixels(pixels); | |
| 512 return succeeded; | |
| 513 } | |
| 514 | |
| 515 jint AwContents::GetWebContents(JNIEnv* env, jobject obj) { | 155 jint AwContents::GetWebContents(JNIEnv* env, jobject obj) { |
| 516 return reinterpret_cast<jint>(web_contents_.get()); | 156 return reinterpret_cast<jint>(web_contents_.get()); |
| 517 } | 157 } |
| 518 | 158 |
| 519 void AwContents::DidInitializeContentViewCore(JNIEnv* env, jobject obj, | 159 void AwContents::DidInitializeContentViewCore(JNIEnv* env, jobject obj, |
| 520 jint content_view_core) { | 160 jint content_view_core) { |
| 521 ContentViewCore* core = reinterpret_cast<ContentViewCore*>(content_view_core); | 161 ContentViewCore* core = reinterpret_cast<ContentViewCore*>(content_view_core); |
| 522 DCHECK(core == ContentViewCore::FromWebContents(web_contents_.get())); | 162 DCHECK(core == ContentViewCore::FromWebContents(web_contents_.get())); |
| 523 | 163 browser_view_renderer_->SetContents(core); |
| 524 dpi_scale_ = core->GetDpiScale(); | |
| 525 | |
| 526 // Ensures content keeps clipped within the view during transformations. | |
| 527 view_clip_layer_ = cc::Layer::create(); | |
| 528 view_clip_layer_->setBounds(view_size_); | |
| 529 view_clip_layer_->addChild(core->GetLayer()); | |
| 530 | |
| 531 // Applies the transformation matrix. | |
| 532 transform_layer_ = cc::Layer::create(); | |
| 533 transform_layer_->addChild(view_clip_layer_); | |
| 534 | |
| 535 // Ensures content is drawn within the scissor clip rect provided by the | |
| 536 // Android framework. | |
| 537 scissor_clip_layer_ = cc::Layer::create(); | |
| 538 scissor_clip_layer_->addChild(transform_layer_); | |
| 539 | |
| 540 AttachLayerTree(); | |
| 541 } | |
| 542 | |
| 543 void AwContents::AttachLayerTree() { | |
| 544 DCHECK(scissor_clip_layer_.get()); | |
| 545 compositor_->SetRootLayer(scissor_clip_layer_); | |
| 546 Invalidate(); | |
| 547 } | 164 } |
| 548 | 165 |
| 549 void AwContents::Destroy(JNIEnv* env, jobject obj) { | 166 void AwContents::Destroy(JNIEnv* env, jobject obj) { |
| 550 delete this; | 167 delete this; |
| 551 } | 168 } |
| 552 | 169 |
| 553 // static | 170 // static |
| 554 void SetAwDrawSWFunctionTable(JNIEnv* env, jclass, jint function_table) { | 171 void SetAwDrawSWFunctionTable(JNIEnv* env, jclass, jint function_table) { |
| 555 g_draw_sw_functions = | 172 BrowserViewRendererImpl::SetAwDrawSWFunctionTable( |
| 556 reinterpret_cast<AwDrawSWFunctionTable*>(function_table); | 173 reinterpret_cast<AwDrawSWFunctionTable*>(function_table)); |
| 557 g_is_skia_version_compatible = | |
| 558 g_draw_sw_functions->is_skia_version_compatible(&SkGraphics::GetVersion); | |
| 559 LOG_IF(WARNING, !g_is_skia_version_compatible) << | |
| 560 "Skia native versions are not compatible."; | |
| 561 } | 174 } |
| 562 | 175 |
| 563 // static | 176 // static |
| 564 jint GetAwDrawGLFunction(JNIEnv* env, jclass) { | 177 jint GetAwDrawGLFunction(JNIEnv* env, jclass) { |
| 565 return reinterpret_cast<jint>(&DrawGLFunction); | 178 return reinterpret_cast<jint>(&DrawGLFunction); |
| 566 } | 179 } |
| 567 | 180 |
| 181 jint AwContents::GetAwDrawGLViewContext(JNIEnv* env, jobject obj) { |
| 182 return reinterpret_cast<jint>(browser_view_renderer_.get()); |
| 183 } |
| 184 |
| 568 namespace { | 185 namespace { |
| 569 void DocumentHasImagesCallback(const ScopedJavaGlobalRef<jobject>& message, | 186 void DocumentHasImagesCallback(const ScopedJavaGlobalRef<jobject>& message, |
| 570 bool has_images) { | 187 bool has_images) { |
| 571 Java_AwContents_onDocumentHasImagesResponse(AttachCurrentThread(), | 188 Java_AwContents_onDocumentHasImagesResponse(AttachCurrentThread(), |
| 572 has_images, | 189 has_images, |
| 573 message.obj()); | 190 message.obj()); |
| 574 } | 191 } |
| 575 } // namespace | 192 } // namespace |
| 576 | 193 |
| 577 void AwContents::DocumentHasImages(JNIEnv* env, jobject obj, jobject message) { | 194 void AwContents::DocumentHasImages(JNIEnv* env, jobject obj, jobject message) { |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 bool precomposed) { | 500 bool precomposed) { |
| 884 JNIEnv* env = AttachCurrentThread(); | 501 JNIEnv* env = AttachCurrentThread(); |
| 885 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); | 502 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); |
| 886 if (obj.is_null()) | 503 if (obj.is_null()) |
| 887 return; | 504 return; |
| 888 | 505 |
| 889 Java_AwContents_onReceivedTouchIconUrl( | 506 Java_AwContents_onReceivedTouchIconUrl( |
| 890 env, obj.obj(), ConvertUTF8ToJavaString(env, url).obj(), precomposed); | 507 env, obj.obj(), ConvertUTF8ToJavaString(env, url).obj(), precomposed); |
| 891 } | 508 } |
| 892 | 509 |
| 893 void AwContents::ScheduleComposite() { | |
| 894 TRACE_EVENT0("AwContents", "AwContents::ScheduleComposite"); | |
| 895 | |
| 896 if (is_composite_pending_) | |
| 897 return; | |
| 898 | |
| 899 is_composite_pending_ = true; | |
| 900 Invalidate(); | |
| 901 } | |
| 902 | |
| 903 void AwContents::Invalidate() { | 510 void AwContents::Invalidate() { |
| 904 JNIEnv* env = AttachCurrentThread(); | 511 JNIEnv* env = AttachCurrentThread(); |
| 905 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); | 512 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); |
| 906 if (obj.is_null()) | 513 if (!obj.is_null()) |
| 907 return; | |
| 908 | |
| 909 if (view_visible_) | |
| 910 Java_AwContents_invalidate(env, obj.obj()); | 514 Java_AwContents_invalidate(env, obj.obj()); |
| 911 | |
| 912 // When not in invalidation-only mode onNewPicture will be triggered | |
| 913 // from the OnPictureUpdated callback. | |
| 914 if (on_new_picture_mode_ == kOnNewPictureInvalidationOnly) | |
| 915 Java_AwContents_onNewPicture(env, obj.obj(), NULL); | |
| 916 } | 515 } |
| 917 | 516 |
| 918 void AwContents::SetCompositorVisibility(bool visible) { | 517 void AwContents::OnNewPicture(const JavaRef<jobject>& picture) { |
| 919 if (compositor_visible_ != visible) { | 518 JNIEnv* env = AttachCurrentThread(); |
| 920 compositor_visible_ = visible; | 519 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); |
| 921 compositor_->SetVisible(compositor_visible_); | 520 if (!obj.is_null()) |
| 922 } | 521 Java_AwContents_onNewPicture(env, obj.obj(), picture.obj()); |
| 923 } | |
| 924 | |
| 925 void AwContents::OnSwapBuffersCompleted() { | |
| 926 } | 522 } |
| 927 | 523 |
| 928 base::android::ScopedJavaLocalRef<jbyteArray> | 524 base::android::ScopedJavaLocalRef<jbyteArray> |
| 929 AwContents::GetCertificate(JNIEnv* env, | 525 AwContents::GetCertificate(JNIEnv* env, |
| 930 jobject obj) { | 526 jobject obj) { |
| 931 content::NavigationEntry* entry = | 527 content::NavigationEntry* entry = |
| 932 web_contents_->GetController().GetActiveEntry(); | 528 web_contents_->GetController().GetActiveEntry(); |
| 933 if (!entry) | 529 if (!entry) |
| 934 return ScopedJavaLocalRef<jbyteArray>(); | 530 return ScopedJavaLocalRef<jbyteArray>(); |
| 935 // Get the certificate | 531 // Get the certificate |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 979 obj, | 575 obj, |
| 980 data.type, | 576 data.type, |
| 981 extra_data_for_type.obj(), | 577 extra_data_for_type.obj(), |
| 982 href.obj(), | 578 href.obj(), |
| 983 anchor_text.obj(), | 579 anchor_text.obj(), |
| 984 img_src.obj()); | 580 img_src.obj()); |
| 985 } | 581 } |
| 986 | 582 |
| 987 void AwContents::OnSizeChanged(JNIEnv* env, jobject obj, | 583 void AwContents::OnSizeChanged(JNIEnv* env, jobject obj, |
| 988 int w, int h, int ow, int oh) { | 584 int w, int h, int ow, int oh) { |
| 989 view_size_ = gfx::Size(w, h); | 585 browser_view_renderer_->OnSizeChanged(w, h); |
| 990 if (view_clip_layer_.get()) | |
| 991 view_clip_layer_->setBounds(view_size_); | |
| 992 } | 586 } |
| 993 | 587 |
| 994 void AwContents::SetWindowViewVisibility(JNIEnv* env, jobject obj, | 588 void AwContents::SetWindowViewVisibility(JNIEnv* env, jobject obj, |
| 995 bool window_visible, | 589 bool window_visible, |
| 996 bool view_visible) { | 590 bool view_visible) { |
| 997 view_visible_ = window_visible && view_visible; | 591 browser_view_renderer_->OnVisibilityChanged(window_visible, view_visible); |
| 998 Invalidate(); | |
| 999 } | 592 } |
| 1000 | 593 |
| 1001 void AwContents::OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h) { | 594 void AwContents::OnAttachedToWindow(JNIEnv* env, jobject obj, int w, int h) { |
| 1002 view_size_ = gfx::Size(w, h); | 595 browser_view_renderer_->OnAttachedToWindow(w, h); |
| 1003 if (view_clip_layer_.get()) | |
| 1004 view_clip_layer_->setBounds(view_size_); | |
| 1005 } | 596 } |
| 1006 | 597 |
| 1007 void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) { | 598 void AwContents::OnDetachedFromWindow(JNIEnv* env, jobject obj) { |
| 1008 view_visible_ = false; | 599 browser_view_renderer_->OnDetachedFromWindow(); |
| 1009 SetCompositorVisibility(false); | |
| 1010 } | 600 } |
| 1011 | 601 |
| 1012 base::android::ScopedJavaLocalRef<jbyteArray> | 602 base::android::ScopedJavaLocalRef<jbyteArray> |
| 1013 AwContents::GetOpaqueState(JNIEnv* env, jobject obj) { | 603 AwContents::GetOpaqueState(JNIEnv* env, jobject obj) { |
| 1014 // Required optimization in WebViewClassic to not save any state if | 604 // Required optimization in WebViewClassic to not save any state if |
| 1015 // there has been no navigations. | 605 // there has been no navigations. |
| 1016 if (!web_contents_->GetController().GetEntryCount()) | 606 if (!web_contents_->GetController().GetEntryCount()) |
| 1017 return ScopedJavaLocalRef<jbyteArray>(); | 607 return ScopedJavaLocalRef<jbyteArray>(); |
| 1018 | 608 |
| 1019 Pickle pickle; | 609 Pickle pickle; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1032 std::vector<uint8> state_vector; | 622 std::vector<uint8> state_vector; |
| 1033 base::android::JavaByteArrayToByteVector(env, state, &state_vector); | 623 base::android::JavaByteArrayToByteVector(env, state, &state_vector); |
| 1034 | 624 |
| 1035 Pickle pickle(reinterpret_cast<const char*>(state_vector.begin()), | 625 Pickle pickle(reinterpret_cast<const char*>(state_vector.begin()), |
| 1036 state_vector.size()); | 626 state_vector.size()); |
| 1037 PickleIterator iterator(pickle); | 627 PickleIterator iterator(pickle); |
| 1038 | 628 |
| 1039 return RestoreFromPickle(&iterator, web_contents_.get()); | 629 return RestoreFromPickle(&iterator, web_contents_.get()); |
| 1040 } | 630 } |
| 1041 | 631 |
| 632 bool AwContents::DrawSW(JNIEnv* env, |
| 633 jobject obj, |
| 634 jobject canvas, |
| 635 jint clip_x, |
| 636 jint clip_y, |
| 637 jint clip_w, |
| 638 jint clip_h) { |
| 639 return browser_view_renderer_->DrawSW( |
| 640 canvas, gfx::Rect(clip_x, clip_y, clip_w, clip_h)); |
| 641 } |
| 642 |
| 1042 void AwContents::SetScrollForHWFrame(JNIEnv* env, jobject obj, | 643 void AwContents::SetScrollForHWFrame(JNIEnv* env, jobject obj, |
| 1043 int scroll_x, int scroll_y) { | 644 int scroll_x, int scroll_y) { |
| 1044 hw_rendering_scroll_ = gfx::Point(scroll_x, scroll_y); | 645 browser_view_renderer_->SetScrollForHWFrame(scroll_x, scroll_y); |
| 1045 } | 646 } |
| 1046 | 647 |
| 1047 void AwContents::SetPendingWebContentsForPopup( | 648 void AwContents::SetPendingWebContentsForPopup( |
| 1048 scoped_ptr<content::WebContents> pending) { | 649 scoped_ptr<content::WebContents> pending) { |
| 1049 if (pending_contents_.get()) { | 650 if (pending_contents_.get()) { |
| 1050 // TODO(benm): Support holding multiple pop up window requests. | 651 // TODO(benm): Support holding multiple pop up window requests. |
| 1051 LOG(WARNING) << "Blocking popup window creation as an outstanding " | 652 LOG(WARNING) << "Blocking popup window creation as an outstanding " |
| 1052 << "popup window is still pending."; | 653 << "popup window is still pending."; |
| 1053 MessageLoop::current()->DeleteSoon(FROM_HERE, pending.release()); | 654 MessageLoop::current()->DeleteSoon(FROM_HERE, pending.release()); |
| 1054 return; | 655 return; |
| 1055 } | 656 } |
| 1056 pending_contents_ = pending.Pass(); | 657 pending_contents_ = pending.Pass(); |
| 1057 } | 658 } |
| 1058 | 659 |
| 1059 void AwContents::FocusFirstNode(JNIEnv* env, jobject obj) { | 660 void AwContents::FocusFirstNode(JNIEnv* env, jobject obj) { |
| 1060 web_contents_->FocusThroughTabTraversal(false); | 661 web_contents_->FocusThroughTabTraversal(false); |
| 1061 } | 662 } |
| 1062 | 663 |
| 1063 jint AwContents::ReleasePopupWebContents(JNIEnv* env, jobject obj) { | 664 jint AwContents::ReleasePopupWebContents(JNIEnv* env, jobject obj) { |
| 1064 return reinterpret_cast<jint>(pending_contents_.release()); | 665 return reinterpret_cast<jint>(pending_contents_.release()); |
| 1065 } | 666 } |
| 1066 | 667 |
| 1067 ScopedJavaLocalRef<jobject> AwContents::CapturePicture(JNIEnv* env, | 668 ScopedJavaLocalRef<jobject> AwContents::CapturePicture(JNIEnv* env, |
| 1068 jobject obj) { | 669 jobject obj) { |
| 1069 skia::RefPtr<SkPicture> picture = GetLastCapturedPicture(); | 670 return browser_view_renderer_->CapturePicture(); |
| 1070 if (!picture || !g_draw_sw_functions) | |
| 1071 return ScopedJavaLocalRef<jobject>(); | |
| 1072 | |
| 1073 if (g_is_skia_version_compatible) | |
| 1074 return ScopedJavaLocalRef<jobject>(env, | |
| 1075 g_draw_sw_functions->create_picture(env, picture->clone())); | |
| 1076 | |
| 1077 // If Skia versions are not compatible, workaround it by rasterizing the | |
| 1078 // picture into a bitmap and drawing it into a new Java picture. | |
| 1079 ScopedJavaLocalRef<jobject> jbitmap(Java_AwContents_createBitmap( | |
| 1080 env, picture->width(), picture->height())); | |
| 1081 if (!jbitmap.obj()) | |
| 1082 return ScopedJavaLocalRef<jobject>(); | |
| 1083 | |
| 1084 if (!RasterizeIntoBitmap(env, jbitmap.obj(), 0, 0, | |
| 1085 base::Bind(&AwContents::RenderPicture, base::Unretained(this)))) | |
| 1086 return ScopedJavaLocalRef<jobject>(); | |
| 1087 | |
| 1088 return Java_AwContents_recordBitmapIntoPicture(env, jbitmap.obj()); | |
| 1089 } | |
| 1090 | |
| 1091 bool AwContents::RenderSW(SkCanvas* canvas) { | |
| 1092 // TODO(leandrogracia): once Ubercompositor is ready and we support software | |
| 1093 // rendering mode, we should avoid this as much as we can, ideally always. | |
| 1094 // This includes finding a proper replacement for onDraw calls in hardware | |
| 1095 // mode with software canvases. http://crbug.com/170086. | |
| 1096 return RenderPicture(canvas); | |
| 1097 } | |
| 1098 | |
| 1099 bool AwContents::RenderPicture(SkCanvas* canvas) { | |
| 1100 skia::RefPtr<SkPicture> picture = GetLastCapturedPicture(); | |
| 1101 if (!picture) | |
| 1102 return false; | |
| 1103 | |
| 1104 // Correct device scale. | |
| 1105 canvas->scale(dpi_scale_, dpi_scale_); | |
| 1106 | |
| 1107 picture->draw(canvas); | |
| 1108 return true; | |
| 1109 } | 671 } |
| 1110 | 672 |
| 1111 void AwContents::EnableOnNewPicture(JNIEnv* env, | 673 void AwContents::EnableOnNewPicture(JNIEnv* env, |
| 1112 jobject obj, | 674 jobject obj, |
| 1113 jboolean enabled, | 675 jboolean enabled, |
| 1114 jboolean invalidation_only) { | 676 jboolean invalidation_only) { |
| 677 BrowserViewRenderer::OnNewPictureMode mode = |
| 678 BrowserViewRenderer::kOnNewPictureDisabled; |
| 1115 if (enabled) { | 679 if (enabled) { |
| 1116 on_new_picture_mode_ = invalidation_only ? kOnNewPictureInvalidationOnly : | 680 mode = invalidation_only ? |
| 1117 kOnNewPictureEnabled; | 681 BrowserViewRenderer::kOnNewPictureInvalidationOnly : |
| 1118 } else { | 682 BrowserViewRenderer::kOnNewPictureEnabled; |
| 1119 on_new_picture_mode_ = kOnNewPictureDisabled; | |
| 1120 } | 683 } |
| 1121 | 684 |
| 1122 // If onNewPicture is triggered only on invalidation do not capture | 685 browser_view_renderer_->EnableOnNewPicture(mode); |
| 1123 // pictures on every new frame. | |
| 1124 if (on_new_picture_mode_ == kOnNewPictureInvalidationOnly) | |
| 1125 enabled = false; | |
| 1126 | |
| 1127 // TODO(leandrogracia): when SW rendering uses the compositor rather than | |
| 1128 // picture rasterization, send update the renderer side with the correct | |
| 1129 // listener state. (For now, we always leave render picture listener enabled). | |
| 1130 // render_view_host_ext_->EnableCapturePictureCallback(enabled); | |
| 1131 } | |
| 1132 | |
| 1133 void AwContents::OnPictureUpdated(int process_id, int render_view_id) { | |
| 1134 CHECK_EQ(web_contents_->GetRenderProcessHost()->GetID(), process_id); | |
| 1135 if (render_view_id != web_contents_->GetRoutingID()) | |
| 1136 return; | |
| 1137 | |
| 1138 // TODO(leandrogracia): this can be made unconditional once software rendering | |
| 1139 // uses Ubercompositor. Until then this path is required for SW invalidations. | |
| 1140 if (on_new_picture_mode_ == kOnNewPictureEnabled) { | |
| 1141 JNIEnv* env = AttachCurrentThread(); | |
| 1142 ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); | |
| 1143 if (!obj.is_null()) { | |
| 1144 ScopedJavaLocalRef<jobject> picture = CapturePicture(env, obj.obj()); | |
| 1145 Java_AwContents_onNewPicture(env, obj.obj(), picture.obj()); | |
| 1146 } | |
| 1147 } | |
| 1148 | |
| 1149 // TODO(leandrogracia): delete when sw rendering uses Ubercompositor. | |
| 1150 // Invalidation should be provided by the compositor only. | |
| 1151 Invalidate(); | |
| 1152 } | |
| 1153 | |
| 1154 skia::RefPtr<SkPicture> AwContents::GetLastCapturedPicture() { | |
| 1155 // Use the latest available picture if the listener callback is enabled. | |
| 1156 skia::RefPtr<SkPicture> picture; | |
| 1157 if (on_new_picture_mode_ == kOnNewPictureEnabled) | |
| 1158 picture = RendererPictureMap::GetInstance()->GetRendererPicture( | |
| 1159 web_contents_->GetRoutingID()); | |
| 1160 | |
| 1161 // If not available or not in listener mode get it synchronously. | |
| 1162 if (!picture) { | |
| 1163 render_view_host_ext_->CapturePictureSync(); | |
| 1164 picture = RendererPictureMap::GetInstance()->GetRendererPicture( | |
| 1165 web_contents_->GetRoutingID()); | |
| 1166 } | |
| 1167 | |
| 1168 return picture; | |
| 1169 } | 686 } |
| 1170 | 687 |
| 1171 } // namespace android_webview | 688 } // namespace android_webview |
| OLD | NEW |