test_graphics_3d.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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 22const int32_t kInvalidContext = 0; 23 24REGISTER_TEST_CASE(Graphics3D); 25 26bool 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 33void 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 RUN_CALLBACK_TEST(TestGraphics3D, BadResource, filter); 38} 39 40std::string TestGraphics3D::TestFramePPAPI() { 41 const int width = 16; 42 const int height = 16; 43 const int32_t attribs[] = { 44 PP_GRAPHICS3DATTRIB_WIDTH, width, 45 PP_GRAPHICS3DATTRIB_HEIGHT, height, 46 PP_GRAPHICS3DATTRIB_NONE 47 }; 48 pp::Graphics3D context(instance_, attribs); 49 ASSERT_FALSE(context.is_null()); 50 51 const uint8_t red_color[4] = {255, 0, 0, 255}; 52 53 // Access OpenGLES API through the PPAPI interface. 54 // Clear color buffer to opaque red. 55 opengl_es2_->ClearColor(context.pp_resource(), 1.0f, 0.0f, 0.0f, 1.0f); 56 opengl_es2_->Clear(context.pp_resource(), GL_COLOR_BUFFER_BIT); 57 // Check if the color buffer has opaque red. 58 std::string error = CheckPixelPPAPI(&context, width/2, height/2, red_color); 59 if (!error.empty()) 60 return error; 61 62 int32_t rv = SwapBuffersSync(&context); 63 ASSERT_EQ(rv, PP_OK); 64 65 PASS(); 66} 67 68std::string TestGraphics3D::TestFrameGL() { 69 const int width = 16; 70 const int height = 16; 71 const int32_t attribs[] = { 72 PP_GRAPHICS3DATTRIB_WIDTH, width, 73 PP_GRAPHICS3DATTRIB_HEIGHT, height, 74 PP_GRAPHICS3DATTRIB_NONE 75 }; 76 pp::Graphics3D context(instance_, attribs); 77 ASSERT_FALSE(context.is_null()); 78 79 const uint8_t red_color[4] = {255, 0, 0, 255}; 80 // Perform same operations as TestFramePPAPI, but use OpenGLES API directly. 81 // This is how most developers will use OpenGLES. 82 glSetCurrentContextPPAPI(context.pp_resource()); 83 glClearColor(1.0f, 0.0f, 0.0f, 1.0f); 84 glClear(GL_COLOR_BUFFER_BIT); 85 std::string error = CheckPixelGL(width/2, height/2, red_color); 86 glSetCurrentContextPPAPI(kInvalidContext); 87 if (!error.empty()) 88 return error; 89 90 int32_t rv = SwapBuffersSync(&context); 91 ASSERT_EQ(rv, PP_OK); 92 93 PASS(); 94} 95 96std::string TestGraphics3D::TestExtensionsGL() { 97 const int width = 16; 98 const int height = 16; 99 const int32_t attribs[] = { 100 PP_GRAPHICS3DATTRIB_WIDTH, width, 101 PP_GRAPHICS3DATTRIB_HEIGHT, height, 102 PP_GRAPHICS3DATTRIB_NONE 103 }; 104 pp::Graphics3D context(instance_, attribs); 105 ASSERT_FALSE(context.is_null()); 106 107 glSetCurrentContextPPAPI(context.pp_resource()); 108 glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 109 glClear(GL_COLOR_BUFFER_BIT); 110 111 // Ask about a couple of extensions via glGetString. If an extension is 112 // available, try a couple of trivial calls. This test is not intended 113 // to be exhaustive; check the source can compile, link, and run without 114 // crashing. 115 ASSERT_NE(glGetString(GL_VERSION), NULL); 116 const char* ext = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); 117 if (strstr(ext, "GL_EXT_occlusion_query_boolean")) { 118 GLuint a_query; 119 GLboolean is_a_query; 120 glGenQueriesEXT(1, &a_query); 121 ASSERT_NE(a_query, 0); 122 glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, a_query); 123 is_a_query = glIsQueryEXT(a_query); 124 ASSERT_EQ(is_a_query, GL_TRUE); 125 glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT); 126 glDeleteQueriesEXT(1, &a_query); 127 } 128 if (strstr(ext, "GL_ANGLE_instanced_arrays")) { 129 glDrawArraysInstancedANGLE(GL_TRIANGLE_STRIP, 0, 0, 0); 130 } 131 glSetCurrentContextPPAPI(kInvalidContext); 132 133 int32_t rv = SwapBuffersSync(&context); 134 ASSERT_EQ(rv, PP_OK); 135 136 PASS(); 137} 138 139int32_t TestGraphics3D::SwapBuffersSync(pp::Graphics3D* context) { 140 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 141 callback.WaitForResult(context->SwapBuffers(callback.GetCallback())); 142 return callback.result(); 143} 144 145std::string TestGraphics3D::CheckPixelPPAPI( 146 pp::Graphics3D* context, 147 int x, int y, const uint8_t expected_color[4]) { 148 GLubyte pixel_color[4]; 149 opengl_es2_->ReadPixels(context->pp_resource(), 150 x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel_color); 151 152 ASSERT_EQ(pixel_color[0], expected_color[0]); 153 ASSERT_EQ(pixel_color[1], expected_color[1]); 154 ASSERT_EQ(pixel_color[2], expected_color[2]); 155 ASSERT_EQ(pixel_color[3], expected_color[3]); 156 PASS(); 157} 158 159std::string TestGraphics3D::CheckPixelGL( 160 int x, int y, const uint8_t expected_color[4]) { 161 GLubyte pixel_color[4]; 162 glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel_color); 163 164 ASSERT_EQ(pixel_color[0], expected_color[0]); 165 ASSERT_EQ(pixel_color[1], expected_color[1]); 166 ASSERT_EQ(pixel_color[2], expected_color[2]); 167 ASSERT_EQ(pixel_color[3], expected_color[3]); 168 PASS(); 169} 170 171std::string TestGraphics3D::TestBadResource() { 172 // The point of this test is mostly just to make sure that we don't crash and 173 // provide reasonable (error) results when the resource is bad. 174 const PP_Resource kBadResource = 123; 175 176 // Access OpenGLES API through the PPAPI interface. 177 opengl_es2_->ClearColor(kBadResource, 0.0f, 0.0f, 0.0f, 0.0f); 178 opengl_es2_->Clear(kBadResource, GL_COLOR_BUFFER_BIT); 179 ASSERT_EQ(0, opengl_es2_->GetError(kBadResource)); 180 ASSERT_EQ(NULL, opengl_es2_->GetString(kBadResource, GL_VERSION)); 181 ASSERT_EQ(-1, opengl_es2_->GetUniformLocation(kBadResource, 0, NULL)); 182 ASSERT_EQ(GL_FALSE, opengl_es2_->IsBuffer(kBadResource, 0)); 183 ASSERT_EQ(0, opengl_es2_->CheckFramebufferStatus(kBadResource, 184 GL_DRAW_FRAMEBUFFER)); 185 186 glSetCurrentContextPPAPI(kBadResource); 187 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 188 glClear(GL_COLOR_BUFFER_BIT); 189 ASSERT_EQ(0, glGetError()); 190 ASSERT_EQ(NULL, glGetString(GL_VERSION)); 191 ASSERT_EQ(-1, glGetUniformLocation(0, NULL)); 192 ASSERT_EQ(GL_FALSE, glIsBuffer(0)); 193 ASSERT_EQ(0, glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)); 194 glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 195 glClear(GL_COLOR_BUFFER_BIT); 196 197 PASS(); 198} 199 200