Home | History | Annotate | Download | only in service
      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