OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "android_webview/browser/browser_view_renderer_impl.h" | |
6 | |
7 #include <android/bitmap.h> | |
8 #include <sys/system_properties.h> | |
9 | |
10 #include "android_webview/common/renderer_picture_map.h" | |
11 #include "android_webview/public/browser/draw_gl.h" | |
12 #include "android_webview/public/browser/draw_sw.h" | |
13 #include "base/android/jni_android.h" | |
14 #include "base/debug/trace_event.h" | |
15 #include "base/logging.h" | |
16 #include "cc/layer.h" | |
17 #include "content/public/browser/android/content_view_core.h" | |
18 #include "content/public/browser/render_process_host.h" | |
19 #include "content/public/browser/web_contents.h" | |
20 #include "third_party/skia/include/core/SkBitmap.h" | |
21 #include "third_party/skia/include/core/SkCanvas.h" | |
22 #include "third_party/skia/include/core/SkDevice.h" | |
23 #include "ui/gfx/size.h" | |
24 #include "ui/gfx/transform.h" | |
25 #include "ui/gl/gl_bindings.h" | |
26 | |
27 // TODO(leandrogracia): remove when crbug.com/164140 is closed. | |
28 // Borrowed from gl2ext.h. Cannot be included due to conflicts with | |
29 // gl_bindings.h and the EGL library methods (eglGetCurrentContext). | |
30 #ifndef GL_TEXTURE_EXTERNAL_OES | |
31 #define GL_TEXTURE_EXTERNAL_OES 0x8D65 | |
32 #endif | |
33 | |
34 #ifndef GL_TEXTURE_BINDING_EXTERNAL_OES | |
35 #define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 | |
36 #endif | |
37 | |
38 using base::android::AttachCurrentThread; | |
39 using base::android::JavaRef; | |
40 using base::android::ScopedJavaLocalRef; | |
41 using content::Compositor; | |
42 using content::ContentViewCore; | |
43 | |
44 namespace { | |
45 | |
46 typedef base::Callback<bool(SkCanvas*)> RenderMethod; | |
47 | |
48 static bool RasterizeIntoBitmap(JNIEnv* env, | |
49 const JavaRef<jobject>& jbitmap, | |
50 int scroll_x, | |
51 int scroll_y, | |
52 const RenderMethod& renderer) { | |
53 DCHECK(jbitmap.obj()); | |
54 | |
55 AndroidBitmapInfo bitmap_info; | |
56 if (AndroidBitmap_getInfo(env, jbitmap.obj(), &bitmap_info) < 0) { | |
57 LOG(ERROR) << "Error getting java bitmap info."; | |
58 return false; | |
59 } | |
60 | |
61 void* pixels = NULL; | |
62 if (AndroidBitmap_lockPixels(env, jbitmap.obj(), &pixels) < 0) { | |
63 LOG(ERROR) << "Error locking java bitmap pixels."; | |
64 return false; | |
65 } | |
66 | |
67 bool succeeded = false; | |
joth
2013/02/06 20:26:31
nit: you can remove = false here, as it's uncondit
Leandro Graciá Gil
2013/02/07 12:43:56
Done.
| |
68 { | |
69 SkBitmap bitmap; | |
70 bitmap.setConfig(SkBitmap::kARGB_8888_Config, | |
71 bitmap_info.width, | |
72 bitmap_info.height, | |
73 bitmap_info.stride); | |
74 bitmap.setPixels(pixels); | |
75 | |
76 SkDevice device(bitmap); | |
77 SkCanvas canvas(&device); | |
78 canvas.translate(-scroll_x, -scroll_y); | |
79 succeeded = renderer.Run(&canvas); | |
80 } | |
81 | |
82 if (AndroidBitmap_unlockPixels(env, jbitmap.obj()) < 0) { | |
83 LOG(ERROR) << "Error unlocking java bitmap pixels."; | |
84 return false; | |
85 } | |
86 | |
87 return succeeded; | |
88 } | |
89 | |
90 } // namespace | |
91 | |
92 namespace android_webview { | |
93 | |
94 // static | |
95 BrowserViewRendererImpl* BrowserViewRendererImpl::Create( | |
96 BrowserViewRenderer::Client* client, | |
97 JavaHelper* java_helper) { | |
98 return new BrowserViewRendererImpl(client, java_helper); | |
99 } | |
100 | |
101 BrowserViewRendererImpl::BrowserViewRendererImpl( | |
102 BrowserViewRenderer::Client* client, | |
103 JavaHelper* java_helper) | |
104 : BrowserViewRenderer(client, java_helper), | |
105 ALLOW_THIS_IN_INITIALIZER_LIST(compositor_(Compositor::Create(this))), | |
106 view_clip_layer_(cc::Layer::create()), | |
107 transform_layer_(cc::Layer::create()), | |
108 scissor_clip_layer_(cc::Layer::create()), | |
109 view_visible_(false), | |
110 compositor_visible_(false), | |
111 is_composite_pending_(false), | |
112 dpi_scale_(1.0f), | |
113 on_new_picture_mode_(kOnNewPictureDisabled), | |
114 last_frame_context_(NULL), | |
115 web_contents_(NULL) { | |
116 DCHECK(java_helper); | |
117 | |
118 // Define the view hierarchy. | |
119 transform_layer_->addChild(view_clip_layer_); | |
120 scissor_clip_layer_->addChild(transform_layer_); | |
121 compositor_->SetRootLayer(scissor_clip_layer_); | |
122 | |
123 RendererPictureMap::CreateInstance(); | |
124 } | |
125 | |
126 BrowserViewRendererImpl::~BrowserViewRendererImpl() { | |
127 } | |
128 | |
129 void BrowserViewRendererImpl::SetContents(ContentViewCore* content_view_core) { | |
130 dpi_scale_ = content_view_core->GetDpiScale(); | |
131 web_contents_ = content_view_core->GetWebContents(); | |
132 if (!view_renderer_host_) | |
133 view_renderer_host_.reset(new ViewRendererHost(web_contents_, this)); | |
134 else | |
135 view_renderer_host_->Observe(web_contents_); | |
136 | |
137 view_clip_layer_->removeAllChildren(); | |
138 view_clip_layer_->addChild(content_view_core->GetLayer()); | |
139 Invalidate(); | |
140 } | |
141 | |
142 void BrowserViewRendererImpl::DrawGL(AwDrawGLInfo* draw_info) { | |
143 TRACE_EVENT0("android_webview", "BrowserViewRendererImpl::DrawGL"); | |
144 | |
145 if (view_size_.IsEmpty() || !scissor_clip_layer_ || | |
146 draw_info->mode == AwDrawGLInfo::kModeProcess) | |
147 return; | |
148 | |
149 DCHECK_EQ(draw_info->mode, AwDrawGLInfo::kModeDraw); | |
150 | |
151 SetCompositorVisibility(view_visible_); | |
152 if (!compositor_visible_) | |
153 return; | |
154 | |
155 // TODO(leandrogracia): remove when crbug.com/164140 is closed. | |
156 // --------------------------------------------------------------------------- | |
157 GLint texture_external_oes_binding; | |
158 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texture_external_oes_binding); | |
159 | |
160 GLint vertex_array_buffer_binding; | |
161 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertex_array_buffer_binding); | |
162 | |
163 GLint index_array_buffer_binding; | |
164 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &index_array_buffer_binding); | |
165 | |
166 GLint pack_alignment; | |
167 glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment); | |
168 | |
169 GLint unpack_alignment; | |
170 glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment); | |
171 | |
172 struct { | |
173 GLint enabled; | |
174 GLint size; | |
175 GLint type; | |
176 GLint normalized; | |
177 GLint stride; | |
178 GLvoid* pointer; | |
179 } vertex_attrib[3]; | |
180 | |
181 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib); ++i) { | |
182 glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, | |
183 &vertex_attrib[i].enabled); | |
184 glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, | |
185 &vertex_attrib[i].size); | |
186 glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, | |
187 &vertex_attrib[i].type); | |
188 glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, | |
189 &vertex_attrib[i].normalized); | |
190 glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, | |
191 &vertex_attrib[i].stride); | |
192 glGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, | |
193 &vertex_attrib[i].pointer); | |
194 } | |
195 | |
196 GLboolean depth_test; | |
197 glGetBooleanv(GL_DEPTH_TEST, &depth_test); | |
198 | |
199 GLboolean cull_face; | |
200 glGetBooleanv(GL_CULL_FACE, &cull_face); | |
201 | |
202 GLboolean color_mask[4]; | |
203 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask); | |
204 | |
205 GLboolean blend_enabled; | |
206 glGetBooleanv(GL_BLEND, &blend_enabled); | |
207 | |
208 GLint blend_src_rgb; | |
209 glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb); | |
210 | |
211 GLint blend_src_alpha; | |
212 glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_alpha); | |
213 | |
214 GLint blend_dest_rgb; | |
215 glGetIntegerv(GL_BLEND_DST_RGB, &blend_dest_rgb); | |
216 | |
217 GLint blend_dest_alpha; | |
218 glGetIntegerv(GL_BLEND_DST_ALPHA, &blend_dest_alpha); | |
219 | |
220 GLint active_texture; | |
221 glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture); | |
222 | |
223 GLint viewport[4]; | |
224 glGetIntegerv(GL_VIEWPORT, viewport); | |
225 | |
226 GLboolean scissor_test; | |
227 glGetBooleanv(GL_SCISSOR_TEST, &scissor_test); | |
228 | |
229 GLint scissor_box[4]; | |
230 glGetIntegerv(GL_SCISSOR_BOX, scissor_box); | |
231 | |
232 GLint current_program; | |
233 glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program); | |
234 // --------------------------------------------------------------------------- | |
235 | |
236 // We need to watch if the current Android context has changed and enforce | |
237 // a clean-up in the compositor. | |
238 EGLContext current_context = eglGetCurrentContext(); | |
239 if (!current_context) { | |
240 LOG(WARNING) << "No current context attached. Skipping composite."; | |
241 return; | |
242 } | |
243 | |
244 if (last_frame_context_ != current_context) { | |
245 if (last_frame_context_) | |
246 ResetCompositor(); | |
247 last_frame_context_ = current_context; | |
248 } | |
249 | |
250 compositor_->SetWindowBounds(gfx::Size(draw_info->width, draw_info->height)); | |
251 | |
252 if (draw_info->is_layer) { | |
253 // When rendering into a separate layer no view clipping, transform, | |
254 // scissoring or background transparency need to be handled. | |
255 // The Android framework will composite us afterwards. | |
256 compositor_->SetHasTransparentBackground(false); | |
257 view_clip_layer_->setMasksToBounds(false); | |
258 transform_layer_->setTransform(gfx::Transform()); | |
259 scissor_clip_layer_->setMasksToBounds(false); | |
260 scissor_clip_layer_->setPosition(gfx::PointF()); | |
261 scissor_clip_layer_->setBounds(gfx::Size()); | |
262 scissor_clip_layer_->setSublayerTransform(gfx::Transform()); | |
263 | |
264 } else { | |
265 compositor_->SetHasTransparentBackground(true); | |
266 | |
267 gfx::Rect clip_rect(draw_info->clip_left, draw_info->clip_top, | |
268 draw_info->clip_right - draw_info->clip_left, | |
269 draw_info->clip_bottom - draw_info->clip_top); | |
270 | |
271 scissor_clip_layer_->setPosition(clip_rect.origin()); | |
272 scissor_clip_layer_->setBounds(clip_rect.size()); | |
273 scissor_clip_layer_->setMasksToBounds(true); | |
274 | |
275 // The compositor clipping architecture enforces us to have the clip layer | |
276 // as an ancestor of the area we want to clip, but this makes the transform | |
277 // become relative to the clip area rather than the full surface. The clip | |
278 // position offset needs to be undone before applying the transform. | |
279 gfx::Transform undo_clip_position; | |
280 undo_clip_position.Translate(-clip_rect.x(), -clip_rect.y()); | |
281 scissor_clip_layer_->setSublayerTransform(undo_clip_position); | |
282 | |
283 gfx::Transform transform; | |
284 transform.matrix().setColMajorf(draw_info->transform); | |
285 | |
286 // The scrolling values of the Android Framework affect the transformation | |
287 // matrix. This needs to be undone to let the compositor handle scrolling. | |
288 transform.Translate(hw_rendering_scroll_.x(), hw_rendering_scroll_.y()); | |
mkosiba (inactive)
2013/02/07 10:10:29
like we discussed earlier - when we have syncrhono
Leandro Graciá Gil
2013/02/07 12:43:56
Good point. Done.
| |
289 transform_layer_->setTransform(transform); | |
290 | |
291 view_clip_layer_->setMasksToBounds(true); | |
292 } | |
293 | |
294 compositor_->Composite(); | |
295 is_composite_pending_ = false; | |
296 | |
297 // TODO(leandrogracia): remove when crbug.com/164140 is closed. | |
298 // --------------------------------------------------------------------------- | |
299 char no_gl_restore_prop[PROP_VALUE_MAX]; | |
300 __system_property_get("webview.chromium_no_gl_restore", no_gl_restore_prop); | |
301 if (!strcmp(no_gl_restore_prop, "true")) { | |
302 LOG(WARNING) << "Android GL functor not restoring the previous GL state."; | |
303 } else { | |
304 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_external_oes_binding); | |
305 glBindBuffer(GL_ARRAY_BUFFER, vertex_array_buffer_binding); | |
306 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding); | |
307 | |
308 glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment); | |
309 glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment); | |
310 | |
311 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib); ++i) { | |
312 glVertexAttribPointer(i, vertex_attrib[i].size, | |
313 vertex_attrib[i].type, vertex_attrib[i].normalized, | |
314 vertex_attrib[i].stride, vertex_attrib[i].pointer); | |
315 | |
316 if (vertex_attrib[i].enabled) | |
317 glEnableVertexAttribArray(i); | |
318 else | |
319 glDisableVertexAttribArray(i); | |
320 } | |
321 | |
322 if (depth_test) | |
323 glEnable(GL_DEPTH_TEST); | |
324 else | |
325 glDisable(GL_DEPTH_TEST); | |
326 | |
327 if (cull_face) | |
328 glEnable(GL_CULL_FACE); | |
329 else | |
330 glDisable(GL_CULL_FACE); | |
331 | |
332 glColorMask(color_mask[0], color_mask[1], color_mask[2], | |
333 color_mask[3]); | |
mkosiba (inactive)
2013/02/07 10:10:29
nit: indent
Leandro Graciá Gil
2013/02/07 12:43:56
Done.
| |
334 | |
335 if (blend_enabled) | |
336 glEnable(GL_BLEND); | |
337 else | |
338 glDisable(GL_BLEND); | |
339 | |
340 glBlendFuncSeparate(blend_src_rgb, blend_dest_rgb, | |
341 blend_src_alpha, blend_dest_alpha); | |
mkosiba (inactive)
2013/02/07 10:10:29
nit:indent
Leandro Graciá Gil
2013/02/07 12:43:56
Done.
| |
342 | |
343 glActiveTexture(active_texture); | |
344 | |
345 glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); | |
346 | |
347 if (scissor_test) | |
348 glEnable(GL_SCISSOR_TEST); | |
349 else | |
350 glDisable(GL_SCISSOR_TEST); | |
351 | |
352 glScissor(scissor_box[0], scissor_box[1], scissor_box[2], | |
353 scissor_box[3]); | |
mkosiba (inactive)
2013/02/07 10:10:29
nit: indent
Leandro Graciá Gil
2013/02/07 12:43:56
Done.
| |
354 | |
355 glUseProgram(current_program); | |
356 } | |
357 // --------------------------------------------------------------------------- | |
358 } | |
359 | |
360 void BrowserViewRendererImpl::SetScrollForHWFrame(int x, int y) { | |
361 hw_rendering_scroll_ = gfx::Point(x, y); | |
362 } | |
363 | |
364 bool BrowserViewRendererImpl::DrawSW(jobject java_canvas, | |
365 const gfx::Rect& clip) { | |
366 TRACE_EVENT0("android_webview", "BrowserViewRendererImpl::DrawSW"); | |
367 | |
368 if (clip.IsEmpty()) | |
369 return true; | |
370 | |
371 AwPixelInfo* pixels; | |
372 JNIEnv* env = AttachCurrentThread(); | |
373 | |
374 // Render into an auxiliary bitmap if pixel info is not available. | |
375 if (!SWDrawFunctions() || | |
376 (pixels = SWDrawFunctions()->access_pixels(env, java_canvas)) == NULL) { | |
377 ScopedJavaLocalRef<jobject> jbitmap(java_helper()->CreateBitmap( | |
378 env, clip.width(), clip.height())); | |
379 if (!jbitmap.obj()) | |
380 return false; | |
381 | |
382 if (!RasterizeIntoBitmap(env, jbitmap, clip.x(), clip.y(), | |
383 base::Bind(&BrowserViewRendererImpl::RenderSW, base::Unretained(this)))) | |
joth
2013/02/06 20:26:31
if (!RasterizeIntoBitmap(env, jbitmap, clip.x(), c
Leandro Graciá Gil
2013/02/07 12:43:56
Done.
| |
384 return false; | |
385 | |
386 ScopedJavaLocalRef<jobject> jcanvas(env, java_canvas); | |
387 java_helper()->DrawBitmapIntoCanvas(env, jbitmap, jcanvas); | |
388 return true; | |
389 } | |
390 | |
391 // Draw in a SkCanvas built over the pixel information. | |
392 bool succeeded = false; | |
393 { | |
394 SkBitmap bitmap; | |
395 bitmap.setConfig(static_cast<SkBitmap::Config>(pixels->config), | |
396 pixels->width, | |
397 pixels->height, | |
398 pixels->row_bytes); | |
399 bitmap.setPixels(pixels->pixels); | |
400 SkDevice device(bitmap); | |
401 SkCanvas canvas(&device); | |
joth
2013/02/06 20:26:31
feels like there's some repetition here with Raste
Leandro Graciá Gil
2013/02/07 12:43:56
It's similar but not quite the same. RasterizeInto
| |
402 SkMatrix matrix; | |
403 for (int i = 0; i < 9; i++) | |
404 matrix.set(i, pixels->matrix[i]); | |
405 canvas.setMatrix(matrix); | |
406 | |
407 SkRegion clip; | |
408 if (pixels->clip_region_size) { | |
409 size_t bytes_read = clip.readFromMemory(pixels->clip_region); | |
410 DCHECK_EQ(pixels->clip_region_size, bytes_read); | |
411 canvas.setClipRegion(clip); | |
412 } else { | |
413 clip.setRect(SkIRect::MakeWH(pixels->width, pixels->height)); | |
414 } | |
415 | |
416 succeeded = RenderSW(&canvas); | |
417 } | |
418 | |
419 SWDrawFunctions()->release_pixels(pixels); | |
420 return succeeded; | |
421 } | |
422 | |
423 ScopedJavaLocalRef<jobject> BrowserViewRendererImpl::CapturePicture() { | |
424 skia::RefPtr<SkPicture> picture = GetLastCapturedPicture(); | |
425 if (!picture || !SWDrawFunctions()) | |
426 return ScopedJavaLocalRef<jobject>(); | |
427 | |
428 JNIEnv* env = AttachCurrentThread(); | |
429 if (IsSkiaVersionCompatible()) { | |
430 return ScopedJavaLocalRef<jobject>(env, | |
431 SWDrawFunctions()->create_picture(env, picture->clone())); | |
432 } | |
433 | |
434 // If Skia versions are not compatible, workaround it by rasterizing the | |
435 // picture into a bitmap and drawing it into a new Java picture. | |
436 ScopedJavaLocalRef<jobject> jbitmap(java_helper()->CreateBitmap( | |
437 env, picture->width(), picture->height())); | |
438 if (!jbitmap.obj()) | |
439 return ScopedJavaLocalRef<jobject>(); | |
440 | |
441 if (!RasterizeIntoBitmap(env, jbitmap, 0, 0, | |
442 base::Bind(&BrowserViewRendererImpl::RenderPicture, | |
443 base::Unretained(this)))) { | |
444 return ScopedJavaLocalRef<jobject>(); | |
445 } | |
446 | |
447 return java_helper()->RecordBitmapIntoPicture(env, jbitmap); | |
448 } | |
449 | |
450 void BrowserViewRendererImpl::EnableOnNewPicture(OnNewPictureMode mode) { | |
451 on_new_picture_mode_ = mode; | |
452 | |
453 // TODO(leandrogracia): when SW rendering uses the compositor rather than | |
454 // picture rasterization, send update the renderer side with the correct | |
455 // listener state. (For now, we always leave render picture listener enabled). | |
456 // render_view_host_ext_->EnableCapturePictureCallback(enabled); | |
457 //DCHECK(view_renderer_host_); | |
458 //view_renderer_host_->EnableCapturePictureCallback( | |
459 // on_new_picture_mode_ == kOnNewPictureEnabled); | |
460 } | |
461 | |
462 void BrowserViewRendererImpl::OnVisibilityChanged(bool view_visible, | |
463 bool window_visible) { | |
joth
2013/02/06 20:26:31
indent
Leandro Graciá Gil
2013/02/07 12:43:56
Done.
| |
464 view_visible_ = window_visible && view_visible; | |
465 Invalidate(); | |
466 } | |
467 | |
468 void BrowserViewRendererImpl::OnSizeChanged(int width, int height) { | |
469 view_size_ = gfx::Size(width, height); | |
470 view_clip_layer_->setBounds(view_size_); | |
471 } | |
472 | |
473 void BrowserViewRendererImpl::OnAttachedToWindow(int width, int height) { | |
474 view_size_ = gfx::Size(width, height); | |
475 view_clip_layer_->setBounds(view_size_); | |
476 } | |
477 | |
478 void BrowserViewRendererImpl::OnDetachedFromWindow() { | |
479 view_visible_ = false; | |
480 SetCompositorVisibility(false); | |
481 } | |
482 | |
483 void BrowserViewRendererImpl::ScheduleComposite() { | |
484 TRACE_EVENT0("android_webview", "BrowserViewRendererImpl::ScheduleComposite"); | |
485 | |
486 if (is_composite_pending_) | |
487 return; | |
488 | |
489 is_composite_pending_ = true; | |
490 Invalidate(); | |
491 } | |
492 | |
493 skia::RefPtr<SkPicture> BrowserViewRendererImpl::GetLastCapturedPicture() { | |
494 // Use the latest available picture if the listener callback is enabled. | |
495 skia::RefPtr<SkPicture> picture; | |
496 if (on_new_picture_mode_ == kOnNewPictureEnabled) | |
497 picture = RendererPictureMap::GetInstance()->GetRendererPicture( | |
498 web_contents_->GetRoutingID()); | |
499 | |
500 // If not available or not in listener mode get it synchronously. | |
501 if (!picture) { | |
502 DCHECK(view_renderer_host_); | |
503 view_renderer_host_->CapturePictureSync(); | |
504 picture = RendererPictureMap::GetInstance()->GetRendererPicture( | |
505 web_contents_->GetRoutingID()); | |
506 } | |
507 | |
508 return picture; | |
509 } | |
510 | |
511 void BrowserViewRendererImpl::OnPictureUpdated(int process_id, | |
512 int render_view_id) { | |
513 CHECK_EQ(web_contents_->GetRenderProcessHost()->GetID(), process_id); | |
514 if (render_view_id != web_contents_->GetRoutingID()) | |
515 return; | |
516 | |
517 // TODO(leandrogracia): this can be made unconditional once software rendering | |
518 // uses Ubercompositor. Until then this path is required for SW invalidations. | |
519 if (on_new_picture_mode_ == kOnNewPictureEnabled) | |
520 client()->OnNewPicture(CapturePicture()); | |
521 | |
522 // TODO(leandrogracia): delete when sw rendering uses Ubercompositor. | |
523 // Invalidation should be provided by the compositor only. | |
524 Invalidate(); | |
525 } | |
526 | |
527 void BrowserViewRendererImpl::SetCompositorVisibility(bool visible) { | |
528 if (compositor_visible_ != visible) { | |
529 compositor_visible_ = visible; | |
530 compositor_->SetVisible(compositor_visible_); | |
531 } | |
532 } | |
533 | |
534 void BrowserViewRendererImpl::ResetCompositor() { | |
535 compositor_.reset(content::Compositor::Create(this)); | |
536 compositor_->SetRootLayer(scissor_clip_layer_); | |
537 } | |
538 | |
539 void BrowserViewRendererImpl::Invalidate() { | |
540 if (view_visible_) | |
541 client()->Invalidate(); | |
542 | |
543 // When not in invalidation-only mode onNewPicture will be triggered | |
544 // from the OnPictureUpdated callback. | |
545 if (on_new_picture_mode_ == kOnNewPictureInvalidationOnly) | |
546 client()->OnNewPicture(ScopedJavaLocalRef<jobject>()); | |
547 } | |
548 | |
549 bool BrowserViewRendererImpl::RenderSW(SkCanvas* canvas) { | |
550 // TODO(leandrogracia): once Ubercompositor is ready and we support software | |
551 // rendering mode, we should avoid this as much as we can, ideally always. | |
552 // This includes finding a proper replacement for onDraw calls in hardware | |
553 // mode with software canvases. http://crbug.com/170086. | |
554 return RenderPicture(canvas); | |
555 | |
556 //compositor_->Composite(); | |
557 //is_composite_pending_ = false; | |
558 //return true; | |
559 } | |
560 | |
561 bool BrowserViewRendererImpl::RenderPicture(SkCanvas* canvas) { | |
562 skia::RefPtr<SkPicture> picture = GetLastCapturedPicture(); | |
563 if (!picture) | |
564 return false; | |
565 | |
566 // Correct device scale. | |
567 canvas->scale(dpi_scale_, dpi_scale_); | |
568 | |
569 picture->draw(canvas); | |
570 return true; | |
571 } | |
572 | |
573 } // namespace android_webview | |
OLD | NEW |