Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

try to use metal #8

Open
wants to merge 18 commits into
base: waldo
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions OpenParsec.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
27E61AAA2929B92200FF6563 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27E61AA92929B92200FF6563 /* MainView.swift */; };
27ED36FF292D4F9800B1BE3D /* NetworkHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27ED36FE292D4F9800B1BE3D /* NetworkHandler.swift */; };
84480EBE2ADC4FDA007DE5F1 /* GameController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84480EBD2ADC4FDA007DE5F1 /* GameController.swift */; };
84480EC02AEE0ECE007DE5F1 /* ParsecMTLRender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84480EBF2AEE0ECD007DE5F1 /* ParsecMTLRender.swift */; };
84480EC22AEE0EDB007DE5F1 /* ParsecMetalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84480EC12AEE0EDB007DE5F1 /* ParsecMetalView.swift */; };
FC16A7AD29A97BDA00BB70A7 /* Shared.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC16A7AC29A97BDA00BB70A7 /* Shared.swift */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -74,6 +76,8 @@
27E61AA92929B92200FF6563 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
27ED36FE292D4F9800B1BE3D /* NetworkHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkHandler.swift; sourceTree = "<group>"; };
84480EBD2ADC4FDA007DE5F1 /* GameController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameController.swift; sourceTree = "<group>"; };
84480EBF2AEE0ECD007DE5F1 /* ParsecMTLRender.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParsecMTLRender.swift; sourceTree = "<group>"; };
84480EC12AEE0EDB007DE5F1 /* ParsecMetalView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParsecMetalView.swift; sourceTree = "<group>"; };
FC16A7AC29A97BDA00BB70A7 /* Shared.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shared.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -117,6 +121,8 @@
27E61A90292965FC00FF6563 /* OpenParsec */ = {
isa = PBXGroup;
children = (
84480EC12AEE0EDB007DE5F1 /* ParsecMetalView.swift */,
84480EBF2AEE0ECD007DE5F1 /* ParsecMTLRender.swift */,
84480EBD2ADC4FDA007DE5F1 /* GameController.swift */,
27899AC5292FE2A9001ACA33 /* audio.c */,
27899AC6292FE2A9001ACA33 /* audio.h */,
Expand Down Expand Up @@ -233,6 +239,8 @@
27E61A92292965FC00FF6563 /* AppDelegate.swift in Sources */,
27E61AAA2929B92200FF6563 /* MainView.swift in Sources */,
271D14FD292EAA3600D7F1D6 /* ParsecGLKViewController.swift in Sources */,
84480EC02AEE0ECE007DE5F1 /* ParsecMTLRender.swift in Sources */,
84480EC22AEE0EDB007DE5F1 /* ParsecMetalView.swift in Sources */,
274A69CF29EA07FA00F595A5 /* SettingsView.swift in Sources */,
27E61AA8292994B500FF6563 /* ActivityIndicator.swift in Sources */,
271D14FC292EAA3600D7F1D6 /* ParsecGLKRenderer.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions OpenParsec/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class AppDelegate:UIResponder, UIApplicationDelegate
func application(_ application:UIApplication, didFinishLaunchingWithOptions launchOptions:[UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
// Override point for customization after application launch.
UIApplication.shared.isIdleTimerDisabled = true
return true
}

Expand Down
6 changes: 5 additions & 1 deletion OpenParsec/CParsec.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import ParsecSDK
import UIKit
import MetalKit

enum RendererType
{
case opengl
case metal
}

class CParsec
Expand Down Expand Up @@ -91,12 +93,14 @@ class CParsec
hostHeight = Float(height)
}

static func renderFrame(_ type:RendererType, timeout:UInt32 = 16) // timeout in ms, 16 == 60 FPS, 8 == 120 FPS
static func renderFrame(_ type:RendererType, cq: inout MTLCommandQueue, texturePtr: inout UnsafeMutableRawPointer?, timeout:UInt32 = 16) // timeout in ms, 16 == 60 FPS, 8 == 120 FPS
{
switch type
{
case .opengl:
ParsecClientGLRenderFrame(_parsec, UInt8(DEFAULT_STREAM), nil, nil, timeout)
case .metal:
ParsecClientMetalRenderFrame(_parsec, UInt8(DEFAULT_STREAM), &cq, &texturePtr, nil, nil, timeout)
}
}

Expand Down
2 changes: 2 additions & 0 deletions OpenParsec/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
</array>
<key>UIRequiresFullScreen</key>
<false/>
<key>UIStatusBarHidden</key>
<true/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
<key>UISupportedInterfaceOrientations</key>
Expand Down
7 changes: 4 additions & 3 deletions OpenParsec/ParsecGLKRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ class ParsecGLKRenderer:NSObject, GLKViewDelegate, GLKViewControllerDelegate
var glkView:GLKView
var glkViewController:GLKViewController
var lastWidth:CGFloat

//var FramesNotFlush:UInt32
init(_ view:GLKView, _ viewController:GLKViewController)
{
glkView = view
glkViewController = viewController
lastWidth = 1.0

//FramesNotFlush = 0
super.init()

glkView.delegate = self
Expand All @@ -34,8 +34,9 @@ class ParsecGLKRenderer:NSObject, GLKViewDelegate, GLKViewControllerDelegate
CParsec.setFrame(view.frame.size.width, view.frame.size.height, view.contentScaleFactor)
lastWidth = view.frame.size.width
}
CParsec.renderFrame(.opengl)
//CParsec.renderFrame(.opengl, cq: nil, texturePtr: nil)
//glFlush()

}

func glkViewControllerUpdate(_ controller:GLKViewController) { }
Expand Down
42 changes: 42 additions & 0 deletions OpenParsec/ParsecMTLRender.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import SwiftUI
import MetalKit

class MTLRender: NSObject, MTKViewDelegate
{
private let device = MTLCreateSystemDefaultDevice()
private var commandQueue: MTLCommandQueue?
private var texture: MTLTexture?
private var texturePtr: UnsafeMutableRawPointer?

override init(){}

func initWithView(_ view: MTKView)
{
view.delegate = self
view.device = device
self.commandQueue = device?.makeCommandQueue()
print("zxx commandQueue:", commandQueue)
let textureDescriptor = MTLTextureDescriptor()
textureDescriptor.pixelFormat = .rgba8Unorm
self.texture = device?.makeTexture(descriptor: textureDescriptor)
print("zxx texture:", texture)
self.texturePtr = withUnsafeMutablePointer(to: &texture, { UnsafeMutableRawPointer($0) })
print("zxx:", texturePtr)
}

func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize)
{
CParsec.setFrame(size.width, size.height, view.contentScaleFactor)
}

func draw(in view: MTKView)
{
guard let commandBuffer = commandQueue?.makeCommandBuffer() else { return }
guard let renderPassDescriptor = view.currentRenderPassDescriptor else { return }
guard let renderCommandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) else {return}
renderCommandEncoder.endEncoding()
CParsec.renderFrame(.metal, cq: &commandQueue!, texturePtr:&texturePtr)

}
}

20 changes: 20 additions & 0 deletions OpenParsec/ParsecMetalView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import SwiftUI
import MetalKit
import UIKit

struct MetalView: UIViewRepresentable
{
let view = MTKView()
let renderer = MTLRender()
func makeUIView(context:UIViewRepresentableContext<MetalView>) -> MTKView
{
renderer.initWithView(view)
return view
}

func updateUIView(_ uiView:MTKView, context:UIViewRepresentableContext<MetalView>)
{
}

typealias UIViewType = MTKView
}
5 changes: 3 additions & 2 deletions OpenParsec/ParsecView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ struct ParsecView:View
ZStack()
{
// Stream view controller
ParsecGLKViewController()
//ParsecGLKViewController()
MetalView()
.zIndex(0)
.edgesIgnoringSafeArea(.all)
//.onAppear(perform:startAudioPollTimer)
Expand Down Expand Up @@ -149,7 +150,7 @@ struct ParsecView:View
func FromBuf(ptr: UnsafeMutablePointer<CChar>, length len: Int) -> String {
// convert the bytes using the UTF8 encoding
//let theString = NSString(bytes: ptr, length: len, encoding: NSUTF8StringEncoding)
let theString = NSString(bytes: ptr, length: len, encoding: NSASCIIStringEncoding)
let theString = NSString(bytes: ptr, length: len, encoding: String.Encoding.ascii.rawValue)
return theString as! String
}

Expand Down
108 changes: 90 additions & 18 deletions OpenParsec/audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@
#define BUFFER_SIZE 4096
#define SILENT_SIZE 4096
#define FAKE_SIZE 0
#define ALLOW_DELAY 8
#define LOWEST_NUM_BUFFER 3
bool isMuted = false;
bool isStart = false;
int lastbuf = 0;

unsigned int silence_inqueue = 0;
unsigned int silence_outqueue = 0;

AudioQueueBufferRef silence_buf;
typedef struct RecycleChain {
Expand All @@ -28,6 +34,7 @@ struct audio {
AudioQueueRef q;
AudioQueueBufferRef audio_buf[NUM_AUDIO_BUF];
char *mem[NUM_AUDIO_BUF * 2];
int loc[NUM_AUDIO_BUF];
RecycleChainMgr rcm;
int32_t fail_num;
int32_t in_use;
Expand All @@ -36,7 +43,9 @@ struct audio {
static void audio_queue_callback(void *opaque, AudioQueueRef queue, AudioQueueBufferRef buffer)
{
struct audio *ctx = (struct audio *) opaque;

int deltaBuf = 0;
//int silence_use_count = (int)(silence_buf->mUserData);

if (ctx == NULL)
return;

Expand All @@ -45,26 +54,85 @@ static void audio_queue_callback(void *opaque, AudioQueueRef queue, AudioQueueBu
ctx->in_use -= buffer->mAudioDataByteSize;
}

if(buffer != silence_buf) buffer->mAudioDataByteSize = FAKE_SIZE;
RecycleChain *tmp = ctx->rcm.last_to_queue->next;
if ( /*(*tmp->curt)->mAudioDataByteSize != FAKE_SIZE &&*/ tmp != ctx->rcm.first)
if(buffer != silence_buf)
{
//while(ctx->rcm.last_to_queue->next != ctx->rcm.first)
//{
AudioQueueEnqueueBuffer(ctx->q, (*(ctx->rcm.last_to_queue->next->curt)), 0, NULL);
ctx->rcm.last_to_queue = ctx->rcm.last_to_queue->next;
//}
buffer->mAudioDataByteSize = FAKE_SIZE;
lastbuf = *((int *)(buffer->mUserData));
}
else //if ((*ctx->rcm.last_use)->mAudioDataByteSize == FAKE_SIZE)
else
{
AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
/*AudioQueueStop(ctx->q, true);
isStart = false;
ctx->in_use = 0;*/
//silence_use_count = 0;
//silence_buf->mUserData = (void *)(0);
++silence_outqueue;
}

if (isMuted) return;

deltaBuf = *((int *)((*ctx->rcm.first->curt)->mUserData));
deltaBuf = deltaBuf - lastbuf - 1;
if (deltaBuf < 0) deltaBuf += NUM_AUDIO_BUF;

while(ctx->rcm.last_to_queue->next != ctx->rcm.first)
{
AudioQueueEnqueueBuffer(ctx->q, (*(ctx->rcm.last_to_queue->next->curt)), 0, NULL);
ctx->rcm.last_to_queue = ctx->rcm.last_to_queue->next;
}

if (deltaBuf + silence_inqueue < LOWEST_NUM_BUFFER + silence_outqueue)
{
int numAddBuffer = ((silence_inqueue >= silence_outqueue) ? (LOWEST_NUM_BUFFER - deltaBuf - (int)(silence_inqueue-silence_outqueue)) : (LOWEST_NUM_BUFFER - deltaBuf - (int)((unsigned int)(0xFFFFFFFF)-silence_outqueue + silence_inqueue + 1)));
if (numAddBuffer > LOWEST_NUM_BUFFER)
{
numAddBuffer = LOWEST_NUM_BUFFER - deltaBuf;
}
else
{
silence_inqueue = silence_outqueue = 0;
}
for (int i=0; i<numAddBuffer; ++i)
{
AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
}
if (numAddBuffer > 0) silence_inqueue += numAddBuffer;
}

//RecycleChain *tmp = ctx->rcm.last_to_queue->next;
//if ( /*(*tmp->curt)->mAudioDataByteSize != FAKE_SIZE &&*/ tmp != ctx->rcm.first)
//if (deltaBuf > ALLOW_DELAY)
//{
// //while(ctx->rcm.last_to_queue->next != ctx->rcm.first)
// for (int i = 0; i < deltaBuf - ALLOW_DELAY + 1; ++i)
// {
// AudioQueueEnqueueBuffer(ctx->q, (*(ctx->rcm.last_to_queue->next->curt)), 0, NULL);
// ctx->rcm.last_to_queue = ctx->rcm.last_to_queue->next;
// }
//}
//else
//{
// int silence_use_count = (int)(silence_buf->mUserData);
// if ( deltaBuf > 0 )
// {
// AudioQueueEnqueueBuffer(ctx->q, (*(ctx->rcm.last_to_queue->next->curt)), 0, NULL);
// ctx->rcm.last_to_queue = ctx->rcm.last_to_queue->next;
// }
// else if (silence_use_count == 0)
// {
// AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
// //int tmp = (int)(silence_buf->mUserData);
// //++tmp;
// silence_buf->mUserData = (void *)(1);
// }
//}
//else //if ((*ctx->rcm.last_use)->mAudioDataByteSize == FAKE_SIZE)
//{
// AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
// AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
// AudioQueueEnqueueBuffer(ctx->q, silence_buf, 0, NULL);
// /*AudioQueueStop(ctx->q, true);
// isStart = false;
// ctx->in_use = 0;*/
//}

/*if(ctx->rcm.last_to_queue->curt == &buffer && ctx->rcm.last_to_queue->next == ctx->rcm.first) // && (*ctx->rcm.first->curt)->mAudioDataByteSize == FAKE_SIZE)
{
AudioQueueStop(ctx->q, true);
Expand Down Expand Up @@ -107,7 +175,8 @@ void audio_init(struct audio **ctx_out)
for (int32_t x = 0; x < NUM_AUDIO_BUF; x++) {
AudioQueueAllocateBuffer(ctx->q, BUFFER_SIZE, &ctx->audio_buf[x]);
ctx->audio_buf[x]->mAudioDataByteSize = FAKE_SIZE;

ctx->loc[x] = x;
ctx->audio_buf[x]->mUserData = (void *)(&ctx->loc[x]);
rcTraverse->curt = &ctx->audio_buf[x];
if( x != NUM_AUDIO_BUF - 1)
{
Expand All @@ -119,16 +188,17 @@ void audio_init(struct audio **ctx_out)
//ctx->rcm.first = rcTraverse;
rcTraverse->next = ctx->rcm.rc;
}

}
isStart = false;
ctx->fail_num = 0;
ctx->in_use = 0;

silence_inqueue = silence_outqueue = 0;
char silence[SILENT_SIZE] = {0};
AudioQueueAllocateBuffer(ctx->q, SILENT_SIZE, &silence_buf);
memcpy(silence_buf->mAudioData, &silence[0], SILENT_SIZE);
silence_buf->mAudioDataByteSize = SILENT_SIZE;
silence_buf->mUserData = NULL;
}

void audio_destroy(struct audio **ctx_out)
Expand All @@ -151,6 +221,7 @@ void audio_destroy(struct audio **ctx_out)
*ctx_out = NULL;
isStart = false;
AudioQueueFreeBuffer(ctx->q, silence_buf);
silence_inqueue = silence_outqueue = 0;
}

void audio_clear(struct audio **ctx_out)
Expand Down Expand Up @@ -181,6 +252,7 @@ void audio_clear(struct audio **ctx_out)
isStart = false;
ctx->in_use = 0;
ctx->fail_num = 0;
silence_inqueue = silence_outqueue = 0;
}

void audio_cb(const int16_t *pcm, uint32_t frames, void *opaque)
Expand Down