OLD | NEW |
---|---|
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 Loading... | |
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 |
OLD | NEW |