Skip to content

Commit 86f7309

Browse files
kenrussellCommit Bot
authored andcommitted
Upstream support for iOS Simulator.
Originally authored in the WebKit repository: https://bugs.webkit.org/show_bug.cgi?id=205618 Has been tested with WebKit's WebGL backend on top of ANGLE inside the iOS Simulator. TODOs will be addressed in forthcoming CLs. Bug: angleproject:4263 Change-Id: Ic879866aaee5f933599d956b0646d0c01db55d0d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1995824 Reviewed-by: Shahbaz Youssefi <[email protected]> Reviewed-by: Jonah Ryan-Davis <[email protected]> Commit-Queue: Kenneth Russell <[email protected]>
1 parent 2e1beb4 commit 86f7309

File tree

6 files changed

+113
-26
lines changed

6 files changed

+113
-26
lines changed

extensions/EGL_ANGLE_iosurface_client_buffer.txt

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Status
2121
Draft
2222

2323
Version
24-
Version 3, Aug 13, 2019
24+
Version 4, Dec 28, 2019
2525

2626
Number
2727

@@ -53,6 +53,7 @@ New Tokens
5353
EGL_TEXTURE_RECTANGLE_ANGLE 0x345B
5454
EGL_TEXTURE_TYPE_ANGLE 0x345C
5555
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D
56+
EGL_IOSURFACE_USAGE_HINT_ANGLE 0x348A
5657

5758
Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
5859

@@ -80,15 +81,24 @@ Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
8081
- EGL_TEXTURE_FORMAT with a value of EGL_TEXTURE_RGBA
8182
- EGL_WIDTH with a value between 1 and the width of <buffer>.
8283
- EGL_HEIGHT with a value between 1 and the height of <buffer>.
83-
- EGL_TEXTURE_TARGET with a value of EGL_TEXTURE_RECTANGLE_ANGLE
84+
- EGL_TEXTURE_TARGET with a value of EGL_TEXTURE_RECTANGLE_ANGLE (macOS)
85+
or EGL_TEXTURE_2D (iOS)
8486
- EGL_IOSURFACE_PLANE_ANGLE with a value between 0 and the number of
8587
planes of <buffer> (exclusive).
8688

8789
In addition the EGL_TEXTURE_TYPE_ANGLE and
8890
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE attributes must be one of the
8991
combinations listed in table egl.iosurface.formats or an
9092
EGL_BAD_PARAMETER is generated. The combination must also be a valid
91-
combinations for glTexImage2D or EGL_BAD_PARAMETER is generated."
93+
combinations for glTexImage2D or EGL_BAD_PARAMETER is generated.
94+
95+
The attribute EGL_IOSURFACE_USAGE_HINT_ANGLE may optionally be specified as
96+
a combination of the bits EGL_IOSURFACE_READ_HINT_ANGLE and
97+
EGL_IOSURFACE_WRITE_HINT_ANGLE. On the iOS Simulator platform, where
98+
IOSurface support is incomplete, these hints indicate whether the intent is
99+
to read from the IOSurface, write to it, or both. Explicitly passing 0 for
100+
this attribute is equivalent to setting both the read and write usage
101+
bits. This attribute is ignored on other platforms."
92102

93103
---------------------------------------------------------------------------
94104
Texture Type Texture Internal Format
@@ -122,3 +132,5 @@ Revision History
122132
Version 1, 2017/12/06 - first draft.
123133
Version 2, 2019/04/01 - Allow MakeCurrent.
124134
Version 3, 2019/08/13 - Allow RGB internal formats
135+
Version 4, 2019/12/28 - Add usage hint; require TEXTURE_RECTANGLE on macOS
136+
and TEXTURE_2D on iOS

include/EGL/eglext_angle.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@ EGLAPI EGLint EGLAPIENTRY eglProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limi
194194
#define EGL_TEXTURE_RECTANGLE_ANGLE 0x345B
195195
#define EGL_TEXTURE_TYPE_ANGLE 0x345C
196196
#define EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D
197+
#define EGL_IOSURFACE_USAGE_HINT_ANGLE 0x348A
198+
#define EGL_IOSURFACE_READ_HINT_ANGLE 0x0001
199+
#define EGL_IOSURFACE_WRITE_HINT_ANGLE 0x0002
197200
#endif /* EGL_ANGLE_iosurface_client_buffer */
198201

199202
#ifndef EGL_ANGLE_create_context_extensions_enabled

src/libANGLE/renderer/gl/eagl/DisplayEAGL.mm

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,13 @@
2929

3030
# define GLES_SILENCE_DEPRECATION
3131

32-
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
33-
3432
namespace
3533
{
3634

3735
const char *kOpenGLESDylibName = "/System/Library/Frameworks/OpenGLES.framework/OpenGLES";
3836

3937
}
4038

41-
# endif
42-
4339
namespace rx
4440
{
4541

@@ -69,10 +65,6 @@
6965
{
7066
mEGLDisplay = display;
7167

72-
# if defined(ANGLE_PLATFORM_IOS_SIMULATOR)
73-
return egl::EglNotInitialized()
74-
<< "ANGLE with EAGL not supported on iOS Simulator due to lack of IOSurface support.";
75-
# else
7668
angle::SystemInfo info;
7769
if (!angle::GetSystemInfo(&info))
7870
{
@@ -105,7 +97,6 @@
10597
}
10698

10799
return DisplayGL::initialize(display);
108-
# endif
109100
}
110101

111102
void DisplayEAGL::terminate()

src/libANGLE/renderer/gl/eagl/IOSurfaceSurfaceEAGL.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
#include "libANGLE/renderer/gl/SurfaceGL.h"
1111
#include "libANGLE/renderer/gl/eagl/DisplayEAGL.h"
1212

13-
struct __IOSurface;
14-
typedef __IOSurface *IOSurfaceRef;
13+
#include <IOSurface/IOSurfaceRef.h>
1514

1615
namespace egl
1716
{
@@ -66,6 +65,10 @@ class IOSurfaceSurfaceEAGL : public SurfaceGL
6665
private:
6766
angle::Result initializeAlphaChannel(const gl::Context *context, GLuint texture);
6867

68+
#if defined(ANGLE_PLATFORM_IOS_SIMULATOR)
69+
IOSurfaceLockOptions getIOSurfaceLockOptions() const;
70+
#endif
71+
6972
EAGLContextObj mEAGLContext;
7073
IOSurfaceRef mIOSurface;
7174
int mWidth;
@@ -74,6 +77,11 @@ class IOSurfaceSurfaceEAGL : public SurfaceGL
7477
int mFormatIndex;
7578

7679
bool mAlphaInitialized;
80+
#if defined(ANGLE_PLATFORM_IOS_SIMULATOR)
81+
GLuint mBoundTextureID;
82+
bool mUploadFromIOSurface;
83+
bool mReadbackToIOSurface;
84+
#endif
7785
};
7886

7987
} // namespace rx

src/libANGLE/renderer/gl/eagl/IOSurfaceSurfaceEAGL.mm

Lines changed: 69 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,15 @@ int FindIOSurfaceFormatIndex(GLenum internalFormat, GLenum type)
102102
ASSERT(mFormatIndex >= 0);
103103

104104
mAlphaInitialized = !hasEmulatedAlphaChannel();
105+
106+
# if defined(ANGLE_PLATFORM_IOS_SIMULATOR)
107+
mBoundTextureID = 0;
108+
EGLAttrib usageHint =
109+
attribs.get(EGL_IOSURFACE_USAGE_HINT_ANGLE,
110+
EGL_IOSURFACE_READ_HINT_ANGLE | EGL_IOSURFACE_WRITE_HINT_ANGLE);
111+
mUploadFromIOSurface = ((usageHint & EGL_IOSURFACE_READ_HINT_ANGLE) != 0);
112+
mReadbackToIOSurface = ((usageHint & EGL_IOSURFACE_WRITE_HINT_ANGLE) != 0);
113+
# endif
105114
}
106115

107116
IOSurfaceSurfaceEAGL::~IOSurfaceSurfaceEAGL()
@@ -154,14 +163,14 @@ int FindIOSurfaceFormatIndex(GLenum internalFormat, GLenum type)
154163
gl::Texture *texture,
155164
EGLint)
156165
{
157-
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
158166
StateManagerGL *stateManager = GetStateManagerGL(context);
159167

160168
const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
161169
GLuint textureID = textureGL->getTextureID();
162170
stateManager->bindTexture(gl::TextureType::_2D, textureID);
163171
const auto &format = kIOSurfaceFormats[mFormatIndex];
164172

173+
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
165174
if (![mEAGLContext texImageIOSurface:mIOSurface
166175
target:GL_TEXTURE_2D
167176
internalFormat:format.nativeInternalFormat
@@ -178,17 +187,58 @@ int FindIOSurfaceFormatIndex(GLenum internalFormat, GLenum type)
178187
{
179188
return egl::EglContextLost() << "Failed to initialize IOSurface alpha channel.";
180189
}
190+
# else // !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
191+
const FunctionsGL *functions = GetFunctionsGL(context);
192+
193+
IOSurfaceLock(mIOSurface, getIOSurfaceLockOptions(), nullptr);
194+
void *textureData = nullptr;
195+
if (mUploadFromIOSurface)
196+
{
197+
// TODO(kbr): possibly more state to be set here, including setting any
198+
// pixel unpack buffer to 0 when using ES 3.0 contexts.
199+
gl::PixelUnpackState defaultUnpackState;
200+
stateManager->setPixelUnpackState(defaultUnpackState);
201+
textureData = IOSurfaceGetBaseAddress(mIOSurface);
202+
}
203+
204+
// TODO(kbr): consider trying to optimize away texture reallocations by
205+
// keeping track of which textures have already been allocated.
206+
functions->texImage2D(GL_TEXTURE_2D, 0, format.nativeInternalFormat, mWidth, mHeight, 0,
207+
format.nativeFormat, format.nativeType, textureData);
208+
209+
mBoundTextureID = textureID;
210+
# endif // !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
181211

182212
return egl::NoError();
183-
# else
184-
return egl::EglContextLost() << "EAGLContext IOSurface not supported in the simulator.";
185-
# endif
186213
}
187214

188215
egl::Error IOSurfaceSurfaceEAGL::releaseTexImage(const gl::Context *context, EGLint buffer)
189216
{
190217
const FunctionsGL *functions = GetFunctionsGL(context);
218+
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
191219
functions->flush();
220+
# else // !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
221+
if (mReadbackToIOSurface)
222+
{
223+
StateManagerGL *stateManager = GetStateManagerGL(context);
224+
GLuint tempFBO = 0;
225+
functions->genFramebuffers(1, &tempFBO);
226+
stateManager->bindFramebuffer(GL_FRAMEBUFFER, tempFBO);
227+
functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
228+
mBoundTextureID, 0);
229+
gl::PixelPackState state;
230+
state.alignment = 1;
231+
stateManager->setPixelPackState(state);
232+
// TODO(kbr): possibly more state to be set here, including setting any
233+
// pixel pack buffer to 0 when using ES 3.0 contexts.
234+
const auto &format = kIOSurfaceFormats[mFormatIndex];
235+
functions->readPixels(0, 0, mWidth, mHeight, format.nativeFormat, format.nativeType,
236+
IOSurfaceGetBaseAddress(mIOSurface));
237+
}
238+
239+
IOSurfaceUnlock(mIOSurface, getIOSurfaceLockOptions(), nullptr);
240+
# endif // !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
241+
192242
return egl::NoError();
193243
}
194244

@@ -223,7 +273,6 @@ int FindIOSurfaceFormatIndex(GLenum internalFormat, GLenum type)
223273
bool IOSurfaceSurfaceEAGL::validateAttributes(EGLClientBuffer buffer,
224274
const egl::AttributeMap &attribs)
225275
{
226-
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
227276
IOSurfaceRef ioSurface = reinterpret_cast<IOSurfaceRef>(buffer);
228277

229278
// The plane must exist for this IOSurface. IOSurfaceGetPlaneCount can return 0 for non-planar
@@ -264,9 +313,6 @@ int FindIOSurfaceFormatIndex(GLenum internalFormat, GLenum type)
264313
}
265314

266315
return true;
267-
# else
268-
return false;
269-
# endif
270316
}
271317

272318
// Wraps a FramebufferGL to hook the destroy function to delete the texture associated with the
@@ -316,9 +362,9 @@ void destroy(const gl::Context *context) override
316362
ERR() << "[EAGLContext texImageIOSurface] failed";
317363
return nullptr;
318364
}
319-
# else
320-
ERR() << "IOSurfaces not supported on iOS Simulator";
321-
# endif
365+
# else // !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
366+
ERR() << "IOSurfaces with OpenGL ES not supported on iOS Simulator";
367+
# endif // !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
322368

323369
if (IsError(initializeAlphaChannel(context, texture)))
324370
{
@@ -357,6 +403,18 @@ void destroy(const gl::Context *context) override
357403
return format.internalFormat == GL_RGB;
358404
}
359405

406+
# if defined(ANGLE_PLATFORM_IOS_SIMULATOR)
407+
IOSurfaceLockOptions IOSurfaceSurfaceEAGL::getIOSurfaceLockOptions() const
408+
{
409+
IOSurfaceLockOptions options = 0;
410+
if (!mReadbackToIOSurface)
411+
{
412+
options |= kIOSurfaceLockReadOnly;
413+
}
414+
return options;
415+
}
416+
# endif // defined(ANGLE_PLATFORM_IOS_SIMULATOR)
417+
360418
} // namespace rx
361419

362420
#endif // defined(ANGLE_PLATFORM_IOS)

src/libANGLE/validationEGL.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,13 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display,
17751775
return EglBadAttribute() << "<buftype> doesn't support setting GL colorspace";
17761776
}
17771777
break;
1778+
case EGL_IOSURFACE_USAGE_HINT_ANGLE:
1779+
if (value & ~(EGL_IOSURFACE_READ_HINT_ANGLE | EGL_IOSURFACE_WRITE_HINT_ANGLE))
1780+
{
1781+
return EglBadAttribute()
1782+
<< "IOSurface usage hint must only contain READ or WRITE";
1783+
}
1784+
break;
17781785
default:
17791786
return EglBadAttribute();
17801787
}
@@ -1834,10 +1841,18 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display,
18341841

18351842
if (buftype == EGL_IOSURFACE_ANGLE)
18361843
{
1844+
#if ANGLE_PLATFORM_MACOS || ANGLE_PLATFORM_MACCATALYST
18371845
if (textureTarget != EGL_TEXTURE_RECTANGLE_ANGLE)
18381846
{
1839-
return EglBadAttribute() << "EGL_IOSURFACE requires the EGL_TEXTURE_RECTANGLE target";
1847+
return EglBadAttribute()
1848+
<< "EGL_IOSURFACE requires the EGL_TEXTURE_RECTANGLE target on desktop macOS";
1849+
}
1850+
#else // ANGLE_PLATFORM_MACOS || ANGLE_PLATFORM_MACCATALYST
1851+
if (textureTarget != EGL_TEXTURE_2D)
1852+
{
1853+
return EglBadAttribute() << "EGL_IOSURFACE requires the EGL_TEXTURE_2D target on iOS";
18401854
}
1855+
#endif // ANGLE_PLATFORM_MACOS || ANGLE_PLATFORM_MACCATALYST
18411856

18421857
if (textureFormat != EGL_TEXTURE_RGBA)
18431858
{

0 commit comments

Comments
 (0)