mfreerdp-server: begin transition to IOSurface API

This commit is contained in:
C-o-r-E 2012-12-09 17:40:37 -05:00
parent e9f008d161
commit 9391e60c13
4 changed files with 113 additions and 24 deletions

View File

@ -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}

View File

@ -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;
}

View File

@ -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);

View File

@ -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);