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

Side by Side Diff: android_webview/native/aw_contents.cc

Issue 12041009: [Android WebView] Migrate the rendering code to a separate set of classes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: upload error, re-uploading. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (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
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, &current_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
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
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
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
OLDNEW
« no previous file with comments | « android_webview/native/aw_contents.h ('k') | android_webview/native/java_browser_view_renderer_helper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698