|  | // Copyright 2015 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include <stdint.h> | 
|  |  | 
|  | #include <memory> | 
|  |  | 
|  | #include "base/command_line.h" | 
|  | #include "base/macros.h" | 
|  | #include "testing/gtest/include/gtest/gtest.h" | 
|  | #include "ui/gl/gl_context.h" | 
|  | #include "ui/gl/gl_gl_api_implementation.h" | 
|  | #include "ui/gl/gl_implementation.h" | 
|  | #include "ui/gl/gl_switches.h" | 
|  | #include "ui/gl/gl_version_info.h" | 
|  | #include "ui/gl/gpu_timing.h" | 
|  |  | 
|  | namespace gl { | 
|  |  | 
|  | class GLApiTest : public testing::Test { | 
|  | public: | 
|  | void SetUp() override { | 
|  | fake_extension_string_ = ""; | 
|  | fake_version_string_ = ""; | 
|  | num_fake_extension_strings_ = 0; | 
|  | fake_extension_strings_ = nullptr; | 
|  |  | 
|  | SetGLGetProcAddressProc( | 
|  | static_cast<GLGetProcAddressProc>(&FakeGLGetProcAddress)); | 
|  | } | 
|  |  | 
|  | static GLFunctionPointerType GL_BINDING_CALL | 
|  | FakeGLGetProcAddress(const char* proc) { | 
|  | return reinterpret_cast<GLFunctionPointerType>(0x1); | 
|  | } | 
|  |  | 
|  | void TearDown() override { | 
|  | api_.reset(nullptr); | 
|  | driver_.reset(nullptr); | 
|  |  | 
|  | SetGLImplementation(kGLImplementationNone); | 
|  | fake_extension_string_ = ""; | 
|  | fake_version_string_ = ""; | 
|  | num_fake_extension_strings_ = 0; | 
|  | fake_extension_strings_ = nullptr; | 
|  | } | 
|  |  | 
|  | void InitializeAPI(const char* disabled_extensions) { | 
|  | driver_.reset(new DriverGL()); | 
|  | driver_->fn.glGetStringFn = &FakeGetString; | 
|  | driver_->fn.glGetStringiFn = &FakeGetStringi; | 
|  | driver_->fn.glGetIntegervFn = &FakeGetIntegervFn; | 
|  |  | 
|  | api_.reset(new RealGLApi()); | 
|  | if (disabled_extensions) { | 
|  | api_->SetDisabledExtensions(disabled_extensions); | 
|  | } | 
|  | api_->Initialize(driver_.get()); | 
|  |  | 
|  | std::string extensions_string = | 
|  | GetGLExtensionsFromCurrentContext(api_.get()); | 
|  | ExtensionSet extension_set = MakeExtensionSet(extensions_string); | 
|  |  | 
|  | auto version = std::make_unique<GLVersionInfo>( | 
|  | reinterpret_cast<const char*>(api_->glGetStringFn(GL_VERSION)), | 
|  | reinterpret_cast<const char*>(api_->glGetStringFn(GL_RENDERER)), | 
|  | extension_set); | 
|  |  | 
|  | driver_->InitializeDynamicBindings(version.get(), extension_set); | 
|  | api_->set_version(std::move(version)); | 
|  | } | 
|  |  | 
|  | void SetFakeExtensionString(const char* fake_string) { | 
|  | SetGLImplementation(kGLImplementationDesktopGL); | 
|  | fake_extension_string_ = fake_string; | 
|  | fake_version_string_ = "2.1"; | 
|  | } | 
|  |  | 
|  | void SetFakeExtensionStrings(const char** fake_strings, uint32_t count) { | 
|  | SetGLImplementation(kGLImplementationDesktopGL); | 
|  | num_fake_extension_strings_ = count; | 
|  | fake_extension_strings_ = fake_strings; | 
|  | fake_version_string_ = "3.0"; | 
|  | } | 
|  |  | 
|  | static const GLubyte* GL_BINDING_CALL FakeGetString(GLenum name) { | 
|  | if (name == GL_VERSION) | 
|  | return reinterpret_cast<const GLubyte*>(fake_version_string_); | 
|  | return reinterpret_cast<const GLubyte*>(fake_extension_string_); | 
|  | } | 
|  |  | 
|  | static void GL_BINDING_CALL FakeGetIntegervFn(GLenum pname, GLint* params) { | 
|  | *params = num_fake_extension_strings_; | 
|  | } | 
|  |  | 
|  | static const GLubyte* GL_BINDING_CALL FakeGetStringi(GLenum name, | 
|  | GLuint index) { | 
|  | return (index < num_fake_extension_strings_) ? | 
|  | reinterpret_cast<const GLubyte*>(fake_extension_strings_[index]) : | 
|  | nullptr; | 
|  | } | 
|  |  | 
|  | const char* GetExtensions() { | 
|  | return reinterpret_cast<const char*>(api_->glGetStringFn(GL_EXTENSIONS)); | 
|  | } | 
|  |  | 
|  | uint32_t GetNumExtensions() { | 
|  | GLint num_extensions = 0; | 
|  | api_->glGetIntegervFn(GL_NUM_EXTENSIONS, &num_extensions); | 
|  | return static_cast<uint32_t>(num_extensions); | 
|  | } | 
|  |  | 
|  | const char* GetExtensioni(uint32_t index) { | 
|  | return reinterpret_cast<const char*>(api_->glGetStringiFn(GL_EXTENSIONS, | 
|  | index)); | 
|  | } | 
|  |  | 
|  | protected: | 
|  | static const char* fake_extension_string_; | 
|  | static const char* fake_version_string_; | 
|  |  | 
|  | static uint32_t num_fake_extension_strings_; | 
|  | static const char** fake_extension_strings_; | 
|  |  | 
|  | std::unique_ptr<DriverGL> driver_; | 
|  | std::unique_ptr<RealGLApi> api_; | 
|  | }; | 
|  |  | 
|  | const char* GLApiTest::fake_extension_string_ = ""; | 
|  | const char* GLApiTest::fake_version_string_ = ""; | 
|  |  | 
|  | uint32_t GLApiTest::num_fake_extension_strings_ = 0; | 
|  | const char** GLApiTest::fake_extension_strings_ = nullptr; | 
|  |  | 
|  | TEST_F(GLApiTest, DisabledExtensionStringTest) { | 
|  | static const char* kFakeExtensions = "GL_EXT_1 GL_EXT_2 GL_EXT_3 GL_EXT_4"; | 
|  | static const char* kFakeDisabledExtensions = "GL_EXT_1,GL_EXT_2,GL_FAKE"; | 
|  | static const char* kFilteredExtensions = "GL_EXT_3 GL_EXT_4"; | 
|  |  | 
|  | SetFakeExtensionString(kFakeExtensions); | 
|  | InitializeAPI(nullptr); | 
|  | EXPECT_STREQ(kFakeExtensions, GetExtensions()); | 
|  |  | 
|  | InitializeAPI(kFakeDisabledExtensions); | 
|  | EXPECT_STREQ(kFilteredExtensions, GetExtensions()); | 
|  | } | 
|  |  | 
|  | TEST_F(GLApiTest, DisabledExtensionBitTest) { | 
|  | static const char* kFakeExtensions[] = { | 
|  | "GL_ARB_timer_query" | 
|  | }; | 
|  | static const char* kFakeDisabledExtensions = "GL_ARB_timer_query"; | 
|  |  | 
|  | SetFakeExtensionStrings(kFakeExtensions, arraysize(kFakeExtensions)); | 
|  | InitializeAPI(nullptr); | 
|  | EXPECT_TRUE(driver_->ext.b_GL_ARB_timer_query); | 
|  |  | 
|  | InitializeAPI(kFakeDisabledExtensions); | 
|  | EXPECT_FALSE(driver_->ext.b_GL_ARB_timer_query); | 
|  | } | 
|  |  | 
|  | TEST_F(GLApiTest, DisabledExtensionStringIndexTest) { | 
|  | static const char* kFakeExtensions[] = { | 
|  | "GL_EXT_1", | 
|  | "GL_EXT_2", | 
|  | "GL_EXT_3", | 
|  | "GL_EXT_4" | 
|  | }; | 
|  | static const char* kFakeDisabledExtensions = "GL_EXT_1,GL_EXT_2,GL_FAKE"; | 
|  | static const char* kFilteredExtensions[] = { | 
|  | "GL_EXT_3", | 
|  | "GL_EXT_4" | 
|  | }; | 
|  |  | 
|  | SetFakeExtensionStrings(kFakeExtensions, arraysize(kFakeExtensions)); | 
|  | InitializeAPI(nullptr); | 
|  |  | 
|  | EXPECT_EQ(arraysize(kFakeExtensions), GetNumExtensions()); | 
|  | for (uint32_t i = 0; i < arraysize(kFakeExtensions); ++i) { | 
|  | EXPECT_STREQ(kFakeExtensions[i], GetExtensioni(i)); | 
|  | } | 
|  |  | 
|  | InitializeAPI(kFakeDisabledExtensions); | 
|  | EXPECT_EQ(arraysize(kFilteredExtensions), GetNumExtensions()); | 
|  | for (uint32_t i = 0; i < arraysize(kFilteredExtensions); ++i) { | 
|  | EXPECT_STREQ(kFilteredExtensions[i], GetExtensioni(i)); | 
|  | } | 
|  | } | 
|  |  | 
|  | }  // namespace gl |