gl_oes_egl_image_unittest.cc 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <GLES2/gl2.h>
  5. #include "build/build_config.h"
  6. #include "gpu/command_buffer/client/gles2_implementation.h"
  7. #include "gpu/command_buffer/tests/gl_test_utils.h"
  8. #include "gpu/config/gpu_test_config.h"
  9. #include "testing/gmock/include/gmock/gmock.h"
  10. #include "testing/gtest/include/gtest/gtest.h"
  11. #include "ui/gfx/buffer_format_util.h"
  12. #include "ui/gl/gl_image.h"
  13. #include "ui/gl/init/gl_factory.h"
  14. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  15. #include "ui/gl/gl_image_native_pixmap.h"
  16. #endif
  17. #define SKIP_TEST_IF(cmd) \
  18. do { \
  19. if (cmd) { \
  20. LOG(INFO) << "Skip test because " << #cmd; \
  21. return; \
  22. } \
  23. } while (false)
  24. namespace {
  25. static const int kImageWidth = 64;
  26. static const int kImageHeight = 64;
  27. class GpuOESEGLImageTest : public testing::Test,
  28. public gpu::GpuCommandBufferTestEGL {
  29. protected:
  30. void SetUp() override {
  31. egl_initialized_ = InitializeEGL(kImageWidth, kImageHeight);
  32. }
  33. void TearDown() override { RestoreGLDefault(); }
  34. bool egl_initialized_{false};
  35. };
  36. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  37. // TODO(crbug.com/835072): re-enable this test on ASAN once bugs are fixed.
  38. #if !defined(ADDRESS_SANITIZER)
  39. #define SHADER(Src) #Src
  40. // clang-format off
  41. const char kVertexShader[] =
  42. SHADER(
  43. attribute vec4 a_position;
  44. varying vec2 v_texCoord;
  45. void main() {
  46. gl_Position = a_position;
  47. v_texCoord = vec2((a_position.x + 1.0) * 0.5, (a_position.y + 1.0) * 0.5);
  48. }
  49. );
  50. const char* kFragmentShader =
  51. SHADER(
  52. precision mediump float;
  53. uniform sampler2D a_texture;
  54. varying vec2 v_texCoord;
  55. void main() {
  56. gl_FragColor = texture2D(a_texture, v_texCoord);
  57. }
  58. );
  59. // clang-format on
  60. // The test verifies that the content of an EGLImage can be drawn. Indeed the
  61. // test upload some colored pixels into a GL texture. Then it creates an
  62. // EGLImage from this texture and binds this image to draw it into another
  63. // GL texture. At the end the test downloads the pixels from the final GL
  64. // texture and verifies that the colors match with the pixels uploaded into
  65. // the initial GL texture.
  66. TEST_F(GpuOESEGLImageTest, EGLImageToTexture) {
  67. SKIP_TEST_IF(!egl_initialized_);
  68. // This extension is required for creating an EGLImage from a GL texture.
  69. SKIP_TEST_IF(!HasEGLExtension("EGL_KHR_image_base"));
  70. // This extension is required to render an EGLImage into a GL texture.
  71. SKIP_TEST_IF(!HasGLExtension("GL_OES_EGL_image"));
  72. gfx::BufferFormat format = gfx::BufferFormat::RGBX_8888;
  73. gfx::Size size(kImageWidth, kImageHeight);
  74. size_t buffer_size = gfx::BufferSizeForBufferFormat(size, format);
  75. uint8_t pixel[] = {128u, 92u, 45u, 255u};
  76. size_t plane = 0;
  77. uint32_t stride = gfx::RowSizeForBufferFormat(size.width(), format, plane);
  78. std::unique_ptr<uint8_t[]> pixels(new uint8_t[buffer_size]);
  79. // Assign a value to each pixel.
  80. for (int y = 0; y < size.height(); ++y) {
  81. uint8_t* line = static_cast<uint8_t*>(pixels.get()) + y * stride;
  82. for (int x = 0; x < size.width() * 4; x += 4) {
  83. line[x + 0] = pixel[0];
  84. line[x + 1] = pixel[1];
  85. line[x + 2] = pixel[2];
  86. line[x + 3] = pixel[3];
  87. }
  88. }
  89. // Create an EGLImage from a GL texture.
  90. scoped_refptr<gl::GLImageNativePixmap> image =
  91. CreateGLImageNativePixmap(format, size, pixels.get());
  92. EXPECT_TRUE(image);
  93. EXPECT_EQ(size, image->GetSize());
  94. // Need a texture to bind the image.
  95. GLuint texture_id = 0;
  96. glGenTextures(1, &texture_id);
  97. ASSERT_NE(0u, texture_id);
  98. glActiveTexture(GL_TEXTURE0);
  99. glBindTexture(GL_TEXTURE_2D, texture_id);
  100. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  101. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  102. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  103. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  104. // Make sure the texture exists in the service side.
  105. glFinish();
  106. // Bind the image.
  107. EXPECT_TRUE(image->BindTexImage(GL_TEXTURE_2D));
  108. gl_.decoder()->SetLevelInfo(
  109. texture_id, 0 /* level */, image->GetInternalFormat(), size.width(),
  110. size.height(), 1 /* depth */, image->GetDataFormat(),
  111. image->GetDataType(), gfx::Rect(size));
  112. gl_.decoder()->BindImage(texture_id, GL_TEXTURE_2D, image.get(),
  113. true /* can_bind_to_sampler */);
  114. // Build program, buffers and draw the texture.
  115. GLuint vertex_shader =
  116. gpu::GLTestHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader);
  117. GLuint fragment_shader =
  118. gpu::GLTestHelper::LoadShader(GL_FRAGMENT_SHADER, kFragmentShader);
  119. GLuint program =
  120. gpu::GLTestHelper::SetupProgram(vertex_shader, fragment_shader);
  121. ASSERT_NE(0u, program);
  122. glUseProgram(program);
  123. GLint sampler_location = glGetUniformLocation(program, "a_texture");
  124. ASSERT_NE(-1, sampler_location);
  125. glUniform1i(sampler_location, 0);
  126. GLuint vbo = gpu::GLTestHelper::SetupUnitQuad(
  127. glGetAttribLocation(program, "a_position"));
  128. ASSERT_NE(0u, vbo);
  129. glViewport(0, 0, kImageWidth, kImageHeight);
  130. // Render the EGLImage into the GL texture.
  131. glDrawArrays(GL_TRIANGLES, 0, 6);
  132. ASSERT_TRUE(glGetError() == GL_NO_ERROR);
  133. // Check if pixels match the values that were assigned to the mapped buffer.
  134. gpu::GLTestHelper::CheckPixels(0, 0, kImageWidth, kImageHeight, 0, pixel,
  135. nullptr);
  136. EXPECT_TRUE(GL_NO_ERROR == glGetError());
  137. // Release the image.
  138. gl_.decoder()->BindImage(texture_id, GL_TEXTURE_2D, image.get(),
  139. false /* can_bind_to_sampler */);
  140. image->ReleaseTexImage(GL_TEXTURE_2D);
  141. // Clean up.
  142. glDeleteProgram(program);
  143. glDeleteShader(vertex_shader);
  144. glDeleteShader(fragment_shader);
  145. glDeleteBuffers(1, &vbo);
  146. glDeleteTextures(1, &texture_id);
  147. }
  148. #endif // !defined(ADDRESS_SANITIZER)
  149. #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  150. } // namespace