@@ -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
107116IOSurfaceSurfaceEAGL::~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
188215egl::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)
223273bool 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)
0 commit comments