Hash :
5d9d9b9b
Author :
Date :
2025-08-19T17:12:03
test: Use eglGetPlatformDisplay()
From the EGL 1.5 spec:
Appendix F
Version 1.5
EGL version 1.5 was voted out of the Khronos Technical Working Group
on January 31, 2014, and formally approved by the Khronos Board of
Promoters on March 14, 2014.
EGL 1.5 is the sixth release of EGL. It introduces the following new
features (the EGL extension(s) each feature is based on are also shown
parenthetically):
* Platform support:
– Providing a mechanism for support of multiple platforms (such as
window systems or offscreen rendering frameworks) in a single EGL
implementation at runtime (EGL_EXT_platform_base).
Until https://crrev.com/c/6552257, many tests used
eglGetPlatformDisplayEXT() which is provided by the EGL
extension EGL_EXT_platform_base. With the promotion of the
EGL_EXT_platform_base functions to core EGL in version 1.5 and ANGLE
supporting EGL 1.5 (as of at least 2019), the calls were updated to use
eglGetPlatformDisplay().
Unfortunately, EGLContextPassthroughShadersTest was missed.
Bug: b/409384875
Test: angle_end2end_tests
Change-Id: I5c620bce98c8e76113588f4c94b77d95a5223171
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/6862841
Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Commit-Queue: Tim Van Patten <timvp@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
//
// Copyright 2025 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.
//
// EGLContextPassthroughShadersTest.cpp:
// Tests of the EGL_ANGLE_create_context_passthrough_shaders extension.
//
#include <gtest/gtest.h>
#include "GLES2/gl2.h"
#include "test_utils/ANGLETest.h"
#include "test_utils/angle_test_instantiate.h"
#include "test_utils/angle_test_platform.h"
#include "util/gles_loader_autogen.h"
using namespace angle;
class EGLContextPassthroughShadersTest : public ANGLETest<>
{
public:
EGLContextPassthroughShadersTest() : mDisplay(EGL_NO_DISPLAY) {}
void testSetUp() override
{
EGLAttrib dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(), EGL_NONE};
mDisplay = eglGetPlatformDisplay(GetEglPlatform(),
reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr) != EGL_FALSE);
EGLint attribs[] = {EGL_RED_SIZE,
8,
EGL_GREEN_SIZE,
8,
EGL_BLUE_SIZE,
8,
EGL_ALPHA_SIZE,
8,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE,
EGL_PBUFFER_BIT,
EGL_NONE};
EGLint count = 0;
EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, attribs, &mConfig, 1, &count));
ANGLE_SKIP_TEST_IF(mConfig == EGL_NO_CONFIG_KHR);
EXPECT_GT(count, 0);
EGLint pBufferAttribs[] = {EGL_WIDTH, 32, EGL_HEIGHT, 32, EGL_NONE};
mSurface = eglCreatePbufferSurface(mDisplay, mConfig, pBufferAttribs);
EXPECT_NE(mSurface, EGL_NO_SURFACE);
}
void testTearDown() override
{
if (mDisplay != EGL_NO_DISPLAY)
{
eglTerminate(mDisplay);
eglReleaseThread();
mDisplay = EGL_NO_DISPLAY;
}
ASSERT_EGL_SUCCESS() << "Error during test TearDown";
}
bool supportsPassthroughShadersExtension()
{
return IsEGLDisplayExtensionEnabled(mDisplay,
"EGL_ANGLE_create_context_passthrough_shaders");
}
EGLDisplay mDisplay;
EGLConfig mConfig;
EGLSurface mSurface;
};
// Test creating a context with passthrough shaders enabled and verify by querying translated
// shaders source
TEST_P(EGLContextPassthroughShadersTest, CreateContext)
{
ANGLE_SKIP_TEST_IF(!supportsPassthroughShadersExtension());
EGLint ctxAttribs[] = {EGL_CONTEXT_MAJOR_VERSION, 2, EGL_CONTEXT_PASSTHROUGH_SHADERS_ANGLE,
EGL_TRUE, EGL_NONE};
EGLContext context = eglCreateContext(mDisplay, mConfig, nullptr, ctxAttribs);
EXPECT_NE(context, EGL_NO_CONTEXT);
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, context));
constexpr const char kFragmentShader[] = R"(
precision highp float;
uniform sampler2D tex;
varying vec2 texcoord;
#define TEST_MACRO_THAT_WOULD_BE_REMOVED
void main()
{
gl_FragColor = texture2D(tex, texcoord);
}
)";
GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kFragmentShader);
EXPECT_TRUE(EnsureGLExtensionEnabled("GL_ANGLE_translated_shader_source"));
std::array<char, std::size(kFragmentShader) + 1> translatedSourceBuffer;
glGetTranslatedShaderSourceANGLE(shader, static_cast<GLsizei>(translatedSourceBuffer.size()),
nullptr, translatedSourceBuffer.data());
EXPECT_EQ(std::string(kFragmentShader), std::string(translatedSourceBuffer.data()));
}
// Regression test for a Skia shader which had assertion failures in CollectVariables
TEST_P(EGLContextPassthroughShadersTest, ShaderRegressionTest)
{
ANGLE_SKIP_TEST_IF(!supportsPassthroughShadersExtension());
EGLint ctxAttribs[] = {EGL_CONTEXT_MAJOR_VERSION, 3, EGL_CONTEXT_PASSTHROUGH_SHADERS_ANGLE,
EGL_TRUE, EGL_NONE};
EGLContext context = eglCreateContext(mDisplay, mConfig, nullptr, ctxAttribs);
EXPECT_NE(context, EGL_NO_CONTEXT);
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, context));
constexpr const char kShader[] = R"(#version 300 es
precision mediump float;
precision mediump sampler2D;
const highp float PRECISION = 4.0;
const highp float MAX_FIXED_RESOLVE_LEVEL = 5.0;
const highp float MAX_FIXED_SEGMENTS = 32.0;
uniform highp vec4 sk_RTAdjust;
uniform highp vec4 uaffineMatrix_S0;
uniform highp vec2 utranslate_S0;
in highp vec2 resolveLevel_and_idx;
in highp vec4 p01;
in highp vec4 p23;
in highp vec2 fanPointAttrib;
highp float wangs_formula_max_fdiff_p2_ff2f2f2f2f22(highp vec2 p0, highp vec2 p1, highp vec2 p2, highp vec2 p3, highp mat2 matrix) {
highp vec2 d0 = matrix * (((vec2(-2.0)) * (p1) + (p2)) + p0);
highp vec2 d1 = matrix * (((vec2(-2.0)) * (p2) + (p3)) + p1);
return max(dot(d0, d0), dot(d1, d1));
}
highp float wangs_formula_conic_p2_fff2f2f2f(highp float _precision_, highp vec2 p0, highp vec2 p1, highp vec2 p2, highp float w) {
highp vec2 C = (min(min(p0, p1), p2) + max(max(p0, p1), p2)) * 0.5;
p0 -= C;
p1 -= C;
p2 -= C;
highp float m = sqrt(max(max(dot(p0, p0), dot(p1, p1)), dot(p2, p2)));
highp vec2 dp = ((vec2(-2.0 * w)) * (p1) + (p0)) + p2;
highp float dw = abs(((-2.0) * (w) + (2.0)));
highp float rp_minus_1 = max(0.0, ((m) * (_precision_) + (-1.0)));
highp float numer = length(dp) * _precision_ + rp_minus_1 * dw;
highp float denom = 4.0 * min(w, 1.0);
return numer / denom;
}
void main() {
highp mat2 AFFINE_MATRIX = mat2(uaffineMatrix_S0.xy, uaffineMatrix_S0.zw);
highp vec2 TRANSLATE = utranslate_S0;
highp float resolveLevel = resolveLevel_and_idx.x;
highp float idxInResolveLevel = resolveLevel_and_idx.y;
highp vec2 localcoord;
if (resolveLevel < 0.0) {
localcoord = fanPointAttrib;
} else {
if (isinf(p23.z)) {
localcoord = resolveLevel != 0.0 ? p01.zw : (idxInResolveLevel != 0.0 ? p23.xy : p01.xy);
} else {
highp vec2 p0 = p01.xy;
highp vec2 p1 = p01.zw;
highp vec2 p2 = p23.xy;
highp vec2 p3 = p23.zw;
highp float w = -1.0;
highp float maxResolveLevel;
if (isinf(p23.w)) {
w = p3.x;
highp float _0_n2 = wangs_formula_conic_p2_fff2f2f2f(PRECISION, AFFINE_MATRIX * p0, AFFINE_MATRIX * p1, AFFINE_MATRIX * p2, w);
maxResolveLevel = ceil(log2(max(_0_n2, 1.0)) * 0.5);
p1 *= w;
p3 = p2;
} else {
highp float _1_m = wangs_formula_max_fdiff_p2_ff2f2f2f2f22(p0, p1, p2, p3, AFFINE_MATRIX);
maxResolveLevel = ceil(log2(max(9.0 * _1_m, 1.0)) * 0.25);
}
if (resolveLevel > maxResolveLevel) {
idxInResolveLevel = floor(idxInResolveLevel * exp2(maxResolveLevel - resolveLevel));
resolveLevel = maxResolveLevel;
}
highp float fixedVertexID = floor(0.5 + idxInResolveLevel * exp2(MAX_FIXED_RESOLVE_LEVEL - resolveLevel));
if (0.0 < fixedVertexID && fixedVertexID < MAX_FIXED_SEGMENTS) {
highp float T = fixedVertexID * 0.03125;
highp vec2 ab = mix(p0, p1, T);
highp vec2 bc = mix(p1, p2, T);
highp vec2 cd = mix(p2, p3, T);
highp vec2 abc = mix(ab, bc, T);
highp vec2 bcd = mix(bc, cd, T);
highp vec2 abcd = mix(abc, bcd, T);
highp float u = mix(1.0, w, T);
highp float v = (w + 1.0) - u;
highp float uv = mix(u, v, T);
localcoord = w < 0.0 ? abcd : abc / uv;
} else {
localcoord = fixedVertexID == 0.0 ? p0 : p3;
}
}
}
highp vec2 vertexpos = AFFINE_MATRIX * localcoord + TRANSLATE;
gl_Position = vec4(vertexpos, 0.0, 1.0);
gl_Position = vec4(gl_Position.xy * sk_RTAdjust.xz + gl_Position.ww * sk_RTAdjust.yw, 0.0, gl_Position.w);
}
)";
GLuint shader = CompileShader(GL_VERTEX_SHADER, kShader);
EXPECT_NE(0u, shader);
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLContextPassthroughShadersTest);
ANGLE_INSTANTIATE_TEST(EGLContextPassthroughShadersTest,
WithNoFixture(ES2_D3D9()),
WithNoFixture(ES2_D3D11()),
WithNoFixture(ES2_OPENGL()),
WithNoFixture(ES2_OPENGLES()),
WithNoFixture(ES2_VULKAN()),
WithNoFixture(ES3_D3D11()),
WithNoFixture(ES3_OPENGL()),
WithNoFixture(ES3_OPENGLES()),
WithNoFixture(ES3_VULKAN()));