context_state.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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
16namespace gpu {
17namespace gles2 {
18
19namespace {
20
21void EnableDisable(GLenum pname, bool enable) {
22  if (enable) {
23    glEnable(pname);
24  } else {
25    glDisable(pname);
26  }
27}
28
29}  // anonymous namespace.
30
31TextureUnit::TextureUnit()
32    : bind_target(GL_TEXTURE_2D) {
33}
34
35TextureUnit::~TextureUnit() {
36}
37
38ContextState::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
47ContextState::~ContextState() {
48}
49
50void 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
78void 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
89void ContextState::RestoreRenderbufferBindings() const {
90  // Restore Bindings
91  glBindRenderbufferEXT(
92      GL_RENDERBUFFER,
93      bound_renderbuffer.get() ? bound_renderbuffer->service_id() : 0);
94}
95
96void ContextState::RestoreProgramBindings() const {
97  glUseProgram(current_program.get() ? current_program->service_id() : 0);
98}
99
100void ContextState::RestoreActiveTexture() const {
101  glActiveTexture(GL_TEXTURE0 + active_texture_unit);
102}
103
104void 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
112void 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
137void ContextState::RestoreGlobalState() const {
138  InitCapabilities();
139  InitState();
140}
141
142void 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
162ErrorState* 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