OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 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/browser/in_process_renderer/in_process_view_renderer.h
" | 5 #include "android_webview/browser/in_process_renderer/in_process_view_renderer.h
" |
6 | 6 |
7 #include <android/bitmap.h> | 7 #include <android/bitmap.h> |
8 | 8 |
9 #include "android_webview/public/browser/draw_gl.h" | 9 #include "android_webview/public/browser/draw_gl.h" |
10 #include "android_webview/public/browser/draw_sw.h" | 10 #include "android_webview/public/browser/draw_sw.h" |
11 #include "base/android/jni_android.h" | 11 #include "base/android/jni_android.h" |
12 #include "base/debug/trace_event.h" | 12 #include "base/debug/trace_event.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "content/public/browser/android/content_view_core.h" | 14 #include "content/public/browser/android/content_view_core.h" |
15 #include "content/public/browser/render_view_host.h" | 15 #include "content/public/browser/render_view_host.h" |
16 #include "content/public/browser/web_contents.h" | 16 #include "content/public/browser/web_contents.h" |
17 #include "content/public/renderer/android/synchronous_compositor.h" | 17 #include "content/public/renderer/android/synchronous_compositor.h" |
18 #include "third_party/skia/include/core/SkBitmap.h" | 18 #include "third_party/skia/include/core/SkBitmap.h" |
19 #include "third_party/skia/include/core/SkCanvas.h" | 19 #include "third_party/skia/include/core/SkCanvas.h" |
20 #include "third_party/skia/include/core/SkDevice.h" | 20 #include "third_party/skia/include/core/SkDevice.h" |
21 #include "third_party/skia/include/core/SkGraphics.h" | 21 #include "third_party/skia/include/core/SkGraphics.h" |
22 #include "third_party/skia/include/core/SkPicture.h" | 22 #include "third_party/skia/include/core/SkPicture.h" |
23 #include "ui/gfx/size_conversions.h" | 23 #include "ui/gfx/size_conversions.h" |
24 #include "ui/gfx/transform.h" | 24 #include "ui/gfx/transform.h" |
25 #include "ui/gfx/vector2d_f.h" | 25 #include "ui/gfx/vector2d_f.h" |
26 #include "ui/gl/gl_bindings.h" | 26 #include "ui/gl/gl_bindings.h" |
27 | 27 |
| 28 // TODO(leandrogracia): Borrowed from gl2ext.h. Cannot be included due to |
| 29 // conflicts with gl_bindings.h and the EGL library methods |
| 30 // (eglGetCurrentContext). |
| 31 #ifndef GL_TEXTURE_EXTERNAL_OES |
| 32 #define GL_TEXTURE_EXTERNAL_OES 0x8D65 |
| 33 #endif |
| 34 |
| 35 #ifndef GL_TEXTURE_BINDING_EXTERNAL_OES |
| 36 #define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 |
| 37 #endif |
| 38 |
28 using base::android::AttachCurrentThread; | 39 using base::android::AttachCurrentThread; |
29 using base::android::JavaRef; | 40 using base::android::JavaRef; |
30 using base::android::ScopedJavaLocalRef; | 41 using base::android::ScopedJavaLocalRef; |
31 using content::Compositor; | 42 using content::Compositor; |
32 using content::ContentViewCore; | 43 using content::ContentViewCore; |
33 | 44 |
34 namespace android_webview { | 45 namespace android_webview { |
35 | 46 |
36 namespace { | 47 namespace { |
| 48 |
| 49 class GLStateRestore { |
| 50 public: |
| 51 GLStateRestore() { |
| 52 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, |
| 53 &texture_external_oes_binding_); |
| 54 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertex_array_buffer_binding_); |
| 55 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, |
| 56 &index_array_buffer_binding_); |
| 57 glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment_); |
| 58 glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment_); |
| 59 |
| 60 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) { |
| 61 glGetVertexAttribiv( |
| 62 i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &vertex_attrib_[i].enabled); |
| 63 glGetVertexAttribiv( |
| 64 i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &vertex_attrib_[i].size); |
| 65 glGetVertexAttribiv( |
| 66 i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &vertex_attrib_[i].type); |
| 67 glGetVertexAttribiv( |
| 68 i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &vertex_attrib_[i].normalized); |
| 69 glGetVertexAttribiv( |
| 70 i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &vertex_attrib_[i].stride); |
| 71 glGetVertexAttribPointerv( |
| 72 i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &vertex_attrib_[i].pointer); |
| 73 } |
| 74 |
| 75 glGetBooleanv(GL_DEPTH_TEST, &depth_test_); |
| 76 glGetBooleanv(GL_CULL_FACE, &cull_face_); |
| 77 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask_); |
| 78 glGetBooleanv(GL_BLEND, &blend_enabled_); |
| 79 glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb_); |
| 80 glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_alpha_); |
| 81 glGetIntegerv(GL_BLEND_DST_RGB, &blend_dest_rgb_); |
| 82 glGetIntegerv(GL_BLEND_DST_ALPHA, &blend_dest_alpha_); |
| 83 glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture_); |
| 84 glGetIntegerv(GL_VIEWPORT, viewport_); |
| 85 glGetBooleanv(GL_SCISSOR_TEST, &scissor_test_); |
| 86 glGetIntegerv(GL_SCISSOR_BOX, scissor_box_); |
| 87 glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_); |
| 88 |
| 89 DCHECK_EQ(0, vertex_array_buffer_binding_); |
| 90 DCHECK_EQ(0, index_array_buffer_binding_); |
| 91 } |
| 92 |
| 93 ~GLStateRestore() { |
| 94 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_external_oes_binding_); |
| 95 glBindBuffer(GL_ARRAY_BUFFER, vertex_array_buffer_binding_); |
| 96 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding_); |
| 97 glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment_); |
| 98 glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment_); |
| 99 |
| 100 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) { |
| 101 glVertexAttribPointer(i, |
| 102 vertex_attrib_[i].size, |
| 103 vertex_attrib_[i].type, |
| 104 vertex_attrib_[i].normalized, |
| 105 vertex_attrib_[i].stride, |
| 106 vertex_attrib_[i].pointer); |
| 107 |
| 108 if (vertex_attrib_[i].enabled) { |
| 109 glEnableVertexAttribArray(i); |
| 110 } else { |
| 111 glDisableVertexAttribArray(i); |
| 112 } |
| 113 } |
| 114 |
| 115 if (depth_test_) { |
| 116 glEnable(GL_DEPTH_TEST); |
| 117 } else { |
| 118 glDisable(GL_DEPTH_TEST); |
| 119 } |
| 120 |
| 121 if (cull_face_) { |
| 122 glEnable(GL_CULL_FACE); |
| 123 } else { |
| 124 glDisable(GL_CULL_FACE); |
| 125 } |
| 126 |
| 127 glColorMask(color_mask_[0], color_mask_[1], color_mask_[2], color_mask_[3]); |
| 128 |
| 129 if (blend_enabled_) { |
| 130 glEnable(GL_BLEND); |
| 131 } else { |
| 132 glDisable(GL_BLEND); |
| 133 } |
| 134 |
| 135 glBlendFuncSeparate( |
| 136 blend_src_rgb_, blend_dest_rgb_, blend_src_alpha_, blend_dest_alpha_); |
| 137 glActiveTexture(active_texture_); |
| 138 |
| 139 glViewport(viewport_[0], viewport_[1], viewport_[2], viewport_[3]); |
| 140 |
| 141 if (scissor_test_) { |
| 142 glEnable(GL_SCISSOR_TEST); |
| 143 } else { |
| 144 glDisable(GL_SCISSOR_TEST); |
| 145 } |
| 146 |
| 147 glScissor( |
| 148 scissor_box_[0], scissor_box_[1], scissor_box_[2], scissor_box_[3]); |
| 149 |
| 150 glUseProgram(current_program_); |
| 151 } |
| 152 |
| 153 private: |
| 154 GLint texture_external_oes_binding_; |
| 155 GLint vertex_array_buffer_binding_; |
| 156 GLint index_array_buffer_binding_; |
| 157 GLint pack_alignment_; |
| 158 GLint unpack_alignment_; |
| 159 |
| 160 struct { |
| 161 GLint enabled; |
| 162 GLint size; |
| 163 GLint type; |
| 164 GLint normalized; |
| 165 GLint stride; |
| 166 GLvoid* pointer; |
| 167 } vertex_attrib_[3]; |
| 168 |
| 169 GLboolean depth_test_; |
| 170 GLboolean cull_face_; |
| 171 GLboolean color_mask_[4]; |
| 172 GLboolean blend_enabled_; |
| 173 GLint blend_src_rgb_; |
| 174 GLint blend_src_alpha_; |
| 175 GLint blend_dest_rgb_; |
| 176 GLint blend_dest_alpha_; |
| 177 GLint active_texture_; |
| 178 GLint viewport_[4]; |
| 179 GLboolean scissor_test_; |
| 180 GLint scissor_box_[4]; |
| 181 GLint current_program_; |
| 182 }; |
| 183 |
37 const void* kUserDataKey = &kUserDataKey; | 184 const void* kUserDataKey = &kUserDataKey; |
38 | 185 |
39 class UserData : public content::WebContents::Data { | 186 class UserData : public content::WebContents::Data { |
40 public: | 187 public: |
41 UserData(InProcessViewRenderer* ptr) : instance_(ptr) {} | 188 UserData(InProcessViewRenderer* ptr) : instance_(ptr) {} |
42 virtual ~UserData() { | 189 virtual ~UserData() { |
43 instance_->WebContentsGone(); | 190 instance_->WebContentsGone(); |
44 } | 191 } |
45 | 192 |
46 static InProcessViewRenderer* GetInstance(content::WebContents* contents) { | 193 static InProcessViewRenderer* GetInstance(content::WebContents* contents) { |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 DCHECK(view_visible_); | 338 DCHECK(view_visible_); |
192 | 339 |
193 // We need to watch if the current Android context has changed and enforce | 340 // We need to watch if the current Android context has changed and enforce |
194 // a clean-up in the compositor. | 341 // a clean-up in the compositor. |
195 EGLContext current_context = eglGetCurrentContext(); | 342 EGLContext current_context = eglGetCurrentContext(); |
196 if (!current_context) { | 343 if (!current_context) { |
197 LOG(WARNING) << "No current context attached. Skipping composite."; | 344 LOG(WARNING) << "No current context attached. Skipping composite."; |
198 return; | 345 return; |
199 } | 346 } |
200 | 347 |
| 348 GLStateRestore state_restore; |
| 349 |
201 if (attached_to_window_ && compositor_ && !hardware_initialized_) { | 350 if (attached_to_window_ && compositor_ && !hardware_initialized_) { |
202 // TODO(boliu): Actually initialize the compositor GL path. | 351 // TODO(boliu): Actually initialize the compositor GL path. |
203 hardware_initialized_ = true; | 352 hardware_initialized_ = true; |
204 egl_context_at_init_ = current_context; | 353 egl_context_at_init_ = current_context; |
205 } | 354 } |
206 | 355 |
207 if (draw_info->mode == AwDrawGLInfo::kModeProcess) | 356 if (draw_info->mode == AwDrawGLInfo::kModeProcess) |
208 return; | 357 return; |
209 | 358 |
210 if (egl_context_at_init_ != current_context) { | 359 if (egl_context_at_init_ != current_context) { |
(...skipping 10 matching lines...) Expand all Loading... |
221 transform.Translate(hw_rendering_scroll_.x(), hw_rendering_scroll_.y()); | 370 transform.Translate(hw_rendering_scroll_.x(), hw_rendering_scroll_.y()); |
222 // TODO(joth): Check return value. | 371 // TODO(joth): Check return value. |
223 compositor_->DemandDrawHw( | 372 compositor_->DemandDrawHw( |
224 gfx::Size(draw_info->width, draw_info->height), | 373 gfx::Size(draw_info->width, draw_info->height), |
225 transform, | 374 transform, |
226 gfx::Rect(draw_info->clip_left, | 375 gfx::Rect(draw_info->clip_left, |
227 draw_info->clip_top, | 376 draw_info->clip_top, |
228 draw_info->clip_right - draw_info->clip_left, | 377 draw_info->clip_right - draw_info->clip_left, |
229 draw_info->clip_bottom - draw_info->clip_top)); | 378 draw_info->clip_bottom - draw_info->clip_top)); |
230 | 379 |
231 // The GL functor must ensure these are set to zero before returning. | |
232 // Not setting them leads to graphical artifacts that can affect other apps. | |
233 glBindBuffer(GL_ARRAY_BUFFER, 0); | |
234 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
235 | |
236 EnsureContinuousInvalidation(); | 380 EnsureContinuousInvalidation(); |
237 } | 381 } |
238 | 382 |
239 bool InProcessViewRenderer::DrawSW(jobject java_canvas, | 383 bool InProcessViewRenderer::DrawSW(jobject java_canvas, |
240 const gfx::Rect& clip) { | 384 const gfx::Rect& clip) { |
241 bool result = DrawSWInternal(java_canvas, clip); | 385 bool result = DrawSWInternal(java_canvas, clip); |
242 EnsureContinuousInvalidation(); | 386 EnsureContinuousInvalidation(); |
243 return result; | 387 return result; |
244 } | 388 } |
245 | 389 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 // TODO(joth): BrowserViewRendererImpl had a bunch of logic for dpi and page | 580 // TODO(joth): BrowserViewRendererImpl had a bunch of logic for dpi and page |
437 // scale here. Determine what if any needs bringing over to this class. | 581 // scale here. Determine what if any needs bringing over to this class. |
438 return CompositeSW(canvas); | 582 return CompositeSW(canvas); |
439 } | 583 } |
440 | 584 |
441 bool InProcessViewRenderer::CompositeSW(SkCanvas* canvas) { | 585 bool InProcessViewRenderer::CompositeSW(SkCanvas* canvas) { |
442 return compositor_ && compositor_->DemandDrawSw(canvas); | 586 return compositor_ && compositor_->DemandDrawSw(canvas); |
443 } | 587 } |
444 | 588 |
445 } // namespace android_webview | 589 } // namespace android_webview |
OLD | NEW |