Chromium Code Reviews| 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 } | |
|
joth
2013/05/25 23:04:16
we could DCHECK vertex_array_buffer_binding_ == 0
| |
| 89 | |
| 90 ~GLStateRestore() { | |
| 91 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_external_oes_binding_); | |
| 92 glBindBuffer(GL_ARRAY_BUFFER, vertex_array_buffer_binding_); | |
| 93 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding_); | |
| 94 glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment_); | |
| 95 glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment_); | |
| 96 | |
| 97 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) { | |
| 98 glVertexAttribPointer(i, | |
| 99 vertex_attrib_[i].size, | |
| 100 vertex_attrib_[i].type, | |
| 101 vertex_attrib_[i].normalized, | |
| 102 vertex_attrib_[i].stride, | |
| 103 vertex_attrib_[i].pointer); | |
| 104 | |
| 105 if (vertex_attrib_[i].enabled) | |
| 106 glEnableVertexAttribArray(i); | |
| 107 else | |
| 108 glDisableVertexAttribArray(i); | |
|
joth
2013/05/25 23:04:16
nit: if/else need {}
(+several below)
| |
| 109 } | |
| 110 | |
| 111 if (depth_test_) | |
| 112 glEnable(GL_DEPTH_TEST); | |
| 113 else | |
| 114 glDisable(GL_DEPTH_TEST); | |
| 115 | |
| 116 if (cull_face_) | |
| 117 glEnable(GL_CULL_FACE); | |
| 118 else | |
| 119 glDisable(GL_CULL_FACE); | |
| 120 | |
| 121 glColorMask(color_mask_[0], color_mask_[1], color_mask_[2], color_mask_[3]); | |
| 122 | |
| 123 if (blend_enabled_) | |
| 124 glEnable(GL_BLEND); | |
| 125 else | |
| 126 glDisable(GL_BLEND); | |
| 127 | |
| 128 glBlendFuncSeparate( | |
| 129 blend_src_rgb_, blend_dest_rgb_, blend_src_alpha_, blend_dest_alpha_); | |
| 130 glActiveTexture(active_texture_); | |
| 131 | |
| 132 glViewport(viewport_[0], viewport_[1], viewport_[2], viewport_[3]); | |
| 133 | |
| 134 if (scissor_test_) | |
| 135 glEnable(GL_SCISSOR_TEST); | |
| 136 else | |
| 137 glDisable(GL_SCISSOR_TEST); | |
| 138 | |
| 139 glScissor( | |
| 140 scissor_box_[0], scissor_box_[1], scissor_box_[2], scissor_box_[3]); | |
| 141 | |
| 142 glUseProgram(current_program_); | |
| 143 } | |
| 144 | |
| 145 private: | |
| 146 GLint texture_external_oes_binding_; | |
| 147 GLint vertex_array_buffer_binding_; | |
| 148 GLint index_array_buffer_binding_; | |
| 149 GLint pack_alignment_; | |
| 150 GLint unpack_alignment_; | |
| 151 | |
| 152 struct { | |
| 153 GLint enabled; | |
| 154 GLint size; | |
| 155 GLint type; | |
| 156 GLint normalized; | |
| 157 GLint stride; | |
| 158 GLvoid* pointer; | |
| 159 } vertex_attrib_[3]; | |
| 160 | |
| 161 GLboolean depth_test_; | |
| 162 GLboolean cull_face_; | |
| 163 GLboolean color_mask_[4]; | |
| 164 GLboolean blend_enabled_; | |
| 165 GLint blend_src_rgb_; | |
| 166 GLint blend_src_alpha_; | |
| 167 GLint blend_dest_rgb_; | |
| 168 GLint blend_dest_alpha_; | |
| 169 GLint active_texture_; | |
| 170 GLint viewport_[4]; | |
| 171 GLboolean scissor_test_; | |
| 172 GLint scissor_box_[4]; | |
| 173 GLint current_program_; | |
| 174 }; | |
| 175 | |
| 37 const void* kUserDataKey = &kUserDataKey; | 176 const void* kUserDataKey = &kUserDataKey; |
| 38 | 177 |
| 39 class UserData : public content::WebContents::Data { | 178 class UserData : public content::WebContents::Data { |
| 40 public: | 179 public: |
| 41 UserData(InProcessViewRenderer* ptr) : instance_(ptr) {} | 180 UserData(InProcessViewRenderer* ptr) : instance_(ptr) {} |
| 42 virtual ~UserData() { | 181 virtual ~UserData() { |
| 43 instance_->WebContentsGone(); | 182 instance_->WebContentsGone(); |
| 44 } | 183 } |
| 45 | 184 |
| 46 static InProcessViewRenderer* GetInstance(content::WebContents* contents) { | 185 static InProcessViewRenderer* GetInstance(content::WebContents* contents) { |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 191 DCHECK(view_visible_); | 330 DCHECK(view_visible_); |
| 192 | 331 |
| 193 // We need to watch if the current Android context has changed and enforce | 332 // We need to watch if the current Android context has changed and enforce |
| 194 // a clean-up in the compositor. | 333 // a clean-up in the compositor. |
| 195 EGLContext current_context = eglGetCurrentContext(); | 334 EGLContext current_context = eglGetCurrentContext(); |
| 196 if (!current_context) { | 335 if (!current_context) { |
| 197 LOG(WARNING) << "No current context attached. Skipping composite."; | 336 LOG(WARNING) << "No current context attached. Skipping composite."; |
| 198 return; | 337 return; |
| 199 } | 338 } |
| 200 | 339 |
| 340 GLStateRestore state_restore; | |
| 341 | |
| 201 if (attached_to_window_ && compositor_ && !hardware_initialized_) { | 342 if (attached_to_window_ && compositor_ && !hardware_initialized_) { |
| 202 // TODO(boliu): Actually initialize the compositor GL path. | 343 // TODO(boliu): Actually initialize the compositor GL path. |
| 203 hardware_initialized_ = true; | 344 hardware_initialized_ = true; |
| 204 egl_context_at_init_ = current_context; | 345 egl_context_at_init_ = current_context; |
| 205 } | 346 } |
| 206 | 347 |
| 207 if (draw_info->mode == AwDrawGLInfo::kModeProcess) | 348 if (draw_info->mode == AwDrawGLInfo::kModeProcess) |
| 208 return; | 349 return; |
| 209 | 350 |
| 210 if (egl_context_at_init_ != current_context) { | 351 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()); | 362 transform.Translate(hw_rendering_scroll_.x(), hw_rendering_scroll_.y()); |
| 222 // TODO(joth): Check return value. | 363 // TODO(joth): Check return value. |
| 223 compositor_->DemandDrawHw( | 364 compositor_->DemandDrawHw( |
| 224 gfx::Size(draw_info->width, draw_info->height), | 365 gfx::Size(draw_info->width, draw_info->height), |
| 225 transform, | 366 transform, |
| 226 gfx::Rect(draw_info->clip_left, | 367 gfx::Rect(draw_info->clip_left, |
| 227 draw_info->clip_top, | 368 draw_info->clip_top, |
| 228 draw_info->clip_right - draw_info->clip_left, | 369 draw_info->clip_right - draw_info->clip_left, |
| 229 draw_info->clip_bottom - draw_info->clip_top)); | 370 draw_info->clip_bottom - draw_info->clip_top)); |
| 230 | 371 |
| 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(); | 372 EnsureContinuousInvalidation(); |
| 237 } | 373 } |
| 238 | 374 |
| 239 bool InProcessViewRenderer::DrawSW(jobject java_canvas, | 375 bool InProcessViewRenderer::DrawSW(jobject java_canvas, |
| 240 const gfx::Rect& clip) { | 376 const gfx::Rect& clip) { |
| 241 bool result = DrawSWInternal(java_canvas, clip); | 377 bool result = DrawSWInternal(java_canvas, clip); |
| 242 EnsureContinuousInvalidation(); | 378 EnsureContinuousInvalidation(); |
| 243 return result; | 379 return result; |
| 244 } | 380 } |
| 245 | 381 |
| (...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 | 572 // 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. | 573 // scale here. Determine what if any needs bringing over to this class. |
| 438 return CompositeSW(canvas); | 574 return CompositeSW(canvas); |
| 439 } | 575 } |
| 440 | 576 |
| 441 bool InProcessViewRenderer::CompositeSW(SkCanvas* canvas) { | 577 bool InProcessViewRenderer::CompositeSW(SkCanvas* canvas) { |
| 442 return compositor_ && compositor_->DemandDrawSw(canvas); | 578 return compositor_ && compositor_->DemandDrawSw(canvas); |
| 443 } | 579 } |
| 444 | 580 |
| 445 } // namespace android_webview | 581 } // namespace android_webview |
| OLD | NEW |