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

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

Issue 2318313004: emulate srgb format for generateMipmap (Closed)
Patch Set: srgb-generateMipmap Created 4 years, 3 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) 2016 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2016 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_srgb_converter.h" 5 #include "gpu/command_buffer/service/gles2_cmd_srgb_converter.h"
6 6
7 #include "gpu/command_buffer/service/texture_manager.h" 7 #include "gpu/command_buffer/service/texture_manager.h"
8 #include "ui/gl/gl_version_info.h" 8 #include "ui/gl/gl_version_info.h"
9 9
10 namespace { 10 namespace {
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 // Restore state 315 // Restore state
316 decoder->RestoreAllAttributes(); 316 decoder->RestoreAllAttributes();
317 decoder->RestoreTextureUnitBindings(0); 317 decoder->RestoreTextureUnitBindings(0);
318 decoder->RestoreActiveTexture(); 318 decoder->RestoreActiveTexture();
319 decoder->RestoreProgramBindings(); 319 decoder->RestoreProgramBindings();
320 decoder->RestoreBufferBindings(); 320 decoder->RestoreBufferBindings();
321 decoder->RestoreFramebufferBindings(); 321 decoder->RestoreFramebufferBindings();
322 decoder->RestoreGlobalState(); 322 decoder->RestoreGlobalState();
323 } 323 }
324 324
325 void SRGBConverter::InitializeSRGBEncoder(const gles2::GLES2Decoder* decoder) {
326 if (srgb_encoder_initialized_) {
327 return;
328 }
329
330 GLuint srgb_encoder_program_ = 0;
331
332 std::array<GLuint, 1> srgb_encoder_textures_ = {{0}};
333 GLuint srgb_encoder_fbo_ = 0;
334 GLuint srgb_encoder_vao_ = 0;
335
336 srgb_encoder_program_ = glCreateProgram();
337
338 const char* vs_source =
339 "#version 150\n"
340 "out vec2 v_texcoord;\n"
341 "\n"
342 "void main()\n"
343 "{\n"
344 " const vec2 quad_positions[6] = vec2[6]\n"
345 " (\n"
346 " vec2(0.0f, 0.0f),\n"
347 " vec2(0.0f, 1.0f),\n"
348 " vec2(1.0f, 0.0f),\n"
349 "\n"
350 " vec2(0.0f, 1.0f),\n"
351 " vec2(1.0f, 0.0f),\n"
352 " vec2(1.0f, 1.0f)\n"
353 " );\n"
354 "\n"
355 " vec2 xy = vec2((quad_positions[gl_VertexID] * 2.0) - 1.0);\n"
356 " gl_Position = vec4(xy, 0.0, 1.0);\n"
357 " v_texcoord = quad_positions[gl_VertexID];\n"
358 "}\n";
359
360 // Compile the vertex shader
361 GLuint vs = glCreateShader(GL_VERTEX_SHADER);
362 CompileShader(vs, vs_source);
363 glAttachShader(srgb_encoder_program_, vs);
364 glDeleteShader(vs);
365
366 // Compile the fragment shader
367
368 // Sampling texels from a srgb texture to a linear image, it will convert
369 // the srgb color space to linear color space automatically as a part of
370 // filtering. See the section <sRGB Texture Color Conversion> in GLES and
371 // OpenGL spec. So in decoder, we don't need to decode again.
372 // However, sampling texels from a linear texture to a srgb image, it will
373 // not convert linear to srgb automatically. Shader should always operates
374 // in linear space. So in encoder, we need to encode explicitly in shader.
375 const char* fs_source =
376 "#version 150\n"
377 "uniform sampler2D u_source_texture;\n"
378 "in vec2 v_texcoord;\n"
379 "out vec4 output_color;\n"
380 "\n"
381 "float encode(float color)\n"
382 "{\n"
383 " float encoded_color;\n"
384 " if (color <= 0.0) {\n"
385 " return 0.0;\n"
386 " } else if (color < 0.0031308) {\n"
387 " return color * 12.92;\n"
388 " } else if (color < 1) {\n"
389 " return pow(color, 0.41666) * 1.055 - 0.055;\n"
390 " } else {\n"
391 " return 1.0;\n"
392 " }\n"
393 "}\n"
394 "\n"
395 "void main()\n"
396 "{\n"
397 " vec4 c = texture(u_source_texture, v_texcoord);\n"
398 " output_color = vec4(encode(c.r), encode(c.g), encode(c.b), c.a);\n"
399 "}\n";
400 /* const char* fs_source =
401 "#version 150\n"
402 "uniform sampler2D u_source_texture;\n"
403 "in vec2 v_texcoord;\n"
404 "out vec4 output_color;\n"
405 "\n"
406 "void main()\n"
407 "{\n"
408 " vec4 c = texture(u_source_texture, v_texcoord);\n"
409 " output_color = c;\n"
410 "}\n";*/
411
412 GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
413 CompileShader(fs, fs_source);
414 glAttachShader(srgb_encoder_program_, fs);
415 glDeleteShader(fs);
416
417 glLinkProgram(srgb_encoder_program_);
418 #ifndef NDEBUG
419 GLint linked = 0;
420 glGetProgramiv(srgb_encoder_program_, GL_LINK_STATUS, &linked);
421 if (!linked) {
422 DLOG(ERROR) << "SRGB Encoder for BlitFramebuffer: program link failure.";
423 }
424 #endif
425
426 GLuint texture_uniform =
427 glGetUniformLocation(srgb_encoder_program_, "u_source_texture");
428 glUseProgram(srgb_encoder_program_);
429 glUniform1i(texture_uniform, 0);
430
431 glGenTextures(srgb_encoder_textures_.size(), srgb_encoder_textures_.data());
432 glActiveTexture(GL_TEXTURE0);
433 for (auto srgb_encoder_texture : srgb_encoder_textures_) {
434 glBindTexture(GL_TEXTURE_2D, srgb_encoder_texture);
435
436 // Use linear, non-mipmapped sampling with the srgb encoder texture
437 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
438 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
439 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
440 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
441 }
442
443 glGenFramebuffersEXT(1, &srgb_encoder_fbo_);
444 glGenVertexArraysOES(1, &srgb_encoder_vao_);
445
446 decoder->RestoreTextureUnitBindings(0);
447 decoder->RestoreActiveTexture();
448 decoder->RestoreProgramBindings();
449
450 srgb_encoder_initialized_ = true;
451 }
yunchao 2016/09/19 15:25:48 Please remove this function above, Yizhou.
yizhou.jiang 2016/09/20 07:00:27 Done.
452
453 void SRGBConverter::SRGBGenerateMipmap(const gles2::GLES2Decoder* decoder,
454 Texture* tex,
455 GLenum target) {
456 DCHECK(srgb_converter_initialized_);
457
458 GLsizei width;
459 GLsizei height;
460 GLsizei depth;
461 GLenum type = 0;
462 GLenum internal_format = 0;
463 GLsizei base_level = tex->base_level();
464 tex->GetLevelSize(target, base_level, &width, &height, &depth);
465 tex->GetLevelType(target, 0, &type, &internal_format);
466 const GLint mipmap_level =
467 TextureManager::ComputeMipMapCount(target, width, height, depth);
468
469 // copy tex to srgb_decoder_textures_[0] with srgb format
470 glBindTexture(target, tex->service_id());
471 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, srgb_decoder_fbo_);
472 glFramebufferTexture2DEXT(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
473 GL_TEXTURE_2D, tex->service_id(), 0);
474
475 GLenum error = glCheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER);
476 error = glGetError();
yunchao 2016/09/19 15:25:48 please remove the debugging code.
yizhou.jiang 2016/09/20 07:00:27 Done.
477
478 glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[0]);
479 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, GL_SRGB,
480 GL_UNSIGNED_BYTE, nullptr);
yunchao 2016/09/19 15:25:48 This is not necessary, copyTexImage2D will allocat
yizhou.jiang 2016/09/20 07:00:27 Done.
481 glCopyTexImage2D(GL_TEXTURE_2D, 0, internal_format, 0, 0, width, height, 0);
482 error = glGetError();
483 unsigned char bytes3[width * height * 4];
484 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, bytes3);
yunchao 2016/09/19 15:25:48 please remove debug code
yizhou.jiang 2016/09/20 07:00:27 Done.
485
486 // bind srgb_decoder_textures_[1] to draw framebuffer
487 glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[1]);
488 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
489 GL_UNSIGNED_BYTE, nullptr);
490 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, srgb_decoder_fbo_);
491 glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
492 GL_TEXTURE_2D, srgb_converter_textures_[1], 0);
493
494 error = glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER);
495 error = glGetError();
496 unsigned char bytes2[width * height * 4];
497 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, bytes2);
yunchao 2016/09/19 15:25:47 remove debug code
yizhou.jiang 2016/09/20 07:00:27 Done.
498
499 // bind texture with srgb format and render with srgb_decoder_program_
500 glUseProgram(srgb_converter_program_);
501 glViewport(0, 0, width, height);
502 glDisable(GL_SCISSOR_TEST);
503 glDisable(GL_DEPTH_TEST);
504 glDisable(GL_STENCIL_TEST);
505 glDisable(GL_CULL_FACE);
506 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
507 glDepthMask(GL_FALSE);
508 glEnable(GL_BLEND);
yunchao 2016/09/19 15:25:48 glDisable blend
yizhou.jiang 2016/09/20 07:00:27 Done.
509 glDisable(GL_DITHER);
510
511 glBindVertexArrayOES(srgb_converter_vao_);
512 glActiveTexture(GL_TEXTURE0);
513 glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[0]);
514
515 error = glGetError();
yunchao 2016/09/19 15:25:48 remove debug code
yizhou.jiang 2016/09/20 07:00:27 Done.
516
517 glDrawArrays(GL_TRIANGLES, 0, 6);
518
519 error = glGetError();
520 unsigned char bytes1[width * height * 4];
521 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, srgb_decoder_fbo_);
522 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, bytes1);
yunchao 2016/09/19 15:25:47 remove debug code
yizhou.jiang 2016/09/20 07:00:27 Done.
523
524 // generateMipmap for tex and srgb_decoder_textures_[1]
525 glBindTexture(GL_TEXTURE_2D, tex->service_id());
526 glGenerateMipmapEXT(GL_TEXTURE_2D);
527 glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[1]);
528 glGenerateMipmapEXT(GL_TEXTURE_2D);
529
530 error = glGetError();
yunchao 2016/09/19 15:25:47 remove debug code
yizhou.jiang 2016/09/20 07:00:27 Done.
531
532 // bind tex with rgba format and render with srgb_encoder_program_
533
534 glClearColor(0, 0, 0, 255);
yunchao 2016/09/19 15:25:47 It is not necessary to set clear color.
yizhou.jiang 2016/09/20 07:00:27 Done.
535 glBindTexture(GL_TEXTURE_2D, tex->service_id());
536 glBindFramebufferEXT(GL_FRAMEBUFFER, srgb_encoder_fbo_);
537
538 //InitializeSRGBEncoder(decoder);
539 //glUseProgram(srgb_encoder_program_);
540
541 /*glDeleteProgram(srgb_converter_program_);
542 srgb_converter_program_ = 0;
543 srgb_converter_initialized_ = false;
544 InitializeSRGBConverterProgram();
545 */
yunchao 2016/09/19 15:25:47 remove debug code.
yizhou.jiang 2016/09/20 07:00:27 Done.
546 glUseProgram(srgb_converter_program_);
547
548 glBindVertexArrayOES(srgb_converter_vao_);
yunchao 2016/09/19 15:25:48 These two lines are not necessary, you have called
yizhou.jiang 2016/09/20 07:00:27 Done.
549
550 for (GLint level = base_level; level < mipmap_level; level++) {
551 glBindTexture(GL_TEXTURE_2D, tex->service_id());
yunchao 2016/09/19 15:25:47 This is not necessary.
yizhou.jiang 2016/09/20 07:00:26 Done.
552 glBindFramebufferEXT(GL_FRAMEBUFFER, srgb_encoder_fbo_);
yunchao 2016/09/19 15:25:48 move this outside the for loop.
yizhou.jiang 2016/09/20 07:00:27 Done.
553 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
554 GL_TEXTURE_2D, tex->service_id(), level);
555
556 error = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
557 error = glGetError();
558 unsigned char bytes2[width * height * 4];
559 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, bytes2);
yunchao 2016/09/19 15:25:48 remove debug code.
yizhou.jiang 2016/09/20 07:00:27 Done.
560
561 glActiveTexture(GL_TEXTURE0);
yunchao 2016/09/19 15:25:48 This is not necessary.
yizhou.jiang 2016/09/20 07:00:27 Done.
562 glBindTexture(GL_TEXTURE_2D, srgb_converter_textures_[1]);
563 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
yunchao 2016/09/19 15:25:48 move these two lines outside the for loop.
yizhou.jiang 2016/09/20 07:00:27 Done.
564 glViewport(0, 0, width, height);
565 glDrawArrays(GL_TRIANGLES, 0, 6);
566
567 error = glGetError();
568 unsigned char bytes[width * height * 4];
569 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, bytes);
yunchao 2016/09/19 15:25:48 remove the debug code.
yizhou.jiang 2016/09/20 07:00:27 Done.
570
571 width /= 2;
572 height /= 2;
573 }
574
575 // Restore state
576 decoder->RestoreAllAttributes();
577 decoder->RestoreTextureUnitBindings(0);
578 decoder->RestoreActiveTexture();
579 decoder->RestoreProgramBindings();
580 decoder->RestoreBufferBindings();
581 decoder->RestoreFramebufferBindings();
582 decoder->RestoreGlobalState();
583 }
584
325 } // namespace gles2. 585 } // namespace gles2.
326 } // namespace gpu 586 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698