diff --git a/apple/RetroArch_iOS.xcodeproj/project.pbxproj b/apple/RetroArch_iOS.xcodeproj/project.pbxproj index 24061f5980..c5888a4a4c 100644 --- a/apple/RetroArch_iOS.xcodeproj/project.pbxproj +++ b/apple/RetroArch_iOS.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 509FC979183F9F18007A5A30 /* menu.m in Sources */ = {isa = PBXBuildFile; fileRef = 509FC978183F9F18007A5A30 /* menu.m */; }; + 50E7189F184B88AA001956CE /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50E7189E184B88AA001956CE /* CoreVideo.framework */; }; 50F54A871848F9FC00E19EFD /* ic_pause.png in Resources */ = {isa = PBXBuildFile; fileRef = 50F54A861848F9FC00E19EFD /* ic_pause.png */; }; 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; @@ -37,6 +38,7 @@ /* Begin PBXFileReference section */ 509FC978183F9F18007A5A30 /* menu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = menu.m; path = iOS/menu.m; sourceTree = SOURCE_ROOT; }; + 50E7189E184B88AA001956CE /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; 50F54A861848F9FC00E19EFD /* ic_pause.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ic_pause.png; sourceTree = ""; }; 962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = ""; }; 962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = ""; }; @@ -78,6 +80,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 50E7189F184B88AA001956CE /* CoreVideo.framework in Frameworks */, 96366C5916C9ACF500D64A22 /* AudioToolbox.framework in Frameworks */, 96366C5516C9AC3300D64A22 /* CoreAudio.framework in Frameworks */, 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */, @@ -132,6 +135,7 @@ 96AFAE2816C1D4EA009DE44C /* Frameworks */ = { isa = PBXGroup; children = ( + 50E7189E184B88AA001956CE /* CoreVideo.framework */, 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */, 96366C5416C9AC3300D64A22 /* CoreAudio.framework */, 96AFAE2916C1D4EA009DE44C /* UIKit.framework */, diff --git a/camera/ios.c b/camera/ios.c index 6378e9b2d7..c433d3d976 100644 --- a/camera/ios.c +++ b/camera/ios.c @@ -16,15 +16,24 @@ #include #include +#include +#include +#include #include "../driver.h" typedef struct ios_camera { - GLuint tex; + CFDictionaryRef empty; + CFMutableDictionaryRef attrs; + CVPixelBufferRef renderTarget; + CVOpenGLESTextureRef renderTexture; + CVOpenGLESTextureCacheRef textureCache; + GLuint renderFrameBuffer; } ioscamera_t; static void *ios_camera_init(const char *device, uint64_t caps, unsigned width, unsigned height) { + int ret = 0; if ((caps & (1ULL << RETRO_CAMERA_BUFFER_OPENGL_TEXTURE)) == 0) { RARCH_ERR("ioscamera returns OpenGL texture.\n"); @@ -35,6 +44,33 @@ static void *ios_camera_init(const char *device, uint64_t caps, unsigned width, if (!ioscamera) return NULL; + ioscamera->empty = CFDictionaryCreate(kCFAllocatorDefault, + NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + ioscamera->attrs = CFDictionaryCreateMutable(kCFAllocatorDefault, + 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFDictionarySetValue(ioscamera->attrs, kCVPixelBufferIOSurfacePropertiesKey, + ioscamera->empty); + + // TODO: for testing, image is 640x480 for now + //if (width > 640) + width = 640; + //if (height > 480) + height = 480; + + ret = CVPixelBufferCreate(kCFAllocatorDefault, width, height, + kCVPixelFormatType_32BGRA, ioscamera->attrs, &ioscamera->renderTarget); + if (ret != 0) + goto dealloc; + + // create a texture from our render target. + // textureCache will be what you previously made with CVOpenGLESTextureCacheCreate + ret = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, + ioscamera->textureCache, ioscamera->renderTarget, NULL, GL_TEXTURE_2D, + GL_RGBA, width, height, GL_BGRA, GL_UNSIGNED_BYTE, 0, &ioscamera->renderTexture); + if (ret != 0) + goto dealloc; + return ioscamera; dealloc: free(ioscamera); @@ -44,6 +80,8 @@ dealloc: static void ios_camera_free(void *data) { ioscamera_t *ioscamera = (ioscamera_t*)data; + + //TODO - anything to free here? if (ioscamera) free(ioscamera); @@ -54,22 +92,28 @@ static bool ios_camera_start(void *data) { ioscamera_t *ioscamera = (ioscamera_t*)data; - glGenTextures(1, &ioscamera->tex); - glBindTexture(GL_TEXTURE_2D, ioscamera->tex); + glBindTexture(CVOpenGLESTextureGetTarget(ioscamera->renderTexture), + CVOpenGLESTextureGetName(ioscamera->renderTexture)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + // bind the texture to teh fraembuffer you're going to render to + // (boilerplate code to make a framebuffer not shown) + glBindFramebuffer(GL_FRAMEBUFFER, ioscamera->renderFrameBuffer); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, CVOpenGLESTextureGetName(ioscamera->renderTexture), 0); + return true; } static void ios_camera_stop(void *data) { ioscamera_t *ioscamera = (ioscamera_t*)data; - - if (ioscamera->tex) - glDeleteTextures(1, &ioscamera->tex); + (void)ioscamera; + + //TODO - anything to do here? } static bool ios_camera_poll(void *data, retro_camera_frame_raw_framebuffer_t frame_raw_cb, @@ -77,27 +121,20 @@ static bool ios_camera_poll(void *data, retro_camera_frame_raw_framebuffer_t fra { ioscamera_t *ioscamera = (ioscamera_t*)data; - bool newFrame = false; (void)frame_raw_cb; - (void)newFrame; - if (newFrame) - { - // FIXME: Identity for now. Use proper texture matrix as returned by iOS Camera (if at all?). - static const float affine[] = { - 1.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 1.0f - }; + // FIXME: Identity for now. Use proper texture matrix as returned by iOS Camera (if at all?). + static const float affine[] = { + 1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f + }; - if (frame_gl_cb) - frame_gl_cb(ioscamera->tex, - GL_TEXTURE_2D, - affine); - return true; - } - - return false; + if (frame_gl_cb) + frame_gl_cb(CVOpenGLESTextureGetName(ioscamera->renderTexture), + GL_TEXTURE_2D, + affine); + return true; } const camera_driver_t camera_ios = {