Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc

Issue 374193002: gpu: Optimize and cleanup code used for CHROMIUM_copy_texture. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Simplify format selecting logic and support GL_BGRA_EXT Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" 5 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "gpu/command_buffer/service/gl_utils.h" 10 #include "gpu/command_buffer/service/gl_utils.h"
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 return shader_ids[index][SAMPLER_2D]; 160 return shader_ids[index][SAMPLER_2D];
161 case GL_TEXTURE_RECTANGLE_ARB: 161 case GL_TEXTURE_RECTANGLE_ARB:
162 return shader_ids[index][SAMPLER_RECTANGLE_ARB]; 162 return shader_ids[index][SAMPLER_RECTANGLE_ARB];
163 case GL_TEXTURE_EXTERNAL_OES: 163 case GL_TEXTURE_EXTERNAL_OES:
164 return shader_ids[index][SAMPLER_EXTERNAL_OES]; 164 return shader_ids[index][SAMPLER_EXTERNAL_OES];
165 default: 165 default:
166 break; 166 break;
167 } 167 }
168 168
169 NOTREACHED(); 169 NOTREACHED();
170 return shader_ids[index][SAMPLER_2D]; 170 return shader_ids[0][SAMPLER_2D];
171 } 171 }
172 172
173 void CompileShader(GLuint shader, const char* shader_source) { 173 void CompileShader(GLuint shader, const char* shader_source) {
174 glShaderSource(shader, 1, &shader_source, 0); 174 glShaderSource(shader, 1, &shader_source, 0);
175 glCompileShader(shader); 175 glCompileShader(shader);
176 #ifndef NDEBUG 176 #ifndef NDEBUG
177 GLint compile_status; 177 GLint compile_status;
178 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); 178 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
179 if (GL_TRUE != compile_status) 179 if (GL_TRUE != compile_status)
180 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; 180 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure.";
181 #endif 181 #endif
182 } 182 }
183 183
184 void DeleteShader(GLuint shader) { 184 void DeleteShader(GLuint shader) {
185 if (shader) 185 if (shader)
186 glDeleteShader(shader); 186 glDeleteShader(shader);
187 } 187 }
188 188
189 bool BindFramebufferTexture2D(GLenum target,
190 GLuint texture_id,
191 GLint level,
192 GLuint framebuffer) {
193 DCHECK(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB);
194 glActiveTexture(GL_TEXTURE0);
195 glBindTexture(target, texture_id);
196 // NVidia drivers require texture settings to be a certain way
197 // or they won't report FRAMEBUFFER_COMPLETE.
198 glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
199 glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
200 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
201 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
202 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
203 glFramebufferTexture2DEXT(
204 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, texture_id, level);
205
206 #ifndef NDEBUG
207 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
208 if (GL_FRAMEBUFFER_COMPLETE != fb_status) {
209 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer.";
210 return false;
211 }
212 #endif
213 return true;
214 }
215
216 void DoCopyTexImage2D(const gpu::gles2::GLES2Decoder* decoder,
217 GLenum source_target,
218 GLuint source_id,
219 GLuint dest_id,
220 GLint dest_level,
221 GLenum dest_internal_format,
222 GLsizei width,
223 GLsizei height,
224 GLuint framebuffer) {
225 DCHECK(source_target == GL_TEXTURE_2D ||
226 source_target == GL_TEXTURE_RECTANGLE_ARB);
227 if (BindFramebufferTexture2D(
228 source_target, source_id, 0 /* level */, framebuffer)) {
229 glBindTexture(GL_TEXTURE_2D, dest_id);
230 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
231 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
232 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
233 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
234 glCopyTexImage2D(GL_TEXTURE_2D,
235 dest_level,
236 dest_internal_format,
237 0 /* x */,
238 0 /* y */,
239 width,
240 height,
241 0 /* border */);
242 }
243
244 decoder->RestoreTextureState(source_id);
245 decoder->RestoreTextureState(dest_id);
246 decoder->RestoreTextureUnitBindings(0);
247 decoder->RestoreActiveTexture();
248 decoder->RestoreFramebufferBindings();
249 }
250
251 bool DoesSourceContainSupersetOfDestination(GLenum source_format,
252 GLenum dest_format) {
reveman 2014/08/11 20:48:46 Is it really worth having this function? If you wa
dshwang 2014/08/12 07:03:01 I remove this function and reuse your naming for l
253 // The format should be GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE,
254 // GL_LUMINANCE_ALPHA.
255 DCHECK(dest_format >= GL_ALPHA && dest_format <= GL_LUMINANCE_ALPHA);
256 DCHECK((source_format >= GL_ALPHA && source_format <= GL_LUMINANCE_ALPHA) ||
257 source_format == GL_BGRA_EXT);
reveman 2014/08/11 20:48:46 Do you need these DCHECKs here? It doesn't seem re
258 // Support only important format combinations.
259 return source_format == dest_format ||
260 (source_format == GL_RGBA && dest_format == GL_RGB);
261 }
262
189 } // namespace 263 } // namespace
190 264
191 namespace gpu { 265 namespace gpu {
192 266
193 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() 267 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager()
194 : initialized_(false), 268 : initialized_(false),
195 vertex_shaders_(NUM_VERTEX_SHADERS, 0u), 269 vertex_shaders_(NUM_VERTEX_SHADERS, 0u),
196 fragment_shaders_(NUM_FRAGMENT_SHADERS, 0u), 270 fragment_shaders_(NUM_FRAGMENT_SHADERS, 0u),
197 buffer_id_(0u), 271 buffer_id_(0u),
198 framebuffer_(0u) {} 272 framebuffer_(0u) {}
199 273
200 CopyTextureCHROMIUMResourceManager::~CopyTextureCHROMIUMResourceManager() {} 274 CopyTextureCHROMIUMResourceManager::~CopyTextureCHROMIUMResourceManager() {
275 DCHECK(!buffer_id_);
276 DCHECK(!framebuffer_);
277 }
201 278
202 void CopyTextureCHROMIUMResourceManager::Initialize( 279 void CopyTextureCHROMIUMResourceManager::Initialize(
203 const gles2::GLES2Decoder* decoder) { 280 const gles2::GLES2Decoder* decoder) {
204 COMPILE_ASSERT( 281 COMPILE_ASSERT(
205 kVertexPositionAttrib == 0u, 282 kVertexPositionAttrib == 0u,
206 Position_attribs_must_be_0); 283 Position_attribs_must_be_0);
284 DCHECK(!buffer_id_);
285 DCHECK(!framebuffer_);
286 DCHECK(programs_.empty());
207 287
208 // Initialize all of the GPU resources required to perform the copy. 288 // Initialize all of the GPU resources required to perform the copy.
209 glGenBuffersARB(1, &buffer_id_); 289 glGenBuffersARB(1, &buffer_id_);
210 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); 290 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_);
211 const GLfloat kQuadVertices[] = {-1.0f, -1.0f, 291 const GLfloat kQuadVertices[] = {-1.0f, -1.0f,
212 1.0f, -1.0f, 292 1.0f, -1.0f,
213 1.0f, 1.0f, 293 1.0f, 1.0f,
214 -1.0f, 1.0f}; 294 -1.0f, 1.0f};
215 glBufferData( 295 glBufferData(
216 GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, GL_STATIC_DRAW); 296 GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, GL_STATIC_DRAW);
217 297
218 glGenFramebuffersEXT(1, &framebuffer_); 298 glGenFramebuffersEXT(1, &framebuffer_);
219 299
220 decoder->RestoreBufferBindings(); 300 decoder->RestoreBufferBindings();
221 301
222 initialized_ = true; 302 initialized_ = true;
223 } 303 }
224 304
225 void CopyTextureCHROMIUMResourceManager::Destroy() { 305 void CopyTextureCHROMIUMResourceManager::Destroy() {
226 if (!initialized_) 306 if (!initialized_)
227 return; 307 return;
228 308
229 glDeleteFramebuffersEXT(1, &framebuffer_); 309 glDeleteFramebuffersEXT(1, &framebuffer_);
310 framebuffer_ = 0;
230 311
231 std::for_each(vertex_shaders_.begin(), vertex_shaders_.end(), DeleteShader); 312 std::for_each(vertex_shaders_.begin(), vertex_shaders_.end(), DeleteShader);
232 std::for_each( 313 std::for_each(
233 fragment_shaders_.begin(), fragment_shaders_.end(), DeleteShader); 314 fragment_shaders_.begin(), fragment_shaders_.end(), DeleteShader);
234 315
235 for (ProgramMap::const_iterator it = programs_.begin(); it != programs_.end(); 316 for (ProgramMap::const_iterator it = programs_.begin(); it != programs_.end();
236 ++it) { 317 ++it) {
237 const ProgramInfo& info = it->second; 318 const ProgramInfo& info = it->second;
238 glDeleteProgram(info.program); 319 glDeleteProgram(info.program);
239 } 320 }
240 321
241 glDeleteBuffersARB(1, &buffer_id_); 322 glDeleteBuffersARB(1, &buffer_id_);
323 buffer_id_ = 0;
242 } 324 }
243 325
244 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( 326 void CopyTextureCHROMIUMResourceManager::DoCopyTexture(
245 const gles2::GLES2Decoder* decoder, 327 const gles2::GLES2Decoder* decoder,
246 GLenum source_target, 328 GLenum source_target,
247 GLenum dest_target,
248 GLuint source_id, 329 GLuint source_id,
330 GLenum source_internal_format,
249 GLuint dest_id, 331 GLuint dest_id,
250 GLint level, 332 GLint dest_level,
333 GLenum dest_internal_format,
251 GLsizei width, 334 GLsizei width,
252 GLsizei height, 335 GLsizei height,
253 bool flip_y, 336 bool flip_y,
254 bool premultiply_alpha, 337 bool premultiply_alpha,
255 bool unpremultiply_alpha) { 338 bool unpremultiply_alpha) {
339 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha;
340 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's
341 // format does not contain a superset of the components required by the base
342 // format of internalformat.
343 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml
344 bool source_contain_superset_of_dest = DoesSourceContainSupersetOfDestination(
345 source_internal_format, dest_internal_format);
346 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2,
347 // so restrict this to GL_TEXTURE_2D.
348 if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change &&
349 source_contain_superset_of_dest) {
350 DoCopyTexImage2D(decoder,
351 source_target,
352 source_id,
353 dest_id,
354 dest_level,
355 dest_internal_format,
356 width,
357 height,
358 framebuffer_);
359 return;
360 }
361
256 // Use default transform matrix if no transform passed in. 362 // Use default transform matrix if no transform passed in.
257 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 363 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
258 0.0f, 1.0f, 0.0f, 0.0f, 364 0.0f, 1.0f, 0.0f, 0.0f,
259 0.0f, 0.0f, 1.0f, 0.0f, 365 0.0f, 0.0f, 1.0f, 0.0f,
260 0.0f, 0.0f, 0.0f, 1.0f}; 366 0.0f, 0.0f, 0.0f, 1.0f};
261 DoCopyTextureWithTransform(decoder, source_target, dest_target, source_id, 367 DoCopyTextureWithTransform(decoder,
262 dest_id, level, width, height, flip_y, premultiply_alpha, 368 source_target,
263 unpremultiply_alpha, default_matrix); 369 source_id,
370 dest_id,
371 dest_level,
372 width,
373 height,
374 flip_y,
375 premultiply_alpha,
376 unpremultiply_alpha,
377 default_matrix);
264 } 378 }
265 379
266 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( 380 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
267 const gles2::GLES2Decoder* decoder, 381 const gles2::GLES2Decoder* decoder,
268 GLenum source_target, 382 GLenum source_target,
269 GLenum dest_target,
270 GLuint source_id, 383 GLuint source_id,
271 GLuint dest_id, 384 GLuint dest_id,
272 GLint level, 385 GLint dest_level,
273 GLsizei width, 386 GLsizei width,
274 GLsizei height, 387 GLsizei height,
275 bool flip_y, 388 bool flip_y,
276 bool premultiply_alpha, 389 bool premultiply_alpha,
277 bool unpremultiply_alpha, 390 bool unpremultiply_alpha,
278 const GLfloat transform_matrix[16]) { 391 const GLfloat transform_matrix[16]) {
279 DCHECK(source_target == GL_TEXTURE_2D || 392 DCHECK(source_target == GL_TEXTURE_2D ||
280 source_target == GL_TEXTURE_RECTANGLE_ARB || 393 source_target == GL_TEXTURE_RECTANGLE_ARB ||
281 source_target == GL_TEXTURE_EXTERNAL_OES); 394 source_target == GL_TEXTURE_EXTERNAL_OES);
282 if (!initialized_) { 395 if (!initialized_) {
283 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; 396 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager.";
284 return; 397 return;
285 } 398 }
286 399
287 VertexShaderId vertex_shader_id = GetVertexShaderId(flip_y); 400 VertexShaderId vertex_shader_id = GetVertexShaderId(flip_y);
288 DCHECK_LT(static_cast<size_t>(vertex_shader_id), vertex_shaders_.size()); 401 DCHECK_LT(static_cast<size_t>(vertex_shader_id), vertex_shaders_.size());
289 GLuint* vertex_shader = &vertex_shaders_[vertex_shader_id];
290 if (!*vertex_shader) {
291 *vertex_shader = glCreateShader(GL_VERTEX_SHADER);
292 CompileShader(*vertex_shader, vertex_shader_source[vertex_shader_id]);
293 }
294
295 FragmentShaderId fragment_shader_id = GetFragmentShaderId( 402 FragmentShaderId fragment_shader_id = GetFragmentShaderId(
296 premultiply_alpha, unpremultiply_alpha, source_target); 403 premultiply_alpha, unpremultiply_alpha, source_target);
297 DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size()); 404 DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size());
298 GLuint* fragment_shader = &fragment_shaders_[fragment_shader_id];
299 if (!*fragment_shader) {
300 *fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
301 CompileShader(*fragment_shader, fragment_shader_source[fragment_shader_id]);
302 }
303 405
304 ProgramMapKey key(vertex_shader_id, fragment_shader_id); 406 ProgramMapKey key(vertex_shader_id, fragment_shader_id);
305 ProgramInfo* info = &programs_[key]; 407 ProgramInfo* info = &programs_[key];
306 // Create program if necessary. 408 // Create program if necessary.
307 if (!info->program) { 409 if (!info->program) {
308 info->program = glCreateProgram(); 410 info->program = glCreateProgram();
411 GLuint* vertex_shader = &vertex_shaders_[vertex_shader_id];
412 if (!*vertex_shader) {
413 *vertex_shader = glCreateShader(GL_VERTEX_SHADER);
414 CompileShader(*vertex_shader, vertex_shader_source[vertex_shader_id]);
415 }
309 glAttachShader(info->program, *vertex_shader); 416 glAttachShader(info->program, *vertex_shader);
417 GLuint* fragment_shader = &fragment_shaders_[fragment_shader_id];
418 if (!*fragment_shader) {
419 *fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
420 CompileShader(*fragment_shader,
421 fragment_shader_source[fragment_shader_id]);
422 }
310 glAttachShader(info->program, *fragment_shader); 423 glAttachShader(info->program, *fragment_shader);
311 glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position"); 424 glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position");
312 glLinkProgram(info->program); 425 glLinkProgram(info->program);
313 #ifndef NDEBUG 426 #ifndef NDEBUG
314 GLint linked; 427 GLint linked;
315 glGetProgramiv(info->program, GL_LINK_STATUS, &linked); 428 glGetProgramiv(info->program, GL_LINK_STATUS, &linked);
316 if (!linked) 429 if (!linked)
317 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; 430 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure.";
318 #endif 431 #endif
319 info->matrix_handle = glGetUniformLocation(info->program, "u_matrix"); 432 info->matrix_handle = glGetUniformLocation(info->program, "u_matrix");
(...skipping 10 matching lines...) Expand all
330 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; 443 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader.";
331 return; 444 return;
332 } 445 }
333 #endif 446 #endif
334 447
335 glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix); 448 glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix);
336 if (source_target == GL_TEXTURE_RECTANGLE_ARB) 449 if (source_target == GL_TEXTURE_RECTANGLE_ARB)
337 glUniform2f(info->half_size_handle, width / 2.0f, height / 2.0f); 450 glUniform2f(info->half_size_handle, width / 2.0f, height / 2.0f);
338 else 451 else
339 glUniform2f(info->half_size_handle, 0.5f, 0.5f); 452 glUniform2f(info->half_size_handle, 0.5f, 0.5f);
340 glActiveTexture(GL_TEXTURE0);
341 glBindTexture(GL_TEXTURE_2D, dest_id);
342 // NVidia drivers require texture settings to be a certain way
343 // or they won't report FRAMEBUFFER_COMPLETE.
344 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
345 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
346 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
347 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
348 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_);
349 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dest_target,
350 dest_id, level);
351 453
352 #ifndef NDEBUG 454 if (BindFramebufferTexture2D(
353 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 455 GL_TEXTURE_2D, dest_id, dest_level, framebuffer_)) {
354 if (GL_FRAMEBUFFER_COMPLETE != fb_status) {
355 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer.";
356 } else
357 #endif
358 {
359 decoder->ClearAllAttributes(); 456 decoder->ClearAllAttributes();
360 glEnableVertexAttribArray(kVertexPositionAttrib); 457 glEnableVertexAttribArray(kVertexPositionAttrib);
361 458
362 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); 459 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_);
363 glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); 460 glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
364 461
365 glUniform1i(info->sampler_handle, 0); 462 glUniform1i(info->sampler_handle, 0);
366 463
367 glBindTexture(source_target, source_id); 464 glBindTexture(source_target, source_id);
368 glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 465 glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
(...skipping 18 matching lines...) Expand all
387 decoder->RestoreTextureState(dest_id); 484 decoder->RestoreTextureState(dest_id);
388 decoder->RestoreTextureUnitBindings(0); 485 decoder->RestoreTextureUnitBindings(0);
389 decoder->RestoreActiveTexture(); 486 decoder->RestoreActiveTexture();
390 decoder->RestoreProgramBindings(); 487 decoder->RestoreProgramBindings();
391 decoder->RestoreBufferBindings(); 488 decoder->RestoreBufferBindings();
392 decoder->RestoreFramebufferBindings(); 489 decoder->RestoreFramebufferBindings();
393 decoder->RestoreGlobalState(); 490 decoder->RestoreGlobalState();
394 } 491 }
395 492
396 } // namespace gpu 493 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698