mfreerdp-server: begin transition to IOSurface API
authorC-o-r-E <can.of.tuna@gmail.com>
Sun, 9 Dec 2012 22:40:37 +0000 (17:40 -0500)
committerC-o-r-E <can.of.tuna@gmail.com>
Sun, 9 Dec 2012 22:40:37 +0000 (17:40 -0500)
server/Mac/CMakeLists.txt
server/Mac/mf_mountain_lion.c
server/Mac/mf_mountain_lion.h
server/Mac/mf_peer.c

index 39a43a7..3958413 100644 (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
@@ -53,9 +55,11 @@ add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
 
 set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} 
        freerdp-server
-    ${CORE_VIDEO}
+       ${CORE_VIDEO}
        ${CORE_GRAPHICS}
-       ${APP_SERVICES})
+       ${APP_SERVICES}
+       ${IOKIT}
+       ${IOSURFACE})
 
 set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
        MONOLITHIC ${MONOLITHIC_BUILD}
index 726cea0..2ab5307 100644 (file)
 
 #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);
     
@@ -74,7 +113,10 @@ int mf_mlion_screen_updates_init()
     size_t pixelHeight = CGDisplayModeGetPixelHeight(mode);
     
     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,39 +183,71 @@ 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)
 {
-    size_t num_rects;
-    CGRect dirtyRegion;
+    dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER);
     
-    //it may be faster to copy the cgrect and then convert....
+    if (lastUpdate != NULL)
+    {
+        mf_mlion_peek_dirty_region(invalid);
+        
+        CFRelease(lastUpdate);
+        
+        lastUpdate = NULL;
+
+    }
+
     
-    dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER);
+    dispatch_semaphore_signal(region_sem);
+    
+    return 0;
+}
 
+int mf_mlion_peek_dirty_region(RFX_RECT* invalid)
+{
+    size_t num_rects;
+    CGRect dirtyRegion;
+    
     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;
     }
     
     dirtyRegion = *rects;
     for (size_t i = 0; i < num_rects; i++)
-    {        
+    {
         dirtyRegion = CGRectUnion(dirtyRegion, *(rects+i));
     }
     
@@ -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);
     }
@@ -219,6 +301,8 @@ int mf_mlion_get_pixelData(long x, long y, long width, long height, BYTE** pxDat
                        image);
     
     *pxData = baseAddress;
+     
+     */
     
     return 0;
 }
index 1158798..d370d6c 100644 (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);
index b0c3a29..5ef61a6 100644 (file)
@@ -252,7 +252,7 @@ void mf_peer_init(freerdp_peer* client)
     if(info_timer)\r
     {\r
         //printf("created timer\n");\r
-        dispatch_source_set_timer(info_timer, DISPATCH_TIME_NOW, 500ull * NSEC_PER_MSEC, 100ull * NSEC_PER_MSEC);\r
+        dispatch_source_set_timer(info_timer, DISPATCH_TIME_NOW, 1ull * NSEC_PER_SEC, 100ull * NSEC_PER_MSEC);\r
         dispatch_source_set_event_handler(info_timer, ^{\r
             printf("dispatch\n");\r
             mfEvent* event = mf_event_new(MF_EVENT_TYPE_FRAME_TICK);\r