| // |
| // Copyright 2014 The ANGLE Project 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 "gmock/gmock.h" |
| #include "gtest/gtest.h" |
| |
| #include "libANGLE/AttributeMap.h" |
| #include "libANGLE/Config.h" |
| |
| // Create a generic, valid EGL config that can be modified to test sorting and |
| // filtering routines |
| static egl::Config GenerateGenericConfig() |
| { |
| egl::Config config; |
| |
| config.bufferSize = 24; |
| config.redSize = 8; |
| config.greenSize = 8; |
| config.blueSize = 8; |
| config.luminanceSize = 0; |
| config.alphaSize = 8; |
| config.alphaMaskSize = 0; |
| config.bindToTextureRGB = EGL_TRUE; |
| config.bindToTextureRGBA = EGL_TRUE; |
| config.colorBufferType = EGL_RGB_BUFFER; |
| config.configCaveat = EGL_NONE; |
| config.configID = 0; |
| config.conformant = EGL_OPENGL_ES2_BIT; |
| config.depthSize = 24; |
| config.level = 0; |
| config.matchNativePixmap = EGL_NONE; |
| config.maxPBufferWidth = 1024; |
| config.maxPBufferHeight = 1024; |
| config.maxPBufferPixels = config.maxPBufferWidth * config.maxPBufferWidth; |
| config.maxSwapInterval = 0; |
| config.minSwapInterval = 4; |
| config.nativeRenderable = EGL_OPENGL_ES2_BIT; |
| config.nativeVisualID = 0; |
| config.nativeVisualType = 0; |
| config.renderableType = EGL_FALSE; |
| config.sampleBuffers = 0; |
| config.samples = 0; |
| config.stencilSize = 8; |
| config.surfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; |
| config.transparentType = EGL_NONE; |
| config.transparentRedValue = 0; |
| config.transparentGreenValue = 0; |
| config.transparentBlueValue = 0; |
| |
| return config; |
| } |
| |
| static std::vector<egl::Config> GenerateUniqueConfigs(size_t count) |
| { |
| std::vector<egl::Config> configs; |
| |
| for (size_t i = 0; i < count; i++) |
| { |
| egl::Config config = GenerateGenericConfig(); |
| config.samples = static_cast<EGLint>(i); |
| configs.push_back(config); |
| } |
| |
| return configs; |
| } |
| |
| // Add unique configs to a ConfigSet and expect that the size of the |
| // set is equal to the number of configs added. |
| TEST(ConfigSetTest, Size) |
| { |
| egl::ConfigSet set; |
| |
| std::vector<egl::Config> uniqueConfigs = GenerateUniqueConfigs(16); |
| for (size_t i = 0; i < uniqueConfigs.size(); i++) |
| { |
| set.add(uniqueConfigs[i]); |
| EXPECT_EQ(set.size(), i + 1); |
| } |
| } |
| |
| // [EGL 1.5] section 3.4: |
| // EGL_CONFIG_ID is a unique integer identifying different EGLConfigs. Configuration IDs |
| // must be small positive integers starting at 1 and ID assignment should be compact; |
| // that is, if there are N EGLConfigs defined by the EGL implementation, their |
| // configuration IDs should be in the range [1, N]. |
| TEST(ConfigSetTest, IDs) |
| { |
| egl::ConfigSet set; |
| |
| std::set<EGLint> ids; |
| |
| std::vector<egl::Config> uniqueConfigs = GenerateUniqueConfigs(16); |
| for (size_t i = 0; i < uniqueConfigs.size(); i++) |
| { |
| EGLint id = set.add(uniqueConfigs[i]); |
| |
| // Check that the config that was inserted has the ID that was returned |
| // by ConfigSet::add |
| EXPECT_EQ(id, set.get(id).configID); |
| |
| ids.insert(id); |
| } |
| |
| // Verify configCount unique IDs |
| EXPECT_EQ(ids.size(), set.size()); |
| |
| // Check that there are no gaps and the IDs are in the range [1, N]. |
| EXPECT_EQ(*std::min_element(ids.begin(), ids.end()), 1); |
| EXPECT_EQ(*std::max_element(ids.begin(), ids.end()), static_cast<EGLint>(set.size())); |
| } |
| |
| TEST(ConfigSetTest, Filtering_BitSizes) |
| { |
| egl::ConfigSet set; |
| |
| struct VariableConfigBitSize |
| { |
| EGLint Name; |
| EGLint(egl::Config::*ConfigMember); |
| }; |
| |
| VariableConfigBitSize testMembers[] = { |
| {EGL_RED_SIZE, &egl::Config::redSize}, {EGL_GREEN_SIZE, &egl::Config::greenSize}, |
| {EGL_BLUE_SIZE, &egl::Config::blueSize}, {EGL_ALPHA_SIZE, &egl::Config::alphaSize}, |
| {EGL_DEPTH_SIZE, &egl::Config::depthSize}, {EGL_STENCIL_SIZE, &egl::Config::stencilSize}, |
| }; |
| |
| // Generate configsPerType configs with varying bit sizes of each type |
| size_t configsPerType = 4; |
| for (size_t i = 0; i < ArraySize(testMembers); i++) |
| { |
| for (size_t j = 0; j < configsPerType; j++) |
| { |
| egl::Config config = GenerateGenericConfig(); |
| |
| // Set all the other tested members of this config to 0 |
| for (size_t k = 0; k < ArraySize(testMembers); k++) |
| { |
| config.*(testMembers[k].ConfigMember) = 0; |
| } |
| |
| // Set the tested member of this config to i so it ranges from |
| // [1, configsPerType] |
| config.*(testMembers[i].ConfigMember) = static_cast<EGLint>(j) + 1; |
| |
| set.add(config); |
| } |
| } |
| |
| // for each tested member, filter by it's type and verify that the correct number |
| // of results are returned |
| for (size_t i = 0; i < ArraySize(testMembers); i++) |
| { |
| // Start with a filter of 1 to not grab the other members |
| for (EGLint j = 0; j < static_cast<EGLint>(configsPerType); j++) |
| { |
| egl::AttributeMap filter; |
| filter.insert(testMembers[i].Name, j + 1); |
| |
| std::vector<const egl::Config *> filteredConfigs = set.filter(filter); |
| |
| EXPECT_EQ(filteredConfigs.size(), configsPerType - j); |
| } |
| } |
| } |
| |
| // Verify the sorting, [EGL 1.5] section 3.4.1.2 pg 30: |
| // [configs are sorted] by larger total number of color bits (for an RGB |
| // color buffer this is the sum of EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_BLUE_SIZE, |
| // and EGL_ALPHA_SIZE; for a luminance color buffer, the sum of EGL_LUMINANCE_SIZE |
| // and EGL_ALPHA_SIZE).If the requested number of bits in attrib list for a |
| // particular color component is 0 or EGL_DONT_CARE, then the number of bits |
| // for that component is not considered. |
| TEST(ConfigSetTest, Sorting_BitSizes) |
| { |
| egl::ConfigSet set; |
| size_t testConfigCount = 64; |
| for (size_t i = 0; i < testConfigCount; i++) |
| { |
| egl::Config config = GenerateGenericConfig(); |
| |
| // Give random-ish bit sizes to the config |
| config.redSize = (i * 2) % 3; |
| config.greenSize = (i + 5) % 7; |
| config.blueSize = (i + 7) % 11; |
| config.alphaSize = (i + 13) % 17; |
| |
| set.add(config); |
| } |
| |
| egl::AttributeMap greaterThan1BitFilter; |
| greaterThan1BitFilter.insert(EGL_RED_SIZE, 1); |
| greaterThan1BitFilter.insert(EGL_GREEN_SIZE, 1); |
| greaterThan1BitFilter.insert(EGL_BLUE_SIZE, 1); |
| greaterThan1BitFilter.insert(EGL_ALPHA_SIZE, 1); |
| |
| std::vector<const egl::Config *> filteredConfigs = set.filter(greaterThan1BitFilter); |
| for (size_t i = 1; i < filteredConfigs.size(); i++) |
| { |
| const egl::Config &prevConfig = *filteredConfigs[i - 1]; |
| size_t prevBitCount = |
| prevConfig.redSize + prevConfig.greenSize + prevConfig.blueSize + prevConfig.alphaSize; |
| |
| const egl::Config &curConfig = *filteredConfigs[i]; |
| size_t curBitCount = |
| curConfig.redSize + curConfig.greenSize + curConfig.blueSize + curConfig.alphaSize; |
| |
| EXPECT_GE(prevBitCount, curBitCount); |
| } |
| } |