summaryrefslogtreecommitdiff
path: root/chromium/gpu/command_buffer/service/context_state.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/gpu/command_buffer/service/context_state.cc')
-rw-r--r--chromium/gpu/command_buffer/service/context_state.cc174
1 files changed, 174 insertions, 0 deletions
diff --git a/chromium/gpu/command_buffer/service/context_state.cc b/chromium/gpu/command_buffer/service/context_state.cc
new file mode 100644
index 00000000000..e8912cfe162
--- /dev/null
+++ b/chromium/gpu/command_buffer/service/context_state.cc
@@ -0,0 +1,174 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/context_state.h"
+
+#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "gpu/command_buffer/service/buffer_manager.h"
+#include "gpu/command_buffer/service/error_state.h"
+#include "gpu/command_buffer/service/framebuffer_manager.h"
+#include "gpu/command_buffer/service/program_manager.h"
+#include "gpu/command_buffer/service/renderbuffer_manager.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_implementation.h"
+
+namespace gpu {
+namespace gles2 {
+
+namespace {
+
+void EnableDisable(GLenum pname, bool enable) {
+ if (enable) {
+ glEnable(pname);
+ } else {
+ glDisable(pname);
+ }
+}
+
+} // anonymous namespace.
+
+TextureUnit::TextureUnit()
+ : bind_target(GL_TEXTURE_2D) {
+}
+
+TextureUnit::~TextureUnit() {
+}
+
+ContextState::ContextState(FeatureInfo* feature_info, Logger* logger)
+ : active_texture_unit(0),
+ pack_reverse_row_order(false),
+ fbo_binding_for_scissor_workaround_dirty_(false),
+ feature_info_(feature_info),
+ error_state_(ErrorState::Create(logger)) {
+ Initialize();
+}
+
+ContextState::~ContextState() {
+}
+
+void ContextState::RestoreTextureUnitBindings(GLuint unit) const {
+ DCHECK_LT(unit, texture_units.size());
+ const TextureUnit& texture_unit = texture_units[unit];
+ glActiveTexture(GL_TEXTURE0 + unit);
+ GLuint service_id = texture_unit.bound_texture_2d.get()
+ ? texture_unit.bound_texture_2d->service_id()
+ : 0;
+ glBindTexture(GL_TEXTURE_2D, service_id);
+ service_id = texture_unit.bound_texture_cube_map.get()
+ ? texture_unit.bound_texture_cube_map->service_id()
+ : 0;
+ glBindTexture(GL_TEXTURE_CUBE_MAP, service_id);
+
+ if (feature_info_->feature_flags().oes_egl_image_external) {
+ service_id = texture_unit.bound_texture_external_oes.get()
+ ? texture_unit.bound_texture_external_oes->service_id()
+ : 0;
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, service_id);
+ }
+
+ if (feature_info_->feature_flags().arb_texture_rectangle) {
+ service_id = texture_unit.bound_texture_rectangle_arb.get()
+ ? texture_unit.bound_texture_rectangle_arb->service_id()
+ : 0;
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, service_id);
+ }
+}
+
+void ContextState::RestoreBufferBindings() const {
+ if (vertex_attrib_manager.get()) {
+ Buffer* element_array_buffer =
+ vertex_attrib_manager->element_array_buffer();
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
+ element_array_buffer ? element_array_buffer->service_id() : 0);
+ }
+ glBindBuffer(GL_ARRAY_BUFFER,
+ bound_array_buffer.get() ? bound_array_buffer->service_id() : 0);
+}
+
+void ContextState::RestoreRenderbufferBindings() const {
+ // Restore Bindings
+ glBindRenderbufferEXT(
+ GL_RENDERBUFFER,
+ bound_renderbuffer.get() ? bound_renderbuffer->service_id() : 0);
+}
+
+void ContextState::RestoreProgramBindings() const {
+ glUseProgram(current_program.get() ? current_program->service_id() : 0);
+}
+
+void ContextState::RestoreActiveTexture() const {
+ glActiveTexture(GL_TEXTURE0 + active_texture_unit);
+}
+
+void ContextState::RestoreAllTextureUnitBindings() const {
+ // Restore Texture state.
+ for (size_t ii = 0; ii < texture_units.size(); ++ii) {
+ RestoreTextureUnitBindings(ii);
+ }
+ RestoreActiveTexture();
+}
+
+void ContextState::RestoreAttribute(GLuint attrib_index) const {
+ const VertexAttrib* attrib =
+ vertex_attrib_manager->GetVertexAttrib(attrib_index);
+ const void* ptr = reinterpret_cast<const void*>(attrib->offset());
+ Buffer* buffer = attrib->buffer();
+ glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
+ glVertexAttribPointer(
+ attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
+ attrib->gl_stride(), ptr);
+ if (attrib->divisor())
+ glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
+ // Never touch vertex attribute 0's state (in particular, never
+ // disable it) when running on desktop GL because it will never be
+ // re-enabled.
+ if (attrib_index != 0 ||
+ gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
+ if (attrib->enabled()) {
+ glEnableVertexAttribArray(attrib_index);
+ } else {
+ glDisableVertexAttribArray(attrib_index);
+ }
+ }
+ glVertexAttrib4fv(attrib_index, attrib_values[attrib_index].v);
+}
+
+void ContextState::RestoreGlobalState() const {
+ InitCapabilities();
+ InitState();
+}
+
+void ContextState::RestoreState() const {
+ RestoreAllTextureUnitBindings();
+
+ // Restore Attrib State
+ // TODO: This if should not be needed. RestoreState is getting called
+ // before GLES2Decoder::Initialize which is a bug.
+ if (vertex_attrib_manager.get()) {
+ // TODO(gman): Move this restoration to VertexAttribManager.
+ for (size_t attrib = 0; attrib < vertex_attrib_manager->num_attribs();
+ ++attrib) {
+ RestoreAttribute(attrib);
+ }
+ }
+
+ RestoreBufferBindings();
+ RestoreRenderbufferBindings();
+ RestoreProgramBindings();
+ RestoreGlobalState();
+}
+
+ErrorState* ContextState::GetErrorState() {
+ return error_state_.get();
+}
+
+// Include the auto-generated part of this file. We split this because it means
+// we can easily edit the non-auto generated parts right here in this file
+// instead of having to edit some template or the code generator.
+#include "gpu/command_buffer/service/context_state_impl_autogen.h"
+
+} // namespace gles2
+} // namespace gpu
+
+