Add default implementations for AppWindowRegistry::Observer notifications.
[chromium-blink-merge.git] / android_webview / browser / scoped_app_gl_state_restore.cc
blobf7987dab8211f86772e210548b364a8d098c3282
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 <string>
9 #include "base/debug/trace_event.h"
10 #include "base/lazy_instance.h"
11 #include "ui/gl/gl_context.h"
12 #include "ui/gl/gl_surface_stub.h"
14 namespace android_webview {
16 namespace {
18 // "App" context is a bit of a stretch. Basically we use this context while
19 // saving and restoring the App GL state.
20 class AppContextSurface {
21 public:
22 AppContextSurface()
23 : surface(new gfx::GLSurfaceStub),
24 context(gfx::GLContext::CreateGLContext(NULL,
25 surface.get(),
26 gfx::PreferDiscreteGpu)) {}
27 void MakeCurrent() { context->MakeCurrent(surface.get()); }
29 private:
30 scoped_refptr<gfx::GLSurfaceStub> surface;
31 scoped_refptr<gfx::GLContext> context;
33 DISALLOW_COPY_AND_ASSIGN(AppContextSurface);
36 base::LazyInstance<AppContextSurface> g_app_context_surface =
37 LAZY_INSTANCE_INITIALIZER;
39 // Make the global g_app_context_surface current so that the gl_binding is not
40 // NULL for making gl* calls. The binding can be null if another GlContext was
41 // destroyed immediately before gl* calls here.
42 void MakeAppContextCurrent() {
43 g_app_context_surface.Get().MakeCurrent();
46 void GLEnableDisable(GLenum cap, bool enable) {
47 if (enable)
48 glEnable(cap);
49 else
50 glDisable(cap);
53 bool g_globals_initialized = false;
54 GLint g_gl_max_texture_units = 0;
55 bool g_supports_oes_vertex_array_object = false;
57 } // namespace
59 ScopedAppGLStateRestore::ScopedAppGLStateRestore(CallMode mode) : mode_(mode) {
60 TRACE_EVENT0("android_webview", "AppGLStateSave");
61 MakeAppContextCurrent();
63 if (!g_globals_initialized) {
64 g_globals_initialized = true;
66 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &g_gl_max_texture_units);
67 DCHECK_GT(g_gl_max_texture_units, 0);
69 std::string extensions(
70 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
71 g_supports_oes_vertex_array_object =
72 extensions.find("GL_OES_vertex_array_object") != std::string::npos;
75 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertex_array_buffer_binding_);
76 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &index_array_buffer_binding_);
78 switch(mode_) {
79 case MODE_DRAW:
80 DCHECK_EQ(0, vertex_array_buffer_binding_);
81 DCHECK_EQ(0, index_array_buffer_binding_);
82 break;
83 case MODE_RESOURCE_MANAGEMENT:
84 glGetBooleanv(GL_BLEND, &blend_enabled_);
85 glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb_);
86 glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_alpha_);
87 glGetIntegerv(GL_BLEND_DST_RGB, &blend_dest_rgb_);
88 glGetIntegerv(GL_BLEND_DST_ALPHA, &blend_dest_alpha_);
89 glGetIntegerv(GL_VIEWPORT, viewport_);
90 glGetBooleanv(GL_SCISSOR_TEST, &scissor_test_);
91 glGetIntegerv(GL_SCISSOR_BOX, scissor_box_);
92 break;
95 glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment_);
96 glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack_alignment_);
98 glGetBooleanv(GL_DEPTH_TEST, &depth_test_);
99 glGetBooleanv(GL_CULL_FACE, &cull_face_);
100 glGetIntegerv(GL_CULL_FACE_MODE, &cull_face_mode_);
101 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask_);
102 glGetIntegerv(GL_CURRENT_PROGRAM, &current_program_);
103 glGetFloatv(GL_COLOR_CLEAR_VALUE, color_clear_);
104 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &depth_clear_);
105 glGetIntegerv(GL_DEPTH_FUNC, &depth_func_);
106 glGetBooleanv(GL_DEPTH_WRITEMASK, &depth_mask_);
107 glGetFloatv(GL_DEPTH_RANGE, depth_rage_);
108 glGetIntegerv(GL_FRONT_FACE, &front_face_);
109 glGetIntegerv(GL_GENERATE_MIPMAP_HINT, &hint_generate_mipmap_);
110 glGetFloatv(GL_LINE_WIDTH, &line_width_);
111 glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &polygon_offset_factor_);
112 glGetFloatv(GL_POLYGON_OFFSET_UNITS, &polygon_offset_units_);
113 glGetFloatv(GL_SAMPLE_COVERAGE_VALUE, &sample_coverage_value_);
114 glGetBooleanv(GL_SAMPLE_COVERAGE_INVERT, &sample_coverage_invert_);
116 glGetBooleanv(GL_DITHER, &enable_dither_);
117 glGetBooleanv(GL_POLYGON_OFFSET_FILL, &enable_polygon_offset_fill_);
118 glGetBooleanv(GL_SAMPLE_ALPHA_TO_COVERAGE, &enable_sample_alpha_to_coverage_);
119 glGetBooleanv(GL_SAMPLE_COVERAGE, &enable_sample_coverage_);
121 glGetBooleanv(GL_STENCIL_TEST, &stencil_test_);
122 glGetIntegerv(GL_STENCIL_FUNC, &stencil_func_);
123 glGetIntegerv(GL_STENCIL_VALUE_MASK, &stencil_mask_);
124 glGetIntegerv(GL_STENCIL_REF, &stencil_ref_);
126 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &framebuffer_binding_ext_);
128 glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture_);
130 texture_bindings_.resize(g_gl_max_texture_units);
131 for (int ii = 0; ii < g_gl_max_texture_units; ++ii) {
132 glActiveTexture(GL_TEXTURE0 + ii);
133 TextureBindings& bindings = texture_bindings_[ii];
134 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bindings.texture_2d);
135 glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &bindings.texture_cube_map);
136 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES,
137 &bindings.texture_external_oes);
140 if (g_supports_oes_vertex_array_object) {
141 glGetIntegerv(GL_VERTEX_ARRAY_BINDING_OES, &vertex_array_bindings_oes_);
142 glBindVertexArrayOES(0);
145 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) {
146 glGetVertexAttribiv(
147 i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &vertex_attrib_[i].enabled);
148 glGetVertexAttribiv(
149 i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &vertex_attrib_[i].size);
150 glGetVertexAttribiv(
151 i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &vertex_attrib_[i].type);
152 glGetVertexAttribiv(
153 i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &vertex_attrib_[i].normalized);
154 glGetVertexAttribiv(
155 i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &vertex_attrib_[i].stride);
156 glGetVertexAttribPointerv(
157 i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &vertex_attrib_[i].pointer);
158 glGetVertexAttribPointerv(
159 i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &vertex_attrib_[i].pointer);
160 glGetVertexAttribiv(i,
161 GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING,
162 &vertex_attrib_[i].vertex_attrib_array_buffer_binding);
163 glGetVertexAttribfv(
164 i, GL_CURRENT_VERTEX_ATTRIB, vertex_attrib_[i].current_vertex_attrib);
168 ScopedAppGLStateRestore::~ScopedAppGLStateRestore() {
169 TRACE_EVENT0("android_webview", "AppGLStateRestore");
170 MakeAppContextCurrent();
172 glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_binding_ext_);
173 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding_);
175 if (g_supports_oes_vertex_array_object)
176 glBindVertexArrayOES(0);
178 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(vertex_attrib_); ++i) {
179 glBindBuffer(GL_ARRAY_BUFFER,
180 vertex_attrib_[i].vertex_attrib_array_buffer_binding);
181 glVertexAttribPointer(i,
182 vertex_attrib_[i].size,
183 vertex_attrib_[i].type,
184 vertex_attrib_[i].normalized,
185 vertex_attrib_[i].stride,
186 vertex_attrib_[i].pointer);
188 glVertexAttrib4fv(i, vertex_attrib_[i].current_vertex_attrib);
190 if (vertex_attrib_[i].enabled) {
191 glEnableVertexAttribArray(i);
192 } else {
193 glDisableVertexAttribArray(i);
197 if (g_supports_oes_vertex_array_object && vertex_array_bindings_oes_ != 0)
198 glBindVertexArrayOES(vertex_array_bindings_oes_);
200 glBindBuffer(GL_ARRAY_BUFFER, vertex_array_buffer_binding_);
202 for (int ii = 0; ii < g_gl_max_texture_units; ++ii) {
203 glActiveTexture(GL_TEXTURE0 + ii);
204 TextureBindings& bindings = texture_bindings_[ii];
205 glBindTexture(GL_TEXTURE_2D, bindings.texture_2d);
206 glBindTexture(GL_TEXTURE_CUBE_MAP, bindings.texture_cube_map);
207 glBindTexture(GL_TEXTURE_EXTERNAL_OES, bindings.texture_external_oes);
209 glActiveTexture(active_texture_);
211 glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment_);
212 glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment_);
214 GLEnableDisable(GL_DEPTH_TEST, depth_test_);
216 GLEnableDisable(GL_CULL_FACE, cull_face_);
217 glCullFace(cull_face_mode_);
219 glColorMask(color_mask_[0], color_mask_[1], color_mask_[2], color_mask_[3]);
221 glUseProgram(current_program_);
223 glClearColor(
224 color_clear_[0], color_clear_[1], color_clear_[2], color_clear_[3]);
225 glClearDepth(depth_clear_);
226 glDepthFunc(depth_func_);
227 glDepthMask(depth_mask_);
228 glDepthRange(depth_rage_[0], depth_rage_[1]);
229 glFrontFace(front_face_);
230 glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap_);
231 // TODO(boliu): GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES ??
232 glLineWidth(line_width_);
233 glPolygonOffset(polygon_offset_factor_, polygon_offset_units_);
234 glSampleCoverage(sample_coverage_value_, sample_coverage_invert_);
236 GLEnableDisable(GL_DITHER, enable_dither_);
237 GLEnableDisable(GL_POLYGON_OFFSET_FILL, enable_polygon_offset_fill_);
238 GLEnableDisable(GL_SAMPLE_ALPHA_TO_COVERAGE,
239 enable_sample_alpha_to_coverage_);
240 GLEnableDisable(GL_SAMPLE_COVERAGE, enable_sample_coverage_);
242 switch(mode_) {
243 case MODE_DRAW:
244 // No-op.
245 break;
246 case MODE_RESOURCE_MANAGEMENT:
247 GLEnableDisable(GL_BLEND, blend_enabled_);
248 glBlendFuncSeparate(
249 blend_src_rgb_, blend_dest_rgb_, blend_src_alpha_, blend_dest_alpha_);
251 glViewport(viewport_[0], viewport_[1], viewport_[2], viewport_[3]);
253 GLEnableDisable(GL_SCISSOR_TEST, scissor_test_);
255 glScissor(
256 scissor_box_[0], scissor_box_[1], scissor_box_[2], scissor_box_[3]);
257 break;
260 GLEnableDisable(GL_STENCIL_TEST, stencil_test_);
261 glStencilFunc(stencil_func_, stencil_mask_, stencil_ref_);
264 } // namespace android_webview