Commit 0dbe7cdd by James Darpinian Committed by Commit Bot

iOS testing support

angle_white_box_tests build and runs and passes on the iOS simulator with this change. angle_end2end_tests builds and runs but crashes. Bug: angleproject:4256 Bug: angleproject:5417 Change-Id: I8817e46415c4598cbfae49804727a2e9b21baff1 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2600361 Commit-Queue: James Darpinian <jdarpinian@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org>
parent eeb14308
...@@ -852,7 +852,7 @@ angle_source_set("libANGLE_with_capture") { ...@@ -852,7 +852,7 @@ angle_source_set("libANGLE_with_capture") {
} }
config("shared_library_public_config") { config("shared_library_public_config") {
if ((is_ios || is_mac) && !is_component_build) { if (is_mac && !is_component_build) {
# Executable targets that depend on the shared libraries below need to have # Executable targets that depend on the shared libraries below need to have
# the rpath setup in non-component build configurations. # the rpath setup in non-component build configurations.
ldflags = [ ldflags = [
......
...@@ -250,7 +250,16 @@ template("angle_executable") { ...@@ -250,7 +250,16 @@ template("angle_executable") {
} }
template("angle_shared_library") { template("angle_shared_library") {
shared_library(target_name) { # On ios, define an ios_framework_bundle instead of a shared library.
# ios_framework_bundle doesn't automatically link, so we have to create
# a group that links and bundles the framework as well.
target_type = "shared_library"
internal_target_name = target_name
if (is_ios) {
target_type = "ios_framework_bundle"
internal_target_name = target_name + "_framework"
}
target(target_type, internal_target_name) {
forward_variables_from(invoker, forward_variables_from(invoker,
"*", "*",
[ [
...@@ -271,6 +280,22 @@ template("angle_shared_library") { ...@@ -271,6 +280,22 @@ template("angle_shared_library") {
configs += [ angle_root + ":build_id_config" ] configs += [ angle_root + ":build_id_config" ]
configs -= [ "//build/config/android:hide_all_but_jni_onload" ] configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
} }
if (is_ios) {
info_plist = "$angle_root/util/ios/Info.plist"
}
}
if (is_ios) {
group(target_name) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
public_deps = [
":${internal_target_name}+bundle",
":${internal_target_name}+link",
]
}
} }
} }
...@@ -380,5 +405,13 @@ template("angle_test") { ...@@ -380,5 +405,13 @@ template("angle_test") {
use_raw_android_executable = true use_raw_android_executable = true
} }
} }
if (is_ios) {
# We use a special main function on iOS to initialize UIKit before the normal main runs.
ldflags = [
"-e",
"_ios_main",
]
sources += [ "$angle_root/util/ios/ios_main.mm" ]
}
} }
} }
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// system_utils_apple.cpp: Implementation of OS-specific functions for Apple platforms
#include "system_utils.h"
#include <unistd.h>
#include <CoreServices/CoreServices.h>
#include <mach-o/dyld.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <cstdlib>
#include <vector>
#include <array>
namespace angle
{
std::string GetExecutablePath()
{
std::string result;
uint32_t size = 0;
_NSGetExecutablePath(nullptr, &size);
std::vector<char> buffer;
buffer.resize(size + 1);
_NSGetExecutablePath(buffer.data(), &size);
buffer[size] = '\0';
if (!strrchr(buffer.data(), '/'))
{
return "";
}
return buffer.data();
}
std::string GetExecutableDirectory()
{
std::string executablePath = GetExecutablePath();
size_t lastPathSepLoc = executablePath.find_last_of("/");
return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : "";
}
double GetCurrentTime()
{
mach_timebase_info_data_t timebaseInfo;
mach_timebase_info(&timebaseInfo);
double secondCoeff = timebaseInfo.numer * 1e-9 / timebaseInfo.denom;
return secondCoeff * mach_absolute_time();
}
} // namespace angle
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// system_utils_osx.cpp: Implementation of OS-specific functions for OSX
#include "system_utils.h"
#include <unistd.h>
#include <CoreServices/CoreServices.h>
#include <mach-o/dyld.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <cstdlib>
#include <vector>
#include <array>
namespace angle
{
const char *GetSharedLibraryExtension()
{
return "framework";
}
} // namespace angle
...@@ -21,44 +21,8 @@ ...@@ -21,44 +21,8 @@
namespace angle namespace angle
{ {
std::string GetExecutablePath()
{
std::string result;
uint32_t size = 0;
_NSGetExecutablePath(nullptr, &size);
std::vector<char> buffer;
buffer.resize(size + 1);
_NSGetExecutablePath(buffer.data(), &size);
buffer[size] = '\0';
if (!strrchr(buffer.data(), '/'))
{
return "";
}
return buffer.data();
}
std::string GetExecutableDirectory()
{
std::string executablePath = GetExecutablePath();
size_t lastPathSepLoc = executablePath.find_last_of("/");
return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : "";
}
const char *GetSharedLibraryExtension() const char *GetSharedLibraryExtension()
{ {
return "dylib"; return "dylib";
} }
double GetCurrentTime()
{
mach_timebase_info_data_t timebaseInfo;
mach_timebase_info(&timebaseInfo);
double secondCoeff = timebaseInfo.numer * 1e-9 / timebaseInfo.denom;
return secondCoeff * mach_absolute_time();
}
} // namespace angle } // namespace angle
...@@ -103,10 +103,19 @@ Library *OpenSharedLibrary(const char *libraryName, SearchType searchType) ...@@ -103,10 +103,19 @@ Library *OpenSharedLibrary(const char *libraryName, SearchType searchType)
std::string directory; std::string directory;
if (searchType == SearchType::ApplicationDir) if (searchType == SearchType::ApplicationDir)
{ {
#if ANGLE_PLATFORM_IOS
// On iOS, shared libraries must be loaded from within the app bundle.
directory = GetExecutableDirectory() + "/Frameworks/";
#else
directory = GetHelperExecutableDir(); directory = GetHelperExecutableDir();
#endif
} }
std::string fullPath = directory + libraryName + "." + GetSharedLibraryExtension(); std::string fullPath = directory + libraryName + "." + GetSharedLibraryExtension();
#if ANGLE_PLATFORM_IOS
// On iOS, dlopen needs a suffix on the framework name to work.
fullPath = fullPath + "/" + libraryName;
#endif
return new PosixLibrary(fullPath); return new PosixLibrary(fullPath);
} }
......
...@@ -13,6 +13,9 @@ ...@@ -13,6 +13,9 @@
#if defined(ANGLE_ENABLE_EAGL) #if defined(ANGLE_ENABLE_EAGL)
// OpenGL ES is technically deprecated on iOS. Silence associated warnings.
# define GLES_SILENCE_DEPRECATION
# import <OpenGLES/EAGL.h> # import <OpenGLES/EAGL.h>
# import <OpenGLES/EAGLDrawable.h> # import <OpenGLES/EAGLDrawable.h>
# import <OpenGLES/EAGLIOSurface.h> # import <OpenGLES/EAGLIOSurface.h>
......
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
#if defined(ANGLE_ENABLE_EAGL) #if defined(ANGLE_ENABLE_EAGL)
// OpenGL ES is technically deprecated on iOS. Silence associated warnings.
# define GLES_SILENCE_DEPRECATION
# import <OpenGLES/EAGL.h> # import <OpenGLES/EAGL.h>
# import <OpenGLES/EAGLDrawable.h> # import <OpenGLES/EAGLDrawable.h>
# import <OpenGLES/EAGLIOSurface.h> # import <OpenGLES/EAGLIOSurface.h>
......
...@@ -82,9 +82,15 @@ if (is_mac || is_ios) { ...@@ -82,9 +82,15 @@ if (is_mac || is_ios) {
"src/common/apple/SoftLinking.h", "src/common/apple/SoftLinking.h",
"src/common/gl/cgl/FunctionsCGL.cpp", "src/common/gl/cgl/FunctionsCGL.cpp",
"src/common/gl/cgl/FunctionsCGL.h", "src/common/gl/cgl/FunctionsCGL.h",
"src/common/system_utils_mac.cpp", "src/common/system_utils_apple.cpp",
"src/common/system_utils_posix.cpp", "src/common/system_utils_posix.cpp",
] ]
if (is_mac) {
libangle_common_sources += [ "src/common/system_utils_mac.cpp" ]
}
if (is_ios) {
libangle_common_sources += [ "src/common/system_utils_ios.cpp" ]
}
} }
if (is_win) { if (is_win) {
......
...@@ -48,6 +48,12 @@ angle_static_library("angle_test_expectations") { ...@@ -48,6 +48,12 @@ angle_static_library("angle_test_expectations") {
sources += test_expectations_sources_mac sources += test_expectations_sources_mac
frameworks = [ "Cocoa.framework" ] frameworks = [ "Cocoa.framework" ]
} }
if (is_ios) {
sources += [
"test_expectations/GPUTestConfig_ios.h",
"test_expectations/GPUTestConfig_ios.mm",
]
}
} }
config("angle_common_test_utils_config") { config("angle_common_test_utils_config") {
...@@ -189,6 +195,19 @@ if (is_win || is_linux || is_chromeos || is_mac || is_android || is_fuchsia || ...@@ -189,6 +195,19 @@ if (is_win || is_linux || is_chromeos || is_mac || is_android || is_fuchsia ||
if (is_fuchsia) { if (is_fuchsia) {
manifest = "//build/config/fuchsia/gfx_tests.cmx" manifest = "//build/config/fuchsia/gfx_tests.cmx"
} }
if (is_ios) {
xcode_extra_attributes = {
SUPPORTS_MACCATALYST = "YES"
}
# Need to bundle the libraries inside the .app.
deps += [
"$angle_root:libEGL",
"$angle_root:libGLESv1_CM",
"$angle_root:libGLESv2",
]
}
} }
} }
......
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// GPUTestConfig_ios.h:
// Helper functions for GPUTestConfig that have to be compiled in ObjectiveC++
//
#ifndef TEST_EXPECTATIONS_GPU_TEST_CONFIG_IOS_H_
#define TEST_EXPECTATIONS_GPU_TEST_CONFIG_IOS_H_
#include <stdint.h>
namespace angle
{
void GetOperatingSystemVersionNumbers(int32_t *majorVersion, int32_t *minorVersion);
} // namespace angle
#endif // TEST_EXPECTATIONS_GPU_TEST_CONFIG_IOS_H_
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// GPUTestConfig_iOS.mm:
// Helper functions for GPUTestConfig that have to be compiled in ObjectiveC++
#include "GPUTestConfig_ios.h"
#include "common/apple_platform_utils.h"
namespace angle
{
void GetOperatingSystemVersionNumbers(int32_t *majorVersion, int32_t *minorVersion)
{
// TODO(jdarpinian): Implement this. http://anglebug.com/5485
*majorVersion = 0;
*minorVersion = 0;
}
} // namespace angle
...@@ -86,6 +86,15 @@ if (is_mac) { ...@@ -86,6 +86,15 @@ if (is_mac) {
] ]
} }
if (is_ios) {
_util_sources += [
"ios/IOSPixmap.h",
"ios/IOSPixmap.mm",
"ios/IOSWindow.h",
"ios/IOSWindow.mm",
]
}
if (is_android) { if (is_android) {
_util_sources += [ _util_sources += [
"android/AndroidPixmap.cpp", "android/AndroidPixmap.cpp",
...@@ -189,6 +198,9 @@ foreach(is_shared_library, ...@@ -189,6 +198,9 @@ foreach(is_shared_library,
if (is_mac) { if (is_mac) {
frameworks += [ "AppKit.framework" ] frameworks += [ "AppKit.framework" ]
} }
if (is_ios) {
frameworks += [ "UIKit.framework" ]
}
} }
if (is_android) { if (is_android) {
...@@ -221,7 +233,7 @@ foreach(is_shared_library, ...@@ -221,7 +233,7 @@ foreach(is_shared_library,
public_deps += [ ":angle_util_loader" ] public_deps += [ ":angle_util_loader" ]
if ((is_ios || is_mac) && !is_component_build) { if (is_mac && !is_component_build) {
ldflags = [ ldflags = [
"-install_name", "-install_name",
"@rpath/libangle_util.dylib", "@rpath/libangle_util.dylib",
......
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// iOSPixmap.h: Definition of the implementation of OSPixmap for iOS
#ifndef UTIL_IOS_PIXMAP_H_
#define UTIL_IOS_PIXMAP_H_
#include "util/OSPixmap.h"
#endif // UTIL_IOS_PIXMAP_H_
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// iOSPixmap.cpp: Implementation of OSPixmap for iOS
#include "util/ios/IOSPixmap.h"
// TODO(jdarpinian): find out the native iOS pixmap type and implement this
// http://anglebug.com/5485
OSPixmap *CreateOSPixmap()
{
return nullptr;
}
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// IOSWindow.h: Definition of the implementation of OSWindow for iOS
#ifndef UTIL_IOS_WINDOW_H_
#define UTIL_IOS_WINDOW_H_
#include "common/debug.h"
#include "util/OSWindow.h"
class IOSWindow : public OSWindow
{
public:
IOSWindow() {}
~IOSWindow() override {}
void disableErrorMessageDialog() override {}
void destroy() override {}
void resetNativeWindow() override {}
EGLNativeWindowType getNativeWindow() const override;
EGLNativeDisplayType getNativeDisplay() const override { return EGL_DEFAULT_DISPLAY; }
void messageLoop() override {}
void setMousePosition(int x, int y) override { UNIMPLEMENTED(); }
bool setOrientation(int width, int height) override;
bool setPosition(int x, int y) override
{
UNIMPLEMENTED();
return false;
}
bool resize(int width, int height) override;
void setVisible(bool isVisible) override {}
void signalTestEvent() override { UNIMPLEMENTED(); }
private:
bool initializeImpl(const std::string &name, int width, int height) override;
};
#endif // UTIL_IOS_WINDOW_H_
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// IOSWindow.mm: Implementation of OSWindow for iOS
#include "util/ios/IOSWindow.h"
#include <set>
#include "anglebase/no_destructor.h"
#include "common/debug.h"
#import <UIKit/UIKit.h>
static CALayer *rootLayer()
{
return [[[[[UIApplication sharedApplication] delegate] window] rootViewController] view].layer;
}
bool IOSWindow::initializeImpl(const std::string &name, int width, int height)
{
return true;
}
EGLNativeWindowType IOSWindow::getNativeWindow() const
{
return rootLayer();
}
bool IOSWindow::setOrientation(int width, int height)
{
UNIMPLEMENTED();
return false;
}
bool IOSWindow::resize(int width, int height)
{
rootLayer().frame = CGRectMake(0, 0, width, height);
return true;
}
// static
OSWindow *OSWindow::New()
{
return new IOSWindow;
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleIdentifier</key>
<string>${IOS_BUNDLE_ID_PREFIX}.${EXECUTABLE_NAME:rfc1034identifier}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
</dict>
</plist>
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ios_main.mm: Alternative entry point for iOS executables that initializes UIKit before calling
// the default entry point.
#import <UIKit/UIKit.h>
#include <stdio.h>
static int original_argc;
static char **original_argv;
extern "C" int main(int argc, char **argv);
@interface AngleUtilAppDelegate : UIResponder <UIApplicationDelegate>
@property(nullable, nonatomic, strong) UIWindow *window;
@end
@implementation AngleUtilAppDelegate
@synthesize window;
- (void)runMain
{
exit(main(original_argc, original_argv));
}
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController = [[UIViewController alloc] initWithNibName:nil bundle:nil];
[self.window makeKeyAndVisible];
// We need to return from this function before the app finishes launching, so call main in a
// timer callback afterward.
[NSTimer scheduledTimerWithTimeInterval:0
target:self
selector:@selector(runMain)
userInfo:nil
repeats:NO];
return YES;
}
@end
extern "C" int ios_main(int argc, char **argv)
{
original_argc = argc;
original_argv = argv;
return UIApplicationMain(argc, argv, nullptr, NSStringFromClass([AngleUtilAppDelegate class]));
}
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