mfreerdp-server: begin transition to IOSurface API
This commit is contained in:
parent
e9f008d161
commit
9391e60c13
@ -21,6 +21,8 @@ set(MODULE_PREFIX "FREERDP_SERVER_MAC")
|
||||
FIND_LIBRARY(CORE_VIDEO CoreVideo)
|
||||
FIND_LIBRARY(CORE_GRAPHICS CoreGraphics)
|
||||
FIND_LIBRARY(APP_SERVICES ApplicationServices)
|
||||
FIND_LIBRARY(IOKIT IOKit)
|
||||
FIND_LIBRARY(IOSURFACE IOSurface)
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
mfreerdp.c
|
||||
@ -55,7 +57,9 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
|
||||
freerdp-server
|
||||
${CORE_VIDEO}
|
||||
${CORE_GRAPHICS}
|
||||
${APP_SERVICES})
|
||||
${APP_SERVICES}
|
||||
${IOKIT}
|
||||
${IOSURFACE})
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
|
@ -19,28 +19,66 @@
|
||||
|
||||
#include <dispatch/dispatch.h>
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include "CoreVideo/CoreVideo.h"
|
||||
#include <CoreVideo/CoreVideo.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOSurface/IOSurface.h>
|
||||
|
||||
#include "mf_mountain_lion.h"
|
||||
|
||||
dispatch_semaphore_t region_sem;
|
||||
dispatch_semaphore_t data_sem;
|
||||
dispatch_queue_t screen_update_q;
|
||||
CGDisplayStreamRef stream;
|
||||
|
||||
CGDisplayStreamUpdateRef lastUpdate = NULL;
|
||||
|
||||
CVPixelBufferRef pxbuffer = NULL;
|
||||
void *baseAddress = NULL;
|
||||
BYTE* localBuf = NULL;
|
||||
|
||||
CGContextRef bitmapcontext = NULL;
|
||||
//CVPixelBufferRef pxbuffer = NULL;
|
||||
//void *baseAddress = NULL;
|
||||
|
||||
CGImageRef image = NULL;
|
||||
//CGContextRef bitmapcontext = NULL;
|
||||
|
||||
//CGImageRef image = NULL;
|
||||
|
||||
BOOL ready = FALSE;
|
||||
|
||||
void (^streamHandler)(CGDisplayStreamFrameStatus, uint64_t, IOSurfaceRef, CGDisplayStreamUpdateRef) = ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, IOSurfaceRef frameSurface, CGDisplayStreamUpdateRef updateRef)
|
||||
{
|
||||
|
||||
dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER);
|
||||
|
||||
//may need to move this down
|
||||
if(ready == TRUE);
|
||||
{
|
||||
RFX_RECT rect;
|
||||
unsigned long offset_beg;
|
||||
unsigned long offset_end;
|
||||
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.width = 2880;
|
||||
rect.height = 1800;
|
||||
//mf_mlion_peek_dirty_region(&rect);
|
||||
|
||||
//offset_beg = ((rect.width * 4) * rect.y) + rect.x * 4;
|
||||
//offset_end =
|
||||
|
||||
//lock surface
|
||||
IOSurfaceLock(frameSurface, kIOSurfaceLockReadOnly, NULL);
|
||||
//get pointer
|
||||
void* baseAddress = IOSurfaceGetBaseAddress(frameSurface);
|
||||
//copy region
|
||||
|
||||
//offset_beg =
|
||||
|
||||
memcpy(localBuf, baseAddress, rect.width * rect.height * 4);
|
||||
|
||||
//unlock surface
|
||||
IOSurfaceUnlock(frameSurface, kIOSurfaceLockReadOnly, NULL);
|
||||
dispatch_semaphore_signal(data_sem);
|
||||
}
|
||||
|
||||
if (lastUpdate == NULL)
|
||||
{
|
||||
CFRetain(updateRef);
|
||||
@ -67,6 +105,7 @@ int mf_mlion_screen_updates_init()
|
||||
screen_update_q = dispatch_queue_create("mfreerdp.server.screenUpdate", NULL);
|
||||
|
||||
region_sem = dispatch_semaphore_create(1);
|
||||
data_sem = dispatch_semaphore_create(1);
|
||||
|
||||
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(display_id);
|
||||
|
||||
@ -75,6 +114,9 @@ int mf_mlion_screen_updates_init()
|
||||
|
||||
CGDisplayModeRelease(mode);
|
||||
|
||||
localBuf = malloc(pixelWidth * pixelHeight * 4);
|
||||
|
||||
|
||||
stream = CGDisplayStreamCreateWithDispatchQueue(display_id,
|
||||
pixelWidth,
|
||||
pixelHeight,
|
||||
@ -82,7 +124,7 @@ int mf_mlion_screen_updates_init()
|
||||
NULL,
|
||||
screen_update_q,
|
||||
streamHandler);
|
||||
|
||||
/*
|
||||
|
||||
CFDictionaryRef opts;
|
||||
|
||||
@ -133,7 +175,7 @@ int mf_mlion_screen_updates_init()
|
||||
printf("context = null!!!\n\n\n");
|
||||
}
|
||||
CGColorSpaceRelease(rgbColorSpace);
|
||||
|
||||
*/
|
||||
|
||||
return 0;
|
||||
|
||||
@ -141,33 +183,65 @@ int mf_mlion_screen_updates_init()
|
||||
|
||||
int mf_mlion_start_getting_screen_updates()
|
||||
{
|
||||
CGDisplayStreamStart(stream);
|
||||
CGError err;
|
||||
|
||||
err = CGDisplayStreamStart(stream);
|
||||
if(err != kCGErrorSuccess)
|
||||
{
|
||||
printf("Failed to start displaystream!! err = %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
int mf_mlion_stop_getting_screen_updates()
|
||||
{
|
||||
CGDisplayStreamStop(stream);
|
||||
CGError err;
|
||||
|
||||
err = CGDisplayStreamStop(stream);
|
||||
if(err != kCGErrorSuccess)
|
||||
{
|
||||
printf("Failed to stop displaystream!! err = %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mf_mlion_get_dirty_region(RFX_RECT* invalid)
|
||||
{
|
||||
dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER);
|
||||
|
||||
if (lastUpdate != NULL)
|
||||
{
|
||||
mf_mlion_peek_dirty_region(invalid);
|
||||
|
||||
CFRelease(lastUpdate);
|
||||
|
||||
lastUpdate = NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
dispatch_semaphore_signal(region_sem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mf_mlion_peek_dirty_region(RFX_RECT* invalid)
|
||||
{
|
||||
size_t num_rects;
|
||||
CGRect dirtyRegion;
|
||||
|
||||
//it may be faster to copy the cgrect and then convert....
|
||||
|
||||
dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER);
|
||||
|
||||
const CGRect * rects = CGDisplayStreamUpdateGetRects(lastUpdate, kCGDisplayStreamUpdateDirtyRects, &num_rects);
|
||||
|
||||
printf("\trectangles: %zd\n", num_rects);
|
||||
|
||||
if (num_rects == 0) {
|
||||
dispatch_semaphore_signal(region_sem);
|
||||
//dispatch_semaphore_signal(region_sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -182,12 +256,6 @@ int mf_mlion_get_dirty_region(RFX_RECT* invalid)
|
||||
invalid->height = dirtyRegion.size.height;
|
||||
invalid->width = dirtyRegion.size.width;
|
||||
|
||||
CFRelease(lastUpdate);
|
||||
|
||||
lastUpdate = NULL;
|
||||
|
||||
dispatch_semaphore_signal(region_sem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -206,6 +274,20 @@ int mf_mlion_clear_dirty_region()
|
||||
|
||||
int mf_mlion_get_pixelData(long x, long y, long width, long height, BYTE** pxData)
|
||||
{
|
||||
printf("waiting for region semaphore...\n");
|
||||
dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER);
|
||||
ready = TRUE;
|
||||
printf("waiting for data semaphore...\n");
|
||||
dispatch_semaphore_wait(data_sem, DISPATCH_TIME_FOREVER);
|
||||
dispatch_semaphore_signal(region_sem);
|
||||
|
||||
//this second wait allows us to block until data is copied... more on this later
|
||||
dispatch_semaphore_wait(data_sem, DISPATCH_TIME_FOREVER);
|
||||
printf("got it\n");
|
||||
*pxData = localBuf;
|
||||
dispatch_semaphore_signal(data_sem);
|
||||
|
||||
/*
|
||||
if (image != NULL) {
|
||||
CGImageRelease(image);
|
||||
}
|
||||
@ -220,6 +302,8 @@ int mf_mlion_get_pixelData(long x, long y, long width, long height, BYTE** pxDat
|
||||
|
||||
*pxData = baseAddress;
|
||||
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ int mf_mlion_start_getting_screen_updates();
|
||||
int mf_mlion_stop_getting_screen_updates();
|
||||
|
||||
int mf_mlion_get_dirty_region(RFX_RECT* invalid);
|
||||
int mf_mlion_peek_dirty_region(RFX_RECT* invalid);
|
||||
int mf_mlion_clear_dirty_region();
|
||||
|
||||
int mf_mlion_get_pixelData(long x, long y, long width, long height, BYTE **pxData);
|
||||
|
@ -252,7 +252,7 @@ void mf_peer_init(freerdp_peer* client)
|
||||
if(info_timer)
|
||||
{
|
||||
//printf("created timer\n");
|
||||
dispatch_source_set_timer(info_timer, DISPATCH_TIME_NOW, 500ull * NSEC_PER_MSEC, 100ull * NSEC_PER_MSEC);
|
||||
dispatch_source_set_timer(info_timer, DISPATCH_TIME_NOW, 1ull * NSEC_PER_SEC, 100ull * NSEC_PER_MSEC);
|
||||
dispatch_source_set_event_handler(info_timer, ^{
|
||||
printf("dispatch\n");
|
||||
mfEvent* event = mf_event_new(MF_EVENT_TYPE_FRAME_TICK);
|
||||
|
Loading…
Reference in New Issue
Block a user