Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / gpu / command_buffer / service / context_state.cc
blob38b70a1f2f537bb5ffddb29a6a28749db7bfe756
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.
5 #include "gpu/command_buffer/service/context_state.h"
7 #include <cmath>
9 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
10 #include "gpu/command_buffer/service/buffer_manager.h"
11 #include "gpu/command_buffer/service/error_state.h"
12 #include "gpu/command_buffer/service/framebuffer_manager.h"
13 #include "gpu/command_buffer/service/program_manager.h"
14 #include "gpu/command_buffer/service/renderbuffer_manager.h"
15 #include "ui/gl/gl_bindings.h"
16 #include "ui/gl/gl_implementation.h"
18 namespace gpu {
19 namespace gles2 {
21 namespace {
23 GLuint Get2dServiceId(const TextureUnit& unit) {
24 return unit.bound_texture_2d.get()
25 ? unit.bound_texture_2d->service_id() : 0;
28 GLuint GetCubeServiceId(const TextureUnit& unit) {
29 return unit.bound_texture_cube_map.get()
30 ? unit.bound_texture_cube_map->service_id() : 0;
33 GLuint GetOesServiceId(const TextureUnit& unit) {
34 return unit.bound_texture_external_oes.get()
35 ? unit.bound_texture_external_oes->service_id() : 0;
38 GLuint GetArbServiceId(const TextureUnit& unit) {
39 return unit.bound_texture_rectangle_arb.get()
40 ? unit.bound_texture_rectangle_arb->service_id() : 0;
43 GLuint GetServiceId(const TextureUnit& unit, GLuint target) {
44 switch (target) {
45 case GL_TEXTURE_2D:
46 return Get2dServiceId(unit);
47 case GL_TEXTURE_CUBE_MAP:
48 return GetCubeServiceId(unit);
49 case GL_TEXTURE_RECTANGLE_ARB:
50 return GetArbServiceId(unit);
51 case GL_TEXTURE_EXTERNAL_OES:
52 return GetOesServiceId(unit);
53 default:
54 NOTREACHED();
55 return 0;
59 bool TargetIsSupported(const FeatureInfo* feature_info, GLuint target) {
60 switch (target) {
61 case GL_TEXTURE_2D:
62 return true;
63 case GL_TEXTURE_CUBE_MAP:
64 return true;
65 case GL_TEXTURE_RECTANGLE_ARB:
66 return feature_info->feature_flags().arb_texture_rectangle;
67 case GL_TEXTURE_EXTERNAL_OES:
68 return feature_info->feature_flags().oes_egl_image_external;
69 default:
70 NOTREACHED();
71 return false;
75 GLuint GetBufferId(const Buffer* buffer) {
76 if (buffer)
77 return buffer->service_id();
78 return 0;
81 } // anonymous namespace.
83 TextureUnit::TextureUnit()
84 : bind_target(GL_TEXTURE_2D) {
87 TextureUnit::~TextureUnit() {
90 bool Vec4::Equal(const Vec4& other) const {
91 if (type_ != other.type_)
92 return false;
93 switch (type_) {
94 case kFloat:
95 for (size_t ii = 0; ii < 4; ++ii) {
96 if (v_[ii].float_value != other.v_[ii].float_value)
97 return false;
99 break;
100 case kInt:
101 for (size_t ii = 0; ii < 4; ++ii) {
102 if (v_[ii].int_value != other.v_[ii].int_value)
103 return false;
105 break;
106 case kUInt:
107 for (size_t ii = 0; ii < 4; ++ii) {
108 if (v_[ii].uint_value != other.v_[ii].uint_value)
109 return false;
111 break;
113 return true;
116 template <>
117 void Vec4::GetValues<GLfloat>(GLfloat* values) const {
118 DCHECK(values);
119 switch (type_) {
120 case kFloat:
121 for (size_t ii = 0; ii < 4; ++ii)
122 values[ii] = v_[ii].float_value;
123 break;
124 case kInt:
125 for (size_t ii = 0; ii < 4; ++ii)
126 values[ii] = static_cast<GLfloat>(v_[ii].int_value);
127 break;
128 case kUInt:
129 for (size_t ii = 0; ii < 4; ++ii)
130 values[ii] = static_cast<GLfloat>(v_[ii].uint_value);
131 break;
135 template <>
136 void Vec4::GetValues<GLint>(GLint* values) const {
137 DCHECK(values);
138 switch (type_) {
139 case kFloat:
140 for (size_t ii = 0; ii < 4; ++ii)
141 values[ii] = static_cast<GLint>(v_[ii].float_value);
142 break;
143 case kInt:
144 for (size_t ii = 0; ii < 4; ++ii)
145 values[ii] = v_[ii].int_value;
146 break;
147 case kUInt:
148 for (size_t ii = 0; ii < 4; ++ii)
149 values[ii] = static_cast<GLint>(v_[ii].uint_value);
150 break;
154 template<>
155 void Vec4::GetValues<GLuint>(GLuint* values) const {
156 DCHECK(values);
157 switch (type_) {
158 case kFloat:
159 for (size_t ii = 0; ii < 4; ++ii)
160 values[ii] = static_cast<GLuint>(v_[ii].float_value);
161 break;
162 case kInt:
163 for (size_t ii = 0; ii < 4; ++ii)
164 values[ii] = static_cast<GLuint>(v_[ii].int_value);
165 break;
166 case kUInt:
167 for (size_t ii = 0; ii < 4; ++ii)
168 values[ii] = v_[ii].uint_value;
169 break;
173 template <>
174 void Vec4::SetValues<GLfloat>(const GLfloat* values) {
175 DCHECK(values);
176 for (size_t ii = 0; ii < 4; ++ii)
177 v_[ii].float_value = values[ii];
178 type_ = kFloat;
181 template <>
182 void Vec4::SetValues<GLint>(const GLint* values) {
183 DCHECK(values);
184 for (size_t ii = 0; ii < 4; ++ii)
185 v_[ii].int_value = values[ii];
186 type_ = kInt;
189 template <>
190 void Vec4::SetValues<GLuint>(const GLuint* values) {
191 DCHECK(values);
192 for (size_t ii = 0; ii < 4; ++ii)
193 v_[ii].uint_value = values[ii];
194 type_ = kUInt;
197 ContextState::ContextState(FeatureInfo* feature_info,
198 ErrorStateClient* error_state_client,
199 Logger* logger)
200 : active_texture_unit(0),
201 bound_renderbuffer_valid(false),
202 pack_reverse_row_order(false),
203 ignore_cached_state(false),
204 fbo_binding_for_scissor_workaround_dirty(false),
205 feature_info_(feature_info),
206 error_state_(ErrorState::Create(error_state_client, logger)) {
207 Initialize();
210 ContextState::~ContextState() {
213 void ContextState::RestoreTextureUnitBindings(
214 GLuint unit, const ContextState* prev_state) const {
215 DCHECK_LT(unit, texture_units.size());
216 const TextureUnit& texture_unit = texture_units[unit];
217 GLuint service_id_2d = Get2dServiceId(texture_unit);
218 GLuint service_id_cube = GetCubeServiceId(texture_unit);
219 GLuint service_id_oes = GetOesServiceId(texture_unit);
220 GLuint service_id_arb = GetArbServiceId(texture_unit);
222 bool bind_texture_2d = true;
223 bool bind_texture_cube = true;
224 bool bind_texture_oes = feature_info_->feature_flags().oes_egl_image_external;
225 bool bind_texture_arb = feature_info_->feature_flags().arb_texture_rectangle;
227 if (prev_state) {
228 const TextureUnit& prev_unit = prev_state->texture_units[unit];
229 bind_texture_2d = service_id_2d != Get2dServiceId(prev_unit);
230 bind_texture_cube = service_id_cube != GetCubeServiceId(prev_unit);
231 bind_texture_oes =
232 bind_texture_oes && service_id_oes != GetOesServiceId(prev_unit);
233 bind_texture_arb =
234 bind_texture_arb && service_id_arb != GetArbServiceId(prev_unit);
237 // Early-out if nothing has changed from the previous state.
238 if (!bind_texture_2d && !bind_texture_cube
239 && !bind_texture_oes && !bind_texture_arb) {
240 return;
243 glActiveTexture(GL_TEXTURE0 + unit);
244 if (bind_texture_2d) {
245 glBindTexture(GL_TEXTURE_2D, service_id_2d);
247 if (bind_texture_cube) {
248 glBindTexture(GL_TEXTURE_CUBE_MAP, service_id_cube);
250 if (bind_texture_oes) {
251 glBindTexture(GL_TEXTURE_EXTERNAL_OES, service_id_oes);
253 if (bind_texture_arb) {
254 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, service_id_arb);
258 void ContextState::RestoreBufferBindings() const {
259 if (vertex_attrib_manager.get()) {
260 Buffer* element_array_buffer =
261 vertex_attrib_manager->element_array_buffer();
262 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, GetBufferId(element_array_buffer));
264 glBindBuffer(GL_ARRAY_BUFFER, GetBufferId(bound_array_buffer.get()));
265 if (feature_info_->IsES3Enabled()) {
266 glBindBuffer(GL_COPY_READ_BUFFER,
267 GetBufferId(bound_copy_read_buffer.get()));
268 glBindBuffer(GL_COPY_WRITE_BUFFER,
269 GetBufferId(bound_copy_write_buffer.get()));
270 glBindBuffer(GL_PIXEL_PACK_BUFFER,
271 GetBufferId(bound_pixel_pack_buffer.get()));
272 glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
273 GetBufferId(bound_pixel_unpack_buffer.get()));
274 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER,
275 GetBufferId(bound_transform_feedback_buffer.get()));
276 glBindBuffer(GL_UNIFORM_BUFFER, GetBufferId(bound_uniform_buffer.get()));
280 void ContextState::RestoreRenderbufferBindings() {
281 // Require Renderbuffer rebind.
282 bound_renderbuffer_valid = false;
285 void ContextState::RestoreProgramBindings() const {
286 glUseProgram(current_program.get() ? current_program->service_id() : 0);
289 void ContextState::RestoreActiveTexture() const {
290 glActiveTexture(GL_TEXTURE0 + active_texture_unit);
293 void ContextState::RestoreAllTextureUnitBindings(
294 const ContextState* prev_state) const {
295 // Restore Texture state.
296 for (size_t ii = 0; ii < texture_units.size(); ++ii) {
297 RestoreTextureUnitBindings(ii, prev_state);
299 RestoreActiveTexture();
302 void ContextState::RestoreActiveTextureUnitBinding(unsigned int target) const {
303 DCHECK_LT(active_texture_unit, texture_units.size());
304 const TextureUnit& texture_unit = texture_units[active_texture_unit];
305 if (TargetIsSupported(feature_info_, target))
306 glBindTexture(target, GetServiceId(texture_unit, target));
309 void ContextState::RestoreVertexAttribValues() const {
310 for (size_t attrib = 0; attrib < vertex_attrib_manager->num_attribs();
311 ++attrib) {
312 switch (attrib_values[attrib].type()) {
313 case Vec4::kFloat:
315 GLfloat v[4];
316 attrib_values[attrib].GetValues(v);
317 glVertexAttrib4fv(attrib, v);
319 break;
320 case Vec4::kInt:
322 GLint v[4];
323 attrib_values[attrib].GetValues(v);
324 glVertexAttribI4iv(attrib, v);
326 break;
327 case Vec4::kUInt:
329 GLuint v[4];
330 attrib_values[attrib].GetValues(v);
331 glVertexAttribI4uiv(attrib, v);
333 break;
338 void ContextState::RestoreVertexAttribArrays(
339 const scoped_refptr<VertexAttribManager> attrib_manager) const {
340 // This is expected to be called only for VAO with service_id 0,
341 // either to restore the default VAO or a virtual VAO with service_id 0.
342 GLuint vao_service_id = attrib_manager->service_id();
343 DCHECK(vao_service_id == 0);
345 // Bind VAO if supported.
346 if (feature_info_->feature_flags().native_vertex_array_object)
347 glBindVertexArrayOES(vao_service_id);
349 // Restore vertex attrib arrays.
350 for (size_t attrib_index = 0; attrib_index < attrib_manager->num_attribs();
351 ++attrib_index) {
352 const VertexAttrib* attrib = attrib_manager->GetVertexAttrib(attrib_index);
354 // Restore vertex array.
355 Buffer* buffer = attrib->buffer();
356 GLuint buffer_service_id = buffer ? buffer->service_id() : 0;
357 glBindBuffer(GL_ARRAY_BUFFER, buffer_service_id);
358 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
359 glVertexAttribPointer(attrib_index,
360 attrib->size(),
361 attrib->type(),
362 attrib->normalized(),
363 attrib->gl_stride(),
364 ptr);
366 // Restore attrib divisor if supported.
367 if (feature_info_->feature_flags().angle_instanced_arrays)
368 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
370 // Never touch vertex attribute 0's state (in particular, never
371 // disable it) when running on desktop GL because it will never be
372 // re-enabled.
373 if (attrib_index != 0 ||
374 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
375 if (attrib->enabled()) {
376 glEnableVertexAttribArray(attrib_index);
377 } else {
378 glDisableVertexAttribArray(attrib_index);
384 void ContextState::RestoreVertexAttribs() const {
385 // Restore Vertex Attrib Arrays
386 // TODO: This if should not be needed. RestoreState is getting called
387 // before GLES2Decoder::Initialize which is a bug.
388 if (vertex_attrib_manager.get()) {
389 // Restore VAOs.
390 if (feature_info_->feature_flags().native_vertex_array_object) {
391 // If default VAO is still using shared id 0 instead of unique ids
392 // per-context, default VAO state must be restored.
393 GLuint default_vao_service_id =
394 default_vertex_attrib_manager->service_id();
395 if (default_vao_service_id == 0)
396 RestoreVertexAttribArrays(default_vertex_attrib_manager);
398 // Restore the current VAO binding, unless it's the same as the
399 // default above.
400 GLuint curr_vao_service_id = vertex_attrib_manager->service_id();
401 if (curr_vao_service_id != 0)
402 glBindVertexArrayOES(curr_vao_service_id);
403 } else {
404 // If native VAO isn't supported, emulated VAOs are used.
405 // Restore to the currently bound VAO.
406 RestoreVertexAttribArrays(vertex_attrib_manager);
410 // glVertexAttrib4fv aren't part of VAO state and must be restored.
411 RestoreVertexAttribValues();
414 void ContextState::RestoreGlobalState(const ContextState* prev_state) const {
415 InitCapabilities(prev_state);
416 InitState(prev_state);
419 void ContextState::RestoreState(const ContextState* prev_state) {
420 RestoreAllTextureUnitBindings(prev_state);
421 RestoreVertexAttribs();
422 RestoreBufferBindings();
423 RestoreRenderbufferBindings();
424 RestoreProgramBindings();
425 RestoreGlobalState(prev_state);
428 ErrorState* ContextState::GetErrorState() {
429 return error_state_.get();
432 void ContextState::EnableDisable(GLenum pname, bool enable) const {
433 if (pname == GL_PRIMITIVE_RESTART_FIXED_INDEX) {
434 if (feature_info_->feature_flags().emulate_primitive_restart_fixed_index)
435 pname = GL_PRIMITIVE_RESTART;
437 if (enable) {
438 glEnable(pname);
439 } else {
440 glDisable(pname);
444 void ContextState::SetBoundBuffer(GLenum target, Buffer* buffer) {
445 switch (target) {
446 case GL_ARRAY_BUFFER:
447 bound_array_buffer = buffer;
448 break;
449 case GL_ELEMENT_ARRAY_BUFFER:
450 vertex_attrib_manager->SetElementArrayBuffer(buffer);
451 break;
452 case GL_COPY_READ_BUFFER:
453 bound_copy_read_buffer = buffer;
454 break;
455 case GL_COPY_WRITE_BUFFER:
456 bound_copy_write_buffer = buffer;
457 break;
458 case GL_PIXEL_PACK_BUFFER:
459 bound_pixel_pack_buffer = buffer;
460 break;
461 case GL_PIXEL_UNPACK_BUFFER:
462 bound_pixel_unpack_buffer = buffer;
463 break;
464 case GL_TRANSFORM_FEEDBACK_BUFFER:
465 bound_transform_feedback_buffer = buffer;
466 break;
467 case GL_UNIFORM_BUFFER:
468 bound_uniform_buffer = buffer;
469 break;
470 default:
471 NOTREACHED();
472 break;
476 void ContextState::RemoveBoundBuffer(Buffer* buffer) {
477 DCHECK(buffer);
478 vertex_attrib_manager->Unbind(buffer);
479 if (bound_array_buffer.get() == buffer) {
480 bound_array_buffer = nullptr;
482 if (bound_copy_read_buffer.get() == buffer) {
483 bound_copy_read_buffer = nullptr;
485 if (bound_copy_write_buffer.get() == buffer) {
486 bound_copy_write_buffer = nullptr;
488 if (bound_pixel_pack_buffer.get() == buffer) {
489 bound_pixel_pack_buffer = nullptr;
491 if (bound_pixel_unpack_buffer.get() == buffer) {
492 bound_pixel_unpack_buffer = nullptr;
494 if (bound_transform_feedback_buffer.get() == buffer) {
495 bound_transform_feedback_buffer = nullptr;
497 if (bound_uniform_buffer.get() == buffer) {
498 bound_uniform_buffer = nullptr;
502 // Include the auto-generated part of this file. We split this because it means
503 // we can easily edit the non-auto generated parts right here in this file
504 // instead of having to edit some template or the code generator.
505 #include "gpu/command_buffer/service/context_state_impl_autogen.h"
507 } // namespace gles2
508 } // namespace gpu