summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/service/context_state.cc
blob: a0e2c8cf574a09266bc93450749976ea0cebe31a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// 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 "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()
    : pack_alignment(4),
      unpack_alignment(4),
      active_texture_unit(0),
      hint_generate_mipmap(GL_DONT_CARE),
      hint_fragment_shader_derivative(GL_DONT_CARE),
      pack_reverse_row_order(false) {
  Initialize();
}

ContextState::~ContextState() {
}

void ContextState::RestoreState() const {
  InitCapabilities();
  InitState();

  glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment);
  glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment);

  glHint(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap);
  // TODO: If OES_standard_derivatives is available
  // restore GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES

  // Restore Texture state.
  for (size_t ii = 0; ii < texture_units.size(); ++ii) {
    const TextureUnit& texture_unit = texture_units[ii];
    glActiveTexture(GL_TEXTURE0 + ii);
    GLuint service_id = texture_unit.bound_texture_2d ?
        texture_unit.bound_texture_2d->service_id() : 0;
    glBindTexture(GL_TEXTURE_2D, service_id);
    service_id = texture_unit.bound_texture_cube_map ?
        texture_unit.bound_texture_cube_map->service_id() : 0;
    glBindTexture(GL_TEXTURE_CUBE_MAP, service_id);
    // TODO: Restore bindings for GL_TEXTURE_RECTANGLE_ARB and
    // GL_TEXTURE_EXTERNAL_OES.
  }
  glActiveTexture(GL_TEXTURE0 + active_texture_unit);

  // 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) {
    // TODO(gman): Move this restoration to VertexAttribManager.
    for (size_t attrib = 0; attrib < vertex_attrib_manager->num_attribs();
         ++attrib) {
      const VertexAttribManager::VertexAttribInfo* info =
          vertex_attrib_manager->GetVertexAttribInfo(attrib);
      const void* ptr = reinterpret_cast<const void*>(info->offset());
      BufferManager::BufferInfo* buffer_info = info->buffer();
      glBindBuffer(
          GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0);
      glVertexAttribPointer(
          attrib, info->size(), info->type(), info->normalized(),
          info->gl_stride(), ptr);
      if (info->divisor())
        glVertexAttribDivisorANGLE(attrib, info->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 != 0 ||
          gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
        if (info->enabled()) {
          glEnableVertexAttribArray(attrib);
        } else {
          glDisableVertexAttribArray(attrib);
        }
      }
      glVertexAttrib4fv(attrib, attrib_values[attrib].v);
    }
    BufferManager::BufferInfo* element_array_buffer =
        vertex_attrib_manager->element_array_buffer();
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
        element_array_buffer ? element_array_buffer->service_id() : 0);
  }

  // Restore Bindings
  glBindBuffer(
      GL_ARRAY_BUFFER,
      bound_array_buffer ? bound_array_buffer->service_id() : 0);
  glBindRenderbufferEXT(
      GL_RENDERBUFFER,
      bound_renderbuffer ? bound_renderbuffer->service_id() : 0);

  glUseProgram(current_program ? current_program->service_id() : 0);
}

// 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