gl_clear_framebuffer_unittest.cc 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. // Copyright 2014 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. #ifndef GL_GLEXT_PROTOTYPES
  5. #define GL_GLEXT_PROTOTYPES
  6. #endif
  7. #include <GLES2/gl2.h>
  8. #include <GLES2/gl2ext.h>
  9. #include <GLES2/gl2extchromium.h>
  10. #include <GLES3/gl3.h>
  11. #include <stdint.h>
  12. #include <vector>
  13. #include "build/build_config.h"
  14. #include "gpu/command_buffer/tests/gl_manager.h"
  15. #include "gpu/command_buffer/tests/gl_test_utils.h"
  16. #include "gpu/config/gpu_test_config.h"
  17. #include "testing/gmock/include/gmock/gmock.h"
  18. #include "testing/gtest/include/gtest/gtest.h"
  19. #include "ui/gfx/extension_set.h"
  20. #include "ui/gl/gl_context.h"
  21. #include "ui/gl/gl_version_info.h"
  22. namespace gpu {
  23. // A collection of tests that exercise the glClear workaround.
  24. class GLClearFramebufferTest : public testing::TestWithParam<bool> {
  25. public:
  26. GLClearFramebufferTest() : color_handle_(0u), depth_handle_(0u) {}
  27. protected:
  28. void SetUp() override {
  29. if (GetParam()) {
  30. // Force the glClear() workaround so we can test it here.
  31. GpuDriverBugWorkarounds workarounds;
  32. workarounds.gl_clear_broken = true;
  33. gl_.InitializeWithWorkarounds(GLManager::Options(), workarounds);
  34. DCHECK(gl_.workarounds().gl_clear_broken);
  35. } else {
  36. gl_.Initialize(GLManager::Options());
  37. DCHECK(!gl_.workarounds().gl_clear_broken);
  38. }
  39. }
  40. bool IsApplicable() {
  41. // The workaround doesn't use VAOs which would cause a failure on a core
  42. // context and the hardware for each the workaround is necessary has a buggy
  43. // VAO implementation. So we skip testing the workaround on core profiles.
  44. return !GetParam() ||
  45. !gl_.context()->GetVersionInfo()->is_desktop_core_profile;
  46. }
  47. void InitDraw();
  48. void SetDrawColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
  49. void SetDrawDepth(GLfloat depth);
  50. void DrawQuad();
  51. void TearDown() override {
  52. GLTestHelper::CheckGLError("no errors", __LINE__);
  53. gl_.Destroy();
  54. }
  55. private:
  56. GLManager gl_;
  57. GLuint color_handle_;
  58. GLuint depth_handle_;
  59. };
  60. void GLClearFramebufferTest::InitDraw() {
  61. static const char* v_shader_str =
  62. "attribute vec4 a_Position;\n"
  63. "uniform float u_depth;\n"
  64. "void main()\n"
  65. "{\n"
  66. " gl_Position = a_Position;\n"
  67. " gl_Position.z = u_depth;\n"
  68. "}\n";
  69. static const char* f_shader_str =
  70. "precision mediump float;\n"
  71. "uniform vec4 u_draw_color;\n"
  72. "void main()\n"
  73. "{\n"
  74. " gl_FragColor = u_draw_color;\n"
  75. "}\n";
  76. GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
  77. DCHECK(program);
  78. glUseProgram(program);
  79. GLuint position_loc = glGetAttribLocation(program, "a_Position");
  80. GLTestHelper::SetupUnitQuad(position_loc);
  81. color_handle_ = glGetUniformLocation(program, "u_draw_color");
  82. DCHECK(color_handle_ != static_cast<GLuint>(-1));
  83. depth_handle_ = glGetUniformLocation(program, "u_depth");
  84. DCHECK(depth_handle_ != static_cast<GLuint>(-1));
  85. }
  86. void GLClearFramebufferTest::SetDrawColor(GLfloat r,
  87. GLfloat g,
  88. GLfloat b,
  89. GLfloat a) {
  90. glUniform4f(color_handle_, r, g, b, a);
  91. }
  92. void GLClearFramebufferTest::SetDrawDepth(GLfloat depth) {
  93. glUniform1f(depth_handle_, depth);
  94. }
  95. void GLClearFramebufferTest::DrawQuad() {
  96. glDrawArrays(GL_TRIANGLES, 0, 6);
  97. }
  98. INSTANTIATE_TEST_SUITE_P(GLClearFramebufferTestWithParam,
  99. GLClearFramebufferTest,
  100. ::testing::Values(true, false));
  101. TEST_P(GLClearFramebufferTest, ClearColor) {
  102. if (!IsApplicable()) {
  103. return;
  104. }
  105. glClearColor(1.0f, 0.5f, 0.25f, 0.5f);
  106. glClear(GL_COLOR_BUFFER_BIT);
  107. // Verify.
  108. const uint8_t expected[] = {255, 128, 64, 128};
  109. EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 1 /* tolerance */, expected,
  110. nullptr));
  111. }
  112. TEST_P(GLClearFramebufferTest, ClearColorWithMask) {
  113. if (!IsApplicable()) {
  114. return;
  115. }
  116. glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
  117. glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  118. glClear(GL_COLOR_BUFFER_BIT);
  119. // Verify.
  120. const uint8_t expected[] = {255, 0, 0, 0};
  121. EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, expected,
  122. nullptr));
  123. }
  124. // crbug.com/434094
  125. #if !BUILDFLAG(IS_MAC)
  126. TEST_P(GLClearFramebufferTest, ClearColorWithScissor) {
  127. if (!IsApplicable()) {
  128. return;
  129. }
  130. // TODO(jonahr): Test fails on Linux with ANGLE/passthrough
  131. // (crbug.com/1099770)
  132. gpu::GPUTestBotConfig bot_config;
  133. if (bot_config.LoadCurrentConfig(nullptr) &&
  134. bot_config.Matches("linux passthrough")) {
  135. return;
  136. }
  137. glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  138. glClear(GL_COLOR_BUFFER_BIT);
  139. // Verify.
  140. const uint8_t expected[] = {255, 255, 255, 255};
  141. EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, expected,
  142. nullptr));
  143. glScissor(0, 0, 0, 0);
  144. glEnable(GL_SCISSOR_TEST);
  145. glClearColor(0, 0, 0, 0);
  146. glClear(GL_COLOR_BUFFER_BIT);
  147. // Verify - no changes.
  148. EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, expected,
  149. nullptr));
  150. }
  151. #endif
  152. TEST_P(GLClearFramebufferTest, ClearDepthStencil) {
  153. if (!IsApplicable()) {
  154. return;
  155. }
  156. // TODO(kainino): https://crbug.com/782317
  157. if (GPUTestBotConfig::CurrentConfigMatches("Intel")) {
  158. return;
  159. }
  160. const GLuint kStencilRef = 1 << 2;
  161. InitDraw();
  162. SetDrawColor(1.0f, 0.0f, 0.0f, 1.0f);
  163. DrawQuad();
  164. // Verify.
  165. const uint8_t kRed[] = {255, 0, 0, 255};
  166. const uint8_t kGreen[] = {0, 255, 0, 255};
  167. EXPECT_TRUE(
  168. GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kRed, nullptr));
  169. glClearStencil(kStencilRef);
  170. glClear(GL_STENCIL_BUFFER_BIT);
  171. glEnable(GL_STENCIL_TEST);
  172. glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  173. glStencilFunc(GL_NOTEQUAL, kStencilRef, 0xFFFFFFFF);
  174. SetDrawColor(0.0f, 1.0f, 0.0f, 1.0f);
  175. DrawQuad();
  176. // Verify - stencil should have failed, so still red.
  177. EXPECT_TRUE(
  178. GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kRed, nullptr));
  179. glStencilFunc(GL_EQUAL, kStencilRef, 0xFFFFFFFF);
  180. DrawQuad();
  181. // Verify - stencil should have passed, so green.
  182. EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kGreen,
  183. nullptr));
  184. glEnable(GL_DEPTH_TEST);
  185. glClearDepthf(0.0f);
  186. glClear(GL_DEPTH_BUFFER_BIT);
  187. SetDrawDepth(0.5f);
  188. SetDrawColor(1.0f, 0.0f, 0.0f, 1.0f);
  189. DrawQuad();
  190. // Verify - depth test should have failed, so still green.
  191. EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kGreen,
  192. nullptr));
  193. glClearDepthf(0.9f);
  194. glClear(GL_DEPTH_BUFFER_BIT);
  195. DrawQuad();
  196. // Verify - depth test should have passed, so red.
  197. EXPECT_TRUE(
  198. GLTestHelper::CheckPixels(0, 0, 1, 1, 0 /* tolerance */, kRed, nullptr));
  199. }
  200. TEST_P(GLClearFramebufferTest, SeparateFramebufferClear) {
  201. const char* extension_string =
  202. reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
  203. gfx::ExtensionSet extensions = gfx::MakeExtensionSet(extension_string);
  204. bool has_separate_framebuffer =
  205. gfx::HasExtension(extensions, "GL_CHROMIUM_framebuffer_multisample");
  206. if (!IsApplicable() || !has_separate_framebuffer) {
  207. return;
  208. }
  209. glClearColor(0.f, 0.f, 0.f, 1.f);
  210. glClear(GL_COLOR_BUFFER_BIT);
  211. // Bind incomplete read framebuffer, should not affect clear.
  212. GLuint fbo;
  213. glGenFramebuffers(1, &fbo);
  214. glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
  215. EXPECT_NE(glCheckFramebufferStatus(GL_READ_FRAMEBUFFER),
  216. static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE));
  217. glClearColor(1.f, 0.f, 0.f, 1.f);
  218. glClear(GL_COLOR_BUFFER_BIT);
  219. glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
  220. const uint8_t kRed[] = {255, 0, 0, 255};
  221. EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, kRed, nullptr));
  222. // Bind complete, but smaller read framebuffer, should not affect clear.
  223. GLuint texture;
  224. glGenTextures(1, &texture);
  225. glBindTexture(GL_TEXTURE_2D, texture);
  226. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  227. nullptr);
  228. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  229. glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
  230. glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
  231. GL_TEXTURE_2D, texture, 0);
  232. EXPECT_EQ(glCheckFramebufferStatus(GL_READ_FRAMEBUFFER),
  233. static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE));
  234. glClearColor(0.f, 1.f, 0.f, 1.f);
  235. glClear(GL_COLOR_BUFFER_BIT);
  236. glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
  237. const uint8_t kGreen[] = {0, 255, 0, 255};
  238. EXPECT_TRUE(GLTestHelper::CheckPixels(3, 3, 1, 1, 0, kGreen, nullptr));
  239. }
  240. class ES3ClearBufferTest : public testing::Test {
  241. protected:
  242. static const GLsizei kCanvasSize = 4;
  243. void SetUp() override {
  244. GLManager::Options options;
  245. options.size = gfx::Size(kCanvasSize, kCanvasSize);
  246. options.context_type = CONTEXT_TYPE_OPENGLES3;
  247. gl_.Initialize(options);
  248. }
  249. bool ShouldSkipTest() const {
  250. // If a driver isn't capable of supporting ES3 context, creating
  251. // ContextGroup will fail.
  252. // See crbug.com/654709.
  253. return (!gl_.decoder() || !gl_.decoder()->GetContextGroup());
  254. }
  255. void TearDown() override {
  256. gl_.Destroy();
  257. }
  258. GLManager gl_;
  259. };
  260. TEST_F(ES3ClearBufferTest, ClearBuffersuiv) {
  261. if (ShouldSkipTest())
  262. return;
  263. // This is a regression test for https://crbug.com/908749
  264. GLuint value[1] = {0u};
  265. glClearBufferuiv(GL_STENCIL, 0, value);
  266. // The above call should not crash in ASAN build.
  267. EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError());
  268. GLTestHelper::CheckGLError("no errors", __LINE__);
  269. }
  270. } // namespace gpu