OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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/scoped_app_gl_state_restore.h" | 5 #include "android_webview/browser/scoped_app_gl_state_restore.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 11 #include "ui/gl/gl_bindings.h" |
11 #include "ui/gl/gl_context.h" | 12 #include "ui/gl/gl_context.h" |
12 #include "ui/gl/gl_surface_stub.h" | 13 #include "ui/gl/gl_surface_stub.h" |
13 | 14 |
14 namespace android_webview { | 15 namespace android_webview { |
15 | 16 |
16 namespace { | 17 namespace { |
17 | 18 |
18 // "App" context is a bit of a stretch. Basically we use this context while | 19 // "App" context is a bit of a stretch. Basically we use this context while |
19 // saving and restoring the App GL state. | 20 // saving and restoring the App GL state. |
20 class AppContextSurface { | 21 class AppContextSurface { |
(...skipping 28 matching lines...) Expand all Loading... |
49 else | 50 else |
50 glDisable(cap); | 51 glDisable(cap); |
51 } | 52 } |
52 | 53 |
53 bool g_globals_initialized = false; | 54 bool g_globals_initialized = false; |
54 GLint g_gl_max_texture_units = 0; | 55 GLint g_gl_max_texture_units = 0; |
55 bool g_supports_oes_vertex_array_object = false; | 56 bool g_supports_oes_vertex_array_object = false; |
56 | 57 |
57 } // namespace | 58 } // namespace |
58 | 59 |
59 ScopedAppGLStateRestore::ScopedAppGLStateRestore(CallMode mode) : mode_(mode) { | 60 namespace internal { |
| 61 |
| 62 class ScopedAppGLStateRestoreImpl { |
| 63 public: |
| 64 ScopedAppGLStateRestoreImpl(ScopedAppGLStateRestore::CallMode mode); |
| 65 ~ScopedAppGLStateRestoreImpl(); |
| 66 |
| 67 bool stencil_enabled() const { return stencil_test_; } |
| 68 GLint framebuffer_binding_ext() const { return framebuffer_binding_ext_; } |
| 69 |
| 70 private: |
| 71 const ScopedAppGLStateRestore::CallMode mode_; |
| 72 |
| 73 GLint pack_alignment_; |
| 74 GLint unpack_alignment_; |
| 75 |
| 76 struct { |
| 77 GLint enabled; |
| 78 GLint size; |
| 79 GLint type; |
| 80 GLint normalized; |
| 81 GLint stride; |
| 82 GLvoid* pointer; |
| 83 GLint vertex_attrib_array_buffer_binding; |
| 84 GLfloat current_vertex_attrib[4]; |
| 85 } vertex_attrib_[3]; |
| 86 |
| 87 GLint vertex_array_buffer_binding_; |
| 88 GLint index_array_buffer_binding_; |
| 89 |
| 90 GLboolean depth_test_; |
| 91 GLboolean cull_face_; |
| 92 GLint cull_face_mode_; |
| 93 GLboolean color_mask_[4]; |
| 94 GLfloat color_clear_[4]; |
| 95 GLfloat depth_clear_; |
| 96 GLint current_program_; |
| 97 GLint depth_func_; |
| 98 GLboolean depth_mask_; |
| 99 GLfloat depth_rage_[2]; |
| 100 GLint front_face_; |
| 101 GLint hint_generate_mipmap_; |
| 102 GLfloat line_width_; |
| 103 GLfloat polygon_offset_factor_; |
| 104 GLfloat polygon_offset_units_; |
| 105 GLfloat sample_coverage_value_; |
| 106 GLboolean sample_coverage_invert_; |
| 107 |
| 108 GLboolean enable_dither_; |
| 109 GLboolean enable_polygon_offset_fill_; |
| 110 GLboolean enable_sample_alpha_to_coverage_; |
| 111 GLboolean enable_sample_coverage_; |
| 112 |
| 113 // Not saved/restored in MODE_DRAW. |
| 114 GLboolean blend_enabled_; |
| 115 GLint blend_src_rgb_; |
| 116 GLint blend_src_alpha_; |
| 117 GLint blend_dest_rgb_; |
| 118 GLint blend_dest_alpha_; |
| 119 GLint active_texture_; |
| 120 GLint viewport_[4]; |
| 121 GLboolean scissor_test_; |
| 122 GLint scissor_box_[4]; |
| 123 |
| 124 GLboolean stencil_test_; |
| 125 GLint stencil_func_; |
| 126 GLint stencil_mask_; |
| 127 GLint stencil_ref_; |
| 128 |
| 129 GLint framebuffer_binding_ext_; |
| 130 |
| 131 struct TextureBindings { |
| 132 GLint texture_2d; |
| 133 GLint texture_cube_map; |
| 134 GLint texture_external_oes; |
| 135 // TODO(boliu): TEXTURE_RECTANGLE_ARB |
| 136 }; |
| 137 |
| 138 std::vector<TextureBindings> texture_bindings_; |
| 139 |
| 140 GLint vertex_array_bindings_oes_; |
| 141 |
| 142 DISALLOW_COPY_AND_ASSIGN(ScopedAppGLStateRestoreImpl); |
| 143 }; |
| 144 |
| 145 ScopedAppGLStateRestoreImpl::ScopedAppGLStateRestoreImpl( |
| 146 ScopedAppGLStateRestore::CallMode mode) |
| 147 : mode_(mode) { |
60 TRACE_EVENT0("android_webview", "AppGLStateSave"); | 148 TRACE_EVENT0("android_webview", "AppGLStateSave"); |
61 MakeAppContextCurrent(); | 149 MakeAppContextCurrent(); |
62 | 150 |
63 if (!g_globals_initialized) { | 151 if (!g_globals_initialized) { |
64 g_globals_initialized = true; | 152 g_globals_initialized = true; |
65 | 153 |
66 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &g_gl_max_texture_units); | 154 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &g_gl_max_texture_units); |
67 DCHECK_GT(g_gl_max_texture_units, 0); | 155 DCHECK_GT(g_gl_max_texture_units, 0); |
68 | 156 |
69 std::string extensions( | 157 std::string extensions( |
70 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); | 158 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); |
71 g_supports_oes_vertex_array_object = | 159 g_supports_oes_vertex_array_object = |
72 extensions.find("GL_OES_vertex_array_object") != std::string::npos; | 160 extensions.find("GL_OES_vertex_array_object") != std::string::npos; |
73 } | 161 } |
74 | 162 |
75 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertex_array_buffer_binding_); | 163 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertex_array_buffer_binding_); |
76 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &index_array_buffer_binding_); | 164 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &index_array_buffer_binding_); |
77 | 165 |
78 switch(mode_) { | 166 switch(mode_) { |
79 case MODE_DRAW: | 167 case ScopedAppGLStateRestore::MODE_DRAW: |
80 DCHECK_EQ(0, vertex_array_buffer_binding_); | 168 DCHECK_EQ(0, vertex_array_buffer_binding_); |
81 DCHECK_EQ(0, index_array_buffer_binding_); | 169 DCHECK_EQ(0, index_array_buffer_binding_); |
82 break; | 170 break; |
83 case MODE_RESOURCE_MANAGEMENT: | 171 case ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT: |
84 glGetBooleanv(GL_BLEND, &blend_enabled_); | 172 glGetBooleanv(GL_BLEND, &blend_enabled_); |
85 glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb_); | 173 glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb_); |
86 glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_alpha_); | 174 glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_alpha_); |
87 glGetIntegerv(GL_BLEND_DST_RGB, &blend_dest_rgb_); | 175 glGetIntegerv(GL_BLEND_DST_RGB, &blend_dest_rgb_); |
88 glGetIntegerv(GL_BLEND_DST_ALPHA, &blend_dest_alpha_); | 176 glGetIntegerv(GL_BLEND_DST_ALPHA, &blend_dest_alpha_); |
89 glGetIntegerv(GL_VIEWPORT, viewport_); | 177 glGetIntegerv(GL_VIEWPORT, viewport_); |
90 glGetBooleanv(GL_SCISSOR_TEST, &scissor_test_); | 178 glGetBooleanv(GL_SCISSOR_TEST, &scissor_test_); |
91 glGetIntegerv(GL_SCISSOR_BOX, scissor_box_); | 179 glGetIntegerv(GL_SCISSOR_BOX, scissor_box_); |
92 break; | 180 break; |
93 } | 181 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 glGetVertexAttribPointerv( | 246 glGetVertexAttribPointerv( |
159 i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &vertex_attrib_[i].pointer); | 247 i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &vertex_attrib_[i].pointer); |
160 glGetVertexAttribiv(i, | 248 glGetVertexAttribiv(i, |
161 GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, | 249 GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, |
162 &vertex_attrib_[i].vertex_attrib_array_buffer_binding); | 250 &vertex_attrib_[i].vertex_attrib_array_buffer_binding); |
163 glGetVertexAttribfv( | 251 glGetVertexAttribfv( |
164 i, GL_CURRENT_VERTEX_ATTRIB, vertex_attrib_[i].current_vertex_attrib); | 252 i, GL_CURRENT_VERTEX_ATTRIB, vertex_attrib_[i].current_vertex_attrib); |
165 } | 253 } |
166 } | 254 } |
167 | 255 |
168 ScopedAppGLStateRestore::~ScopedAppGLStateRestore() { | 256 ScopedAppGLStateRestoreImpl::~ScopedAppGLStateRestoreImpl() { |
169 TRACE_EVENT0("android_webview", "AppGLStateRestore"); | 257 TRACE_EVENT0("android_webview", "AppGLStateRestore"); |
170 MakeAppContextCurrent(); | 258 MakeAppContextCurrent(); |
171 | 259 |
172 glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_binding_ext_); | 260 glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_binding_ext_); |
173 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding_); | 261 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding_); |
174 | 262 |
175 if (g_supports_oes_vertex_array_object) | 263 if (g_supports_oes_vertex_array_object) |
176 glBindVertexArrayOES(0); | 264 glBindVertexArrayOES(0); |
177 | 265 |
178 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) { | 266 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 glPolygonOffset(polygon_offset_factor_, polygon_offset_units_); | 321 glPolygonOffset(polygon_offset_factor_, polygon_offset_units_); |
234 glSampleCoverage(sample_coverage_value_, sample_coverage_invert_); | 322 glSampleCoverage(sample_coverage_value_, sample_coverage_invert_); |
235 | 323 |
236 GLEnableDisable(GL_DITHER, enable_dither_); | 324 GLEnableDisable(GL_DITHER, enable_dither_); |
237 GLEnableDisable(GL_POLYGON_OFFSET_FILL, enable_polygon_offset_fill_); | 325 GLEnableDisable(GL_POLYGON_OFFSET_FILL, enable_polygon_offset_fill_); |
238 GLEnableDisable(GL_SAMPLE_ALPHA_TO_COVERAGE, | 326 GLEnableDisable(GL_SAMPLE_ALPHA_TO_COVERAGE, |
239 enable_sample_alpha_to_coverage_); | 327 enable_sample_alpha_to_coverage_); |
240 GLEnableDisable(GL_SAMPLE_COVERAGE, enable_sample_coverage_); | 328 GLEnableDisable(GL_SAMPLE_COVERAGE, enable_sample_coverage_); |
241 | 329 |
242 switch(mode_) { | 330 switch(mode_) { |
243 case MODE_DRAW: | 331 case ScopedAppGLStateRestore::MODE_DRAW: |
244 // No-op. | 332 // No-op. |
245 break; | 333 break; |
246 case MODE_RESOURCE_MANAGEMENT: | 334 case ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT: |
247 GLEnableDisable(GL_BLEND, blend_enabled_); | 335 GLEnableDisable(GL_BLEND, blend_enabled_); |
248 glBlendFuncSeparate( | 336 glBlendFuncSeparate( |
249 blend_src_rgb_, blend_dest_rgb_, blend_src_alpha_, blend_dest_alpha_); | 337 blend_src_rgb_, blend_dest_rgb_, blend_src_alpha_, blend_dest_alpha_); |
250 | 338 |
251 glViewport(viewport_[0], viewport_[1], viewport_[2], viewport_[3]); | 339 glViewport(viewport_[0], viewport_[1], viewport_[2], viewport_[3]); |
252 | 340 |
253 GLEnableDisable(GL_SCISSOR_TEST, scissor_test_); | 341 GLEnableDisable(GL_SCISSOR_TEST, scissor_test_); |
254 | 342 |
255 glScissor( | 343 glScissor( |
256 scissor_box_[0], scissor_box_[1], scissor_box_[2], scissor_box_[3]); | 344 scissor_box_[0], scissor_box_[1], scissor_box_[2], scissor_box_[3]); |
257 break; | 345 break; |
258 } | 346 } |
259 | 347 |
260 GLEnableDisable(GL_STENCIL_TEST, stencil_test_); | 348 GLEnableDisable(GL_STENCIL_TEST, stencil_test_); |
261 glStencilFunc(stencil_func_, stencil_mask_, stencil_ref_); | 349 glStencilFunc(stencil_func_, stencil_mask_, stencil_ref_); |
262 } | 350 } |
263 | 351 |
| 352 } // namespace internal |
| 353 |
| 354 ScopedAppGLStateRestore::ScopedAppGLStateRestore(CallMode mode) |
| 355 : impl_(new internal::ScopedAppGLStateRestoreImpl(mode)) { |
| 356 } |
| 357 |
| 358 ScopedAppGLStateRestore::~ScopedAppGLStateRestore() {} |
| 359 |
| 360 bool ScopedAppGLStateRestore::stencil_enabled() const { |
| 361 return impl_->stencil_enabled(); |
| 362 } |
| 363 int ScopedAppGLStateRestore::framebuffer_binding_ext() const { |
| 364 return impl_->framebuffer_binding_ext(); |
| 365 } |
| 366 |
264 } // namespace android_webview | 367 } // namespace android_webview |
OLD | NEW |