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 <syoussefi@chromium.org>
Reviewed-by: Jonah Ryan-Davis <jonahr@google.com>
Commit-Queue: Kenneth Russell <kbr@chromium.org>
This commit is contained in:
Kenneth Russell 2020-01-10 16:19:02 -08:00 коммит произвёл Commit Bot
Родитель 2e1beb4005
Коммит 86f7309717
6 изменённых файлов: 113 добавлений и 26 удалений

Просмотреть файл

@ -21,7 +21,7 @@ Status
Draft
Version
Version 3, Aug 13, 2019
Version 4, Dec 28, 2019
Number
@ -53,6 +53,7 @@ New Tokens
EGL_TEXTURE_RECTANGLE_ANGLE 0x345B
EGL_TEXTURE_TYPE_ANGLE 0x345C
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)
@ -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_WIDTH with a value between 1 and the width 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
planes of <buffer> (exclusive).
@ -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
combinations listed in table egl.iosurface.formats or an
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
@ -122,3 +132,5 @@ Revision History
Version 1, 2017/12/06 - first draft.
Version 2, 2019/04/01 - Allow MakeCurrent.
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
#define EGL_TEXTURE_RECTANGLE_ANGLE 0x345B
#define EGL_TEXTURE_TYPE_ANGLE 0x345C
#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 */
#ifndef EGL_ANGLE_create_context_extensions_enabled

Просмотреть файл

@ -29,8 +29,6 @@
# define GLES_SILENCE_DEPRECATION
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
namespace
{
@ -38,8 +36,6 @@ const char *kOpenGLESDylibName = "/System/Library/Frameworks/OpenGLES.framework/
}
# endif
namespace rx
{
@ -69,10 +65,6 @@ egl::Error DisplayEAGL::initialize(egl::Display *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;
if (!angle::GetSystemInfo(&info))
{
@ -105,7 +97,6 @@ egl::Error DisplayEAGL::initialize(egl::Display *display)
}
return DisplayGL::initialize(display);
# endif
}
void DisplayEAGL::terminate()

Просмотреть файл

@ -10,8 +10,7 @@
#include "libANGLE/renderer/gl/SurfaceGL.h"
#include "libANGLE/renderer/gl/eagl/DisplayEAGL.h"
struct __IOSurface;
typedef __IOSurface *IOSurfaceRef;
#include <IOSurface/IOSurfaceRef.h>
namespace egl
{
@ -66,6 +65,10 @@ class IOSurfaceSurfaceEAGL : public SurfaceGL
private:
angle::Result initializeAlphaChannel(const gl::Context *context, GLuint texture);
#if defined(ANGLE_PLATFORM_IOS_SIMULATOR)
IOSurfaceLockOptions getIOSurfaceLockOptions() const;
#endif
EAGLContextObj mEAGLContext;
IOSurfaceRef mIOSurface;
int mWidth;
@ -74,6 +77,11 @@ class IOSurfaceSurfaceEAGL : public SurfaceGL
int mFormatIndex;
bool mAlphaInitialized;
#if defined(ANGLE_PLATFORM_IOS_SIMULATOR)
GLuint mBoundTextureID;
bool mUploadFromIOSurface;
bool mReadbackToIOSurface;
#endif
};
} // namespace rx

Просмотреть файл

@ -102,6 +102,15 @@ IOSurfaceSurfaceEAGL::IOSurfaceSurfaceEAGL(const egl::SurfaceState &state,
ASSERT(mFormatIndex >= 0);
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()
@ -154,7 +163,6 @@ egl::Error IOSurfaceSurfaceEAGL::bindTexImage(const gl::Context *context,
gl::Texture *texture,
EGLint)
{
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
StateManagerGL *stateManager = GetStateManagerGL(context);
const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
@ -162,6 +170,7 @@ egl::Error IOSurfaceSurfaceEAGL::bindTexImage(const gl::Context *context,
stateManager->bindTexture(gl::TextureType::_2D, textureID);
const auto &format = kIOSurfaceFormats[mFormatIndex];
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
if (![mEAGLContext texImageIOSurface:mIOSurface
target:GL_TEXTURE_2D
internalFormat:format.nativeInternalFormat
@ -178,17 +187,58 @@ egl::Error IOSurfaceSurfaceEAGL::bindTexImage(const gl::Context *context,
{
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();
# else
return egl::EglContextLost() << "EAGLContext IOSurface not supported in the simulator.";
# endif
}
egl::Error IOSurfaceSurfaceEAGL::releaseTexImage(const gl::Context *context, EGLint buffer)
{
const FunctionsGL *functions = GetFunctionsGL(context);
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
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();
}
@ -223,7 +273,6 @@ EGLint IOSurfaceSurfaceEAGL::getSwapBehavior() const
bool IOSurfaceSurfaceEAGL::validateAttributes(EGLClientBuffer buffer,
const egl::AttributeMap &attribs)
{
# if !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
IOSurfaceRef ioSurface = reinterpret_cast<IOSurfaceRef>(buffer);
// The plane must exist for this IOSurface. IOSurfaceGetPlaneCount can return 0 for non-planar
@ -264,9 +313,6 @@ bool IOSurfaceSurfaceEAGL::validateAttributes(EGLClientBuffer buffer,
}
return true;
# else
return false;
# endif
}
// 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
ERR() << "[EAGLContext texImageIOSurface] failed";
return nullptr;
}
# else
ERR() << "IOSurfaces not supported on iOS Simulator";
# endif
# else // !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
ERR() << "IOSurfaces with OpenGL ES not supported on iOS Simulator";
# endif // !defined(ANGLE_PLATFORM_IOS_SIMULATOR)
if (IsError(initializeAlphaChannel(context, texture)))
{
@ -357,6 +403,18 @@ bool IOSurfaceSurfaceEAGL::hasEmulatedAlphaChannel() const
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
#endif // defined(ANGLE_PLATFORM_IOS)

Просмотреть файл

@ -1775,6 +1775,13 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display,
return EglBadAttribute() << "<buftype> doesn't support setting GL colorspace";
}
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:
return EglBadAttribute();
}
@ -1834,10 +1841,18 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display,
if (buftype == EGL_IOSURFACE_ANGLE)
{
#if ANGLE_PLATFORM_MACOS || ANGLE_PLATFORM_MACCATALYST
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)
{