1 // Copyright (c) 2012 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 "gpu/command_buffer/service/context_state.h"
7 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
8 #include "gpu/command_buffer/service/buffer_manager.h"
9 #include "gpu/command_buffer/service/error_state.h"
10 #include "gpu/command_buffer/service/framebuffer_manager.h"
11 #include "gpu/command_buffer/service/program_manager.h"
12 #include "gpu/command_buffer/service/renderbuffer_manager.h"
13 #include "ui/gl/gl_bindings.h"
14 #include "ui/gl/gl_implementation.h"
21 void EnableDisable(GLenum pname, bool enable) {
29 } // anonymous namespace.
31 TextureUnit::TextureUnit()
32 : bind_target(GL_TEXTURE_2D) {
35 TextureUnit::~TextureUnit() {
38 ContextState::ContextState(FeatureInfo* feature_info, Logger* logger)
39 : active_texture_unit(0),
40 pack_reverse_row_order(false),
41 fbo_binding_for_scissor_workaround_dirty_(false),
42 feature_info_(feature_info),
43 error_state_(ErrorState::Create(logger)) {
47 ContextState::~ContextState() {
50 void ContextState::RestoreTextureUnitBindings(GLuint unit) const {
51 DCHECK_LT(unit, texture_units.size());
52 const TextureUnit& texture_unit = texture_units[unit];
53 glActiveTexture(GL_TEXTURE0 + unit);
54 GLuint service_id = texture_unit.bound_texture_2d.get()
55 ? texture_unit.bound_texture_2d->service_id()
57 glBindTexture(GL_TEXTURE_2D, service_id);
58 service_id = texture_unit.bound_texture_cube_map.get()
59 ? texture_unit.bound_texture_cube_map->service_id()
61 glBindTexture(GL_TEXTURE_CUBE_MAP, service_id);
63 if (feature_info_->feature_flags().oes_egl_image_external) {
64 service_id = texture_unit.bound_texture_external_oes.get()
65 ? texture_unit.bound_texture_external_oes->service_id()
67 glBindTexture(GL_TEXTURE_EXTERNAL_OES, service_id);
70 if (feature_info_->feature_flags().arb_texture_rectangle) {
71 service_id = texture_unit.bound_texture_rectangle_arb.get()
72 ? texture_unit.bound_texture_rectangle_arb->service_id()
74 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, service_id);
78 void ContextState::RestoreBufferBindings() const {
79 if (vertex_attrib_manager.get()) {
80 Buffer* element_array_buffer =
81 vertex_attrib_manager->element_array_buffer();
82 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
83 element_array_buffer ? element_array_buffer->service_id() : 0);
85 glBindBuffer(GL_ARRAY_BUFFER,
86 bound_array_buffer.get() ? bound_array_buffer->service_id() : 0);
89 void ContextState::RestoreRenderbufferBindings() const {
91 glBindRenderbufferEXT(
93 bound_renderbuffer.get() ? bound_renderbuffer->service_id() : 0);
96 void ContextState::RestoreProgramBindings() const {
97 glUseProgram(current_program.get() ? current_program->service_id() : 0);
100 void ContextState::RestoreActiveTexture() const {
101 glActiveTexture(GL_TEXTURE0 + active_texture_unit);
104 void ContextState::RestoreAllTextureUnitBindings() const {
105 // Restore Texture state.
106 for (size_t ii = 0; ii < texture_units.size(); ++ii) {
107 RestoreTextureUnitBindings(ii);
109 RestoreActiveTexture();
112 void ContextState::RestoreAttribute(GLuint attrib_index) const {
113 const VertexAttrib* attrib =
114 vertex_attrib_manager->GetVertexAttrib(attrib_index);
115 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
116 Buffer* buffer = attrib->buffer();
117 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
118 glVertexAttribPointer(
119 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
120 attrib->gl_stride(), ptr);
121 if (attrib->divisor())
122 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
123 // Never touch vertex attribute 0's state (in particular, never
124 // disable it) when running on desktop GL because it will never be
126 if (attrib_index != 0 ||
127 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
128 if (attrib->enabled()) {
129 glEnableVertexAttribArray(attrib_index);
131 glDisableVertexAttribArray(attrib_index);
134 glVertexAttrib4fv(attrib_index, attrib_values[attrib_index].v);
137 void ContextState::RestoreGlobalState() const {
142 void ContextState::RestoreState() const {
143 RestoreAllTextureUnitBindings();
145 // Restore Attrib State
146 // TODO: This if should not be needed. RestoreState is getting called
147 // before GLES2Decoder::Initialize which is a bug.
148 if (vertex_attrib_manager.get()) {
149 // TODO(gman): Move this restoration to VertexAttribManager.
150 for (size_t attrib = 0; attrib < vertex_attrib_manager->num_attribs();
152 RestoreAttribute(attrib);
156 RestoreBufferBindings();
157 RestoreRenderbufferBindings();
158 RestoreProgramBindings();
159 RestoreGlobalState();
162 ErrorState* ContextState::GetErrorState() {
163 return error_state_.get();
166 // Include the auto-generated part of this file. We split this because it means
167 // we can easily edit the non-auto generated parts right here in this file
168 // instead of having to edit some template or the code generator.
169 #include "gpu/command_buffer/service/context_state_impl_autogen.h"