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. 4 5 #include "gpu/command_buffer/service/context_state.h" 6 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" 15 16 namespace gpu { 17 namespace gles2 { 18 19 namespace { 20 21 void EnableDisable(GLenum pname, bool enable) { 22 if (enable) { 23 glEnable(pname); 24 } else { 25 glDisable(pname); 26 } 27 } 28 29 } // anonymous namespace. 30 31 TextureUnit::TextureUnit() 32 : bind_target(GL_TEXTURE_2D) { 33 } 34 35 TextureUnit::~TextureUnit() { 36 } 37 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)) { 44 Initialize(); 45 } 46 47 ContextState::~ContextState() { 48 } 49 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() 56 : 0; 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() 60 : 0; 61 glBindTexture(GL_TEXTURE_CUBE_MAP, service_id); 62 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() 66 : 0; 67 glBindTexture(GL_TEXTURE_EXTERNAL_OES, service_id); 68 } 69 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() 73 : 0; 74 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, service_id); 75 } 76 } 77 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); 84 } 85 glBindBuffer(GL_ARRAY_BUFFER, 86 bound_array_buffer.get() ? bound_array_buffer->service_id() : 0); 87 } 88 89 void ContextState::RestoreRenderbufferBindings() const { 90 // === Begin android workaround for b/11061206 91 GLuint context_service_id = 92 bound_renderbuffer.get() ? bound_renderbuffer->service_id() : 0; 93 GLint current_service_id = 0; 94 glGetIntegerv(GL_RENDERBUFFER_BINDING_EXT, ¤t_service_id); 95 96 if (context_service_id == static_cast<GLuint>(current_service_id)) 97 return; 98 // === End android workaround for b/11061206 99 100 // Restore Bindings 101 glBindRenderbufferEXT( 102 GL_RENDERBUFFER, 103 bound_renderbuffer.get() ? bound_renderbuffer->service_id() : 0); 104 } 105 106 void ContextState::RestoreProgramBindings() const { 107 glUseProgram(current_program.get() ? current_program->service_id() : 0); 108 } 109 110 void ContextState::RestoreActiveTexture() const { 111 glActiveTexture(GL_TEXTURE0 + active_texture_unit); 112 } 113 114 void ContextState::RestoreAllTextureUnitBindings() const { 115 // Restore Texture state. 116 for (size_t ii = 0; ii < texture_units.size(); ++ii) { 117 RestoreTextureUnitBindings(ii); 118 } 119 RestoreActiveTexture(); 120 } 121 122 void ContextState::RestoreAttribute(GLuint attrib_index) const { 123 const VertexAttrib* attrib = 124 vertex_attrib_manager->GetVertexAttrib(attrib_index); 125 const void* ptr = reinterpret_cast<const void*>(attrib->offset()); 126 Buffer* buffer = attrib->buffer(); 127 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0); 128 glVertexAttribPointer( 129 attrib_index, attrib->size(), attrib->type(), attrib->normalized(), 130 attrib->gl_stride(), ptr); 131 if (attrib->divisor()) 132 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor()); 133 // Never touch vertex attribute 0's state (in particular, never 134 // disable it) when running on desktop GL because it will never be 135 // re-enabled. 136 if (attrib_index != 0 || 137 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 138 if (attrib->enabled()) { 139 glEnableVertexAttribArray(attrib_index); 140 } else { 141 glDisableVertexAttribArray(attrib_index); 142 } 143 } 144 glVertexAttrib4fv(attrib_index, attrib_values[attrib_index].v); 145 } 146 147 void ContextState::RestoreGlobalState() const { 148 InitCapabilities(); 149 InitState(); 150 } 151 152 void ContextState::RestoreState() const { 153 RestoreAllTextureUnitBindings(); 154 155 // Restore Attrib State 156 // TODO: This if should not be needed. RestoreState is getting called 157 // before GLES2Decoder::Initialize which is a bug. 158 if (vertex_attrib_manager.get()) { 159 // TODO(gman): Move this restoration to VertexAttribManager. 160 for (size_t attrib = 0; attrib < vertex_attrib_manager->num_attribs(); 161 ++attrib) { 162 RestoreAttribute(attrib); 163 } 164 } 165 166 RestoreBufferBindings(); 167 RestoreRenderbufferBindings(); 168 RestoreProgramBindings(); 169 RestoreGlobalState(); 170 } 171 172 ErrorState* ContextState::GetErrorState() { 173 return error_state_.get(); 174 } 175 176 // Include the auto-generated part of this file. We split this because it means 177 // we can easily edit the non-auto generated parts right here in this file 178 // instead of having to edit some template or the code generator. 179 #include "gpu/command_buffer/service/context_state_impl_autogen.h" 180 181 } // namespace gles2 182 } // namespace gpu 183 184 185