test_graphics_3d.cc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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
  3. // found in the LICENSE file.
  4. #include "ppapi/tests/test_graphics_3d.h"
  5. #include <GLES2/gl2.h>
  6. #include <GLES2/gl2ext.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "ppapi/c/ppb_opengles2.h"
  11. #include "ppapi/cpp/graphics_3d.h"
  12. #include "ppapi/cpp/module.h"
  13. #include "ppapi/lib/gl/gles2/gl2ext_ppapi.h"
  14. #include "ppapi/tests/test_case.h"
  15. #include "ppapi/tests/test_utils.h"
  16. #include "ppapi/tests/testing_instance.h"
  17. const int32_t kInvalidContext = 0;
  18. REGISTER_TEST_CASE(Graphics3D);
  19. bool TestGraphics3D::Init() {
  20. opengl_es2_ = static_cast<const PPB_OpenGLES2*>(
  21. pp::Module::Get()->GetBrowserInterface(PPB_OPENGLES2_INTERFACE));
  22. glInitializePPAPI(pp::Module::Get()->get_browser_interface());
  23. return opengl_es2_ && CheckTestingInterface();
  24. }
  25. void TestGraphics3D::RunTests(const std::string& filter) {
  26. RUN_CALLBACK_TEST(TestGraphics3D, FramePPAPI, filter);
  27. RUN_CALLBACK_TEST(TestGraphics3D, FrameGL, filter);
  28. RUN_CALLBACK_TEST(TestGraphics3D, ExtensionsGL, filter);
  29. RUN_CALLBACK_TEST(TestGraphics3D, BadResource, filter);
  30. }
  31. std::string TestGraphics3D::TestFramePPAPI() {
  32. const int width = 16;
  33. const int height = 16;
  34. const int32_t attribs[] = {
  35. PP_GRAPHICS3DATTRIB_WIDTH, width,
  36. PP_GRAPHICS3DATTRIB_HEIGHT, height,
  37. PP_GRAPHICS3DATTRIB_NONE
  38. };
  39. pp::Graphics3D context(instance_, attribs);
  40. ASSERT_FALSE(context.is_null());
  41. const uint8_t red_color[4] = {255, 0, 0, 255};
  42. // Access OpenGLES API through the PPAPI interface.
  43. // Clear color buffer to opaque red.
  44. opengl_es2_->ClearColor(context.pp_resource(), 1.0f, 0.0f, 0.0f, 1.0f);
  45. opengl_es2_->Clear(context.pp_resource(), GL_COLOR_BUFFER_BIT);
  46. // Check if the color buffer has opaque red.
  47. std::string error = CheckPixelPPAPI(&context, width/2, height/2, red_color);
  48. if (!error.empty())
  49. return error;
  50. int32_t rv = SwapBuffersSync(&context);
  51. ASSERT_EQ(PP_OK, rv);
  52. PASS();
  53. }
  54. std::string TestGraphics3D::TestFrameGL() {
  55. const int width = 16;
  56. const int height = 16;
  57. const int32_t attribs[] = {
  58. PP_GRAPHICS3DATTRIB_WIDTH, width,
  59. PP_GRAPHICS3DATTRIB_HEIGHT, height,
  60. PP_GRAPHICS3DATTRIB_NONE
  61. };
  62. pp::Graphics3D context(instance_, attribs);
  63. ASSERT_FALSE(context.is_null());
  64. const uint8_t red_color[4] = {255, 0, 0, 255};
  65. // Perform same operations as TestFramePPAPI, but use OpenGLES API directly.
  66. // This is how most developers will use OpenGLES.
  67. glSetCurrentContextPPAPI(context.pp_resource());
  68. glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
  69. glClear(GL_COLOR_BUFFER_BIT);
  70. std::string error = CheckPixelGL(width/2, height/2, red_color);
  71. glSetCurrentContextPPAPI(kInvalidContext);
  72. if (!error.empty())
  73. return error;
  74. int32_t rv = SwapBuffersSync(&context);
  75. ASSERT_EQ(PP_OK, rv);
  76. PASS();
  77. }
  78. std::string TestGraphics3D::TestExtensionsGL() {
  79. const int width = 16;
  80. const int height = 16;
  81. const int32_t attribs[] = {
  82. PP_GRAPHICS3DATTRIB_WIDTH, width,
  83. PP_GRAPHICS3DATTRIB_HEIGHT, height,
  84. PP_GRAPHICS3DATTRIB_NONE
  85. };
  86. pp::Graphics3D context(instance_, attribs);
  87. ASSERT_FALSE(context.is_null());
  88. glSetCurrentContextPPAPI(context.pp_resource());
  89. glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  90. glClear(GL_COLOR_BUFFER_BIT);
  91. // Ask about a couple of extensions via glGetString. If an extension is
  92. // available, try a couple of trivial calls. This test is not intended
  93. // to be exhaustive; check the source can compile, link, and run without
  94. // crashing.
  95. ASSERT_NE(NULL, glGetString(GL_VERSION));
  96. const char* ext = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
  97. if (strstr(ext, "GL_EXT_occlusion_query_boolean")) {
  98. GLuint a_query = 0;
  99. glGenQueriesEXT(1, &a_query);
  100. ASSERT_NE(0, a_query);
  101. glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, a_query);
  102. GLboolean is_a_query = glIsQueryEXT(a_query);
  103. ASSERT_EQ(is_a_query, GL_TRUE);
  104. glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
  105. glDeleteQueriesEXT(1, &a_query);
  106. }
  107. if (strstr(ext, "GL_ANGLE_instanced_arrays")) {
  108. glDrawArraysInstancedANGLE(GL_TRIANGLE_STRIP, 0, 0, 0);
  109. }
  110. if (strstr(ext, "GL_OES_vertex_array_object")) {
  111. GLuint a_vertex_array = 0;
  112. glGenVertexArraysOES(1, &a_vertex_array);
  113. ASSERT_NE(0, a_vertex_array);
  114. glBindVertexArrayOES(a_vertex_array);
  115. GLboolean is_a_vertex_array = glIsVertexArrayOES(a_vertex_array);
  116. ASSERT_EQ(is_a_vertex_array, GL_TRUE);
  117. glBindVertexArrayOES(0);
  118. glDeleteVertexArraysOES(1, &a_vertex_array);
  119. }
  120. glSetCurrentContextPPAPI(kInvalidContext);
  121. int32_t rv = SwapBuffersSync(&context);
  122. ASSERT_EQ(PP_OK, rv);
  123. PASS();
  124. }
  125. int32_t TestGraphics3D::SwapBuffersSync(pp::Graphics3D* context) {
  126. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  127. callback.WaitForResult(context->SwapBuffers(callback.GetCallback()));
  128. return callback.result();
  129. }
  130. std::string TestGraphics3D::CheckPixelPPAPI(
  131. pp::Graphics3D* context,
  132. int x, int y, const uint8_t expected_color[4]) {
  133. GLubyte pixel_color[4];
  134. opengl_es2_->ReadPixels(context->pp_resource(),
  135. x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel_color);
  136. ASSERT_EQ(pixel_color[0], expected_color[0]);
  137. ASSERT_EQ(pixel_color[1], expected_color[1]);
  138. ASSERT_EQ(pixel_color[2], expected_color[2]);
  139. ASSERT_EQ(pixel_color[3], expected_color[3]);
  140. PASS();
  141. }
  142. std::string TestGraphics3D::CheckPixelGL(
  143. int x, int y, const uint8_t expected_color[4]) {
  144. GLubyte pixel_color[4];
  145. glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel_color);
  146. ASSERT_EQ(pixel_color[0], expected_color[0]);
  147. ASSERT_EQ(pixel_color[1], expected_color[1]);
  148. ASSERT_EQ(pixel_color[2], expected_color[2]);
  149. ASSERT_EQ(pixel_color[3], expected_color[3]);
  150. PASS();
  151. }
  152. std::string TestGraphics3D::TestBadResource() {
  153. // The point of this test is mostly just to make sure that we don't crash and
  154. // provide reasonable (error) results when the resource is bad.
  155. const PP_Resource kBadResource = 123;
  156. // Access OpenGLES API through the PPAPI interface.
  157. opengl_es2_->ClearColor(kBadResource, 0.0f, 0.0f, 0.0f, 0.0f);
  158. opengl_es2_->Clear(kBadResource, GL_COLOR_BUFFER_BIT);
  159. ASSERT_EQ(0, opengl_es2_->GetError(kBadResource));
  160. ASSERT_EQ(NULL, opengl_es2_->GetString(kBadResource, GL_VERSION));
  161. ASSERT_EQ(-1, opengl_es2_->GetUniformLocation(kBadResource, 0, NULL));
  162. ASSERT_EQ(GL_FALSE, opengl_es2_->IsBuffer(kBadResource, 0));
  163. ASSERT_EQ(0, opengl_es2_->CheckFramebufferStatus(kBadResource,
  164. GL_DRAW_FRAMEBUFFER));
  165. glSetCurrentContextPPAPI(kBadResource);
  166. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  167. glClear(GL_COLOR_BUFFER_BIT);
  168. ASSERT_EQ(0, glGetError());
  169. ASSERT_EQ(NULL, glGetString(GL_VERSION));
  170. ASSERT_EQ(-1, glGetUniformLocation(0, NULL));
  171. ASSERT_EQ(GL_FALSE, glIsBuffer(0));
  172. ASSERT_EQ(0, glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
  173. glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  174. glClear(GL_COLOR_BUFFER_BIT);
  175. PASS();
  176. }