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