Commit 86f73097 by Kenneth Russell Committed by Commit Bot

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/+/1995824Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Commit-Queue: Kenneth Russell <kbr@chromium.org>
parent 2e1beb40
...@@ -21,7 +21,7 @@ Status ...@@ -21,7 +21,7 @@ Status
Draft Draft
Version Version
Version 3, Aug 13, 2019 Version 4, Dec 28, 2019
Number Number
...@@ -53,6 +53,7 @@ New Tokens ...@@ -53,6 +53,7 @@ New Tokens
EGL_TEXTURE_RECTANGLE_ANGLE 0x345B EGL_TEXTURE_RECTANGLE_ANGLE 0x345B
EGL_TEXTURE_TYPE_ANGLE 0x345C EGL_TEXTURE_TYPE_ANGLE 0x345C
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D
EGL_IOSURFACE_USAGE_HINT_ANGLE 0x348A
Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors) Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
...@@ -80,7 +81,8 @@ Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors) ...@@ -80,7 +81,8 @@ Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
- EGL_TEXTURE_FORMAT with a value of EGL_TEXTURE_RGBA - EGL_TEXTURE_FORMAT with a value of EGL_TEXTURE_RGBA
- EGL_WIDTH with a value between 1 and the width of <buffer>. - EGL_WIDTH with a value between 1 and the width of <buffer>.
- EGL_HEIGHT with a value between 1 and the height of <buffer>. - EGL_HEIGHT with a value between 1 and the height of <buffer>.
- EGL_TEXTURE_TARGET with a value of EGL_TEXTURE_RECTANGLE_ANGLE - EGL_TEXTURE_TARGET with a value of EGL_TEXTURE_RECTANGLE_ANGLE (macOS)
or EGL_TEXTURE_2D (iOS)
- EGL_IOSURFACE_PLANE_ANGLE with a value between 0 and the number of - EGL_IOSURFACE_PLANE_ANGLE with a value between 0 and the number of
planes of <buffer> (exclusive). planes of <buffer> (exclusive).
...@@ -88,7 +90,15 @@ Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors) ...@@ -88,7 +90,15 @@ Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE attributes must be one of the EGL_TEXTURE_INTERNAL_FORMAT_ANGLE attributes must be one of the
combinations listed in table egl.iosurface.formats or an combinations listed in table egl.iosurface.formats or an
EGL_BAD_PARAMETER is generated. The combination must also be a valid EGL_BAD_PARAMETER is generated. The combination must also be a valid
combinations for glTexImage2D or EGL_BAD_PARAMETER is generated." combinations for glTexImage2D or EGL_BAD_PARAMETER is generated.
The attribute EGL_IOSURFACE_USAGE_HINT_ANGLE may optionally be specified as
a combination of the bits EGL_IOSURFACE_READ_HINT_ANGLE and
EGL_IOSURFACE_WRITE_HINT_ANGLE. On the iOS Simulator platform, where
IOSurface support is incomplete, these hints indicate whether the intent is
to read from the IOSurface, write to it, or both. Explicitly passing 0 for
this attribute is equivalent to setting both the read and write usage
bits. This attribute is ignored on other platforms."
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Texture Type Texture Internal Format Texture Type Texture Internal Format
...@@ -122,3 +132,5 @@ Revision History ...@@ -122,3 +132,5 @@ Revision History
Version 1, 2017/12/06 - first draft. Version 1, 2017/12/06 - first draft.
Version 2, 2019/04/01 - Allow MakeCurrent. Version 2, 2019/04/01 - Allow MakeCurrent.
Version 3, 2019/08/13 - Allow RGB internal formats Version 3, 2019/08/13 - Allow RGB internal formats
Version 4, 2019/12/28 - Add usage hint; require TEXTURE_RECTANGLE on macOS
and TEXTURE_2D on iOS
...@@ -194,6 +194,9 @@ EGLAPI EGLint EGLAPIENTRY eglProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limi ...@@ -194,6 +194,9 @@ EGLAPI EGLint EGLAPIENTRY eglProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limi
#define EGL_TEXTURE_RECTANGLE_ANGLE 0x345B #define EGL_TEXTURE_RECTANGLE_ANGLE 0x345B
#define EGL_TEXTURE_TYPE_ANGLE 0x345C #define EGL_TEXTURE_TYPE_ANGLE 0x345C
#define EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D #define EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D
#define EGL_IOSURFACE_USAGE_HINT_ANGLE 0x348A
#define EGL_IOSURFACE_READ_HINT_ANGLE 0x0001
#define EGL_IOSURFACE_WRITE_HINT_ANGLE 0x0002
#endif /* EGL_ANGLE_iosurface_client_buffer */ #endif /* EGL_ANGLE_iosurface_client_buffer */
#ifndef EGL_ANGLE_create_context_extensions_enabled #ifndef EGL_ANGLE_create_context_extensions_enabled
......
...@@ -29,8 +29,6 @@ ...@@ -29,8 +29,6 @@
# define GLES_SILENCE_DEPRECATION # define GLES_SILENCE_DEPRECATION
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
namespace namespace
{ {
...@@ -38,8 +36,6 @@ const char *kOpenGLESDylibName = "/System/Library/Frameworks/OpenGLES.framework/ ...@@ -38,8 +36,6 @@ const char *kOpenGLESDylibName = "/System/Library/Frameworks/OpenGLES.framework/
} }
# endif
namespace rx namespace rx
{ {
...@@ -69,10 +65,6 @@ egl::Error DisplayEAGL::initialize(egl::Display *display) ...@@ -69,10 +65,6 @@ egl::Error DisplayEAGL::initialize(egl::Display *display)
{ {
mEGLDisplay = display; mEGLDisplay = display;
# if defined(ANGLE_PLATFORM_IOS_SIMULATOR)
return egl::EglNotInitialized()
<< "ANGLE with EAGL not supported on iOS Simulator due to lack of IOSurface support.";
# else
angle::SystemInfo info; angle::SystemInfo info;
if (!angle::GetSystemInfo(&info)) if (!angle::GetSystemInfo(&info))
{ {
...@@ -105,7 +97,6 @@ egl::Error DisplayEAGL::initialize(egl::Display *display) ...@@ -105,7 +97,6 @@ egl::Error DisplayEAGL::initialize(egl::Display *display)
} }
return DisplayGL::initialize(display); return DisplayGL::initialize(display);
# endif
} }
void DisplayEAGL::terminate() void DisplayEAGL::terminate()
......
...@@ -10,8 +10,7 @@ ...@@ -10,8 +10,7 @@
#include "libANGLE/renderer/gl/SurfaceGL.h" #include "libANGLE/renderer/gl/SurfaceGL.h"
#include "libANGLE/renderer/gl/eagl/DisplayEAGL.h" #include "libANGLE/renderer/gl/eagl/DisplayEAGL.h"
struct __IOSurface; #include <IOSurface/IOSurfaceRef.h>
typedef __IOSurface *IOSurfaceRef;
namespace egl namespace egl
{ {
...@@ -66,6 +65,10 @@ class IOSurfaceSurfaceEAGL : public SurfaceGL ...@@ -66,6 +65,10 @@ class IOSurfaceSurfaceEAGL : public SurfaceGL
private: private:
angle::Result initializeAlphaChannel(const gl::Context *context, GLuint texture); angle::Result initializeAlphaChannel(const gl::Context *context, GLuint texture);
#if defined(ANGLE_PLATFORM_IOS_SIMULATOR)
IOSurfaceLockOptions getIOSurfaceLockOptions() const;
#endif
EAGLContextObj mEAGLContext; EAGLContextObj mEAGLContext;
IOSurfaceRef mIOSurface; IOSurfaceRef mIOSurface;
int mWidth; int mWidth;
...@@ -74,6 +77,11 @@ class IOSurfaceSurfaceEAGL : public SurfaceGL ...@@ -74,6 +77,11 @@ class IOSurfaceSurfaceEAGL : public SurfaceGL
int mFormatIndex; int mFormatIndex;
bool mAlphaInitialized; bool mAlphaInitialized;
#if defined(ANGLE_PLATFORM_IOS_SIMULATOR)
GLuint mBoundTextureID;
bool mUploadFromIOSurface;
bool mReadbackToIOSurface;
#endif
}; };
} // namespace rx } // namespace rx
......
...@@ -102,6 +102,15 @@ IOSurfaceSurfaceEAGL::IOSurfaceSurfaceEAGL(const egl::SurfaceState &state, ...@@ -102,6 +102,15 @@ IOSurfaceSurfaceEAGL::IOSurfaceSurfaceEAGL(const egl::SurfaceState &state,
ASSERT(mFormatIndex >= 0); ASSERT(mFormatIndex >= 0);
mAlphaInitialized = !hasEmulatedAlphaChannel(); mAlphaInitialized = !hasEmulatedAlphaChannel();
# if defined(ANGLE_PLATFORM_IOS_SIMULATOR)
mBoundTextureID = 0;
EGLAttrib usageHint =
attribs.get(EGL_IOSURFACE_USAGE_HINT_ANGLE,
EGL_IOSURFACE_READ_HINT_ANGLE | EGL_IOSURFACE_WRITE_HINT_ANGLE);
mUploadFromIOSurface = ((usageHint & EGL_IOSURFACE_READ_HINT_ANGLE) != 0);
mReadbackToIOSurface = ((usageHint & EGL_IOSURFACE_WRITE_HINT_ANGLE) != 0);
# endif
} }
IOSurfaceSurfaceEAGL::~IOSurfaceSurfaceEAGL() IOSurfaceSurfaceEAGL::~IOSurfaceSurfaceEAGL()
...@@ -154,7 +163,6 @@ egl::Error IOSurfaceSurfaceEAGL::bindTexImage(const gl::Context *context, ...@@ -154,7 +163,6 @@ egl::Error IOSurfaceSurfaceEAGL::bindTexImage(const gl::Context *context,
gl::Texture *texture, gl::Texture *texture,
EGLint) EGLint)
{ {
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
StateManagerGL *stateManager = GetStateManagerGL(context); StateManagerGL *stateManager = GetStateManagerGL(context);
const TextureGL *textureGL = GetImplAs<TextureGL>(texture); const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
...@@ -162,6 +170,7 @@ egl::Error IOSurfaceSurfaceEAGL::bindTexImage(const gl::Context *context, ...@@ -162,6 +170,7 @@ egl::Error IOSurfaceSurfaceEAGL::bindTexImage(const gl::Context *context,
stateManager->bindTexture(gl::TextureType::_2D, textureID); stateManager->bindTexture(gl::TextureType::_2D, textureID);
const auto &format = kIOSurfaceFormats[mFormatIndex]; const auto &format = kIOSurfaceFormats[mFormatIndex];
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
if (![mEAGLContext texImageIOSurface:mIOSurface if (![mEAGLContext texImageIOSurface:mIOSurface
target:GL_TEXTURE_2D target:GL_TEXTURE_2D
internalFormat:format.nativeInternalFormat internalFormat:format.nativeInternalFormat
...@@ -178,17 +187,58 @@ egl::Error IOSurfaceSurfaceEAGL::bindTexImage(const gl::Context *context, ...@@ -178,17 +187,58 @@ egl::Error IOSurfaceSurfaceEAGL::bindTexImage(const gl::Context *context,
{ {
return egl::EglContextLost() << "Failed to initialize IOSurface alpha channel."; return egl::EglContextLost() << "Failed to initialize IOSurface alpha channel.";
} }
# else // !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
const FunctionsGL *functions = GetFunctionsGL(context);
IOSurfaceLock(mIOSurface, getIOSurfaceLockOptions(), nullptr);
void *textureData = nullptr;
if (mUploadFromIOSurface)
{
// TODO(kbr): possibly more state to be set here, including setting any
// pixel unpack buffer to 0 when using ES 3.0 contexts.
gl::PixelUnpackState defaultUnpackState;
stateManager->setPixelUnpackState(defaultUnpackState);
textureData = IOSurfaceGetBaseAddress(mIOSurface);
}
// TODO(kbr): consider trying to optimize away texture reallocations by
// keeping track of which textures have already been allocated.
functions->texImage2D(GL_TEXTURE_2D, 0, format.nativeInternalFormat, mWidth, mHeight, 0,
format.nativeFormat, format.nativeType, textureData);
mBoundTextureID = textureID;
# endif // !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
return egl::NoError(); return egl::NoError();
# else
return egl::EglContextLost() << "EAGLContext IOSurface not supported in the simulator.";
# endif
} }
egl::Error IOSurfaceSurfaceEAGL::releaseTexImage(const gl::Context *context, EGLint buffer) egl::Error IOSurfaceSurfaceEAGL::releaseTexImage(const gl::Context *context, EGLint buffer)
{ {
const FunctionsGL *functions = GetFunctionsGL(context); const FunctionsGL *functions = GetFunctionsGL(context);
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
functions->flush(); functions->flush();
# else // !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
if (mReadbackToIOSurface)
{
StateManagerGL *stateManager = GetStateManagerGL(context);
GLuint tempFBO = 0;
functions->genFramebuffers(1, &tempFBO);
stateManager->bindFramebuffer(GL_FRAMEBUFFER, tempFBO);
functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
mBoundTextureID, 0);
gl::PixelPackState state;
state.alignment = 1;
stateManager->setPixelPackState(state);
// TODO(kbr): possibly more state to be set here, including setting any
// pixel pack buffer to 0 when using ES 3.0 contexts.
const auto &format = kIOSurfaceFormats[mFormatIndex];
functions->readPixels(0, 0, mWidth, mHeight, format.nativeFormat, format.nativeType,
IOSurfaceGetBaseAddress(mIOSurface));
}
IOSurfaceUnlock(mIOSurface, getIOSurfaceLockOptions(), nullptr);
# endif // !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
return egl::NoError(); return egl::NoError();
} }
...@@ -223,7 +273,6 @@ EGLint IOSurfaceSurfaceEAGL::getSwapBehavior() const ...@@ -223,7 +273,6 @@ EGLint IOSurfaceSurfaceEAGL::getSwapBehavior() const
bool IOSurfaceSurfaceEAGL::validateAttributes(EGLClientBuffer buffer, bool IOSurfaceSurfaceEAGL::validateAttributes(EGLClientBuffer buffer,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
IOSurfaceRef ioSurface = reinterpret_cast<IOSurfaceRef>(buffer); IOSurfaceRef ioSurface = reinterpret_cast<IOSurfaceRef>(buffer);
// The plane must exist for this IOSurface. IOSurfaceGetPlaneCount can return 0 for non-planar // The plane must exist for this IOSurface. IOSurfaceGetPlaneCount can return 0 for non-planar
...@@ -264,9 +313,6 @@ bool IOSurfaceSurfaceEAGL::validateAttributes(EGLClientBuffer buffer, ...@@ -264,9 +313,6 @@ bool IOSurfaceSurfaceEAGL::validateAttributes(EGLClientBuffer buffer,
} }
return true; return true;
# else
return false;
# endif
} }
// Wraps a FramebufferGL to hook the destroy function to delete the texture associated with the // Wraps a FramebufferGL to hook the destroy function to delete the texture associated with the
...@@ -316,9 +362,9 @@ FramebufferImpl *IOSurfaceSurfaceEAGL::createDefaultFramebuffer(const gl::Contex ...@@ -316,9 +362,9 @@ FramebufferImpl *IOSurfaceSurfaceEAGL::createDefaultFramebuffer(const gl::Contex
ERR() << "[EAGLContext texImageIOSurface] failed"; ERR() << "[EAGLContext texImageIOSurface] failed";
return nullptr; return nullptr;
} }
# else # else // !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
ERR() << "IOSurfaces not supported on iOS Simulator"; ERR() << "IOSurfaces with OpenGL ES not supported on iOS Simulator";
# endif # endif // !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
if (IsError(initializeAlphaChannel(context, texture))) if (IsError(initializeAlphaChannel(context, texture)))
{ {
...@@ -357,6 +403,18 @@ bool IOSurfaceSurfaceEAGL::hasEmulatedAlphaChannel() const ...@@ -357,6 +403,18 @@ bool IOSurfaceSurfaceEAGL::hasEmulatedAlphaChannel() const
return format.internalFormat == GL_RGB; return format.internalFormat == GL_RGB;
} }
# if defined(ANGLE_PLATFORM_IOS_SIMULATOR)
IOSurfaceLockOptions IOSurfaceSurfaceEAGL::getIOSurfaceLockOptions() const
{
IOSurfaceLockOptions options = 0;
if (!mReadbackToIOSurface)
{
options |= kIOSurfaceLockReadOnly;
}
return options;
}
# endif // defined(ANGLE_PLATFORM_IOS_SIMULATOR)
} // namespace rx } // namespace rx
#endif // defined(ANGLE_PLATFORM_IOS) #endif // defined(ANGLE_PLATFORM_IOS)
...@@ -1775,6 +1775,13 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, ...@@ -1775,6 +1775,13 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display,
return EglBadAttribute() << "<buftype> doesn't support setting GL colorspace"; return EglBadAttribute() << "<buftype> doesn't support setting GL colorspace";
} }
break; break;
case EGL_IOSURFACE_USAGE_HINT_ANGLE:
if (value & ~(EGL_IOSURFACE_READ_HINT_ANGLE | EGL_IOSURFACE_WRITE_HINT_ANGLE))
{
return EglBadAttribute()
<< "IOSurface usage hint must only contain READ or WRITE";
}
break;
default: default:
return EglBadAttribute(); return EglBadAttribute();
} }
...@@ -1834,10 +1841,18 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, ...@@ -1834,10 +1841,18 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display,
if (buftype == EGL_IOSURFACE_ANGLE) if (buftype == EGL_IOSURFACE_ANGLE)
{ {
#if ANGLE_PLATFORM_MACOS || ANGLE_PLATFORM_MACCATALYST
if (textureTarget != EGL_TEXTURE_RECTANGLE_ANGLE) if (textureTarget != EGL_TEXTURE_RECTANGLE_ANGLE)
{ {
return EglBadAttribute() << "EGL_IOSURFACE requires the EGL_TEXTURE_RECTANGLE target"; return EglBadAttribute()
<< "EGL_IOSURFACE requires the EGL_TEXTURE_RECTANGLE target on desktop macOS";
}
#else // ANGLE_PLATFORM_MACOS || ANGLE_PLATFORM_MACCATALYST
if (textureTarget != EGL_TEXTURE_2D)
{
return EglBadAttribute() << "EGL_IOSURFACE requires the EGL_TEXTURE_2D target on iOS";
} }
#endif // ANGLE_PLATFORM_MACOS || ANGLE_PLATFORM_MACCATALYST
if (textureFormat != EGL_TEXTURE_RGBA) if (textureFormat != EGL_TEXTURE_RGBA)
{ {
......
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