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// This file contains the ContextState class.
6
7#ifndef GPU_COMMAND_BUFFER_SERVICE_CONTEXT_STATE_H_
8#define GPU_COMMAND_BUFFER_SERVICE_CONTEXT_STATE_H_
9
10#include <vector>
11#include "base/logging.h"
12#include "base/memory/scoped_ptr.h"
13#include "gpu/command_buffer/service/gl_utils.h"
14#include "gpu/command_buffer/service/query_manager.h"
15#include "gpu/command_buffer/service/texture_manager.h"
16#include "gpu/command_buffer/service/vertex_attrib_manager.h"
17#include "gpu/command_buffer/service/vertex_array_manager.h"
18#include "gpu/gpu_export.h"
19
20namespace gpu {
21namespace gles2 {
22
23class Buffer;
24class ErrorState;
25class ErrorStateClient;
26class FeatureInfo;
27class Framebuffer;
28class Program;
29class Renderbuffer;
30
31// State associated with each texture unit.
32struct GPU_EXPORT TextureUnit {
33  TextureUnit();
34  ~TextureUnit();
35
36  // The last target that was bound to this texture unit.
37  GLenum bind_target;
38
39  // texture currently bound to this unit's GL_TEXTURE_2D with glBindTexture
40  scoped_refptr<TextureRef> bound_texture_2d;
41
42  // texture currently bound to this unit's GL_TEXTURE_CUBE_MAP with
43  // glBindTexture
44  scoped_refptr<TextureRef> bound_texture_cube_map;
45
46  // texture currently bound to this unit's GL_TEXTURE_EXTERNAL_OES with
47  // glBindTexture
48  scoped_refptr<TextureRef> bound_texture_external_oes;
49
50  // texture currently bound to this unit's GL_TEXTURE_RECTANGLE_ARB with
51  // glBindTexture
52  scoped_refptr<TextureRef> bound_texture_rectangle_arb;
53
54  scoped_refptr<TextureRef> GetInfoForSamplerType(
55      GLenum type) {
56    DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
57           type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
58    switch (type) {
59      case GL_SAMPLER_2D:
60        return bound_texture_2d;
61      case GL_SAMPLER_CUBE:
62        return bound_texture_cube_map;
63      case GL_SAMPLER_EXTERNAL_OES:
64        return bound_texture_external_oes;
65      case GL_SAMPLER_2D_RECT_ARB:
66        return bound_texture_rectangle_arb;
67    }
68
69    NOTREACHED();
70    return NULL;
71  }
72
73  void Unbind(TextureRef* texture) {
74    if (bound_texture_2d.get() == texture) {
75      bound_texture_2d = NULL;
76    }
77    if (bound_texture_cube_map.get() == texture) {
78      bound_texture_cube_map = NULL;
79    }
80    if (bound_texture_external_oes.get() == texture) {
81      bound_texture_external_oes = NULL;
82    }
83  }
84};
85
86struct Vec4 {
87  Vec4() {
88    v[0] = 0.0f;
89    v[1] = 0.0f;
90    v[2] = 0.0f;
91    v[3] = 1.0f;
92  }
93  float v[4];
94};
95
96struct GPU_EXPORT ContextState {
97  ContextState(FeatureInfo* feature_info,
98               ErrorStateClient* error_state_client,
99               Logger* logger);
100  ~ContextState();
101
102  void Initialize();
103
104  void SetIgnoreCachedStateForTest(bool ignore) {
105    ignore_cached_state = ignore;
106  }
107
108  void RestoreState(const ContextState* prev_state);
109  void InitCapabilities(const ContextState* prev_state) const;
110  void InitState(const ContextState* prev_state) const;
111
112  void RestoreActiveTexture() const;
113  void RestoreAllTextureUnitBindings(const ContextState* prev_state) const;
114  void RestoreActiveTextureUnitBinding(unsigned int target) const;
115  void RestoreVertexAttribValues() const;
116  void RestoreVertexAttribArrays(
117      const scoped_refptr<VertexAttribManager> attrib_manager) const;
118  void RestoreVertexAttribs() const;
119  void RestoreBufferBindings() const;
120  void RestoreGlobalState(const ContextState* prev_state) const;
121  void RestoreProgramBindings() const;
122  void RestoreRenderbufferBindings();
123  void RestoreTextureUnitBindings(
124      GLuint unit, const ContextState* prev_state) const;
125
126  // Helper for getting cached state.
127  bool GetStateAsGLint(
128      GLenum pname, GLint* params, GLsizei* num_written) const;
129  bool GetStateAsGLfloat(
130      GLenum pname, GLfloat* params, GLsizei* num_written) const;
131  bool GetEnabled(GLenum cap) const;
132
133  inline void SetDeviceColorMask(GLboolean red,
134                                 GLboolean green,
135                                 GLboolean blue,
136                                 GLboolean alpha) {
137    if (cached_color_mask_red == red && cached_color_mask_green == green &&
138        cached_color_mask_blue == blue && cached_color_mask_alpha == alpha &&
139        !ignore_cached_state)
140      return;
141    cached_color_mask_red = red;
142    cached_color_mask_green = green;
143    cached_color_mask_blue = blue;
144    cached_color_mask_alpha = alpha;
145    glColorMask(red, green, blue, alpha);
146  }
147
148  inline void SetDeviceDepthMask(GLboolean mask) {
149    if (cached_depth_mask == mask && !ignore_cached_state)
150      return;
151    cached_depth_mask = mask;
152    glDepthMask(mask);
153  }
154
155  inline void SetDeviceStencilMaskSeparate(GLenum op, GLuint mask) {
156    if (op == GL_FRONT) {
157      if (cached_stencil_front_writemask == mask && !ignore_cached_state)
158        return;
159      cached_stencil_front_writemask = mask;
160    } else if (op == GL_BACK) {
161      if (cached_stencil_back_writemask == mask && !ignore_cached_state)
162        return;
163      cached_stencil_back_writemask = mask;
164    } else {
165      NOTREACHED();
166      return;
167    }
168    glStencilMaskSeparate(op, mask);
169  }
170
171  ErrorState* GetErrorState();
172
173  #include "gpu/command_buffer/service/context_state_autogen.h"
174
175  EnableFlags enable_flags;
176
177  // Current active texture by 0 - n index.
178  // In other words, if we call glActiveTexture(GL_TEXTURE2) this value would
179  // be 2.
180  GLuint active_texture_unit;
181
182  // The currently bound array buffer. If this is 0 it is illegal to call
183  // glVertexAttribPointer.
184  scoped_refptr<Buffer> bound_array_buffer;
185
186  // Which textures are bound to texture units through glActiveTexture.
187  std::vector<TextureUnit> texture_units;
188
189  // The values for each attrib.
190  std::vector<Vec4> attrib_values;
191
192  // Class that manages vertex attribs.
193  scoped_refptr<VertexAttribManager> vertex_attrib_manager;
194  scoped_refptr<VertexAttribManager> default_vertex_attrib_manager;
195
196  // The program in use by glUseProgram
197  scoped_refptr<Program> current_program;
198
199  // The currently bound renderbuffer
200  scoped_refptr<Renderbuffer> bound_renderbuffer;
201  bool bound_renderbuffer_valid;
202
203  // A map of of target -> Query for current queries
204  typedef std::map<GLuint, scoped_refptr<QueryManager::Query> > QueryMap;
205  QueryMap current_queries;
206
207  bool pack_reverse_row_order;
208  bool ignore_cached_state;
209
210  mutable bool fbo_binding_for_scissor_workaround_dirty_;
211  FeatureInfo* feature_info_;
212
213 private:
214  scoped_ptr<ErrorState> error_state_;
215};
216
217}  // namespace gles2
218}  // namespace gpu
219
220#endif  // GPU_COMMAND_BUFFER_SERVICE_CONTEXT_STATE_H_
221
222