Commit 3d6e3004 by Ian Elliott Committed by Commit Bot

Implement EGL_ANDROID_recordable for Vulkan back-end.

This initial implementation provides the extension, and always answers that the ANativeWindow is not recordable. BUG=angleproject:2511 Change-Id: Id3c57351dd1029bff7adf7166f9c82eee6e634b3 Reviewed-on: https://chromium-review.googlesource.com/c/1412507 Commit-Queue: Ian Elliott <ianelliott@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent d4c09dd3
......@@ -1375,7 +1375,8 @@ DisplayExtensions::DisplayExtensions()
presentationTime(false),
blobCache(false),
imageNativeBuffer(false),
getFrameTimestamps(false)
getFrameTimestamps(false),
recordable(false)
{}
std::vector<std::string> DisplayExtensions::getStrings() const
......@@ -1428,6 +1429,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_ANDROID_blob_cache", blobCache, &extensionStrings);
InsertExtensionString("EGL_ANDROID_image_native_buffer", imageNativeBuffer, &extensionStrings);
InsertExtensionString("EGL_ANDROID_get_frame_timestamps", getFrameTimestamps, &extensionStrings);
InsertExtensionString("EGL_ANDROID_recordable", recordable, &extensionStrings);
// TODO(jmadill): Enable this when complete.
//InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings);
// clang-format on
......
......@@ -843,6 +843,9 @@ struct DisplayExtensions
// EGL_ANDROID_get_frame_timestamps
bool getFrameTimestamps;
// EGL_ANDROID_recordable
bool recordable;
};
struct DeviceExtensions
......
......@@ -59,7 +59,8 @@ Config::Config()
transparentGreenValue(0),
transparentBlueValue(0),
optimalOrientation(0),
colorComponentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT)
colorComponentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT),
recordable(EGL_FALSE)
{}
Config::~Config() {}
......@@ -266,7 +267,7 @@ std::vector<const Config *> ConfigSet::filter(const AttributeMap &attributeMap)
match = config.stencilSize >= attributeValue;
break;
case EGL_CONFIG_CAVEAT:
match = config.configCaveat == (EGLenum)attributeValue;
match = config.configCaveat == static_cast<EGLenum>(attributeValue);
break;
case EGL_CONFIG_ID:
match = config.configID == attributeValue;
......@@ -275,7 +276,7 @@ std::vector<const Config *> ConfigSet::filter(const AttributeMap &attributeMap)
match = config.level >= attributeValue;
break;
case EGL_NATIVE_RENDERABLE:
match = config.nativeRenderable == (EGLBoolean)attributeValue;
match = config.nativeRenderable == static_cast<EGLBoolean>(attributeValue);
break;
case EGL_NATIVE_VISUAL_TYPE:
match = config.nativeVisualType == attributeValue;
......@@ -290,7 +291,7 @@ std::vector<const Config *> ConfigSet::filter(const AttributeMap &attributeMap)
match = (config.surfaceType & attributeValue) == attributeValue;
break;
case EGL_TRANSPARENT_TYPE:
match = config.transparentType == (EGLenum)attributeValue;
match = config.transparentType == static_cast<EGLenum>(attributeValue);
break;
case EGL_TRANSPARENT_BLUE_VALUE:
match = config.transparentBlueValue == attributeValue;
......@@ -302,10 +303,10 @@ std::vector<const Config *> ConfigSet::filter(const AttributeMap &attributeMap)
match = config.transparentRedValue == attributeValue;
break;
case EGL_BIND_TO_TEXTURE_RGB:
match = config.bindToTextureRGB == (EGLBoolean)attributeValue;
match = config.bindToTextureRGB == static_cast<EGLBoolean>(attributeValue);
break;
case EGL_BIND_TO_TEXTURE_RGBA:
match = config.bindToTextureRGBA == (EGLBoolean)attributeValue;
match = config.bindToTextureRGBA == static_cast<EGLBoolean>(attributeValue);
break;
case EGL_MIN_SWAP_INTERVAL:
match = config.minSwapInterval == attributeValue;
......@@ -320,7 +321,7 @@ std::vector<const Config *> ConfigSet::filter(const AttributeMap &attributeMap)
match = config.alphaMaskSize >= attributeValue;
break;
case EGL_COLOR_BUFFER_TYPE:
match = config.colorBufferType == (EGLenum)attributeValue;
match = config.colorBufferType == static_cast<EGLenum>(attributeValue);
break;
case EGL_RENDERABLE_TYPE:
match = (config.renderableType & attributeValue) == attributeValue;
......@@ -347,6 +348,9 @@ std::vector<const Config *> ConfigSet::filter(const AttributeMap &attributeMap)
case EGL_COLOR_COMPONENT_TYPE_EXT:
match = config.colorComponentType == static_cast<EGLenum>(attributeValue);
break;
case EGL_RECORDABLE_ANDROID:
match = config.recordable == static_cast<EGLBoolean>(attributeValue);
break;
default:
UNREACHABLE();
}
......
......@@ -69,6 +69,7 @@ struct Config
EGLint transparentBlueValue; // Transparent blue value
EGLint optimalOrientation; // Optimal window surface orientation
EGLenum colorComponentType; // Color component type
EGLBoolean recordable; // EGL_TRUE if a surface can support recording on Android
};
class ConfigSet
......
......@@ -1195,6 +1195,10 @@ void Display::initDisplayExtensions()
// Blob cache extension is provided by the ANGLE frontend
mDisplayExtensions.blobCache = true;
// The EGL_ANDROID_recordable extension is provided by the ANGLE frontend, and will always say
// that ANativeWindow is not recordable.
mDisplayExtensions.recordable = true;
mDisplayExtensionString = GenerateExtensionsString(mDisplayExtensions);
}
......
......@@ -2867,6 +2867,9 @@ void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value)
case EGL_COLOR_COMPONENT_TYPE_EXT:
*value = config->colorComponentType;
break;
case EGL_RECORDABLE_ANDROID:
*value = config->recordable;
break;
default:
UNREACHABLE();
break;
......
......@@ -211,6 +211,13 @@ Error ValidateConfigAttribute(const Display *display, EGLAttrib attribute)
}
break;
case EGL_RECORDABLE_ANDROID:
if (!display->getExtensions().recordable)
{
return EglBadAttribute() << "EGL_ANDROID_recordable is not enabled.";
}
break;
default:
return EglBadAttribute() << "Unknown attribute.";
}
......@@ -276,6 +283,19 @@ Error ValidateConfigAttributeValue(const Display *display, EGLAttrib attribute,
}
break;
case EGL_RECORDABLE_ANDROID:
switch (value)
{
case EGL_TRUE:
case EGL_FALSE:
case EGL_DONT_CARE:
break;
default:
return EglBadAttribute()
<< "EGL_RECORDABLE_ANDROID invalid attribute: " << value;
}
break;
default:
break;
}
......
......@@ -130,6 +130,7 @@ angle_end2end_tests_sources = [
"egl_tests/EGLDebugTest.cpp",
"egl_tests/EGLProgramCacheControlTest.cpp",
"egl_tests/EGLQueryContextTest.cpp",
"egl_tests/EGLRecordableTest.cpp",
"egl_tests/EGLRobustnessTest.cpp",
"egl_tests/EGLSanityCheckTest.cpp",
"egl_tests/EGLSurfacelessContextTest.cpp",
......
//
// Copyright 2019 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.
//
// EGLRecordableTest.cpp:
// Tests of EGL_ANDROID_recordable extension
#include <gtest/gtest.h>
#include "test_utils/ANGLETest.h"
#include "test_utils/angle_test_configs.h"
#include "util/EGLWindow.h"
using namespace angle;
namespace angle
{
class EGLRecordableTest : public ANGLETest
{
protected:
EGLRecordableTest() : mDisplay(0) {}
void SetUp() override
{
ANGLETest::SetUp();
EGLint dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(), EGL_NONE};
mDisplay = eglGetPlatformDisplayEXT(
EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);
ASSERT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));
}
bool hasExtension() const
{
return ANGLETest::eglDisplayExtensionEnabled(mDisplay, "EGL_ANDROID_recordable");
}
void TearDown() override { eglTerminate(mDisplay); }
EGLDisplay mDisplay = EGL_NO_DISPLAY;
};
// Test that the extension is always available (it is implemented in ANGLE's frontend).
TEST_P(EGLRecordableTest, ExtensionAlwaysAvailable)
{
ASSERT_TRUE(hasExtension());
}
// Check that the default message filters and callbacks are correct
TEST_P(EGLRecordableTest, CheckAllContexts)
{
ANGLE_SKIP_TEST_IF(!hasExtension());
int nConfigs = 0;
ASSERT_EGL_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &nConfigs));
ASSERT_NE(nConfigs, 0);
int nReturnedConfigs = 0;
std::vector<EGLConfig> configs(nConfigs);
ASSERT_EGL_TRUE(eglGetConfigs(mDisplay, configs.data(), nConfigs, &nReturnedConfigs));
ASSERT_EQ(nConfigs, nReturnedConfigs);
for (EGLConfig config : configs)
{
EGLint isRecordable;
eglGetConfigAttrib(mDisplay, config, EGL_RECORDABLE_ANDROID, &isRecordable);
ASSERT_EGL_FALSE(isRecordable);
}
const EGLint configAttributes[] = {
EGL_RED_SIZE, EGL_DONT_CARE, EGL_GREEN_SIZE, EGL_DONT_CARE, EGL_BLUE_SIZE,
EGL_DONT_CARE, EGL_ALPHA_SIZE, EGL_DONT_CARE, EGL_DEPTH_SIZE, EGL_DONT_CARE,
EGL_STENCIL_SIZE, EGL_DONT_CARE, EGL_RECORDABLE_ANDROID, EGL_FALSE, EGL_NONE};
EGLint configCount;
ASSERT_EGL_TRUE(
eglChooseConfig(mDisplay, configAttributes, configs.data(), configs.size(), &configCount));
ASSERT_EGL_SUCCESS();
}
} // namespace angle
ANGLE_INSTANTIATE_TEST(EGLRecordableTest, ES2_D3D11(), ES2_OPENGL(), ES2_VULKAN());
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment