blob: deac0a53470df89be79c371c9fa4b6d6b07511c5 [file] [log] [blame]
Avi Drissman05dfbc822022-09-13 21:25:341// Copyright 2012 The Chromium Authors
gman@chromium.orge259eb412012-10-13 05:47:242// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
gman@chromium.orge259eb412012-10-13 05:47:245#include "gpu/command_buffer/service/context_state.h"
6
avif15d60a2015-12-21 17:06:337#include <stddef.h>
8
Peter Kasting3323e082022-10-28 20:56:119#include <algorithm>
kkinnunen337d59632014-08-26 10:19:5710#include <cmath>
Arthur Sonzogni59ac8222023-11-10 09:46:5411#include <optional>
Arthur Sonzogni5bc3326c2024-02-29 19:39:0512
Tom Sepezd8f7cade2025-07-22 16:48:0113#include "base/compiler_specific.h"
Stephen Nuskof4e53402025-07-23 13:39:4414#include "base/containers/span.h"
gman@chromium.orgf731b9462012-10-30 00:35:2215#include "gpu/command_buffer/common/gles2_cmd_utils.h"
gman@chromium.org31494b82013-02-28 10:10:2616#include "gpu/command_buffer/service/buffer_manager.h"
17#include "gpu/command_buffer/service/framebuffer_manager.h"
18#include "gpu/command_buffer/service/program_manager.h"
19#include "gpu/command_buffer/service/renderbuffer_manager.h"
zmo6c468ba2016-05-04 20:00:5120#include "gpu/command_buffer/service/transform_feedback_manager.h"
gman@chromium.org1868a342012-11-07 15:56:0221#include "ui/gl/gl_bindings.h"
22#include "ui/gl/gl_implementation.h"
martina.kollarova5511bade2015-08-06 17:34:1423#include "ui/gl/gl_version_info.h"
gman@chromium.orgf731b9462012-10-30 00:35:2224
gman@chromium.orge259eb412012-10-13 05:47:2425namespace gpu {
26namespace gles2 {
27
gman@chromium.orgf731b9462012-10-30 00:35:2228namespace {
29
kaanb@chromium.org5baa86bc2014-01-16 04:33:1630GLuint Get2dServiceId(const TextureUnit& unit) {
Peng Huangc6a76072018-11-27 23:17:3131 return unit.bound_texture_2d.get() ? unit.bound_texture_2d->service_id() : 0;
kaanb@chromium.org5baa86bc2014-01-16 04:33:1632}
33
Vikas Sonid128139d2018-02-26 11:51:3334GLuint Get2dArrayServiceId(const TextureUnit& unit) {
35 return unit.bound_texture_2d_array.get()
36 ? unit.bound_texture_2d_array->service_id()
37 : 0;
38}
39
40GLuint Get3dServiceId(const TextureUnit& unit) {
41 return unit.bound_texture_3d.get() ? unit.bound_texture_3d->service_id() : 0;
42}
43
kaanb@chromium.org5baa86bc2014-01-16 04:33:1644GLuint GetCubeServiceId(const TextureUnit& unit) {
45 return unit.bound_texture_cube_map.get()
Peng Huangc6a76072018-11-27 23:17:3146 ? unit.bound_texture_cube_map->service_id()
47 : 0;
kaanb@chromium.org5baa86bc2014-01-16 04:33:1648}
49
50GLuint GetOesServiceId(const TextureUnit& unit) {
51 return unit.bound_texture_external_oes.get()
Peng Huangc6a76072018-11-27 23:17:3152 ? unit.bound_texture_external_oes->service_id()
53 : 0;
kaanb@chromium.org5baa86bc2014-01-16 04:33:1654}
55
56GLuint GetArbServiceId(const TextureUnit& unit) {
57 return unit.bound_texture_rectangle_arb.get()
Peng Huangc6a76072018-11-27 23:17:3158 ? unit.bound_texture_rectangle_arb->service_id()
59 : 0;
kaanb@chromium.org5baa86bc2014-01-16 04:33:1660}
61
epenner@chromium.org4b2d2b262014-03-21 22:05:2762GLuint GetServiceId(const TextureUnit& unit, GLuint target) {
63 switch (target) {
64 case GL_TEXTURE_2D:
65 return Get2dServiceId(unit);
66 case GL_TEXTURE_CUBE_MAP:
67 return GetCubeServiceId(unit);
Geoff Lang8fc21cd2025-05-26 13:13:2968 case GL_TEXTURE_RECTANGLE_ANGLE:
epenner@chromium.org4b2d2b262014-03-21 22:05:2769 return GetArbServiceId(unit);
70 case GL_TEXTURE_EXTERNAL_OES:
71 return GetOesServiceId(unit);
72 default:
Peter BostrÃļma11556e2024-10-31 04:49:1073 NOTREACHED();
epenner@chromium.org4b2d2b262014-03-21 22:05:2774 }
75}
76
77bool TargetIsSupported(const FeatureInfo* feature_info, GLuint target) {
78 switch (target) {
79 case GL_TEXTURE_2D:
80 return true;
81 case GL_TEXTURE_CUBE_MAP:
82 return true;
Geoff Lang8fc21cd2025-05-26 13:13:2983 case GL_TEXTURE_RECTANGLE_ANGLE:
epenner@chromium.org4b2d2b262014-03-21 22:05:2784 return feature_info->feature_flags().arb_texture_rectangle;
85 case GL_TEXTURE_EXTERNAL_OES:
jbauman5d9c5ea42016-05-04 22:00:5886 return feature_info->feature_flags().oes_egl_image_external ||
87 feature_info->feature_flags().nv_egl_stream_consumer_external;
epenner@chromium.org4b2d2b262014-03-21 22:05:2788 default:
Peter BostrÃļma11556e2024-10-31 04:49:1089 NOTREACHED();
epenner@chromium.org4b2d2b262014-03-21 22:05:2790 }
91}
92
zmo4c0c3532015-05-22 20:04:4893GLuint GetBufferId(const Buffer* buffer) {
94 if (buffer)
95 return buffer->service_id();
96 return 0;
97}
98
gman@chromium.orgf731b9462012-10-30 00:35:2299} // anonymous namespace.
100
Peng Huangc6a76072018-11-27 23:17:31101TextureUnit::TextureUnit() : bind_target(GL_TEXTURE_2D) {}
gman@chromium.orge259eb412012-10-13 05:47:24102
vmpstr3b7b8b22016-03-01 23:00:20103TextureUnit::TextureUnit(const TextureUnit& other) = default;
104
Chris Watkins81030772017-12-07 01:20:56105TextureUnit::~TextureUnit() = default;
gman@chromium.orge259eb412012-10-13 05:47:24106
zmo5ee097e2015-05-14 19:13:52107bool Vec4::Equal(const Vec4& other) const {
108 if (type_ != other.type_)
109 return false;
110 switch (type_) {
zmoeaae3bb2016-07-15 19:23:19111 case SHADER_VARIABLE_FLOAT:
zmo5ee097e2015-05-14 19:13:52112 for (size_t ii = 0; ii < 4; ++ii) {
113 if (v_[ii].float_value != other.v_[ii].float_value)
114 return false;
115 }
116 break;
zmoeaae3bb2016-07-15 19:23:19117 case SHADER_VARIABLE_INT:
zmo5ee097e2015-05-14 19:13:52118 for (size_t ii = 0; ii < 4; ++ii) {
119 if (v_[ii].int_value != other.v_[ii].int_value)
120 return false;
121 }
122 break;
zmoeaae3bb2016-07-15 19:23:19123 case SHADER_VARIABLE_UINT:
zmo5ee097e2015-05-14 19:13:52124 for (size_t ii = 0; ii < 4; ++ii) {
125 if (v_[ii].uint_value != other.v_[ii].uint_value)
126 return false;
127 }
128 break;
zmoeaae3bb2016-07-15 19:23:19129 default:
Peter BostrÃļma11556e2024-10-31 04:49:10130 NOTREACHED();
zmo5ee097e2015-05-14 19:13:52131 }
132 return true;
133}
134
135template <>
136void Vec4::GetValues<GLfloat>(GLfloat* values) const {
137 DCHECK(values);
138 switch (type_) {
zmoeaae3bb2016-07-15 19:23:19139 case SHADER_VARIABLE_FLOAT:
zmo5ee097e2015-05-14 19:13:52140 for (size_t ii = 0; ii < 4; ++ii)
Tom Sepezd8f7cade2025-07-22 16:48:01141 UNSAFE_TODO(values[ii]) = v_[ii].float_value;
zmo5ee097e2015-05-14 19:13:52142 break;
zmoeaae3bb2016-07-15 19:23:19143 case SHADER_VARIABLE_INT:
zmo5ee097e2015-05-14 19:13:52144 for (size_t ii = 0; ii < 4; ++ii)
Tom Sepezd8f7cade2025-07-22 16:48:01145 UNSAFE_TODO(values[ii]) = static_cast<GLfloat>(v_[ii].int_value);
zmo5ee097e2015-05-14 19:13:52146 break;
zmoeaae3bb2016-07-15 19:23:19147 case SHADER_VARIABLE_UINT:
zmo5ee097e2015-05-14 19:13:52148 for (size_t ii = 0; ii < 4; ++ii)
Tom Sepezd8f7cade2025-07-22 16:48:01149 UNSAFE_TODO(values[ii]) = static_cast<GLfloat>(v_[ii].uint_value);
zmo5ee097e2015-05-14 19:13:52150 break;
zmoeaae3bb2016-07-15 19:23:19151 default:
Peter BostrÃļma11556e2024-10-31 04:49:10152 NOTREACHED();
zmo5ee097e2015-05-14 19:13:52153 }
154}
155
156template <>
157void Vec4::GetValues<GLint>(GLint* values) const {
158 DCHECK(values);
159 switch (type_) {
zmoeaae3bb2016-07-15 19:23:19160 case SHADER_VARIABLE_FLOAT:
zmo5ee097e2015-05-14 19:13:52161 for (size_t ii = 0; ii < 4; ++ii)
Tom Sepezd8f7cade2025-07-22 16:48:01162 UNSAFE_TODO(values[ii]) = static_cast<GLint>(v_[ii].float_value);
zmo5ee097e2015-05-14 19:13:52163 break;
zmoeaae3bb2016-07-15 19:23:19164 case SHADER_VARIABLE_INT:
zmo5ee097e2015-05-14 19:13:52165 for (size_t ii = 0; ii < 4; ++ii)
Tom Sepezd8f7cade2025-07-22 16:48:01166 UNSAFE_TODO(values[ii]) = v_[ii].int_value;
zmo5ee097e2015-05-14 19:13:52167 break;
zmoeaae3bb2016-07-15 19:23:19168 case SHADER_VARIABLE_UINT:
zmo5ee097e2015-05-14 19:13:52169 for (size_t ii = 0; ii < 4; ++ii)
Tom Sepezd8f7cade2025-07-22 16:48:01170 UNSAFE_TODO(values[ii]) = static_cast<GLint>(v_[ii].uint_value);
zmo5ee097e2015-05-14 19:13:52171 break;
zmoeaae3bb2016-07-15 19:23:19172 default:
Peter BostrÃļma11556e2024-10-31 04:49:10173 NOTREACHED();
zmo5ee097e2015-05-14 19:13:52174 }
175}
176
Peng Huangc6a76072018-11-27 23:17:31177template <>
zmo5ee097e2015-05-14 19:13:52178void Vec4::GetValues<GLuint>(GLuint* values) const {
179 DCHECK(values);
180 switch (type_) {
zmoeaae3bb2016-07-15 19:23:19181 case SHADER_VARIABLE_FLOAT:
zmo5ee097e2015-05-14 19:13:52182 for (size_t ii = 0; ii < 4; ++ii)
Tom Sepezd8f7cade2025-07-22 16:48:01183 UNSAFE_TODO(values[ii]) = static_cast<GLuint>(v_[ii].float_value);
zmo5ee097e2015-05-14 19:13:52184 break;
zmoeaae3bb2016-07-15 19:23:19185 case SHADER_VARIABLE_INT:
zmo5ee097e2015-05-14 19:13:52186 for (size_t ii = 0; ii < 4; ++ii)
Tom Sepezd8f7cade2025-07-22 16:48:01187 UNSAFE_TODO(values[ii]) = static_cast<GLuint>(v_[ii].int_value);
zmo5ee097e2015-05-14 19:13:52188 break;
zmoeaae3bb2016-07-15 19:23:19189 case SHADER_VARIABLE_UINT:
zmo5ee097e2015-05-14 19:13:52190 for (size_t ii = 0; ii < 4; ++ii)
Tom Sepezd8f7cade2025-07-22 16:48:01191 UNSAFE_TODO(values[ii]) = v_[ii].uint_value;
zmo5ee097e2015-05-14 19:13:52192 break;
zmoeaae3bb2016-07-15 19:23:19193 default:
Peter BostrÃļma11556e2024-10-31 04:49:10194 NOTREACHED();
zmo5ee097e2015-05-14 19:13:52195 }
196}
197
198template <>
199void Vec4::SetValues<GLfloat>(const GLfloat* values) {
200 DCHECK(values);
201 for (size_t ii = 0; ii < 4; ++ii)
Tom Sepezd8f7cade2025-07-22 16:48:01202 v_[ii].float_value = UNSAFE_TODO(values[ii]);
zmoeaae3bb2016-07-15 19:23:19203 type_ = SHADER_VARIABLE_FLOAT;
zmo5ee097e2015-05-14 19:13:52204}
205
206template <>
207void Vec4::SetValues<GLint>(const GLint* values) {
208 DCHECK(values);
209 for (size_t ii = 0; ii < 4; ++ii)
Tom Sepezd8f7cade2025-07-22 16:48:01210 v_[ii].int_value = UNSAFE_TODO(values[ii]);
zmoeaae3bb2016-07-15 19:23:19211 type_ = SHADER_VARIABLE_INT;
zmo5ee097e2015-05-14 19:13:52212}
213
214template <>
215void Vec4::SetValues<GLuint>(const GLuint* values) {
216 DCHECK(values);
217 for (size_t ii = 0; ii < 4; ++ii)
Tom Sepezd8f7cade2025-07-22 16:48:01218 v_[ii].uint_value = UNSAFE_TODO(values[ii]);
zmoeaae3bb2016-07-15 19:23:19219 type_ = SHADER_VARIABLE_UINT;
zmo5ee097e2015-05-14 19:13:52220}
221
danakj@chromium.org828a3932014-04-02 14:43:13222ContextState::ContextState(FeatureInfo* feature_info,
Peng Huangc6a76072018-11-27 23:17:31223 bool track_texture_and_sampler_units)
224 : track_texture_and_sampler_units(track_texture_and_sampler_units),
Peng Huangb4ed1852018-12-05 03:35:29225 feature_info_(feature_info) {
gman@chromium.orgf731b9462012-10-30 00:35:22226 Initialize();
gman@chromium.orge259eb412012-10-13 05:47:24227}
228
Chris Watkins81030772017-12-07 01:20:56229ContextState::~ContextState() = default;
gman@chromium.orge259eb412012-10-13 05:47:24230
lof84d5e36962016-11-10 00:35:54231void ContextState::SetLineWidthBounds(GLfloat min, GLfloat max) {
232 line_width_min_ = min;
233 line_width_max_ = max;
234}
235
kaanb@chromium.org5baa86bc2014-01-16 04:33:16236void ContextState::RestoreTextureUnitBindings(
Peng Huangc6a76072018-11-27 23:17:31237 GLuint unit,
238 const ContextState* prev_state) const {
239 DCHECK(unit < texture_units.size() ||
240 (unit == 0 && !track_texture_and_sampler_units));
241
242 GLuint service_id_2d = 0u;
243 GLuint service_id_2d_array = 0u;
244 GLuint service_id_3d = 0u;
245 GLuint service_id_cube = 0u;
246 GLuint service_id_oes = 0u;
247 GLuint service_id_arb = 0u;
248
249 if (track_texture_and_sampler_units) {
250 const TextureUnit& texture_unit = texture_units[unit];
251 service_id_2d = Get2dServiceId(texture_unit);
252 service_id_2d_array = Get2dArrayServiceId(texture_unit);
253 service_id_3d = Get3dServiceId(texture_unit);
254 service_id_cube = GetCubeServiceId(texture_unit);
255 service_id_oes = GetOesServiceId(texture_unit);
256 service_id_arb = GetArbServiceId(texture_unit);
257 }
gman@chromium.org29a4d902013-02-26 20:18:06258
kaanb@chromium.org5baa86bc2014-01-16 04:33:16259 bool bind_texture_2d = true;
260 bool bind_texture_cube = true;
jbauman5d9c5ea42016-05-04 22:00:58261 bool bind_texture_oes =
262 feature_info_->feature_flags().oes_egl_image_external ||
263 feature_info_->feature_flags().nv_egl_stream_consumer_external;
kaanb@chromium.org5baa86bc2014-01-16 04:33:16264 bool bind_texture_arb = feature_info_->feature_flags().arb_texture_rectangle;
Vikas Sonid128139d2018-02-26 11:51:33265 // TEXTURE_2D_ARRAY and TEXTURE_3D are only applicable from ES3 version.
266 // So set it to FALSE by default.
267 bool bind_texture_2d_array = false;
268 bool bind_texture_3d = false;
269 // set the variables to true only if the application is ES3 or newer
270 if (feature_info_->IsES3Capable()) {
271 bind_texture_2d_array = true;
272 bind_texture_3d = true;
273 }
kaanb@chromium.org5baa86bc2014-01-16 04:33:16274
275 if (prev_state) {
Peng Huangc6a76072018-11-27 23:17:31276 if (prev_state->track_texture_and_sampler_units) {
277 const TextureUnit& prev_unit = prev_state->texture_units[unit];
278 bind_texture_2d = service_id_2d != Get2dServiceId(prev_unit);
279 bind_texture_2d_array =
280 bind_texture_2d_array &&
281 service_id_2d_array != Get2dArrayServiceId(prev_unit);
282 bind_texture_3d =
283 bind_texture_3d && service_id_3d != Get3dServiceId(prev_unit);
284 bind_texture_cube = service_id_cube != GetCubeServiceId(prev_unit);
285 bind_texture_oes =
286 bind_texture_oes && service_id_oes != GetOesServiceId(prev_unit);
287 bind_texture_arb =
288 bind_texture_arb && service_id_arb != GetArbServiceId(prev_unit);
289 } else if (prev_state->texture_units_in_ground_state) {
290 bind_texture_2d = service_id_2d;
291 bind_texture_2d_array = bind_texture_2d_array && service_id_2d_array;
292 bind_texture_3d = bind_texture_3d && service_id_3d;
293 bind_texture_cube = service_id_cube;
294 bind_texture_oes = bind_texture_oes && service_id_oes;
295 bind_texture_arb = bind_texture_arb && service_id_arb;
296 } else {
297 // We need bind all restore target binding, if texture units is not in
298 // ground state.
299 }
gman@chromium.org29a4d902013-02-26 20:18:06300 }
301
kaanb@chromium.org5baa86bc2014-01-16 04:33:16302 // Early-out if nothing has changed from the previous state.
Vikas Sonid128139d2018-02-26 11:51:33303 if (!bind_texture_2d && !bind_texture_2d_array && !bind_texture_3d &&
304 !bind_texture_cube && !bind_texture_oes && !bind_texture_arb) {
kaanb@chromium.org5baa86bc2014-01-16 04:33:16305 return;
306 }
307
Antoine Labour2c1ad962017-10-24 23:32:56308 api()->glActiveTextureFn(GL_TEXTURE0 + unit);
kaanb@chromium.org5baa86bc2014-01-16 04:33:16309 if (bind_texture_2d) {
Antoine Labour2c1ad962017-10-24 23:32:56310 api()->glBindTextureFn(GL_TEXTURE_2D, service_id_2d);
kaanb@chromium.org5baa86bc2014-01-16 04:33:16311 }
312 if (bind_texture_cube) {
Antoine Labour2c1ad962017-10-24 23:32:56313 api()->glBindTextureFn(GL_TEXTURE_CUBE_MAP, service_id_cube);
kaanb@chromium.org5baa86bc2014-01-16 04:33:16314 }
315 if (bind_texture_oes) {
Antoine Labour2c1ad962017-10-24 23:32:56316 api()->glBindTextureFn(GL_TEXTURE_EXTERNAL_OES, service_id_oes);
kaanb@chromium.org5baa86bc2014-01-16 04:33:16317 }
318 if (bind_texture_arb) {
Geoff Lang8fc21cd2025-05-26 13:13:29319 api()->glBindTextureFn(GL_TEXTURE_RECTANGLE_ANGLE, service_id_arb);
gman@chromium.org29a4d902013-02-26 20:18:06320 }
Vikas Sonid128139d2018-02-26 11:51:33321 if (bind_texture_2d_array) {
322 api()->glBindTextureFn(GL_TEXTURE_2D_ARRAY, service_id_2d_array);
323 }
324 if (bind_texture_3d) {
325 api()->glBindTextureFn(GL_TEXTURE_3D, service_id_3d);
326 }
Peng Huangc6a76072018-11-27 23:17:31327} // namespace gles2
gman@chromium.org29a4d902013-02-26 20:18:06328
kbr69c721ec2017-04-26 23:58:51329void ContextState::RestoreSamplerBinding(GLuint unit,
330 const ContextState* prev_state) const {
331 if (!feature_info_->IsES3Capable())
332 return;
Peng Huangfc7df8d2020-04-14 20:49:09333
334 GLuint cur_id = 0u;
Peng Huangb03e05c2020-04-15 21:03:07335 if (const auto& cur_sampler = sampler_units[unit])
336 cur_id = cur_sampler->service_id();
Peng Huangfc7df8d2020-04-14 20:49:09337
Arthur Sonzogni59ac8222023-11-10 09:46:54338 std::optional<GLuint> prev_id;
Bo Liu764ca6652025-03-04 21:46:46339 if (prev_state && unit < prev_state->sampler_units.size()) {
Peng Huangb03e05c2020-04-15 21:03:07340 const auto& prev_sampler = prev_state->sampler_units[unit];
341 prev_id.emplace(prev_sampler ? prev_sampler->service_id() : 0);
Peng Huangfc7df8d2020-04-14 20:49:09342 }
343
344 if (!prev_id || cur_id != *prev_id)
Antoine Labour2c1ad962017-10-24 23:32:56345 api()->glBindSamplerFn(unit, cur_id);
kbr69c721ec2017-04-26 23:58:51346}
347
Zhenyao Mo5f72df0c2017-12-08 21:46:26348void ContextState::PushTextureUnpackState() const {
Antoine Labour2c1ad962017-10-24 23:32:56349 api()->glPixelStoreiFn(GL_UNPACK_ALIGNMENT, 1);
geofflang398fb212016-07-13 16:27:42350
351 if (bound_pixel_unpack_buffer.get()) {
Antoine Labour2c1ad962017-10-24 23:32:56352 api()->glBindBufferFn(GL_PIXEL_UNPACK_BUFFER, 0);
353 api()->glPixelStoreiFn(GL_UNPACK_ROW_LENGTH, 0);
354 api()->glPixelStoreiFn(GL_UNPACK_IMAGE_HEIGHT, 0);
Zhenyao Mo5f72df0c2017-12-08 21:46:26355 DCHECK_EQ(0, unpack_skip_pixels);
356 DCHECK_EQ(0, unpack_skip_rows);
357 DCHECK_EQ(0, unpack_skip_images);
geofflang398fb212016-07-13 16:27:42358 }
359}
360
361void ContextState::RestoreUnpackState() const {
Antoine Labour2c1ad962017-10-24 23:32:56362 api()->glPixelStoreiFn(GL_UNPACK_ALIGNMENT, unpack_alignment);
geofflang398fb212016-07-13 16:27:42363 if (bound_pixel_unpack_buffer.get()) {
Antoine Labour2c1ad962017-10-24 23:32:56364 api()->glBindBufferFn(GL_PIXEL_UNPACK_BUFFER,
365 GetBufferId(bound_pixel_unpack_buffer.get()));
366 api()->glPixelStoreiFn(GL_UNPACK_ROW_LENGTH, unpack_row_length);
367 api()->glPixelStoreiFn(GL_UNPACK_IMAGE_HEIGHT, unpack_image_height);
geofflang398fb212016-07-13 16:27:42368 }
369}
370
lof84d5e36962016-11-10 00:35:54371void ContextState::DoLineWidth(GLfloat width) const {
Ho Cheungc878a572023-04-24 09:42:59372 api()->glLineWidthFn(std::clamp(width, line_width_min_, line_width_max_));
lof84d5e36962016-11-10 00:35:54373}
374
gman@chromium.org29a4d902013-02-26 20:18:06375void ContextState::RestoreBufferBindings() const {
rsleevi@chromium.org7cd76fd2013-06-02 21:11:11376 if (vertex_attrib_manager.get()) {
gman@chromium.org16ccec12013-02-28 03:40:21377 Buffer* element_array_buffer =
gman@chromium.org29a4d902013-02-26 20:18:06378 vertex_attrib_manager->element_array_buffer();
Antoine Labour2c1ad962017-10-24 23:32:56379 api()->glBindBufferFn(GL_ELEMENT_ARRAY_BUFFER,
380 GetBufferId(element_array_buffer));
gman@chromium.org29a4d902013-02-26 20:18:06381 }
Antoine Labour2c1ad962017-10-24 23:32:56382 api()->glBindBufferFn(GL_ARRAY_BUFFER, GetBufferId(bound_array_buffer.get()));
bajonesb6964e62015-09-01 18:27:25383 if (feature_info_->IsES3Capable()) {
Antoine Labour2c1ad962017-10-24 23:32:56384 api()->glBindBufferFn(GL_COPY_READ_BUFFER,
385 GetBufferId(bound_copy_read_buffer.get()));
386 api()->glBindBufferFn(GL_COPY_WRITE_BUFFER,
387 GetBufferId(bound_copy_write_buffer.get()));
388 api()->glBindBufferFn(GL_PIXEL_PACK_BUFFER,
389 GetBufferId(bound_pixel_pack_buffer.get()));
zmocdfe65d2015-12-02 17:35:56390 UpdatePackParameters();
Antoine Labour2c1ad962017-10-24 23:32:56391 api()->glBindBufferFn(GL_PIXEL_UNPACK_BUFFER,
392 GetBufferId(bound_pixel_unpack_buffer.get()));
zmocdfe65d2015-12-02 17:35:56393 UpdateUnpackParameters();
Antoine Labour2c1ad962017-10-24 23:32:56394 api()->glBindBufferFn(GL_TRANSFORM_FEEDBACK_BUFFER,
395 GetBufferId(bound_transform_feedback_buffer.get()));
396 api()->glBindBufferFn(GL_UNIFORM_BUFFER,
397 GetBufferId(bound_uniform_buffer.get()));
zmo4c0c3532015-05-22 20:04:48398 }
gman@chromium.org29a4d902013-02-26 20:18:06399}
400
vmiura@chromium.org8875a5f2014-06-27 08:33:47401void ContextState::RestoreRenderbufferBindings() {
402 // Require Renderbuffer rebind.
403 bound_renderbuffer_valid = false;
gman@chromium.org29a4d902013-02-26 20:18:06404}
405
zmo744d40e2016-05-10 20:56:22406void ContextState::RestoreProgramSettings(
407 const ContextState* prev_state,
408 bool restore_transform_feedback_bindings) const {
Peng Huangc6a76072018-11-27 23:17:31409 bool flag =
410 (restore_transform_feedback_bindings && feature_info_->IsES3Capable());
zmo744d40e2016-05-10 20:56:22411 if (flag && prev_state) {
zmo6c468ba2016-05-04 20:00:51412 if (prev_state->bound_transform_feedback.get() &&
413 prev_state->bound_transform_feedback->active() &&
414 !prev_state->bound_transform_feedback->paused()) {
Antoine Labour2c1ad962017-10-24 23:32:56415 api()->glPauseTransformFeedbackFn();
zmo6c468ba2016-05-04 20:00:51416 }
417 }
Antoine Labour2c1ad962017-10-24 23:32:56418 api()->glUseProgramFn(current_program.get() ? current_program->service_id()
419 : 0);
zmo744d40e2016-05-10 20:56:22420 if (flag) {
421 if (bound_transform_feedback.get()) {
James Darpinian61c71162018-03-09 23:25:42422 bound_transform_feedback->DoBindTransformFeedback(
James Darpinianc1648312018-03-10 01:54:05423 GL_TRANSFORM_FEEDBACK, bound_transform_feedback.get(),
424 bound_transform_feedback_buffer.get());
zmo744d40e2016-05-10 20:56:22425 } else {
Antoine Labour2c1ad962017-10-24 23:32:56426 api()->glBindTransformFeedbackFn(GL_TRANSFORM_FEEDBACK, 0);
zmo744d40e2016-05-10 20:56:22427 }
zmo6c468ba2016-05-04 20:00:51428 }
429}
430
zmo48ee6d3f2016-05-06 20:33:26431void ContextState::RestoreIndexedUniformBufferBindings(
432 const ContextState* prev_state) {
433 if (!feature_info_->IsES3Capable())
434 return;
435 indexed_uniform_buffer_bindings->RestoreBindings(
436 prev_state ? prev_state->indexed_uniform_buffer_bindings.get() : nullptr);
437}
438
gman@chromium.org29a4d902013-02-26 20:18:06439void ContextState::RestoreActiveTexture() const {
Antoine Labour2c1ad962017-10-24 23:32:56440 api()->glActiveTextureFn(GL_TEXTURE0 + active_texture_unit);
gman@chromium.org29a4d902013-02-26 20:18:06441}
442
kbr69c721ec2017-04-26 23:58:51443void ContextState::RestoreAllTextureUnitAndSamplerBindings(
kaanb@chromium.org5baa86bc2014-01-16 04:33:16444 const ContextState* prev_state) const {
Peng Huangc6a76072018-11-27 23:17:31445 if (!track_texture_and_sampler_units) {
446 if (prev_state) {
447 if (!prev_state->track_texture_and_sampler_units) {
448 texture_units_in_ground_state =
449 prev_state->texture_units_in_ground_state;
Peng Huangc6a76072018-11-27 23:17:31450 return;
451 }
452
453 texture_units_in_ground_state = true;
454 for (size_t i = 1; i < prev_state->texture_units.size(); ++i) {
455 if (prev_state->texture_units[i].AnyTargetBound()) {
456 texture_units_in_ground_state = false;
457 break;
458 }
459 }
Peng Huangb03e05c2020-04-15 21:03:07460
461 // Make sure all texture units are in ground state, we need to reset the
462 // 0th texture units. If some of non zero textures aren't in ground state,
463 // when another context is being make current, we will restore all texture
464 // units, then it is not necessary to reset the 0th texture units anymore.
465 if (texture_units_in_ground_state)
466 RestoreTextureUnitBindings(0, prev_state);
Peng Huangc6a76072018-11-27 23:17:31467 } else {
468 texture_units_in_ground_state = false;
Peng Huangc6a76072018-11-27 23:17:31469 }
Peng Huangb03e05c2020-04-15 21:03:07470
471 // GrContext is not aware of sampler objects and skia will not restore them,
472 // so we need to reset them to ground state.
473 // TODO(penghuang): Remove it when GrContext is created for ES 3.0.
474 for (size_t i = 0; i < sampler_units.size(); ++i)
475 RestoreSamplerBinding(i, prev_state);
Peng Huangc6a76072018-11-27 23:17:31476 } else {
477 // Restore Texture state.
478 for (size_t i = 0; i < texture_units.size(); ++i) {
479 RestoreTextureUnitBindings(i, prev_state);
480 RestoreSamplerBinding(i, prev_state);
481 }
482 RestoreActiveTexture();
backer@chromium.org217004512013-05-10 21:25:55483 }
backer@chromium.org217004512013-05-10 21:25:55484}
485
epenner@chromium.org4b2d2b262014-03-21 22:05:27486void ContextState::RestoreActiveTextureUnitBinding(unsigned int target) const {
Peng Huangc6a76072018-11-27 23:17:31487 DCHECK(active_texture_unit < texture_units.size() ||
488 (active_texture_unit == 0 && !track_texture_and_sampler_units));
489 GLuint service_id = 0;
490 if (track_texture_and_sampler_units) {
491 const TextureUnit& texture_unit = texture_units[active_texture_unit];
492 service_id = GetServiceId(texture_unit, target);
493 }
epenner@chromium.org4b2d2b262014-03-21 22:05:27494 if (TargetIsSupported(feature_info_, target))
Peng Huangc6a76072018-11-27 23:17:31495 api()->glBindTextureFn(target, service_id);
epenner@chromium.org4b2d2b262014-03-21 22:05:27496}
497
vmiura@chromium.org81f20a622014-04-18 01:54:52498void ContextState::RestoreVertexAttribValues() const {
499 for (size_t attrib = 0; attrib < vertex_attrib_manager->num_attribs();
500 ++attrib) {
zmo5ee097e2015-05-14 19:13:52501 switch (attrib_values[attrib].type()) {
Peng Huangc6a76072018-11-27 23:17:31502 case SHADER_VARIABLE_FLOAT: {
503 GLfloat v[4];
504 attrib_values[attrib].GetValues(v);
505 api()->glVertexAttrib4fvFn(attrib, v);
506 } break;
507 case SHADER_VARIABLE_INT: {
508 GLint v[4];
509 attrib_values[attrib].GetValues(v);
510 api()->glVertexAttribI4ivFn(attrib, v);
511 } break;
512 case SHADER_VARIABLE_UINT: {
513 GLuint v[4];
514 attrib_values[attrib].GetValues(v);
515 api()->glVertexAttribI4uivFn(attrib, v);
516 } break;
zmoeaae3bb2016-07-15 19:23:19517 default:
Peter BostrÃļma11556e2024-10-31 04:49:10518 NOTREACHED();
zmo5ee097e2015-05-14 19:13:52519 }
vmiura@chromium.org81f20a622014-04-18 01:54:52520 }
521}
522
523void ContextState::RestoreVertexAttribArrays(
524 const scoped_refptr<VertexAttribManager> attrib_manager) const {
525 // This is expected to be called only for VAO with service_id 0,
526 // either to restore the default VAO or a virtual VAO with service_id 0.
527 GLuint vao_service_id = attrib_manager->service_id();
528 DCHECK(vao_service_id == 0);
529
530 // Bind VAO if supported.
531 if (feature_info_->feature_flags().native_vertex_array_object)
Antoine Labour2c1ad962017-10-24 23:32:56532 api()->glBindVertexArrayOESFn(vao_service_id);
vmiura@chromium.org81f20a622014-04-18 01:54:52533
534 // Restore vertex attrib arrays.
535 for (size_t attrib_index = 0; attrib_index < attrib_manager->num_attribs();
536 ++attrib_index) {
537 const VertexAttrib* attrib = attrib_manager->GetVertexAttrib(attrib_index);
538
539 // Restore vertex array.
540 Buffer* buffer = attrib->buffer();
541 GLuint buffer_service_id = buffer ? buffer->service_id() : 0;
Antoine Labour2c1ad962017-10-24 23:32:56542 api()->glBindBufferFn(GL_ARRAY_BUFFER, buffer_service_id);
vmiura@chromium.org81f20a622014-04-18 01:54:52543 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
Antoine Labour2c1ad962017-10-24 23:32:56544 api()->glVertexAttribPointerFn(attrib_index, attrib->size(), attrib->type(),
545 attrib->normalized(), attrib->gl_stride(),
546 ptr);
vmiura@chromium.org81f20a622014-04-18 01:54:52547
548 // Restore attrib divisor if supported.
549 if (feature_info_->feature_flags().angle_instanced_arrays)
Antoine Labour2c1ad962017-10-24 23:32:56550 api()->glVertexAttribDivisorANGLEFn(attrib_index, attrib->divisor());
vmiura@chromium.org81f20a622014-04-18 01:54:52551
Kai Ninomiya1f98b982017-08-29 16:49:49552 if (attrib->enabled_in_driver()) {
Antoine Labour2c1ad962017-10-24 23:32:56553 api()->glEnableVertexAttribArrayFn(attrib_index);
Kai Ninomiya1f98b982017-08-29 16:49:49554 } else {
Antoine Labour2c1ad962017-10-24 23:32:56555 api()->glDisableVertexAttribArrayFn(attrib_index);
gman@chromium.org29a4d902013-02-26 20:18:06556 }
557 }
vmiura@chromium.org81f20a622014-04-18 01:54:52558}
559
Zhenyao Mo22a5f662018-04-17 00:33:55560void ContextState::RestoreVertexAttribs(const ContextState* prev_state) const {
vmiura@chromium.org81f20a622014-04-18 01:54:52561 // Restore Vertex Attrib Arrays
zmofe1d1582016-01-22 21:11:56562 DCHECK(vertex_attrib_manager.get());
563 // Restore VAOs.
564 if (feature_info_->feature_flags().native_vertex_array_object) {
565 // If default VAO is still using shared id 0 instead of unique ids
566 // per-context, default VAO state must be restored.
Peng Huangc6a76072018-11-27 23:17:31567 GLuint default_vao_service_id = default_vertex_attrib_manager->service_id();
zmofe1d1582016-01-22 21:11:56568 if (default_vao_service_id == 0)
569 RestoreVertexAttribArrays(default_vertex_attrib_manager);
vmiura@chromium.org81f20a622014-04-18 01:54:52570
zmofe1d1582016-01-22 21:11:56571 // Restore the current VAO binding, unless it's the same as the
572 // default above.
573 GLuint curr_vao_service_id = vertex_attrib_manager->service_id();
574 if (curr_vao_service_id != 0)
Antoine Labour2c1ad962017-10-24 23:32:56575 api()->glBindVertexArrayOESFn(curr_vao_service_id);
zmofe1d1582016-01-22 21:11:56576 } else {
Zhenyao Mo22a5f662018-04-17 00:33:55577 if (prev_state &&
578 prev_state->feature_info_->feature_flags().native_vertex_array_object &&
579 feature_info_->workarounds()
580 .use_client_side_arrays_for_stream_buffers) {
581 // In order to use client side arrays, the driver's default VAO has to be
582 // bound.
583 api()->glBindVertexArrayOESFn(0);
584 }
zmofe1d1582016-01-22 21:11:56585 // If native VAO isn't supported, emulated VAOs are used.
586 // Restore to the currently bound VAO.
587 RestoreVertexAttribArrays(vertex_attrib_manager);
vmiura@chromium.org81f20a622014-04-18 01:54:52588 }
589
590 // glVertexAttrib4fv aren't part of VAO state and must be restored.
591 RestoreVertexAttribValues();
gman@chromium.org29a4d902013-02-26 20:18:06592}
593
vmiura@chromium.org88ba52f2014-04-09 12:39:34594void ContextState::RestoreGlobalState(const ContextState* prev_state) const {
595 InitCapabilities(prev_state);
596 InitState(prev_state);
gman@chromium.org29a4d902013-02-26 20:18:06597}
gman@chromium.org1868a342012-11-07 15:56:02598
vmiura@chromium.org8875a5f2014-06-27 08:33:47599void ContextState::RestoreState(const ContextState* prev_state) {
kbr69c721ec2017-04-26 23:58:51600 RestoreAllTextureUnitAndSamplerBindings(prev_state);
Peng Huang83884c42018-11-14 00:16:06601 // For RasterDecoder, |vertex_attrib_manager| will be nullptr, and we don't
602 // need restore vertex attribs for them.
603 if (vertex_attrib_manager)
604 RestoreVertexAttribs(prev_state);
Kai Ninomiya6400c722017-05-17 21:17:20605 // RestoreIndexedUniformBufferBindings must be called before
606 // RestoreBufferBindings. This is because setting the indexed uniform buffer
607 // bindings via glBindBuffer{Base,Range} also sets the general uniform buffer
608 // bindings (glBindBuffer), but not vice versa.
Peng Huangc52da3652018-11-15 12:57:49609 // For RasterDecoder, |indexed_uniform_buffer_bindings| will be nullptr, and
610 // we don't need restore indexed uniform buffer for them.
611 if (indexed_uniform_buffer_bindings)
612 RestoreIndexedUniformBufferBindings(prev_state);
gman@chromium.org15cc23fa2013-02-26 21:56:25613 RestoreBufferBindings();
gman@chromium.org29a4d902013-02-26 20:18:06614 RestoreRenderbufferBindings();
zmo744d40e2016-05-10 20:56:22615 RestoreProgramSettings(prev_state, true);
vmiura@chromium.org88ba52f2014-04-09 12:39:34616 RestoreGlobalState(prev_state);
zmo0ed71922016-06-23 01:18:42617
ccameronddaa56a2016-12-02 04:05:46618 // FRAMEBUFFER_SRGB will be restored lazily at render time.
619 framebuffer_srgb_valid_ = false;
gman@chromium.org1868a342012-11-07 15:56:02620}
621
zmo8ac3bab2015-04-18 02:30:58622void ContextState::EnableDisable(GLenum pname, bool enable) const {
yunchao.he56aae832016-03-30 08:32:32623 if (pname == GL_PRIMITIVE_RESTART_FIXED_INDEX &&
624 feature_info_->feature_flags().emulate_primitive_restart_fixed_index) {
625 // GLES2DecoderImpl::DoDrawElements can handle this situation
626 return;
zmo8ac3bab2015-04-18 02:30:58627 }
628 if (enable) {
Antoine Labour2c1ad962017-10-24 23:32:56629 api()->glEnableFn(pname);
zmo8ac3bab2015-04-18 02:30:58630 } else {
Antoine Labour2c1ad962017-10-24 23:32:56631 api()->glDisableFn(pname);
zmo8ac3bab2015-04-18 02:30:58632 }
633}
634
zmocdfe65d2015-12-02 17:35:56635void ContextState::UpdatePackParameters() const {
636 if (!feature_info_->IsES3Capable())
637 return;
638 if (bound_pixel_pack_buffer.get()) {
Antoine Labour2c1ad962017-10-24 23:32:56639 api()->glPixelStoreiFn(GL_PACK_ROW_LENGTH, pack_row_length);
zmocdfe65d2015-12-02 17:35:56640 } else {
Antoine Labour2c1ad962017-10-24 23:32:56641 api()->glPixelStoreiFn(GL_PACK_ROW_LENGTH, 0);
zmocdfe65d2015-12-02 17:35:56642 }
643}
644
Kai Ninomiyabcbefdab2017-11-03 19:57:27645void ContextState::SetMaxWindowRectangles(size_t max) {
646 window_rectangles_ = std::vector<GLint>(max * 4, 0);
647}
648
649size_t ContextState::GetMaxWindowRectangles() const {
650 size_t size = window_rectangles_.size();
651 DCHECK_EQ(0ull, size % 4);
652 return size / 4;
653}
654
Stephen Nuskof4e53402025-07-23 13:39:44655void ContextState::SetWindowRectangles(
656 GLenum mode,
657 size_t spanification_suspected_redundant_count,
658 base::span<const volatile GLint> box) {
659 // TODO(crbug.com/431824301): Remove unneeded parameter once validated to be
660 // redundant in M143.
661 CHECK(spanification_suspected_redundant_count == box.size() / 4,
662 base::NotFatalUntil::M143);
663 CHECK(box.size() % 4 == 0, base::NotFatalUntil::M143);
Kai Ninomiyabcbefdab2017-11-03 19:57:27664 window_rectangles_mode = mode;
Stephen Nuskof4e53402025-07-23 13:39:44665 num_window_rectangles = spanification_suspected_redundant_count;
666 DCHECK_LE(spanification_suspected_redundant_count, GetMaxWindowRectangles());
667 if (spanification_suspected_redundant_count) {
668 std::copy(box.data(),
669 box.subspan(spanification_suspected_redundant_count * 4).data(),
670 window_rectangles_.begin());
Kai Ninomiyabcbefdab2017-11-03 19:57:27671 }
672}
673
674void ContextState::UpdateWindowRectangles() const {
675 if (!feature_info_->feature_flags().ext_window_rectangles) {
676 return;
677 }
678
679 if (current_draw_framebuffer_client_id == 0) {
680 // Window rectangles must not take effect for client_id 0 (backbuffer).
681 api()->glWindowRectanglesEXTFn(GL_EXCLUSIVE_EXT, 0, nullptr);
682 } else {
683 DCHECK_LE(static_cast<size_t>(num_window_rectangles),
684 GetMaxWindowRectangles());
685 const GLint* data =
686 num_window_rectangles ? window_rectangles_.data() : nullptr;
687 api()->glWindowRectanglesEXTFn(window_rectangles_mode,
688 num_window_rectangles, data);
689 }
690}
691
692void ContextState::UpdateWindowRectanglesForBoundDrawFramebufferClientID(
693 GLuint client_id) {
694 bool old_id_nonzero = current_draw_framebuffer_client_id != 0;
695 bool new_id_nonzero = client_id != 0;
696 current_draw_framebuffer_client_id = client_id;
697 // If switching from FBO to backbuffer, or vice versa, update driver state.
698 if (old_id_nonzero ^ new_id_nonzero) {
699 UpdateWindowRectangles();
700 }
701}
702
zmocdfe65d2015-12-02 17:35:56703void ContextState::UpdateUnpackParameters() const {
704 if (!feature_info_->IsES3Capable())
705 return;
706 if (bound_pixel_unpack_buffer.get()) {
Antoine Labour2c1ad962017-10-24 23:32:56707 api()->glPixelStoreiFn(GL_UNPACK_ROW_LENGTH, unpack_row_length);
708 api()->glPixelStoreiFn(GL_UNPACK_IMAGE_HEIGHT, unpack_image_height);
zmocdfe65d2015-12-02 17:35:56709 } else {
Antoine Labour2c1ad962017-10-24 23:32:56710 api()->glPixelStoreiFn(GL_UNPACK_ROW_LENGTH, 0);
711 api()->glPixelStoreiFn(GL_UNPACK_IMAGE_HEIGHT, 0);
zmocdfe65d2015-12-02 17:35:56712 }
713}
714
zmo4c0c3532015-05-22 20:04:48715void ContextState::SetBoundBuffer(GLenum target, Buffer* buffer) {
James Darpinian61c71162018-03-09 23:25:42716 bool do_refcounting = feature_info_->IsWebGL2OrES3Context();
zmo4c0c3532015-05-22 20:04:48717 switch (target) {
718 case GL_ARRAY_BUFFER:
James Darpinian61c71162018-03-09 23:25:42719 if (do_refcounting && bound_array_buffer)
James Darpinianf17993f2018-06-27 06:02:12720 bound_array_buffer->OnUnbind(target, false);
zmo4c0c3532015-05-22 20:04:48721 bound_array_buffer = buffer;
James Darpinian61c71162018-03-09 23:25:42722 if (do_refcounting && buffer)
James Darpinianf17993f2018-06-27 06:02:12723 buffer->OnBind(target, false);
zmo4c0c3532015-05-22 20:04:48724 break;
725 case GL_ELEMENT_ARRAY_BUFFER:
726 vertex_attrib_manager->SetElementArrayBuffer(buffer);
727 break;
728 case GL_COPY_READ_BUFFER:
James Darpinian61c71162018-03-09 23:25:42729 if (do_refcounting && bound_copy_read_buffer)
James Darpinianf17993f2018-06-27 06:02:12730 bound_copy_read_buffer->OnUnbind(target, false);
zmo4c0c3532015-05-22 20:04:48731 bound_copy_read_buffer = buffer;
James Darpinian61c71162018-03-09 23:25:42732 if (do_refcounting && buffer)
James Darpinianf17993f2018-06-27 06:02:12733 buffer->OnBind(target, false);
zmo4c0c3532015-05-22 20:04:48734 break;
735 case GL_COPY_WRITE_BUFFER:
James Darpinian61c71162018-03-09 23:25:42736 if (do_refcounting && bound_copy_write_buffer)
James Darpinianf17993f2018-06-27 06:02:12737 bound_copy_write_buffer->OnUnbind(target, false);
zmo4c0c3532015-05-22 20:04:48738 bound_copy_write_buffer = buffer;
James Darpinian61c71162018-03-09 23:25:42739 if (do_refcounting && buffer)
James Darpinianf17993f2018-06-27 06:02:12740 buffer->OnBind(target, false);
zmo4c0c3532015-05-22 20:04:48741 break;
742 case GL_PIXEL_PACK_BUFFER:
James Darpinian61c71162018-03-09 23:25:42743 if (do_refcounting && bound_pixel_pack_buffer)
James Darpinianf17993f2018-06-27 06:02:12744 bound_pixel_pack_buffer->OnUnbind(target, false);
zmo4c0c3532015-05-22 20:04:48745 bound_pixel_pack_buffer = buffer;
James Darpinian61c71162018-03-09 23:25:42746 if (do_refcounting && buffer)
James Darpinianf17993f2018-06-27 06:02:12747 buffer->OnBind(target, false);
zmocdfe65d2015-12-02 17:35:56748 UpdatePackParameters();
zmo4c0c3532015-05-22 20:04:48749 break;
750 case GL_PIXEL_UNPACK_BUFFER:
James Darpinian61c71162018-03-09 23:25:42751 if (do_refcounting && bound_pixel_unpack_buffer)
James Darpinianf17993f2018-06-27 06:02:12752 bound_pixel_unpack_buffer->OnUnbind(target, false);
zmo4c0c3532015-05-22 20:04:48753 bound_pixel_unpack_buffer = buffer;
James Darpinian61c71162018-03-09 23:25:42754 if (do_refcounting && buffer)
James Darpinianf17993f2018-06-27 06:02:12755 buffer->OnBind(target, false);
zmocdfe65d2015-12-02 17:35:56756 UpdateUnpackParameters();
zmo4c0c3532015-05-22 20:04:48757 break;
758 case GL_TRANSFORM_FEEDBACK_BUFFER:
James Darpinian61c71162018-03-09 23:25:42759 if (do_refcounting && bound_transform_feedback_buffer)
James Darpinianf17993f2018-06-27 06:02:12760 bound_transform_feedback_buffer->OnUnbind(target, false);
zmo4c0c3532015-05-22 20:04:48761 bound_transform_feedback_buffer = buffer;
James Darpinian61c71162018-03-09 23:25:42762 if (do_refcounting && buffer)
James Darpinianf17993f2018-06-27 06:02:12763 buffer->OnBind(target, false);
zmo4c0c3532015-05-22 20:04:48764 break;
765 case GL_UNIFORM_BUFFER:
James Darpinian61c71162018-03-09 23:25:42766 if (do_refcounting && bound_uniform_buffer)
James Darpinianf17993f2018-06-27 06:02:12767 bound_uniform_buffer->OnUnbind(target, false);
zmo4c0c3532015-05-22 20:04:48768 bound_uniform_buffer = buffer;
James Darpinian61c71162018-03-09 23:25:42769 if (do_refcounting && buffer)
James Darpinianf17993f2018-06-27 06:02:12770 buffer->OnBind(target, false);
zmo4c0c3532015-05-22 20:04:48771 break;
772 default:
Peter BostrÃļma11556e2024-10-31 04:49:10773 NOTREACHED();
zmo4c0c3532015-05-22 20:04:48774 }
775}
776
777void ContextState::RemoveBoundBuffer(Buffer* buffer) {
778 DCHECK(buffer);
James Darpinian61c71162018-03-09 23:25:42779 bool do_refcounting = feature_info_->IsWebGL2OrES3Context();
zmo4c0c3532015-05-22 20:04:48780 if (bound_array_buffer.get() == buffer) {
781 bound_array_buffer = nullptr;
Zhenyao Mo60fe7722018-03-23 16:26:45782 if (do_refcounting)
James Darpinianf17993f2018-06-27 06:02:12783 buffer->OnUnbind(GL_ARRAY_BUFFER, false);
Zhenyao Mo60fe7722018-03-23 16:26:45784 if (!context_lost_)
785 api()->glBindBufferFn(GL_ARRAY_BUFFER, 0);
zmo4c0c3532015-05-22 20:04:48786 }
Zhenyao Mo60fe7722018-03-23 16:26:45787 // Needs to be called after bound_array_buffer handled.
788 vertex_attrib_manager->Unbind(buffer, bound_array_buffer.get());
zmo4c0c3532015-05-22 20:04:48789 if (bound_copy_read_buffer.get() == buffer) {
790 bound_copy_read_buffer = nullptr;
Zhenyao Mo60fe7722018-03-23 16:26:45791 if (do_refcounting)
James Darpinianf17993f2018-06-27 06:02:12792 buffer->OnUnbind(GL_COPY_READ_BUFFER, false);
Zhenyao Mo60fe7722018-03-23 16:26:45793 if (!context_lost_)
794 api()->glBindBufferFn(GL_COPY_READ_BUFFER, 0);
zmo4c0c3532015-05-22 20:04:48795 }
796 if (bound_copy_write_buffer.get() == buffer) {
797 bound_copy_write_buffer = nullptr;
Zhenyao Mo60fe7722018-03-23 16:26:45798 if (do_refcounting)
James Darpinianf17993f2018-06-27 06:02:12799 buffer->OnUnbind(GL_COPY_WRITE_BUFFER, false);
Zhenyao Mo60fe7722018-03-23 16:26:45800 if (!context_lost_)
801 api()->glBindBufferFn(GL_COPY_WRITE_BUFFER, 0);
zmo4c0c3532015-05-22 20:04:48802 }
803 if (bound_pixel_pack_buffer.get() == buffer) {
804 bound_pixel_pack_buffer = nullptr;
Zhenyao Mo60fe7722018-03-23 16:26:45805 if (do_refcounting)
James Darpinianf17993f2018-06-27 06:02:12806 buffer->OnUnbind(GL_PIXEL_PACK_BUFFER, false);
Zhenyao Mo60fe7722018-03-23 16:26:45807 if (!context_lost_)
808 api()->glBindBufferFn(GL_PIXEL_PACK_BUFFER, 0);
zmocdfe65d2015-12-02 17:35:56809 UpdatePackParameters();
zmo4c0c3532015-05-22 20:04:48810 }
811 if (bound_pixel_unpack_buffer.get() == buffer) {
812 bound_pixel_unpack_buffer = nullptr;
Zhenyao Mo60fe7722018-03-23 16:26:45813 if (do_refcounting)
James Darpinianf17993f2018-06-27 06:02:12814 buffer->OnUnbind(GL_PIXEL_UNPACK_BUFFER, false);
Zhenyao Mo60fe7722018-03-23 16:26:45815 if (!context_lost_)
816 api()->glBindBufferFn(GL_PIXEL_UNPACK_BUFFER, 0);
zmocdfe65d2015-12-02 17:35:56817 UpdateUnpackParameters();
zmo4c0c3532015-05-22 20:04:48818 }
819 if (bound_transform_feedback_buffer.get() == buffer) {
820 bound_transform_feedback_buffer = nullptr;
Zhenyao Mo60fe7722018-03-23 16:26:45821 if (do_refcounting)
James Darpinianf17993f2018-06-27 06:02:12822 buffer->OnUnbind(GL_TRANSFORM_FEEDBACK_BUFFER, false);
Zhenyao Mo60fe7722018-03-23 16:26:45823 if (!context_lost_)
824 api()->glBindBufferFn(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
zmo4c0c3532015-05-22 20:04:48825 }
Zhenyao Mo60fe7722018-03-23 16:26:45826 // Needs to be called after bound_transform_feedback_buffer handled.
zmoe2a05e92016-10-10 23:22:51827 if (bound_transform_feedback.get()) {
Zhenyao Mo60fe7722018-03-23 16:26:45828 bound_transform_feedback->RemoveBoundBuffer(
829 GL_TRANSFORM_FEEDBACK_BUFFER, buffer,
830 bound_transform_feedback_buffer.get(), !context_lost_);
zmoe2a05e92016-10-10 23:22:51831 }
zmo4c0c3532015-05-22 20:04:48832 if (bound_uniform_buffer.get() == buffer) {
833 bound_uniform_buffer = nullptr;
Zhenyao Mo60fe7722018-03-23 16:26:45834 if (do_refcounting)
James Darpinianf17993f2018-06-27 06:02:12835 buffer->OnUnbind(GL_UNIFORM_BUFFER, false);
Zhenyao Mo60fe7722018-03-23 16:26:45836 if (!context_lost_)
837 api()->glBindBufferFn(GL_UNIFORM_BUFFER, 0);
838 }
839 // Needs to be called after bound_uniform_buffer handled.
840 if (indexed_uniform_buffer_bindings) {
841 indexed_uniform_buffer_bindings->RemoveBoundBuffer(
842 GL_UNIFORM_BUFFER, buffer, bound_uniform_buffer.get(), !context_lost_);
zmo4c0c3532015-05-22 20:04:48843 }
844}
845
bajones2b98b2a2015-09-15 02:27:36846void ContextState::UnbindTexture(TextureRef* texture) {
847 GLuint active_unit = active_texture_unit;
848 for (size_t jj = 0; jj < texture_units.size(); ++jj) {
849 TextureUnit& unit = texture_units[jj];
850 if (unit.bound_texture_2d.get() == texture) {
tzikddef02182018-08-14 07:08:33851 unit.bound_texture_2d = nullptr;
bajones2b98b2a2015-09-15 02:27:36852 if (active_unit != jj) {
Antoine Labour2c1ad962017-10-24 23:32:56853 api()->glActiveTextureFn(GL_TEXTURE0 + jj);
bajones2b98b2a2015-09-15 02:27:36854 active_unit = jj;
855 }
Antoine Labour2c1ad962017-10-24 23:32:56856 api()->glBindTextureFn(GL_TEXTURE_2D, 0);
bajones2b98b2a2015-09-15 02:27:36857 } else if (unit.bound_texture_cube_map.get() == texture) {
tzikddef02182018-08-14 07:08:33858 unit.bound_texture_cube_map = nullptr;
bajones2b98b2a2015-09-15 02:27:36859 if (active_unit != jj) {
Antoine Labour2c1ad962017-10-24 23:32:56860 api()->glActiveTextureFn(GL_TEXTURE0 + jj);
bajones2b98b2a2015-09-15 02:27:36861 active_unit = jj;
862 }
Antoine Labour2c1ad962017-10-24 23:32:56863 api()->glBindTextureFn(GL_TEXTURE_CUBE_MAP, 0);
bajones2b98b2a2015-09-15 02:27:36864 } else if (unit.bound_texture_external_oes.get() == texture) {
tzikddef02182018-08-14 07:08:33865 unit.bound_texture_external_oes = nullptr;
bajones2b98b2a2015-09-15 02:27:36866 if (active_unit != jj) {
Antoine Labour2c1ad962017-10-24 23:32:56867 api()->glActiveTextureFn(GL_TEXTURE0 + jj);
bajones2b98b2a2015-09-15 02:27:36868 active_unit = jj;
869 }
Antoine Labour2c1ad962017-10-24 23:32:56870 api()->glBindTextureFn(GL_TEXTURE_EXTERNAL_OES, 0);
erikchena50b9c62015-12-16 21:14:49871 } else if (unit.bound_texture_rectangle_arb.get() == texture) {
tzikddef02182018-08-14 07:08:33872 unit.bound_texture_rectangle_arb = nullptr;
erikchena50b9c62015-12-16 21:14:49873 if (active_unit != jj) {
Antoine Labour2c1ad962017-10-24 23:32:56874 api()->glActiveTextureFn(GL_TEXTURE0 + jj);
erikchena50b9c62015-12-16 21:14:49875 active_unit = jj;
876 }
Geoff Lang8fc21cd2025-05-26 13:13:29877 api()->glBindTextureFn(GL_TEXTURE_RECTANGLE_ANGLE, 0);
bajones2b98b2a2015-09-15 02:27:36878 } else if (unit.bound_texture_3d.get() == texture) {
tzikddef02182018-08-14 07:08:33879 unit.bound_texture_3d = nullptr;
bajones2b98b2a2015-09-15 02:27:36880 if (active_unit != jj) {
Antoine Labour2c1ad962017-10-24 23:32:56881 api()->glActiveTextureFn(GL_TEXTURE0 + jj);
bajones2b98b2a2015-09-15 02:27:36882 active_unit = jj;
883 }
Antoine Labour2c1ad962017-10-24 23:32:56884 api()->glBindTextureFn(GL_TEXTURE_3D, 0);
bajones2b98b2a2015-09-15 02:27:36885 } else if (unit.bound_texture_2d_array.get() == texture) {
tzikddef02182018-08-14 07:08:33886 unit.bound_texture_2d_array = nullptr;
bajones2b98b2a2015-09-15 02:27:36887 if (active_unit != jj) {
Antoine Labour2c1ad962017-10-24 23:32:56888 api()->glActiveTextureFn(GL_TEXTURE0 + jj);
bajones2b98b2a2015-09-15 02:27:36889 active_unit = jj;
890 }
Antoine Labour2c1ad962017-10-24 23:32:56891 api()->glBindTextureFn(GL_TEXTURE_2D_ARRAY, 0);
bajones2b98b2a2015-09-15 02:27:36892 }
893 }
894
895 if (active_unit != active_texture_unit) {
Antoine Labour2c1ad962017-10-24 23:32:56896 api()->glActiveTextureFn(GL_TEXTURE0 + active_texture_unit);
bajones2b98b2a2015-09-15 02:27:36897 }
898}
899
bajones5141d032015-12-07 21:13:39900void ContextState::UnbindSampler(Sampler* sampler) {
901 for (size_t jj = 0; jj < sampler_units.size(); ++jj) {
902 if (sampler_units[jj].get() == sampler) {
903 sampler_units[jj] = nullptr;
Antoine Labour2c1ad962017-10-24 23:32:56904 api()->glBindSamplerFn(jj, 0);
bajones5141d032015-12-07 21:13:39905 }
906 }
907}
908
zmo2b9c47392015-12-11 02:21:32909PixelStoreParams ContextState::GetPackParams() {
zmoccd0b342016-03-09 23:47:36910 DCHECK_EQ(0, pack_skip_pixels);
911 DCHECK_EQ(0, pack_skip_rows);
zmo2b9c47392015-12-11 02:21:32912 PixelStoreParams params;
913 params.alignment = pack_alignment;
914 params.row_length = pack_row_length;
zmo2b9c47392015-12-11 02:21:32915 return params;
916}
917
918PixelStoreParams ContextState::GetUnpackParams(Dimension dimension) {
zmoccd0b342016-03-09 23:47:36919 DCHECK_EQ(0, unpack_skip_pixels);
920 DCHECK_EQ(0, unpack_skip_rows);
921 DCHECK_EQ(0, unpack_skip_images);
zmo2b9c47392015-12-11 02:21:32922 PixelStoreParams params;
923 params.alignment = unpack_alignment;
924 params.row_length = unpack_row_length;
zmo2b9c47392015-12-11 02:21:32925 if (dimension == k3D) {
926 params.image_height = unpack_image_height;
zmo2b9c47392015-12-11 02:21:32927 }
928 return params;
929}
930
zmo0ed71922016-06-23 01:18:42931void ContextState::EnableDisableFramebufferSRGB(bool enable) {
ccameronddaa56a2016-12-02 04:05:46932 if (framebuffer_srgb_valid_ && framebuffer_srgb_ == enable)
zmo0ed71922016-06-23 01:18:42933 return;
Geoff Lang8fc21cd2025-05-26 13:13:29934 EnableDisable(GL_FRAMEBUFFER_SRGB_EXT, enable);
zmo0ed71922016-06-23 01:18:42935 framebuffer_srgb_ = enable;
ccameronddaa56a2016-12-02 04:05:46936 framebuffer_srgb_valid_ = true;
zmo0ed71922016-06-23 01:18:42937}
938
zmob730f32b2016-01-06 20:39:08939void ContextState::InitStateManual(const ContextState*) const {
940 // Here we always reset the states whether it's different from previous ones.
941 // We have very limited states here; also, once we switch to MANGLE, MANGLE
942 // will opmitize this.
943 UpdatePackParameters();
944 UpdateUnpackParameters();
Kai Ninomiyabcbefdab2017-11-03 19:57:27945 UpdateWindowRectangles();
zmob730f32b2016-01-06 20:39:08946}
947
gman@chromium.orgf731b9462012-10-30 00:35:22948// Include the auto-generated part of this file. We split this because it means
949// we can easily edit the non-auto generated parts right here in this file
950// instead of having to edit some template or the code generator.
951#include "gpu/command_buffer/service/context_state_impl_autogen.h"
952
gman@chromium.orge259eb412012-10-13 05:47:24953} // namespace gles2
954} // namespace gpu