15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/context_state.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <cmath>
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/gles2_cmd_utils.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/service/buffer_manager.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "gpu/command_buffer/service/error_state.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/service/framebuffer_manager.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/service/program_manager.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/service/renderbuffer_manager.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_bindings.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_implementation.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gles2 {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)static void EnableDisable(GLenum pname, bool enable) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enable) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glEnable(pname);
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glDisable(pname);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GLuint Get2dServiceId(const TextureUnit& unit) {
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return unit.bound_texture_2d.get()
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ? unit.bound_texture_2d->service_id() : 0;
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GLuint GetCubeServiceId(const TextureUnit& unit) {
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return unit.bound_texture_cube_map.get()
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ? unit.bound_texture_cube_map->service_id() : 0;
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GLuint GetOesServiceId(const TextureUnit& unit) {
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return unit.bound_texture_external_oes.get()
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ? unit.bound_texture_external_oes->service_id() : 0;
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GLuint GetArbServiceId(const TextureUnit& unit) {
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return unit.bound_texture_rectangle_arb.get()
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ? unit.bound_texture_rectangle_arb->service_id() : 0;
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
51effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochGLuint GetServiceId(const TextureUnit& unit, GLuint target) {
52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  switch (target) {
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case GL_TEXTURE_2D:
54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return Get2dServiceId(unit);
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case GL_TEXTURE_CUBE_MAP:
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return GetCubeServiceId(unit);
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case GL_TEXTURE_RECTANGLE_ARB:
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return GetArbServiceId(unit);
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case GL_TEXTURE_EXTERNAL_OES:
60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return GetOesServiceId(unit);
61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    default:
62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      NOTREACHED();
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return 0;
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool TargetIsSupported(const FeatureInfo* feature_info, GLuint target) {
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  switch (target) {
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case GL_TEXTURE_2D:
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return true;
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case GL_TEXTURE_CUBE_MAP:
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return true;
73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case GL_TEXTURE_RECTANGLE_ARB:
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return feature_info->feature_flags().arb_texture_rectangle;
75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case GL_TEXTURE_EXTERNAL_OES:
76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return feature_info->feature_flags().oes_egl_image_external;
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    default:
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      NOTREACHED();
79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return false;
80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // anonymous namespace.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextureUnit::TextureUnit()
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : bind_target(GL_TEXTURE_2D) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextureUnit::~TextureUnit() {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochContextState::ContextState(FeatureInfo* feature_info,
93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                           ErrorStateClient* error_state_client,
94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                           Logger* logger)
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : active_texture_unit(0),
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      bound_renderbuffer_valid(false),
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pack_reverse_row_order(false),
98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      ignore_cached_state(false),
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fbo_binding_for_scissor_workaround_dirty_(false),
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      feature_info_(feature_info),
101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      error_state_(ErrorState::Create(error_state_client, logger)) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Initialize();
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContextState::~ContextState() {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ContextState::RestoreTextureUnitBindings(
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GLuint unit, const ContextState* prev_state) const {
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LT(unit, texture_units.size());
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TextureUnit& texture_unit = texture_units[unit];
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint service_id_2d = Get2dServiceId(texture_unit);
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint service_id_cube = GetCubeServiceId(texture_unit);
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint service_id_oes = GetOesServiceId(texture_unit);
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint service_id_arb = GetArbServiceId(texture_unit);
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool bind_texture_2d = true;
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool bind_texture_cube = true;
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool bind_texture_oes = feature_info_->feature_flags().oes_egl_image_external;
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool bind_texture_arb = feature_info_->feature_flags().arb_texture_rectangle;
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (prev_state) {
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const TextureUnit& prev_unit = prev_state->texture_units[unit];
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bind_texture_2d = service_id_2d != Get2dServiceId(prev_unit);
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bind_texture_cube = service_id_cube != GetCubeServiceId(prev_unit);
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bind_texture_oes =
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        bind_texture_oes && service_id_oes != GetOesServiceId(prev_unit);
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bind_texture_arb =
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        bind_texture_arb && service_id_arb != GetArbServiceId(prev_unit);
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Early-out if nothing has changed from the previous state.
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!bind_texture_2d && !bind_texture_cube
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      && !bind_texture_oes && !bind_texture_arb) {
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  glActiveTexture(GL_TEXTURE0 + unit);
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (bind_texture_2d) {
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glBindTexture(GL_TEXTURE_2D, service_id_2d);
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (bind_texture_cube) {
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glBindTexture(GL_TEXTURE_CUBE_MAP, service_id_cube);
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (bind_texture_oes) {
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glBindTexture(GL_TEXTURE_EXTERNAL_OES, service_id_oes);
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (bind_texture_arb) {
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, service_id_arb);
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ContextState::RestoreBufferBindings() const {
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (vertex_attrib_manager.get()) {
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Buffer* element_array_buffer =
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        vertex_attrib_manager->element_array_buffer();
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        element_array_buffer ? element_array_buffer->service_id() : 0);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  glBindBuffer(GL_ARRAY_BUFFER,
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)               bound_array_buffer.get() ? bound_array_buffer->service_id() : 0);
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ContextState::RestoreRenderbufferBindings() {
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Require Renderbuffer rebind.
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bound_renderbuffer_valid = false;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ContextState::RestoreProgramBindings() const {
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  glUseProgram(current_program.get() ? current_program->service_id() : 0);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ContextState::RestoreActiveTexture() const {
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  glActiveTexture(GL_TEXTURE0 + active_texture_unit);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ContextState::RestoreAllTextureUnitBindings(
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ContextState* prev_state) const {
179a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Restore Texture state.
180a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  for (size_t ii = 0; ii < texture_units.size(); ++ii) {
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RestoreTextureUnitBindings(ii, prev_state);
182a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
183a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RestoreActiveTexture();
184a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
185a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ContextState::RestoreActiveTextureUnitBinding(unsigned int target) const {
187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_LT(active_texture_unit, texture_units.size());
188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const TextureUnit& texture_unit = texture_units[active_texture_unit];
189effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (TargetIsSupported(feature_info_, target))
190effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    glBindTexture(target, GetServiceId(texture_unit, target));
191effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ContextState::RestoreVertexAttribValues() const {
1940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (size_t attrib = 0; attrib < vertex_attrib_manager->num_attribs();
1950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       ++attrib) {
1960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    glVertexAttrib4fv(attrib, attrib_values[attrib].v);
1970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ContextState::RestoreVertexAttribArrays(
2010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const scoped_refptr<VertexAttribManager> attrib_manager) const {
2020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // This is expected to be called only for VAO with service_id 0,
2030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // either to restore the default VAO or a virtual VAO with service_id 0.
2040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  GLuint vao_service_id = attrib_manager->service_id();
2050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(vao_service_id == 0);
2060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Bind VAO if supported.
2080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (feature_info_->feature_flags().native_vertex_array_object)
2090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    glBindVertexArrayOES(vao_service_id);
2100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Restore vertex attrib arrays.
2120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (size_t attrib_index = 0; attrib_index < attrib_manager->num_attribs();
2130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       ++attrib_index) {
2140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const VertexAttrib* attrib = attrib_manager->GetVertexAttrib(attrib_index);
2150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Restore vertex array.
2170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    Buffer* buffer = attrib->buffer();
2180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    GLuint buffer_service_id = buffer ? buffer->service_id() : 0;
2190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    glBindBuffer(GL_ARRAY_BUFFER, buffer_service_id);
2200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const void* ptr = reinterpret_cast<const void*>(attrib->offset());
2210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    glVertexAttribPointer(attrib_index,
2220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                          attrib->size(),
2230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                          attrib->type(),
2240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                          attrib->normalized(),
2250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                          attrib->gl_stride(),
2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                          ptr);
2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Restore attrib divisor if supported.
2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (feature_info_->feature_flags().angle_instanced_arrays)
2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Never touch vertex attribute 0's state (in particular, never
2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // disable it) when running on desktop GL because it will never be
2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // re-enabled.
2350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (attrib_index != 0 ||
2360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (attrib->enabled()) {
2380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        glEnableVertexAttribArray(attrib_index);
2390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      } else {
2400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        glDisableVertexAttribArray(attrib_index);
2410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      }
2420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
2430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
2450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ContextState::RestoreVertexAttribs() const {
2470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Restore Vertex Attrib Arrays
2480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // TODO: This if should not be needed. RestoreState is getting called
2490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // before GLES2Decoder::Initialize which is a bug.
2500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (vertex_attrib_manager.get()) {
2510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Restore VAOs.
2520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (feature_info_->feature_flags().native_vertex_array_object) {
2530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // If default VAO is still using shared id 0 instead of unique ids
2540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // per-context, default VAO state must be restored.
2550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      GLuint default_vao_service_id =
2560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          default_vertex_attrib_manager->service_id();
2570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (default_vao_service_id == 0)
2580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        RestoreVertexAttribArrays(default_vertex_attrib_manager);
2590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // Restore the current VAO binding, unless it's the same as the
2610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // default above.
2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      GLuint curr_vao_service_id = vertex_attrib_manager->service_id();
2630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (curr_vao_service_id != 0)
2640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        glBindVertexArrayOES(curr_vao_service_id);
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
2660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // If native VAO isn't supported, emulated VAOs are used.
2670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // Restore to the currently bound VAO.
2680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      RestoreVertexAttribArrays(vertex_attrib_manager);
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // glVertexAttrib4fv aren't part of VAO state and must be restored.
2730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RestoreVertexAttribValues();
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ContextState::RestoreGlobalState(const ContextState* prev_state) const {
277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  InitCapabilities(prev_state);
278c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  InitState(prev_state);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
281116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ContextState::RestoreState(const ContextState* prev_state) {
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RestoreAllTextureUnitBindings(prev_state);
2830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RestoreVertexAttribs();
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RestoreBufferBindings();
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RestoreRenderbufferBindings();
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RestoreProgramBindings();
287c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RestoreGlobalState(prev_state);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ErrorState* ContextState::GetErrorState() {
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return error_state_.get();
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Include the auto-generated part of this file. We split this because it means
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we can easily edit the non-auto generated parts right here in this file
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instead of having to edit some template or the code generator.
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/context_state_impl_autogen.h"
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gles2
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
303