Move render_view_context_menu.* and related files out of tab_contents.
[chromium-blink-merge.git] / android_webview / browser / scoped_app_gl_state_restore.cc
blob6f71eee68669ff57dfea2e150f3844fb9d21ced8
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
3 // found in the LICENSE file.
5 #include "android_webview/browser/scoped_app_gl_state_restore.h"
7 #include "base/debug/trace_event.h"
8 #include "base/lazy_instance.h"
9 #include "ui/gl/gl_context.h"
10 #include "ui/gl/gl_surface_stub.h"
12 namespace android_webview {
14 namespace {
16 // "App" context is a bit of a stretch. Basically we use this context while
17 // saving and restoring the App GL state.
18 class AppContextSurface {
19 public:
20 AppContextSurface()
21 : surface(new gfx::GLSurfaceStub),
22 context(gfx::GLContext::CreateGLContext(NULL,
23 surface.get(),
24 gfx::PreferDiscreteGpu)) {}
25 void MakeCurrent() { context->MakeCurrent(surface.get()); }
27 private:
28 scoped_refptr<gfx::GLSurfaceStub> surface;
29 scoped_refptr<gfx::GLContext> context;
31 DISALLOW_COPY_AND_ASSIGN(AppContextSurface);
34 base::LazyInstance<AppContextSurface> g_app_context_surface =
35 LAZY_INSTANCE_INITIALIZER;
37 // Make the global g_app_context_surface current so that the gl_binding is not
38 // NULL for making gl* calls. The binding can be null if another GlContext was
39 // destroyed immediately before gl* calls here.
40 void MakeAppContextCurrent() {
41 g_app_context_surface.Get().MakeCurrent();
44 void GLEnableDisable(GLenum cap, bool enable) {
45 if (enable)
46 glEnable(cap);
47 else
48 glDisable(cap);
51 GLint g_gl_max_texture_units = 0;
53 } // namespace
55 ScopedAppGLStateRestore::ScopedAppGLStateRestore(CallMode mode) : mode_(mode) {
56 TRACE_EVENT0("android_webview", "AppGLStateSave");
57 MakeAppContextCurrent();
59 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertex_array_buffer_binding_);
60 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &index_array_buffer_binding_);
62 switch(mode_) {
63 case MODE_DRAW:
64 DCHECK_EQ(0, vertex_array_buffer_binding_);
65 DCHECK_EQ(0, index_array_buffer_binding_);
66 break;
67 case MODE_RESOURCE_MANAGEMENT:
68 glGetBooleanv(GL_BLEND, &blend_enabled_);
69 glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb_);
70 glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_alpha_);
71 glGetIntegerv(GL_BLEND_DST_RGB, &blend_dest_rgb_);
72 glGetIntegerv(GL_BLEND_DST_ALPHA, &blend_dest_alpha_);
73 glGetIntegerv(GL_VIEWPORT, viewport_);
74 glGetBooleanv(GL_SCISSOR_TEST, &scissor_test_);
75 glGetIntegerv(GL_SCISSOR_BOX, scissor_box_);
76 break;
79 glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment_);
80 glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment_);
82 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) {
83 glGetVertexAttribiv(
84 i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &vertex_attrib_[i].enabled);
85 glGetVertexAttribiv(
86 i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &vertex_attrib_[i].size);
87 glGetVertexAttribiv(
88 i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &vertex_attrib_[i].type);
89 glGetVertexAttribiv(
90 i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &vertex_attrib_[i].normalized);
91 glGetVertexAttribiv(
92 i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &vertex_attrib_[i].stride);
93 glGetVertexAttribPointerv(
94 i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &vertex_attrib_[i].pointer);
97 glGetBooleanv(GL_DEPTH_TEST, &depth_test_);
98 glGetBooleanv(GL_CULL_FACE, &cull_face_);
99 glGetIntegerv(GL_CULL_FACE_MODE, &cull_face_mode_);
100 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask_);
101 glGetIntegerv(GL_CURRENT_PROGRAM, &current_program_);
102 glGetFloatv(GL_COLOR_CLEAR_VALUE, color_clear_);
103 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &depth_clear_);
104 glGetIntegerv(GL_DEPTH_FUNC, &depth_func_);
105 glGetBooleanv(GL_DEPTH_WRITEMASK, &depth_mask_);
106 glGetFloatv(GL_DEPTH_RANGE, depth_rage_);
107 glGetIntegerv(GL_FRONT_FACE, &front_face_);
108 glGetIntegerv(GL_GENERATE_MIPMAP_HINT, &hint_generate_mipmap_);
109 glGetFloatv(GL_LINE_WIDTH, &line_width_);
110 glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &polygon_offset_factor_);
111 glGetFloatv(GL_POLYGON_OFFSET_UNITS, &polygon_offset_units_);
112 glGetFloatv(GL_SAMPLE_COVERAGE_VALUE, &sample_coverage_value_);
113 glGetBooleanv(GL_SAMPLE_COVERAGE_INVERT, &sample_coverage_invert_);
115 glGetBooleanv(GL_DITHER, &enable_dither_);
116 glGetBooleanv(GL_POLYGON_OFFSET_FILL, &enable_polygon_offset_fill_);
117 glGetBooleanv(GL_SAMPLE_ALPHA_TO_COVERAGE, &enable_sample_alpha_to_coverage_);
118 glGetBooleanv(GL_SAMPLE_COVERAGE, &enable_sample_coverage_);
120 glGetBooleanv(GL_STENCIL_TEST, &stencil_test_);
121 glGetIntegerv(GL_STENCIL_FUNC, &stencil_func_);
122 glGetIntegerv(GL_STENCIL_VALUE_MASK, &stencil_mask_);
123 glGetIntegerv(GL_STENCIL_REF, &stencil_ref_);
125 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &framebuffer_binding_ext_);
127 if (!g_gl_max_texture_units) {
128 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &g_gl_max_texture_units);
129 DCHECK_GT(g_gl_max_texture_units, 0);
132 glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture_);
134 texture_bindings_.resize(g_gl_max_texture_units);
135 for (int ii = 0; ii < g_gl_max_texture_units; ++ii) {
136 glActiveTexture(GL_TEXTURE0 + ii);
137 TextureBindings& bindings = texture_bindings_[ii];
138 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bindings.texture_2d);
139 glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &bindings.texture_cube_map);
140 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES,
141 &bindings.texture_external_oes);
145 ScopedAppGLStateRestore::~ScopedAppGLStateRestore() {
146 TRACE_EVENT0("android_webview", "AppGLStateRestore");
147 MakeAppContextCurrent();
149 glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_binding_ext_);
150 glBindBuffer(GL_ARRAY_BUFFER, vertex_array_buffer_binding_);
151 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding_);
153 for (int ii = 0; ii < g_gl_max_texture_units; ++ii) {
154 glActiveTexture(GL_TEXTURE0 + ii);
155 TextureBindings& bindings = texture_bindings_[ii];
156 glBindTexture(GL_TEXTURE_2D, bindings.texture_2d);
157 glBindTexture(GL_TEXTURE_CUBE_MAP, bindings.texture_cube_map);
158 glBindTexture(GL_TEXTURE_EXTERNAL_OES, bindings.texture_external_oes);
160 glActiveTexture(active_texture_);
162 glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment_);
163 glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment_);
165 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) {
166 glVertexAttribPointer(i,
167 vertex_attrib_[i].size,
168 vertex_attrib_[i].type,
169 vertex_attrib_[i].normalized,
170 vertex_attrib_[i].stride,
171 vertex_attrib_[i].pointer);
173 if (vertex_attrib_[i].enabled) {
174 glEnableVertexAttribArray(i);
175 } else {
176 glDisableVertexAttribArray(i);
180 GLEnableDisable(GL_DEPTH_TEST, depth_test_);
182 GLEnableDisable(GL_CULL_FACE, cull_face_);
183 glCullFace(cull_face_mode_);
185 glColorMask(color_mask_[0], color_mask_[1], color_mask_[2], color_mask_[3]);
187 glUseProgram(current_program_);
189 glClearColor(
190 color_clear_[0], color_clear_[1], color_clear_[2], color_clear_[3]);
191 glClearDepth(depth_clear_);
192 glDepthFunc(depth_func_);
193 glDepthMask(depth_mask_);
194 glDepthRange(depth_rage_[0], depth_rage_[1]);
195 glFrontFace(front_face_);
196 glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap_);
197 // TODO(boliu): GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES ??
198 glLineWidth(line_width_);
199 glPolygonOffset(polygon_offset_factor_, polygon_offset_units_);
200 glSampleCoverage(sample_coverage_value_, sample_coverage_invert_);
202 GLEnableDisable(GL_DITHER, enable_dither_);
203 GLEnableDisable(GL_POLYGON_OFFSET_FILL, enable_polygon_offset_fill_);
204 GLEnableDisable(GL_SAMPLE_ALPHA_TO_COVERAGE,
205 enable_sample_alpha_to_coverage_);
206 GLEnableDisable(GL_SAMPLE_COVERAGE, enable_sample_coverage_);
208 switch(mode_) {
209 case MODE_DRAW:
210 // No-op.
211 break;
212 case MODE_RESOURCE_MANAGEMENT:
213 GLEnableDisable(GL_BLEND, blend_enabled_);
214 glBlendFuncSeparate(
215 blend_src_rgb_, blend_dest_rgb_, blend_src_alpha_, blend_dest_alpha_);
217 glViewport(viewport_[0], viewport_[1], viewport_[2], viewport_[3]);
219 GLEnableDisable(GL_SCISSOR_TEST, scissor_test_);
221 glScissor(
222 scissor_box_[0], scissor_box_[1], scissor_box_[2], scissor_box_[3]);
223 break;
226 GLEnableDisable(GL_STENCIL_TEST, stencil_test_);
227 glStencilFunc(stencil_func_, stencil_mask_, stencil_ref_);
230 } // namespace android_webview