IOMobileFramebuffer: Difference between revisions

From iPhone Development Wiki
(Driver-mapped, not device-mapped, doh)
((Fixed wrong stuff I wrote))
 
(4 intermediate revisions by the same user not shown)
Line 133: Line 133:


== Sync Notification ==
== Sync Notification ==
The notification can be registered for a IOMobileFramebuffer connection by setting the mach port via IOConnectSetNotificationPort and then setting the data via method setVSyncNotifications.
The notification can be registered for a IOMobileFramebuffer connection by setting the mach port via IOConnectSetNotificationPort and then setting the function and userdata via method setVSyncNotifications.


It is sent in the format of an IO interest notification as follows:
The message is parsed by IODispatchCalloutFromCFMessage, and is most likely an IO Async Completion notification.
<source lang="C">
The function and user data are in elements 1 & 2 of the OSAsyncReference64 array.
struct IOMobileFramebufferSyncNotification {
This async completion notification most likely has the following data as arguments:
  <standard message header (ID is 53)>
  <standard message port object - the service port>
  // note: no NDR


  uint32_t contentSize; // always sizeof(size_t)
<source lang="c">
   uint32_t contentType; // always 160 (service message)
struct IOMobileFramebufferTimingData {
   uint32_t userData[8]; // [1] is functionAddress, [2] is userData, rest ([0], [3..7]) are likely 0.
   int64wtf frameNumber; // frame number
    
   int64wtf frameTime; // frame time, mach absolute time
  // content:
   int64wtf frameDuration; // duration of last frame, mach absolute time
  size_t timingData; // pointer to IOMobileFramebufferTimingData, driver-mapped memory
};
};


struct IOMobileFramebufferTimingData {
// where int64wtf is:
   int64 frameNumber;
 
   int64 currentTime;
#if <is 32bit process>
  int64 frameDuration;
typedef int64_t int64wtf;
};
#else
typedef struct {
   int64_t low32; // low 32 bits of 64 bit value. (upper bits are wasted)
   int64_t high32; // high 32 bits of 64 bit value. (upper bits are wasted)
} int64wtf;
#endif
</source>
</source>



Latest revision as of 10:04, 16 October 2017

IOMobileFramebuffer is a kernel extension for managing the screen framebuffer. It is controlled by the user-land framework IOMobileFramework.

Methods

Selector Action Input Output
3 getDefaultSurface - IOSurfaceID surfaceID
4 swapBegin - IOMobileFramebufferSwapID swapID
5 swapEnd struct IOMobileFramebufferSwapArg -
6 swapWait IOMobileFramebufferSwapID swapID, uint32_t waitOptions, (iOS 4.2+ only) uint64_t timeout_millis -
7 getId - IOSwapNotificationID framebufferID
8 getDisplaySize - struct IOMobileFramebufferDisplaySize
9 setVSyncNotifications size_t functionAddress (if 0, notification is disabled), size_t userData -
12 requestPowerChange uint32_t value -
15 setDebugFlags uint32_t ???[2] uint32_t ???
17 setGammaTable struct IOMobileFramebufferGammaTables -
18 isMainDisplay - uint32_t result
19 setWhiteOnBlackMode uint32_t value -
22 setDisplayDevice uint32_t value -
27 getGammaTable - struct IOMobileFramebufferGammaTables
33(*) setVideoPowerSaving uint32_t value -
50(**) setBrightnessCorrection uint32_t value -

(*) - was 32 before 4.0

(**) - was 49 before 8.0

where

// This can be the first argument to a layer swap notification.
// In that case, the other two arguments are interpreted as
//   IOMobileFramebufferSwapID ''swapID'', uint32_t ''
// Swap notifications can be sent, for example, via -[EAGLContext sendNotification: forTransaction: onLayer:]
typedef uint32_t IOSwapNotificationID;

struct UInt32Rect {
  uint32_t x, y, width, height;
};

struct UInt8Bgra {
  uint8_t b, g, r, a;
};

// bits 0.. 3 - bit per layer
// bit 31 - bit for bg color
typedef uint32_t IOMobileFramebufferSwapFlags;

#if IOS_VERSION >= 7.0
const int NUM_LAYERS = 4;
#else
const int NUM_LAYERS = 3;
#endif

struct IOMobileFramebufferSwapArg {

#if IOS_VERSION >= 7.0
  int64_t timeStamps[3];
#endif

#if IOS_VERSION >= 8.0
  uint64_t imageSources[16]; // ?
  uint32_t numImageSources; // 0..16
  uint32_t ???; // padding?
#endif

  IOMobileFramebufferSwapID swapID;
  IOSurfaceID surfaceID[NUM_LAYERS];

  UInt32Rect bounds[NUM_LAYERS]; // surface source bounds

#if IOS_VERSION >= 4.3
  UInt32Rect uiSubRegion[NUM_LAYERS]; // ?
  uint32_t edgeMode[NUM_LAYERS]; // ?
  float32_t edgeCoverage[NUM_LAYERS]; // ?
#endif

  UInt32Rect frames[NUM_LAYERS]; // framebuffer target frame

  IOMobileFramebufferSwapFlags providedFlags; // which layers are provided for swap (in this structure)
  IOMobileFramebufferSwapFlags readyFlags; // which layers are ready to be swapped
                                           // (layers that aren't ready must be notified as ready later via layer swap notifications)
  
  UInt8Bgra bgColor;
  uint32_t gammaTable; // 0..2, index to gamma table to use
  
  uint32_t rotation[NUM_LAYERS]; // 0 - none, 1 - 90 left, 2 - 180, 3 - 90 right

#if IOS_VERSION >= 4.3
  uint32_t destEdgeAlpha; // ?
#endif
#if IOS_VERSION >= 7.0
  uint32_t ???[2];
#endif
};

struct IOMobileFramebufferDisplaySize {
  uint32_t width;
  uint32_t height;
};

struct IOMobileFramebufferGammaTables {
  struct GammaTable {

    // Each value has 2 bitfields: [0..9] and [10..19]. Meanings unknown.
#if IOS_VERSION >= 7.0
    uint32_t value[0x101];
#else
    uint32_t value[0x100];
#endif

  } gammaTable[3];
};

Sync Notification

The notification can be registered for a IOMobileFramebuffer connection by setting the mach port via IOConnectSetNotificationPort and then setting the function and userdata via method setVSyncNotifications.

The message is parsed by IODispatchCalloutFromCFMessage, and is most likely an IO Async Completion notification. The function and user data are in elements 1 & 2 of the OSAsyncReference64 array. This async completion notification most likely has the following data as arguments:

struct IOMobileFramebufferTimingData {
  int64wtf frameNumber; // frame number
  int64wtf frameTime; // frame time, mach absolute time
  int64wtf frameDuration; // duration of last frame, mach absolute time
};

// where int64wtf is:

#if <is 32bit process>
typedef int64_t int64wtf;
#else
typedef struct {
  int64_t low32; // low 32 bits of 64 bit value. (upper bits are wasted)
  int64_t high32; // high 32 bits of 64 bit value. (upper bits are wasted)
} int64wtf;
#endif