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 // Restore Bindings 91 glBindRenderbufferEXT( 92 GL_RENDERBUFFER, 93 bound_renderbuffer.get() ? bound_renderbuffer->service_id() : 0); 94 } 95 96 void ContextState::RestoreProgramBindings() const { 97 glUseProgram(current_program.get() ? current_program->service_id() : 0); 98 } 99 100 void ContextState::RestoreActiveTexture() const { 101 glActiveTexture(GL_TEXTURE0 + active_texture_unit); 102 } 103 104 void ContextState::RestoreAllTextureUnitBindings() const { 105 // Restore Texture state. 106 for (size_t ii = 0; ii < texture_units.size(); ++ii) { 107 RestoreTextureUnitBindings(ii); 108 } 109 RestoreActiveTexture(); 110 } 111 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 125 // re-enabled. 126 if (attrib_index != 0 || 127 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 128 if (attrib->enabled()) { 129 glEnableVertexAttribArray(attrib_index); 130 } else { 131 glDisableVertexAttribArray(attrib_index); 132 } 133 } 134 glVertexAttrib4fv(attrib_index, attrib_values[attrib_index].v); 135 } 136 137 void ContextState::RestoreGlobalState() const { 138 InitCapabilities(); 139 InitState(); 140 } 141 142 void ContextState::RestoreState() const { 143 RestoreAllTextureUnitBindings(); 144 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(); 151 ++attrib) { 152 RestoreAttribute(attrib); 153 } 154 } 155 156 RestoreBufferBindings(); 157 RestoreRenderbufferBindings(); 158 RestoreProgramBindings(); 159 RestoreGlobalState(); 160 } 161 162 ErrorState* ContextState::GetErrorState() { 163 return error_state_.get(); 164 } 165 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" 170 171 } // namespace gles2 172 } // namespace gpu 173 174 175