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

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: updated and rebased. 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/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
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, &current_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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698