| 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 |