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