Path: blob/main_old/src/tests/egl_tests/EGLIOSurfaceClientBufferTest.cpp
1693 views
//1// Copyright 2017 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// EGLIOSurfaceClientBufferTest.cpp: tests for the EGL_ANGLE_iosurface_client_buffer extension.6//78#include "test_utils/ANGLETest.h"910#include "common/mathutil.h"11#include "test_utils/gl_raii.h"12#include "util/EGLWindow.h"1314#include <CoreFoundation/CoreFoundation.h>15#include <IOSurface/IOSurface.h>1617using namespace angle;1819namespace20{2122constexpr char kIOSurfaceExt[] = "EGL_ANGLE_iosurface_client_buffer";2324void AddIntegerValue(CFMutableDictionaryRef dictionary, const CFStringRef key, int32_t value)25{26CFNumberRef number = CFNumberCreate(nullptr, kCFNumberSInt32Type, &value);27CFDictionaryAddValue(dictionary, key, number);28CFRelease(number);29}3031class ScopedIOSurfaceRef : angle::NonCopyable32{33public:34explicit ScopedIOSurfaceRef(IOSurfaceRef surface) : mSurface(surface) {}3536~ScopedIOSurfaceRef()37{38if (mSurface != nullptr)39{40CFRelease(mSurface);41mSurface = nullptr;42}43}4445IOSurfaceRef get() const { return mSurface; }4647ScopedIOSurfaceRef(ScopedIOSurfaceRef &&other)48{49if (mSurface != nullptr)50{51CFRelease(mSurface);52}53mSurface = other.mSurface;54other.mSurface = nullptr;55}5657ScopedIOSurfaceRef &operator=(ScopedIOSurfaceRef &&other)58{59if (mSurface != nullptr)60{61CFRelease(mSurface);62}63mSurface = other.mSurface;64other.mSurface = nullptr;6566return *this;67}6869private:70IOSurfaceRef mSurface = nullptr;71};7273struct IOSurfacePlaneInfo74{75int width;76int height;77int bytesPerElement;78};7980ScopedIOSurfaceRef CreateIOSurface(int32_t format, const std::vector<IOSurfacePlaneInfo> &planes)81{82EXPECT_GT(planes.size(), 0u);8384CFMutableDictionaryRef dict = CFDictionaryCreateMutable(85kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);86AddIntegerValue(dict, kIOSurfaceWidth, planes[0].width);87AddIntegerValue(dict, kIOSurfaceHeight, planes[0].height);88AddIntegerValue(dict, kIOSurfacePixelFormat, format);8990if (planes.size() > 1)91{92CFMutableArrayRef planesInfo =93CFArrayCreateMutable(kCFAllocatorDefault, planes.size(), &kCFTypeArrayCallBacks);94for (const IOSurfacePlaneInfo &plane : planes)95{96CFMutableDictionaryRef planeInfo =97CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,98&kCFTypeDictionaryValueCallBacks);99AddIntegerValue(planeInfo, kIOSurfacePlaneWidth, plane.width);100AddIntegerValue(planeInfo, kIOSurfacePlaneHeight, plane.height);101AddIntegerValue(planeInfo, kIOSurfacePlaneBytesPerElement, plane.bytesPerElement);102103CFArrayAppendValue(planesInfo, planeInfo);104CFRelease(planeInfo);105}106107CFDictionaryAddValue(dict, kIOSurfacePlaneInfo, planesInfo);108CFRelease(planesInfo);109}110else111{112AddIntegerValue(dict, kIOSurfaceBytesPerElement, planes[0].bytesPerElement);113}114115IOSurfaceRef ioSurface = IOSurfaceCreate(dict);116EXPECT_NE(nullptr, ioSurface);117CFRelease(dict);118119return ScopedIOSurfaceRef(ioSurface);120}121122ScopedIOSurfaceRef CreateSinglePlaneIOSurface(int width,123int height,124int32_t format,125int bytesPerElement)126{127std::vector<IOSurfacePlaneInfo> planes{{width, height, bytesPerElement}};128return CreateIOSurface(format, planes);129}130131} // anonymous namespace132133class IOSurfaceClientBufferTest : public ANGLETest134{135protected:136EGLint getTextureTarget() const137{138EGLint target = 0;139eglGetConfigAttrib(mDisplay, mConfig, EGL_BIND_TO_TEXTURE_TARGET_ANGLE, &target);140return target;141}142143GLint getGLTextureTarget() const144{145EGLint targetEGL = getTextureTarget();146GLenum targetGL = 0;147switch (targetEGL)148{149case EGL_TEXTURE_2D:150targetGL = GL_TEXTURE_2D;151break;152case EGL_TEXTURE_RECTANGLE_ANGLE:153targetGL = GL_TEXTURE_RECTANGLE_ANGLE;154break;155default:156break;157}158return targetGL;159}160161IOSurfaceClientBufferTest() : mConfig(0), mDisplay(nullptr) {}162163void testSetUp() override164{165mConfig = getEGLWindow()->getConfig();166mDisplay = getEGLWindow()->getDisplay();167}168169void createIOSurfacePbuffer(const ScopedIOSurfaceRef &ioSurface,170EGLint width,171EGLint height,172EGLint plane,173GLenum internalFormat,174GLenum type,175EGLSurface *pbuffer) const176{177// clang-format off178const EGLint attribs[] = {179EGL_WIDTH, width,180EGL_HEIGHT, height,181EGL_IOSURFACE_PLANE_ANGLE, plane,182EGL_TEXTURE_TARGET, getTextureTarget(),183EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,184static_cast<EGLint>(internalFormat),185EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,186EGL_TEXTURE_TYPE_ANGLE, static_cast<EGLint>(type),187EGL_NONE, EGL_NONE,188};189// clang-format on190191*pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE, ioSurface.get(),192mConfig, attribs);193EXPECT_NE(EGL_NO_SURFACE, *pbuffer);194}195196void bindIOSurfaceToTexture(const ScopedIOSurfaceRef &ioSurface,197EGLint width,198EGLint height,199EGLint plane,200GLenum internalFormat,201GLenum type,202EGLSurface *pbuffer,203GLTexture *texture) const204{205createIOSurfacePbuffer(ioSurface, width, height, plane, internalFormat, type, pbuffer);206207// Bind the pbuffer208glBindTexture(getGLTextureTarget(), *texture);209EGLBoolean result = eglBindTexImage(mDisplay, *pbuffer, EGL_BACK_BUFFER);210EXPECT_EGL_TRUE(result);211EXPECT_EGL_SUCCESS();212}213214void doClearTest(const ScopedIOSurfaceRef &ioSurface,215EGLint width,216EGLint height,217EGLint plane,218GLenum internalFormat,219GLenum type,220const GLColor &data)221{222std::array<uint8_t, 4> dataArray{data.R, data.G, data.B, data.A};223doClearTest(ioSurface, width, height, plane, internalFormat, type, dataArray);224}225226template <typename T, size_t dataSize>227void doClearTest(const ScopedIOSurfaceRef &ioSurface,228EGLint width,229EGLint height,230EGLint plane,231GLenum internalFormat,232GLenum type,233const std::array<T, dataSize> &data)234{235// Bind the IOSurface to a texture and clear it.236EGLSurface pbuffer;237GLTexture texture;238bindIOSurfaceToTexture(ioSurface, width, height, plane, internalFormat, type, &pbuffer,239&texture);240241GLFramebuffer fbo;242glBindFramebuffer(GL_FRAMEBUFFER, fbo);243EXPECT_GL_NO_ERROR();244glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, getGLTextureTarget(), texture,2450);246EXPECT_GL_NO_ERROR();247ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);248EXPECT_GL_NO_ERROR();249250glClearColor(1.0f / 255.0f, 2.0f / 255.0f, 3.0f / 255.0f, 4.0f / 255.0f);251EXPECT_GL_NO_ERROR();252glClear(GL_COLOR_BUFFER_BIT);253EXPECT_GL_NO_ERROR();254255// Unbind pbuffer and check content.256EGLBoolean result = eglReleaseTexImage(mDisplay, pbuffer, EGL_BACK_BUFFER);257EXPECT_EGL_TRUE(result);258EXPECT_EGL_SUCCESS();259260// IOSurface client buffer's rendering doesn't automatically finish after261// eglReleaseTexImage(). Need to explicitly call glFinish().262glFinish();263264IOSurfaceLock(ioSurface.get(), kIOSurfaceLockReadOnly, nullptr);265std::array<T, dataSize> iosurfaceData;266memcpy(iosurfaceData.data(), IOSurfaceGetBaseAddressOfPlane(ioSurface.get(), plane),267sizeof(T) * data.size());268IOSurfaceUnlock(ioSurface.get(), kIOSurfaceLockReadOnly, nullptr);269270if (internalFormat == GL_RGB && IsOSX() && IsOpenGL())271{272// Ignore alpha component for BGRX, the alpha value is undefined273for (int i = 0; i < 3; i++)274{275ASSERT_EQ(data[i], iosurfaceData[i]);276}277}278else279{280ASSERT_EQ(data, iosurfaceData);281}282283result = eglDestroySurface(mDisplay, pbuffer);284EXPECT_EGL_TRUE(result);285EXPECT_EGL_SUCCESS();286}287288enum ColorMask289{290R = 1,291G = 2,292B = 4,293A = 8,294};295void doSampleTest(const ScopedIOSurfaceRef &ioSurface,296EGLint width,297EGLint height,298EGLint plane,299GLenum internalFormat,300GLenum type,301void *data,302size_t dataSize,303int mask)304{305// Write the data to the IOSurface306IOSurfaceLock(ioSurface.get(), 0, nullptr);307memcpy(IOSurfaceGetBaseAddressOfPlane(ioSurface.get(), plane), data, dataSize);308IOSurfaceUnlock(ioSurface.get(), 0, nullptr);309310GLTexture texture;311glBindTexture(getGLTextureTarget(), texture);312glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST);313glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST);314315// Bind the IOSurface to a texture and clear it.316EGLSurface pbuffer;317bindIOSurfaceToTexture(ioSurface, width, height, plane, internalFormat, type, &pbuffer,318&texture);319320doSampleTestWithTexture(texture, mask);321322EGLBoolean result = eglDestroySurface(mDisplay, pbuffer);323EXPECT_EGL_TRUE(result);324EXPECT_EGL_SUCCESS();325}326327void doSampleTestWithTexture(const GLTexture &texture, int mask)328{329constexpr char kVS[] =330"attribute vec4 position;\n"331"void main()\n"332"{\n"333" gl_Position = vec4(position.xy, 0.0, 1.0);\n"334"}\n";335constexpr char kFS_rect[] =336"#extension GL_ARB_texture_rectangle : require\n"337"precision mediump float;\n"338"uniform sampler2DRect tex;\n"339"void main()\n"340"{\n"341" gl_FragColor = texture2DRect(tex, vec2(0, 0));\n"342"}\n";343constexpr char kFS_2D[] =344"precision mediump float;\n"345"uniform sampler2D tex;\n"346"void main()\n"347"{\n"348" gl_FragColor = texture2D(tex, vec2(0, 0));\n"349"}\n";350351ANGLE_GL_PROGRAM(program, kVS,352(getTextureTarget() == EGL_TEXTURE_RECTANGLE_ANGLE ? kFS_rect : kFS_2D));353glUseProgram(program);354355GLint location = glGetUniformLocation(program, "tex");356ASSERT_NE(-1, location);357glUniform1i(location, 0);358359glClearColor(0.0, 0.0, 0.0, 0.0);360glClear(GL_COLOR_BUFFER_BIT);361drawQuad(program, "position", 0.5f, 1.0f, false);362363GLColor expectedColor((mask & R) ? 1 : 0, (mask & G) ? 2 : 0, (mask & B) ? 3 : 0,364(mask & A) ? 4 : 255);365EXPECT_PIXEL_COLOR_EQ(0, 0, expectedColor);366ASSERT_GL_NO_ERROR();367}368369void doBlitTest(bool ioSurfaceIsSource, int width, int height)370{371if (!hasBlitExt())372{373return;374}375376// Create IOSurface and bind it to a texture.377ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(width, height, 'BGRA', 4);378EGLSurface pbuffer;379GLTexture texture;380bindIOSurfaceToTexture(ioSurface, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, &pbuffer,381&texture);382383GLFramebuffer iosurfaceFbo;384glBindFramebuffer(GL_FRAMEBUFFER, iosurfaceFbo);385EXPECT_GL_NO_ERROR();386glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, getGLTextureTarget(), texture,3870);388EXPECT_GL_NO_ERROR();389ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);390EXPECT_GL_NO_ERROR();391392// Create another framebuffer with a regular renderbuffer.393GLFramebuffer fbo;394glBindFramebuffer(GL_FRAMEBUFFER, fbo);395EXPECT_GL_NO_ERROR();396GLRenderbuffer rbo;397glBindRenderbuffer(GL_RENDERBUFFER, rbo);398EXPECT_GL_NO_ERROR();399glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);400EXPECT_GL_NO_ERROR();401glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);402EXPECT_GL_NO_ERROR();403ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);404EXPECT_GL_NO_ERROR();405406glBindRenderbuffer(GL_RENDERBUFFER, 0);407EXPECT_GL_NO_ERROR();408glBindFramebuffer(GL_FRAMEBUFFER, 0);409EXPECT_GL_NO_ERROR();410411// Choose which is going to be the source and destination.412GLFramebuffer &src = ioSurfaceIsSource ? iosurfaceFbo : fbo;413GLFramebuffer &dst = ioSurfaceIsSource ? fbo : iosurfaceFbo;414415// Clear source to known color.416glBindFramebuffer(GL_FRAMEBUFFER, src);417glClearColor(1.0f / 255.0f, 2.0f / 255.0f, 3.0f / 255.0f, 4.0f / 255.0f);418EXPECT_GL_NO_ERROR();419glClear(GL_COLOR_BUFFER_BIT);420EXPECT_GL_NO_ERROR();421422// Blit to destination.423glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, dst);424glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT,425GL_NEAREST);426427// Read back from destination.428glBindFramebuffer(GL_FRAMEBUFFER, dst);429GLColor expectedColor(1, 2, 3, 4);430EXPECT_PIXEL_COLOR_EQ(0, 0, expectedColor);431432// Unbind pbuffer and check content.433EGLBoolean result = eglReleaseTexImage(mDisplay, pbuffer, EGL_BACK_BUFFER);434EXPECT_EGL_TRUE(result);435EXPECT_EGL_SUCCESS();436437result = eglDestroySurface(mDisplay, pbuffer);438EXPECT_EGL_TRUE(result);439EXPECT_EGL_SUCCESS();440}441442bool hasIOSurfaceExt() const { return IsEGLDisplayExtensionEnabled(mDisplay, kIOSurfaceExt); }443bool hasBlitExt() const444{445return IsEGLDisplayExtensionEnabled(mDisplay, "ANGLE_framebuffer_blit");446}447448EGLConfig mConfig;449EGLDisplay mDisplay;450};451452// Test using BGRA8888 IOSurfaces for rendering453TEST_P(IOSurfaceClientBufferTest, RenderToBGRA8888IOSurface)454{455ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());456457// TODO(http://anglebug.com/4369)458ANGLE_SKIP_TEST_IF(isSwiftshader());459460ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'BGRA', 4);461462GLColor color(3, 2, 1, 4);463doClearTest(ioSurface, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, color);464}465466// Test reading from BGRA8888 IOSurfaces467TEST_P(IOSurfaceClientBufferTest, ReadFromBGRA8888IOSurface)468{469ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());470471// TODO(http://anglebug.com/4369)472ANGLE_SKIP_TEST_IF(isSwiftshader());473474ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'BGRA', 4);475476GLColor color(3, 2, 1, 4);477doSampleTest(ioSurface, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, &color, sizeof(color),478R | G | B | A);479}480481// Test using BGRX8888 IOSurfaces for rendering482TEST_P(IOSurfaceClientBufferTest, RenderToBGRX8888IOSurface)483{484ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());485486// TODO(http://anglebug.com/4369)487ANGLE_SKIP_TEST_IF(isSwiftshader());488489ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'BGRA', 4);490491GLColor color(3, 2, 1, 255);492doClearTest(ioSurface, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, color);493}494495// Test reading from BGRX8888 IOSurfaces496TEST_P(IOSurfaceClientBufferTest, ReadFromBGRX8888IOSurface)497{498ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());499500ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'BGRA', 4);501502GLColor color(3, 2, 1, 4);503doSampleTest(ioSurface, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, &color, sizeof(color), R | G | B);504}505506// Test using RG88 IOSurfaces for rendering507TEST_P(IOSurfaceClientBufferTest, RenderToRG88IOSurface)508{509ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());510511// TODO(http://anglebug.com/4369)512ANGLE_SKIP_TEST_IF(isSwiftshader());513514ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, '2C08', 2);515516std::array<uint8_t, 2> color{1, 2};517doClearTest(ioSurface, 1, 1, 0, GL_RG, GL_UNSIGNED_BYTE, color);518}519520// Test reading from RG88 IOSurfaces521TEST_P(IOSurfaceClientBufferTest, ReadFromRG88IOSurface)522{523ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());524525ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, '2C08', 2);526527uint8_t color[2] = {1, 2};528doSampleTest(ioSurface, 1, 1, 0, GL_RG, GL_UNSIGNED_BYTE, &color, sizeof(color), R | G);529}530531// Test using R8 IOSurfaces for rendering532TEST_P(IOSurfaceClientBufferTest, RenderToR8IOSurface)533{534ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());535536// TODO(http://anglebug.com/4369)537ANGLE_SKIP_TEST_IF(isSwiftshader());538539ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'L008', 1);540541std::array<uint8_t, 1> color{1};542doClearTest(ioSurface, 1, 1, 0, GL_RED, GL_UNSIGNED_BYTE, color);543}544545// Test reading from R8 IOSurfaces546TEST_P(IOSurfaceClientBufferTest, ReadFromR8IOSurface)547{548ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());549550ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'L008', 1);551552uint8_t color = 1;553doSampleTest(ioSurface, 1, 1, 0, GL_RED, GL_UNSIGNED_BYTE, &color, sizeof(color), R);554}555556// Test using R16 IOSurfaces for rendering557TEST_P(IOSurfaceClientBufferTest, RenderToR16IOSurface)558{559ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());560561// This test only works on ES3 since it requires an integer texture.562ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);563564// TODO(http://anglebug.com/4369)565ANGLE_SKIP_TEST_IF(isSwiftshader());566567// HACK([email protected]) 'L016' doesn't seem to be an official pixel format but it works568// sooooooo let's test using it569ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'L016', 2);570571std::array<uint16_t, 1> color{257};572doClearTest(ioSurface, 1, 1, 0, GL_R16UI, GL_UNSIGNED_SHORT, color);573}574// TODO([email protected]): test reading from R16? It returns 0 maybe because samplerRect is575// only for floating textures?576577// Test using BGRA_1010102 IOSurfaces for rendering578TEST_P(IOSurfaceClientBufferTest, RenderToBGRA1010102IOSurface)579{580ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());581582// TODO(http://anglebug.com/4369)583ANGLE_SKIP_TEST_IF(isSwiftshader());584585ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'l10r', 4);586587std::array<uint32_t, 1> color{(0 << 30) | (1 << 22) | (2 << 12) | (3 << 2)};588doClearTest(ioSurface, 1, 1, 0, GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV, color);589}590591// Test reading from BGRA_1010102 IOSurfaces592TEST_P(IOSurfaceClientBufferTest, ReadFromBGRA1010102IOSurface)593{594ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());595596ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'l10r', 4);597598uint32_t color = (3 << 30) | (1 << 22) | (2 << 12) | (3 << 2);599doSampleTest(ioSurface, 1, 1, 0, GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV, &color,600sizeof(color),601R | G | B); // Don't test alpha, unorm '4' can't be represented with 2 bits.602}603604// Test using RGBA_16F IOSurfaces for rendering605TEST_P(IOSurfaceClientBufferTest, RenderToRGBA16FIOSurface)606{607ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());608609// TODO(http://anglebug.com/4369)610ANGLE_SKIP_TEST_IF(isSwiftshader());611612ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'RGhA', 8);613614std::array<GLushort, 4> color{615gl::float32ToFloat16(1.0f / 255.0f), gl::float32ToFloat16(2.0f / 255.0f),616gl::float32ToFloat16(3.0f / 255.0f), gl::float32ToFloat16(4.0f / 255.0f)};617doClearTest(ioSurface, 1, 1, 0, GL_RGBA, GL_HALF_FLOAT, color);618}619620// Test reading from RGBA_16F IOSurfaces621TEST_P(IOSurfaceClientBufferTest, ReadFromToRGBA16FIOSurface)622{623ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());624625// TODO(http://anglebug.com/4369)626ANGLE_SKIP_TEST_IF(isSwiftshader());627628ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'RGhA', 8);629630std::array<GLushort, 4> color{631gl::float32ToFloat16(1.0f / 255.0f), gl::float32ToFloat16(2.0f / 255.0f),632gl::float32ToFloat16(3.0f / 255.0f), gl::float32ToFloat16(4.0f / 255.0f)};633doSampleTest(ioSurface, 1, 1, 0, GL_RGBA, GL_HALF_FLOAT, color.data(), sizeof(GLushort) * 4,634R | G | B | A);635}636637// Test using YUV420 IOSurfaces for rendering638TEST_P(IOSurfaceClientBufferTest, RenderToYUV420IOSurface)639{640ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());641642// TODO(http://anglebug.com/4369)643ANGLE_SKIP_TEST_IF(isSwiftshader());644645std::vector<IOSurfacePlaneInfo> planes{{2, 2, 1}, {1, 1, 2}};646ScopedIOSurfaceRef ioSurface = CreateIOSurface('420v', planes);647648{649std::array<GLubyte, 1> colors{1};650doClearTest(ioSurface, planes[0].width, planes[0].height, 0, GL_RED, GL_UNSIGNED_BYTE,651colors);652}653654{655std::array<GLubyte, 2> colors{1, 2};656doClearTest(ioSurface, planes[1].width, planes[1].height, 1, GL_RG, GL_UNSIGNED_BYTE,657colors);658}659}660661// Test reading from YUV420 IOSurfaces662TEST_P(IOSurfaceClientBufferTest, ReadFromToYUV420IOSurface)663{664ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());665666// TODO(http://anglebug.com/4369)667ANGLE_SKIP_TEST_IF(isSwiftshader());668669std::vector<IOSurfacePlaneInfo> planes{{2, 2, 1}, {1, 1, 2}};670ScopedIOSurfaceRef ioSurface = CreateIOSurface('420v', planes);671672{673std::array<GLubyte, 1> colors{1};674doSampleTest(ioSurface, planes[0].width, planes[0].height, 0, GL_RED, GL_UNSIGNED_BYTE,675colors.data(), sizeof(GLubyte) * colors.size(), R);676}677678{679std::array<GLubyte, 2> colors{1, 2};680doSampleTest(ioSurface, planes[1].width, planes[1].height, 1, GL_RG, GL_UNSIGNED_BYTE,681colors.data(), sizeof(GLubyte) * colors.size(), R | G);682}683}684685// Test using P010 IOSurfaces for rendering686TEST_P(IOSurfaceClientBufferTest, RenderToP010IOSurface)687{688ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());689690// TODO(http://anglebug.com/4369)691ANGLE_SKIP_TEST_IF(isSwiftshader());692693std::vector<IOSurfacePlaneInfo> planes{{2, 2, 2}, {1, 1, 4}};694ScopedIOSurfaceRef ioSurface = CreateIOSurface('x420', planes);695696{697std::array<GLushort, 1> colors{257};698doClearTest(ioSurface, planes[0].width, planes[0].height, 0, GL_RED, GL_UNSIGNED_SHORT,699colors);700}701702{703std::array<GLushort, 2> colors{257, 514};704doClearTest(ioSurface, planes[1].width, planes[1].height, 1, GL_RG, GL_UNSIGNED_SHORT,705colors);706}707}708709// Test reading from P010 IOSurfaces710TEST_P(IOSurfaceClientBufferTest, ReadFromToP010IOSurface)711{712ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());713714// TODO(http://anglebug.com/4369)715ANGLE_SKIP_TEST_IF(isSwiftshader());716717std::vector<IOSurfacePlaneInfo> planes{{2, 2, 2}, {1, 1, 4}};718ScopedIOSurfaceRef ioSurface = CreateIOSurface('x420', planes);719720{721std::array<GLushort, 1> colors{257};722doSampleTest(ioSurface, planes[0].width, planes[0].height, 0, GL_RED, GL_UNSIGNED_SHORT,723colors.data(), sizeof(GLushort) * colors.size(), R);724}725726{727std::array<GLushort, 2> colors{257, 514};728doSampleTest(ioSurface, planes[1].width, planes[1].height, 1, GL_RG, GL_UNSIGNED_SHORT,729colors.data(), sizeof(GLushort) * colors.size(), R | G);730}731}732733// Test blitting from IOSurface734TEST_P(IOSurfaceClientBufferTest, BlitFromIOSurface)735{736ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());737738doBlitTest(true, 2, 2);739}740741// Test blitting to IOSurface742TEST_P(IOSurfaceClientBufferTest, BlitToIOSurface)743{744ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());745746doBlitTest(false, 2, 2);747}748749// Test using glCopyTexSubImage to copy to BGRX8888 IOSurfaces works.750TEST_P(IOSurfaceClientBufferTest, CopySubImageToBGRX8888IOSurface)751{752ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());753754ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'BGRA', 4);755756GLTexture texture;757glBindTexture(getGLTextureTarget(), texture);758glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST);759glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST);760761// Bind the IOSurface to a texture and clear it.762EGLSurface pbuffer;763bindIOSurfaceToTexture(ioSurface, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, &pbuffer, &texture);764765// 1. Clear default framebuffer with desired color.766GLColor color(1, 2, 3, 4);767glClearColor(color.R / 255.f, color.G / 255.f, color.B / 255.f, color.A / 255.f);768glClear(GL_COLOR_BUFFER_BIT);769770// 2. Copy color from default framebuffer to iosurface's bound texture.771glCopyTexSubImage2D(getGLTextureTarget(), 0, 0, 0, 0, 0, 1, 1);772EXPECT_GL_NO_ERROR();773774// 3. Do texture sampling verification.775doSampleTestWithTexture(texture, R | G | B);776}777778// Test the validation errors for missing attributes for eglCreatePbufferFromClientBuffer with779// IOSurface780TEST_P(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes)781{782ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());783784ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(10, 10, 'BGRA', 4);785786// Success case787{788// clang-format off789const EGLint attribs[] = {790EGL_WIDTH, 10,791EGL_HEIGHT, 10,792EGL_IOSURFACE_PLANE_ANGLE, 0,793EGL_TEXTURE_TARGET, getTextureTarget(),794EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,795EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,796EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,797EGL_NONE, EGL_NONE,798};799// clang-format off800801EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE, ioSurface.get(), mConfig, attribs);802EXPECT_NE(EGL_NO_SURFACE, pbuffer);803804EGLBoolean result = eglDestroySurface(mDisplay, pbuffer);805EXPECT_EGL_TRUE(result);806EXPECT_EGL_SUCCESS();807}808809// Missing EGL_WIDTH810{811// clang-format off812const EGLint attribs[] = {813EGL_HEIGHT, 10,814EGL_IOSURFACE_PLANE_ANGLE, 0,815EGL_TEXTURE_TARGET, getTextureTarget(),816EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,817EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,818EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,819EGL_NONE, EGL_NONE,820};821// clang-format on822823EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,824ioSurface.get(), mConfig, attribs);825EXPECT_EQ(EGL_NO_SURFACE, pbuffer);826EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);827}828829// Missing EGL_HEIGHT830{831// clang-format off832const EGLint attribs[] = {833EGL_WIDTH, 10,834EGL_IOSURFACE_PLANE_ANGLE, 0,835EGL_TEXTURE_TARGET, getTextureTarget(),836EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,837EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,838EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,839EGL_NONE, EGL_NONE,840};841// clang-format on842843EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,844ioSurface.get(), mConfig, attribs);845EXPECT_EQ(EGL_NO_SURFACE, pbuffer);846EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);847}848849// Missing EGL_IOSURFACE_PLANE_ANGLE850{851// clang-format off852const EGLint attribs[] = {853EGL_WIDTH, 10,854EGL_HEIGHT, 10,855EGL_TEXTURE_TARGET, getTextureTarget(),856EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,857EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,858EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,859EGL_NONE, EGL_NONE,860};861// clang-format on862863EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,864ioSurface.get(), mConfig, attribs);865EXPECT_EQ(EGL_NO_SURFACE, pbuffer);866EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);867}868869// Missing EGL_TEXTURE_TARGET - EGL_BAD_MATCH from the base spec of870// eglCreatePbufferFromClientBuffer871{872// clang-format off873const EGLint attribs[] = {874EGL_WIDTH, 10,875EGL_HEIGHT, 10,876EGL_IOSURFACE_PLANE_ANGLE, 0,877EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,878EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,879EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,880EGL_NONE, EGL_NONE,881};882// clang-format on883884EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,885ioSurface.get(), mConfig, attribs);886EXPECT_EQ(EGL_NO_SURFACE, pbuffer);887EXPECT_EGL_ERROR(EGL_BAD_MATCH);888}889890// Missing EGL_TEXTURE_INTERNAL_FORMAT_ANGLE891{892// clang-format off893const EGLint attribs[] = {894EGL_WIDTH, 10,895EGL_HEIGHT, 10,896EGL_IOSURFACE_PLANE_ANGLE, 0,897EGL_TEXTURE_TARGET, getTextureTarget(),898EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,899EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,900EGL_NONE, EGL_NONE,901};902// clang-format on903904EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,905ioSurface.get(), mConfig, attribs);906EXPECT_EQ(EGL_NO_SURFACE, pbuffer);907EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);908}909910// Missing EGL_TEXTURE_FORMAT - EGL_BAD_MATCH from the base spec of911// eglCreatePbufferFromClientBuffer912{913// clang-format off914const EGLint attribs[] = {915EGL_WIDTH, 10,916EGL_HEIGHT, 10,917EGL_IOSURFACE_PLANE_ANGLE, 0,918EGL_TEXTURE_TARGET, getTextureTarget(),919EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,920EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,921EGL_NONE, EGL_NONE,922};923// clang-format on924925EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,926ioSurface.get(), mConfig, attribs);927EXPECT_EQ(EGL_NO_SURFACE, pbuffer);928EXPECT_EGL_ERROR(EGL_BAD_MATCH);929}930931// Missing EGL_TEXTURE_TYPE_ANGLE932{933// clang-format off934const EGLint attribs[] = {935EGL_WIDTH, 10,936EGL_HEIGHT, 10,937EGL_IOSURFACE_PLANE_ANGLE, 0,938EGL_TEXTURE_TARGET, getTextureTarget(),939EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,940EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,941EGL_NONE, EGL_NONE,942};943// clang-format on944945EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,946ioSurface.get(), mConfig, attribs);947EXPECT_EQ(EGL_NO_SURFACE, pbuffer);948EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);949}950}951952// Test the validation errors for bad parameters for eglCreatePbufferFromClientBuffer with IOSurface953TEST_P(IOSurfaceClientBufferTest, NegativeValidationBadAttributes)954{955ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());956957ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(10, 10, 'BGRA', 4);958959// Success case960{961// clang-format off962const EGLint attribs[] = {963EGL_WIDTH, 10,964EGL_HEIGHT, 10,965EGL_IOSURFACE_PLANE_ANGLE, 0,966EGL_TEXTURE_TARGET, getTextureTarget(),967EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,968EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,969EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,970EGL_NONE, EGL_NONE,971};972// clang-format off973974EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE, ioSurface.get(), mConfig, attribs);975EXPECT_NE(EGL_NO_SURFACE, pbuffer);976977EGLBoolean result = eglDestroySurface(mDisplay, pbuffer);978EXPECT_EGL_TRUE(result);979EXPECT_EGL_SUCCESS();980}981982// EGL_TEXTURE_FORMAT must be EGL_TEXTURE_RGBA983{984// clang-format off985const EGLint attribs[] = {986EGL_WIDTH, 10,987EGL_HEIGHT, 10,988EGL_IOSURFACE_PLANE_ANGLE, 0,989EGL_TEXTURE_TARGET, getTextureTarget(),990EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,991EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,992EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,993EGL_NONE, EGL_NONE,994};995// clang-format on996997EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,998ioSurface.get(), mConfig, attribs);999EXPECT_EQ(EGL_NO_SURFACE, pbuffer);1000EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);1001}10021003// EGL_WIDTH must be at least 11004{1005// clang-format off1006const EGLint attribs[] = {1007EGL_WIDTH, 0,1008EGL_HEIGHT, 10,1009EGL_IOSURFACE_PLANE_ANGLE, 0,1010EGL_TEXTURE_TARGET, getTextureTarget(),1011EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,1012EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,1013EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,1014EGL_NONE, EGL_NONE,1015};1016// clang-format on10171018EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,1019ioSurface.get(), mConfig, attribs);1020EXPECT_EQ(EGL_NO_SURFACE, pbuffer);1021EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);1022}10231024// EGL_WIDTH must be at most the width of the IOSurface1025{1026// clang-format off1027const EGLint attribs[] = {1028EGL_WIDTH, 11,1029EGL_HEIGHT, 10,1030EGL_IOSURFACE_PLANE_ANGLE, 0,1031EGL_TEXTURE_TARGET, getTextureTarget(),1032EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,1033EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,1034EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,1035EGL_NONE, EGL_NONE,1036};1037// clang-format on10381039EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,1040ioSurface.get(), mConfig, attribs);1041EXPECT_EQ(EGL_NO_SURFACE, pbuffer);1042EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);1043}10441045// EGL_HEIGHT must be at least 11046{1047// clang-format off1048const EGLint attribs[] = {1049EGL_WIDTH, 10,1050EGL_HEIGHT, 0,1051EGL_IOSURFACE_PLANE_ANGLE, 0,1052EGL_TEXTURE_TARGET, getTextureTarget(),1053EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,1054EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,1055EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,1056EGL_NONE, EGL_NONE,1057};1058// clang-format on10591060EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,1061ioSurface.get(), mConfig, attribs);1062EXPECT_EQ(EGL_NO_SURFACE, pbuffer);1063EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);1064}10651066// EGL_HEIGHT must be at most the height of the IOSurface1067{1068// clang-format off1069const EGLint attribs[] = {1070EGL_WIDTH, 10,1071EGL_HEIGHT, 11,1072EGL_IOSURFACE_PLANE_ANGLE, 0,1073EGL_TEXTURE_TARGET, getTextureTarget(),1074EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,1075EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,1076EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,1077EGL_NONE, EGL_NONE,1078};1079// clang-format on10801081EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,1082ioSurface.get(), mConfig, attribs);1083EXPECT_EQ(EGL_NO_SURFACE, pbuffer);1084EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);1085}10861087// EGL_TEXTURE_FORMAT must be equal to the config's texture target1088{1089EGLint target = getTextureTarget();1090EGLint wrongTarget = 0;1091switch (target)1092{1093case EGL_TEXTURE_RECTANGLE_ANGLE:1094wrongTarget = EGL_TEXTURE_2D;1095break;1096case EGL_TEXTURE_2D:1097wrongTarget = EGL_TEXTURE_RECTANGLE_ANGLE;1098break;1099default:1100break;1101}1102// clang-format off1103const EGLint attribs[] = {1104EGL_WIDTH, 10,1105EGL_HEIGHT, 10,1106EGL_IOSURFACE_PLANE_ANGLE, 0,1107EGL_TEXTURE_TARGET, wrongTarget,1108EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,1109EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,1110EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,1111EGL_NONE, EGL_NONE,1112};1113// clang-format on11141115EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,1116ioSurface.get(), mConfig, attribs);1117EXPECT_EQ(EGL_NO_SURFACE, pbuffer);1118EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);1119}11201121// EGL_IOSURFACE_PLANE_ANGLE must be at least 01122{1123// clang-format off1124const EGLint attribs[] = {1125EGL_WIDTH, 10,1126EGL_HEIGHT, 10,1127EGL_IOSURFACE_PLANE_ANGLE, -1,1128EGL_TEXTURE_TARGET, getTextureTarget(),1129EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,1130EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,1131EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,1132EGL_NONE, EGL_NONE,1133};1134// clang-format on11351136EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,1137ioSurface.get(), mConfig, attribs);1138EXPECT_EQ(EGL_NO_SURFACE, pbuffer);1139EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);1140}11411142// EGL_IOSURFACE_PLANE_ANGLE must less than the number of planes of the IOSurface1143{1144// clang-format off1145const EGLint attribs[] = {1146EGL_WIDTH, 10,1147EGL_HEIGHT, 10,1148EGL_IOSURFACE_PLANE_ANGLE, 1,1149EGL_TEXTURE_TARGET, getTextureTarget(),1150EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT,1151EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,1152EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,1153EGL_NONE, EGL_NONE,1154};1155// clang-format on11561157EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,1158ioSurface.get(), mConfig, attribs);1159EXPECT_EQ(EGL_NO_SURFACE, pbuffer);1160EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);1161}11621163// The internal format / type most be listed in the table1164{1165// clang-format off1166const EGLint attribs[] = {1167EGL_WIDTH, 10,1168EGL_HEIGHT, 10,1169EGL_IOSURFACE_PLANE_ANGLE, 0,1170EGL_TEXTURE_TARGET, getTextureTarget(),1171EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_RGBA,1172EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,1173EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE,1174EGL_NONE, EGL_NONE,1175};1176// clang-format on11771178EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(mDisplay, EGL_IOSURFACE_ANGLE,1179ioSurface.get(), mConfig, attribs);1180EXPECT_EQ(EGL_NO_SURFACE, pbuffer);1181EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);1182}1183}11841185// Test IOSurface pbuffers can be made current1186TEST_P(IOSurfaceClientBufferTest, MakeCurrent)1187{1188ANGLE_SKIP_TEST_IF(!hasIOSurfaceExt());11891190ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(10, 10, 'BGRA', 4);11911192EGLSurface pbuffer;1193createIOSurfacePbuffer(ioSurface, 10, 10, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, &pbuffer);11941195EGLContext context = getEGLWindow()->getContext();1196EGLBoolean result = eglMakeCurrent(mDisplay, pbuffer, pbuffer, context);1197EXPECT_EGL_TRUE(result);1198EXPECT_EGL_SUCCESS();1199// The test harness expects the EGL state to be restored before the test exits.1200result = eglMakeCurrent(mDisplay, getEGLWindow()->getSurface(), getEGLWindow()->getSurface(),1201context);1202EXPECT_EGL_TRUE(result);1203EXPECT_EGL_SUCCESS();1204}12051206// TODO([email protected]): Test setting width and height to less than the IOSurface's work as1207// expected.12081209ANGLE_INSTANTIATE_TEST(IOSurfaceClientBufferTest,1210ES2_OPENGL(),1211ES3_OPENGL(),1212ES2_VULKAN_SWIFTSHADER(),1213ES3_VULKAN_SWIFTSHADER(),1214ES2_METAL());121512161217