-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
85b33a0
commit 05189a8
Showing
7 changed files
with
379 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import SwiftUI | ||
import CompositorServices | ||
|
||
|
||
struct ContentStageConfiguration: CompositorLayerConfiguration { | ||
func makeConfiguration(capabilities: LayerRenderer.Capabilities, configuration: inout LayerRenderer.Configuration) { | ||
configuration.depthFormat = .depth32Float | ||
configuration.colorFormat = .bgra8Unorm_srgb | ||
|
||
let foveationEnabled = capabilities.supportsFoveation | ||
configuration.isFoveationEnabled = foveationEnabled | ||
|
||
let options: LayerRenderer.Capabilities.SupportedLayoutsOptions = foveationEnabled ? [.foveationEnabled] : [] | ||
let supportedLayouts = capabilities.supportedLayouts(options: options) | ||
|
||
configuration.layout = supportedLayouts.contains(.layered) ? .layered : .dedicated | ||
} | ||
} | ||
|
||
class Renderer { | ||
let layerRenderer: LayerRenderer | ||
var bgfxAdapter: BgfxAdapter | ||
|
||
init(_ layerRenderer: LayerRenderer) { | ||
self.layerRenderer = layerRenderer | ||
bgfxAdapter = BgfxAdapter(layerRenderer) | ||
} | ||
|
||
func startRenderLoop() { | ||
let renderThread = Thread { | ||
self.renderLoop() | ||
} | ||
renderThread.name = "Render Thread" | ||
renderThread.start() | ||
} | ||
|
||
|
||
func renderLoop() { | ||
while true { | ||
if layerRenderer.state == .invalidated { | ||
print("Layer is invalidated") | ||
|
||
bgfxAdapter.shutdown() | ||
return | ||
} else if layerRenderer.state == .paused { | ||
layerRenderer.waitUntilRunning() | ||
continue | ||
} else { | ||
autoreleasepool { | ||
bgfxAdapter.initialize() | ||
bgfxAdapter.render() | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
||
@main | ||
struct ExampleApp: App { | ||
@State private var showImmersiveSpace = false | ||
@State private var immersiveSpaceIsShown = false | ||
|
||
@Environment(\.openImmersiveSpace) var openImmersiveSpace | ||
@Environment(\.dismissImmersiveSpace) var dismissImmersiveSpace | ||
|
||
var body: some Scene { | ||
WindowGroup { | ||
VStack { | ||
Toggle("Show Immersive Space", isOn: $showImmersiveSpace) | ||
.toggleStyle(.button) | ||
.padding(.top, 50) | ||
} | ||
.onChange(of: showImmersiveSpace) { _, newValue in | ||
Task { | ||
if newValue { | ||
switch await openImmersiveSpace(id: "ImmersiveSpace") { | ||
case .opened: | ||
immersiveSpaceIsShown = true | ||
case .error, .userCancelled: | ||
fallthrough | ||
@unknown default: | ||
immersiveSpaceIsShown = false | ||
showImmersiveSpace = false | ||
} | ||
} else if immersiveSpaceIsShown { | ||
await dismissImmersiveSpace() | ||
immersiveSpaceIsShown = false | ||
} | ||
} | ||
} | ||
|
||
} | ||
ImmersiveSpace(id: "ImmersiveSpace") { | ||
CompositorLayer(configuration: ContentStageConfiguration()) { layerRenderer in | ||
let renderer = Renderer(layerRenderer) | ||
renderer.startRenderLoop() | ||
} | ||
}.immersionStyle(selection: .constant(.full), in: .full) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
#include "entry_p.h" | ||
|
||
#if ENTRY_CONFIG_USE_NATIVE && BX_PLATFORM_VISIONOS | ||
|
||
#include "swift_adapter.hpp" | ||
|
||
#include <bgfx/platform.h> | ||
#include <bx/uint32_t.h> | ||
#include <bx/thread.h> | ||
|
||
namespace entry | ||
{ | ||
struct MainThreadEntry | ||
{ | ||
int m_argc; | ||
const char* const* m_argv; | ||
|
||
static int32_t threadFunc(bx::Thread* _thread, void* _userData); | ||
}; | ||
|
||
static WindowHandle s_defaultWindow = { 0 }; | ||
|
||
struct Context | ||
{ | ||
Context(uint32_t _width, uint32_t _height) | ||
{ | ||
static const char* const argv[] = { "visionos" }; | ||
m_mte.m_argc = BX_COUNTOF(argv); | ||
m_mte.m_argv = argv; | ||
|
||
m_eventQueue.postSizeEvent(s_defaultWindow, _width, _height); | ||
|
||
|
||
// Prevent render thread creation. | ||
bgfx::renderFrame(); | ||
|
||
m_thread.init(MainThreadEntry::threadFunc, &m_mte); | ||
} | ||
|
||
|
||
~Context() | ||
{ | ||
m_thread.shutdown(); | ||
} | ||
|
||
MainThreadEntry m_mte; | ||
bx::Thread m_thread; | ||
void* m_window; | ||
|
||
EventQueue m_eventQueue; | ||
}; | ||
|
||
static Context* s_ctx; | ||
|
||
int32_t MainThreadEntry::threadFunc(bx::Thread* _thread, void* _userData) | ||
{ | ||
BX_UNUSED(_thread); | ||
|
||
if (_thread != NULL) { | ||
_thread->setThreadName("Main Thread BGFX"); | ||
} | ||
|
||
CFBundleRef mainBundle = CFBundleGetMainBundle(); | ||
if (mainBundle != nil) | ||
{ | ||
CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); | ||
if (resourcesURL != nil) | ||
{ | ||
char path[PATH_MAX]; | ||
if (CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8*)path, PATH_MAX) ) | ||
{ | ||
chdir(path); | ||
} | ||
|
||
CFRelease(resourcesURL); | ||
} | ||
} | ||
|
||
MainThreadEntry* self = (MainThreadEntry*)_userData; | ||
int32_t result = main(self->m_argc, self->m_argv); | ||
return result; | ||
} | ||
|
||
const Event* poll() | ||
{ | ||
return s_ctx->m_eventQueue.poll(); | ||
} | ||
|
||
const Event* poll(WindowHandle _handle) | ||
{ | ||
return s_ctx->m_eventQueue.poll(_handle); | ||
} | ||
|
||
void release(const Event* _event) | ||
{ | ||
s_ctx->m_eventQueue.release(_event); | ||
} | ||
|
||
WindowHandle createWindow(int32_t _x, int32_t _y, uint32_t _width, uint32_t _height, uint32_t _flags, const char* _title) | ||
{ | ||
BX_UNUSED(_x, _y, _width, _height, _flags, _title); | ||
WindowHandle handle = { UINT16_MAX }; | ||
return handle; | ||
} | ||
|
||
void destroyWindow(WindowHandle _handle) | ||
{ | ||
BX_UNUSED(_handle); | ||
} | ||
|
||
void setWindowPos(WindowHandle _handle, int32_t _x, int32_t _y) | ||
{ | ||
BX_UNUSED(_handle, _x, _y); | ||
} | ||
|
||
void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height) | ||
{ | ||
BX_UNUSED(_handle, _width, _height); | ||
} | ||
|
||
void setWindowTitle(WindowHandle _handle, const char* _title) | ||
{ | ||
BX_UNUSED(_handle, _title); | ||
} | ||
|
||
void setWindowFlags(WindowHandle _handle, uint32_t _flags, bool _enabled) | ||
{ | ||
BX_UNUSED(_handle, _flags, _enabled); | ||
} | ||
|
||
void toggleFullscreen(WindowHandle _handle) | ||
{ | ||
BX_UNUSED(_handle); | ||
} | ||
|
||
void setMouseLock(WindowHandle _handle, bool _lock) | ||
{ | ||
BX_UNUSED(_handle, _lock); | ||
} | ||
|
||
void* getNativeWindowHandle(WindowHandle _handle) | ||
{ | ||
if (kDefaultWindowHandle.idx == _handle.idx) | ||
{ | ||
return s_ctx->m_window; | ||
} | ||
|
||
return NULL; | ||
} | ||
|
||
void* getNativeDisplayHandle() | ||
{ | ||
return NULL; | ||
} | ||
|
||
bgfx::NativeWindowHandleType::Enum getNativeWindowHandleType() | ||
{ | ||
return bgfx::NativeWindowHandleType::Default; | ||
} | ||
|
||
} // namespace entry | ||
|
||
using namespace entry; | ||
|
||
|
||
|
||
bool BgfxAdapter::initialize(void) { | ||
if (!m_initialized) { | ||
// Set context width and height to default visionOS resolution. | ||
s_ctx = new Context(2732, 2048); | ||
s_ctx->m_window = m_layerRenderer; | ||
m_initialized = true; | ||
} | ||
|
||
return m_initialized; | ||
} | ||
|
||
void BgfxAdapter::shutdown(void) { | ||
if (m_initialized) { | ||
s_ctx->m_eventQueue.postExitEvent(); | ||
s_ctx = NULL; | ||
} | ||
|
||
m_initialized = false; | ||
} | ||
|
||
void BgfxAdapter::render() { | ||
if (!m_initialized) { | ||
return; | ||
} | ||
bgfx::renderFrame(); | ||
} | ||
|
||
#endif // BX_PLATFORM_VISIONOS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#ifndef BgfxAdapter_hpp | ||
#define BgfxAdapter_hpp | ||
|
||
#include <CompositorServices/CompositorServices.h> | ||
|
||
class BgfxAdapter { | ||
private: | ||
bool m_initialized = false; | ||
cp_layer_renderer_t m_layerRenderer = NULL; | ||
|
||
public: | ||
BgfxAdapter(cp_layer_renderer_t layerRenderer) : m_layerRenderer(layerRenderer) { | ||
} | ||
|
||
~BgfxAdapter() { | ||
shutdown(); | ||
} | ||
|
||
bool initialize(void); | ||
void shutdown(void); | ||
void render(void); | ||
}; | ||
|
||
#endif /* BgfxAdapter_hpp */ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
#include "swift_adapter.hpp" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?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>CFBundleDevelopmentRegion</key> | ||
<string>en</string> | ||
<key>CFBundleDisplayName</key> | ||
<string>Examples Debug</string> | ||
<key>CFBundleExecutable</key> | ||
<string>$(EXECUTABLE_NAME)</string> | ||
<key>CFBundleIdentifier</key> | ||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||
<key>CFBundleInfoDictionaryVersion</key> | ||
<string>6.0</string> | ||
<key>CFBundleName</key> | ||
<string>$(PRODUCT_NAME)</string> | ||
<key>CFBundlePackageType</key> | ||
<string>APPL</string> | ||
<key>CFBundleShortVersionString</key> | ||
<string>1.0</string> | ||
<key>CFBundleSignature</key> | ||
<string>????</string> | ||
<key>CFBundleVersion</key> | ||
<string>1</string> | ||
<key>UIApplicationSceneManifest</key> | ||
<dict> | ||
<key>UIApplicationSupportsMultipleScenes</key> | ||
<true/> | ||
<key>UISceneConfigurations</key> | ||
<dict/> | ||
</dict> | ||
</dict> | ||
</plist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.