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 "base/debug/trace_event.h" |
7 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
8 #include "ui/gl/gl_context.h" | 9 #include "ui/gl/gl_context.h" |
9 #include "ui/gl/gl_surface_stub.h" | 10 #include "ui/gl/gl_surface_stub.h" |
10 | 11 |
11 namespace android_webview { | 12 namespace android_webview { |
12 | 13 |
13 namespace { | 14 namespace { |
14 | 15 |
15 // "App" context is a bit of a stretch. Basically we use this context while | 16 // "App" context is a bit of a stretch. Basically we use this context while |
16 // saving and restoring the App GL state. | 17 // saving and restoring the App GL state. |
(...skipping 16 matching lines...) Expand all Loading... |
33 base::LazyInstance<AppContextSurface> g_app_context_surface = | 34 base::LazyInstance<AppContextSurface> g_app_context_surface = |
34 LAZY_INSTANCE_INITIALIZER; | 35 LAZY_INSTANCE_INITIALIZER; |
35 | 36 |
36 // Make the global g_app_context_surface current so that the gl_binding is not | 37 // Make the global g_app_context_surface current so that the gl_binding is not |
37 // NULL for making gl* calls. The binding can be null if another GlContext was | 38 // NULL for making gl* calls. The binding can be null if another GlContext was |
38 // destroyed immediately before gl* calls here. | 39 // destroyed immediately before gl* calls here. |
39 void MakeAppContextCurrent() { | 40 void MakeAppContextCurrent() { |
40 g_app_context_surface.Get().MakeCurrent(); | 41 g_app_context_surface.Get().MakeCurrent(); |
41 } | 42 } |
42 | 43 |
| 44 void GLEnableDisable(GLenum cap, bool enable) { |
| 45 if (enable) |
| 46 glEnable(cap); |
| 47 else |
| 48 glDisable(cap); |
| 49 } |
| 50 |
43 } // namespace | 51 } // namespace |
44 | 52 |
45 ScopedAppGLStateRestore::ScopedAppGLStateRestore(CallMode mode) { | 53 ScopedAppGLStateRestore::ScopedAppGLStateRestore(CallMode mode) : mode_(mode) { |
| 54 TRACE_EVENT0("android_webview", "AppGLStateSave"); |
46 MakeAppContextCurrent(); | 55 MakeAppContextCurrent(); |
47 | 56 |
48 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertex_array_buffer_binding_); | 57 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertex_array_buffer_binding_); |
49 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &index_array_buffer_binding_); | 58 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &index_array_buffer_binding_); |
50 | 59 |
51 switch(mode) { | 60 switch(mode_) { |
52 case MODE_DRAW: | 61 case MODE_DRAW: |
53 // TODO(boliu): These should always be 0 in draw case. When we have | 62 // TODO(boliu): These should always be 0 in draw case. When we have |
54 // guarantee that we are no longer making GL calls outside of draw, DCHECK | 63 // guarantee that we are no longer making GL calls outside of draw, DCHECK |
55 // these are 0 here. | 64 // these are 0 here. |
56 LOG_IF(ERROR, vertex_array_buffer_binding_) | 65 LOG_IF(ERROR, vertex_array_buffer_binding_) |
57 << "GL_ARRAY_BUFFER_BINDING not zero in draw: " | 66 << "GL_ARRAY_BUFFER_BINDING not zero in draw: " |
58 << vertex_array_buffer_binding_; | 67 << vertex_array_buffer_binding_; |
59 LOG_IF(ERROR, index_array_buffer_binding_) | 68 LOG_IF(ERROR, index_array_buffer_binding_) |
60 << "GL_ELEMENT_ARRAY_BUFFER_BINDING not zero in draw: " | 69 << "GL_ELEMENT_ARRAY_BUFFER_BINDING not zero in draw: " |
61 << index_array_buffer_binding_; | 70 << index_array_buffer_binding_; |
62 | 71 |
63 vertex_array_buffer_binding_ = 0; | 72 vertex_array_buffer_binding_ = 0; |
64 index_array_buffer_binding_ = 0; | 73 index_array_buffer_binding_ = 0; |
65 break; | 74 break; |
66 case MODE_DETACH_FROM_WINDOW: | 75 case MODE_DETACH_FROM_WINDOW: |
| 76 glGetBooleanv(GL_BLEND, &blend_enabled_); |
| 77 glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb_); |
| 78 glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_alpha_); |
| 79 glGetIntegerv(GL_BLEND_DST_RGB, &blend_dest_rgb_); |
| 80 glGetIntegerv(GL_BLEND_DST_ALPHA, &blend_dest_alpha_); |
| 81 glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture_); |
| 82 glGetIntegerv(GL_VIEWPORT, viewport_); |
| 83 glGetBooleanv(GL_SCISSOR_TEST, &scissor_test_); |
| 84 glGetIntegerv(GL_SCISSOR_BOX, scissor_box_); |
67 break; | 85 break; |
68 } | 86 } |
69 | 87 |
70 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, | 88 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, |
71 &texture_external_oes_binding_); | 89 &texture_external_oes_binding_); |
72 glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment_); | 90 glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment_); |
73 glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment_); | 91 glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment_); |
74 | 92 |
75 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) { | 93 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) { |
76 glGetVertexAttribiv( | 94 glGetVertexAttribiv( |
77 i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &vertex_attrib_[i].enabled); | 95 i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &vertex_attrib_[i].enabled); |
78 glGetVertexAttribiv( | 96 glGetVertexAttribiv( |
79 i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &vertex_attrib_[i].size); | 97 i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &vertex_attrib_[i].size); |
80 glGetVertexAttribiv( | 98 glGetVertexAttribiv( |
81 i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &vertex_attrib_[i].type); | 99 i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &vertex_attrib_[i].type); |
82 glGetVertexAttribiv( | 100 glGetVertexAttribiv( |
83 i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &vertex_attrib_[i].normalized); | 101 i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &vertex_attrib_[i].normalized); |
84 glGetVertexAttribiv( | 102 glGetVertexAttribiv( |
85 i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &vertex_attrib_[i].stride); | 103 i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &vertex_attrib_[i].stride); |
86 glGetVertexAttribPointerv( | 104 glGetVertexAttribPointerv( |
87 i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &vertex_attrib_[i].pointer); | 105 i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &vertex_attrib_[i].pointer); |
88 } | 106 } |
89 | 107 |
90 glGetBooleanv(GL_DEPTH_TEST, &depth_test_); | 108 glGetBooleanv(GL_DEPTH_TEST, &depth_test_); |
91 glGetBooleanv(GL_CULL_FACE, &cull_face_); | 109 glGetBooleanv(GL_CULL_FACE, &cull_face_); |
| 110 glGetIntegerv(GL_CULL_FACE_MODE, &cull_face_mode_); |
92 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask_); | 111 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask_); |
93 glGetBooleanv(GL_BLEND, &blend_enabled_); | |
94 glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb_); | |
95 glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_alpha_); | |
96 glGetIntegerv(GL_BLEND_DST_RGB, &blend_dest_rgb_); | |
97 glGetIntegerv(GL_BLEND_DST_ALPHA, &blend_dest_alpha_); | |
98 glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture_); | |
99 glGetIntegerv(GL_VIEWPORT, viewport_); | |
100 glGetBooleanv(GL_SCISSOR_TEST, &scissor_test_); | |
101 glGetIntegerv(GL_SCISSOR_BOX, scissor_box_); | |
102 glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_); | 112 glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_); |
| 113 glGetFloatv(GL_COLOR_CLEAR_VALUE, color_clear_); |
| 114 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &depth_clear_); |
| 115 glGetIntegerv(GL_DEPTH_FUNC, &depth_func_); |
| 116 glGetBooleanv(GL_DEPTH_WRITEMASK, &depth_mask_); |
| 117 glGetFloatv(GL_DEPTH_RANGE, depth_rage_); |
| 118 glGetIntegerv(GL_FRONT_FACE, &front_face_); |
| 119 glGetIntegerv(GL_GENERATE_MIPMAP_HINT, &hint_generate_mipmap_); |
| 120 glGetFloatv(GL_LINE_WIDTH, &line_width_); |
| 121 glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &polygon_offset_factor_); |
| 122 glGetFloatv(GL_POLYGON_OFFSET_UNITS, &polygon_offset_units_); |
| 123 glGetFloatv(GL_SAMPLE_COVERAGE_VALUE, &sample_coverage_value_); |
| 124 glGetBooleanv(GL_SAMPLE_COVERAGE_INVERT, &sample_coverage_invert_); |
| 125 |
| 126 glGetBooleanv(GL_DITHER, &enable_dither_); |
| 127 glGetBooleanv(GL_POLYGON_OFFSET_FILL, &enable_polygon_offset_fill_); |
| 128 glGetBooleanv(GL_SAMPLE_ALPHA_TO_COVERAGE, &enable_sample_alpha_to_coverage_); |
| 129 glGetBooleanv(GL_SAMPLE_COVERAGE, &enable_sample_coverage_); |
| 130 |
| 131 // Intentionally not saving/restoring stencil related state. |
103 } | 132 } |
104 | 133 |
105 ScopedAppGLStateRestore::~ScopedAppGLStateRestore() { | 134 ScopedAppGLStateRestore::~ScopedAppGLStateRestore() { |
| 135 TRACE_EVENT0("android_webview", "AppGLStateRestore"); |
106 MakeAppContextCurrent(); | 136 MakeAppContextCurrent(); |
107 | 137 |
108 glBindBuffer(GL_ARRAY_BUFFER, vertex_array_buffer_binding_); | 138 glBindBuffer(GL_ARRAY_BUFFER, vertex_array_buffer_binding_); |
109 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding_); | 139 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding_); |
110 | 140 |
111 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_external_oes_binding_); | 141 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_external_oes_binding_); |
112 glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment_); | 142 glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment_); |
113 glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment_); | 143 glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment_); |
114 | 144 |
115 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) { | 145 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) { |
116 glVertexAttribPointer(i, | 146 glVertexAttribPointer(i, |
117 vertex_attrib_[i].size, | 147 vertex_attrib_[i].size, |
118 vertex_attrib_[i].type, | 148 vertex_attrib_[i].type, |
119 vertex_attrib_[i].normalized, | 149 vertex_attrib_[i].normalized, |
120 vertex_attrib_[i].stride, | 150 vertex_attrib_[i].stride, |
121 vertex_attrib_[i].pointer); | 151 vertex_attrib_[i].pointer); |
122 | 152 |
123 if (vertex_attrib_[i].enabled) { | 153 if (vertex_attrib_[i].enabled) { |
124 glEnableVertexAttribArray(i); | 154 glEnableVertexAttribArray(i); |
125 } else { | 155 } else { |
126 glDisableVertexAttribArray(i); | 156 glDisableVertexAttribArray(i); |
127 } | 157 } |
128 } | 158 } |
129 | 159 |
130 if (depth_test_) { | 160 GLEnableDisable(GL_DEPTH_TEST, depth_test_); |
131 glEnable(GL_DEPTH_TEST); | |
132 } else { | |
133 glDisable(GL_DEPTH_TEST); | |
134 } | |
135 | 161 |
136 if (cull_face_) { | 162 GLEnableDisable(GL_CULL_FACE, cull_face_); |
137 glEnable(GL_CULL_FACE); | 163 glCullFace(cull_face_mode_); |
138 } else { | |
139 glDisable(GL_CULL_FACE); | |
140 } | |
141 | 164 |
142 glColorMask(color_mask_[0], color_mask_[1], color_mask_[2], color_mask_[3]); | 165 glColorMask(color_mask_[0], color_mask_[1], color_mask_[2], color_mask_[3]); |
143 | 166 |
144 if (blend_enabled_) { | 167 glUseProgram(current_program_); |
145 glEnable(GL_BLEND); | 168 |
146 } else { | 169 glClearColor( |
147 glDisable(GL_BLEND); | 170 color_clear_[0], color_clear_[1], color_clear_[2], color_clear_[3]); |
| 171 glClearDepth(depth_clear_); |
| 172 glDepthFunc(depth_func_); |
| 173 glDepthMask(depth_mask_); |
| 174 glDepthRange(depth_rage_[0], depth_rage_[1]); |
| 175 glFrontFace(front_face_); |
| 176 glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap_); |
| 177 // TODO(boliu): GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES ?? |
| 178 glLineWidth(line_width_); |
| 179 glPolygonOffset(polygon_offset_factor_, polygon_offset_units_); |
| 180 glSampleCoverage(sample_coverage_value_, sample_coverage_invert_); |
| 181 |
| 182 GLEnableDisable(GL_DITHER, enable_dither_); |
| 183 GLEnableDisable(GL_POLYGON_OFFSET_FILL, enable_polygon_offset_fill_); |
| 184 GLEnableDisable(GL_SAMPLE_ALPHA_TO_COVERAGE, |
| 185 enable_sample_alpha_to_coverage_); |
| 186 GLEnableDisable(GL_SAMPLE_COVERAGE, enable_sample_coverage_); |
| 187 |
| 188 if (mode_ == MODE_DETACH_FROM_WINDOW) { |
| 189 GLEnableDisable(GL_BLEND, blend_enabled_); |
| 190 glBlendFuncSeparate( |
| 191 blend_src_rgb_, blend_dest_rgb_, blend_src_alpha_, blend_dest_alpha_); |
| 192 glActiveTexture(active_texture_); |
| 193 |
| 194 glViewport(viewport_[0], viewport_[1], viewport_[2], viewport_[3]); |
| 195 |
| 196 GLEnableDisable(GL_SCISSOR_TEST, scissor_test_); |
| 197 |
| 198 glScissor( |
| 199 scissor_box_[0], scissor_box_[1], scissor_box_[2], scissor_box_[3]); |
148 } | 200 } |
149 | |
150 glBlendFuncSeparate( | |
151 blend_src_rgb_, blend_dest_rgb_, blend_src_alpha_, blend_dest_alpha_); | |
152 glActiveTexture(active_texture_); | |
153 | |
154 glViewport(viewport_[0], viewport_[1], viewport_[2], viewport_[3]); | |
155 | |
156 if (scissor_test_) { | |
157 glEnable(GL_SCISSOR_TEST); | |
158 } else { | |
159 glDisable(GL_SCISSOR_TEST); | |
160 } | |
161 | |
162 glScissor( | |
163 scissor_box_[0], scissor_box_[1], scissor_box_[2], scissor_box_[3]); | |
164 | |
165 glUseProgram(current_program_); | |
166 } | 201 } |
167 | 202 |
168 } // namespace android_webview | 203 } // namespace android_webview |
OLD | NEW |