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   // === 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, &current_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