1/* 2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include <CoreFoundation/CoreFoundation.h> 25 26#include <IOKit/IOKitLib.h> 27#include <IOKit/graphics/IOAccelSurfaceControl.h> 28#include <IOKit/graphics/IOGraphicsLib.h> 29#include <stdlib.h> 30 31 32#define arrayCnt(var) (sizeof(var)/sizeof(var[0])) 33#define regionSize(rgn) ((size_t) IOACCEL_SIZEOF_DEVICE_REGION(rgn)) 34 35IOReturn IOAccelFindAccelerator( io_service_t framebuffer, 36 io_service_t * pAccelerator, UInt32 * pFramebufferIndex ) 37{ 38 IOReturn kr; 39 io_service_t accelerator = MACH_PORT_NULL; 40 41 mach_port_t masterPort; 42 CFMutableDictionaryRef props = 0; 43 CFStringRef cfStr; 44 CFNumberRef cfNum; 45 const char * cStr; 46 char * buffer = NULL; 47 48 *pAccelerator = MACH_PORT_NULL; 49 *pFramebufferIndex = 0; 50 51 do { 52 53 IOMasterPort(MACH_PORT_NULL, &masterPort); 54 55 kr = IORegistryEntryCreateCFProperties( framebuffer, &props, 56 kCFAllocatorDefault, kNilOptions); 57 if( kr != kIOReturnSuccess) 58 continue; 59 kr = kIOReturnError; 60 cfStr = CFDictionaryGetValue( props, CFSTR(kIOAccelTypesKey) ); 61 if( !cfStr) 62 continue; 63 64 cStr = CFStringGetCStringPtr( cfStr, kCFStringEncodingMacRoman); 65 if( !cStr) { 66 CFIndex bufferSize = CFStringGetMaximumSizeForEncoding( CFStringGetLength(cfStr), 67 kCFStringEncodingMacRoman) + sizeof('\0'); 68 buffer = malloc( bufferSize); 69 if( buffer && CFStringGetCString( cfStr, buffer, bufferSize, kCFStringEncodingMacRoman)) 70 cStr = buffer; 71 } 72 if( !cStr) 73 continue; 74 75 accelerator = IORegistryEntryFromPath( masterPort, cStr ); 76 if( !accelerator) 77 continue; 78 if( !IOObjectConformsTo( accelerator, kIOAcceleratorClassName )) { 79 IOObjectRelease( accelerator ); 80 accelerator = MACH_PORT_NULL; 81 continue; 82 } 83 84 cfNum = CFDictionaryGetValue( props, CFSTR(kIOAccelIndexKey) ); 85 if( cfNum) 86 CFNumberGetValue( cfNum, kCFNumberSInt32Type, pFramebufferIndex ); 87 88 kr = kIOReturnSuccess; 89 90 } while( false ); 91 92 if( buffer) 93 free( buffer); 94 if( props) 95 CFRelease( props); 96 97 *pAccelerator = accelerator; 98 99 return( kr ); 100} 101 102static io_connect_t idConnect; 103enum { kAlloc, kFree }; 104 105IOReturn IOAccelCreateAccelID(IOOptionBits options, IOAccelID * identifier) 106{ 107 IOReturn err; 108 109 if (!idConnect) 110 { 111 io_service_t 112 service = IORegistryEntryFromPath(kIOMasterPortDefault, 113 kIOServicePlane ":/IOResources/IODisplayWrangler"); 114 if (service) 115 { 116 err = IOServiceOpen(service, mach_task_self(), 0, &idConnect); 117 IOObjectRelease(service); 118 } 119 } 120 121 if (!idConnect) 122 return (kIOReturnNotReady); 123 124 uint64_t inData[] = { options, *identifier }; 125 uint64_t outData; 126 uint32_t outLen = 1; 127 err = IOConnectCallScalarMethod(idConnect, kAlloc, 128 inData, arrayCnt(inData), 129 &outData, &outLen); 130 *identifier = (IOAccelID) outData; 131 132 return (err); 133} 134 135IOReturn IOAccelDestroyAccelID(IOOptionBits options, IOAccelID identifier) 136{ 137 IOReturn err; 138 139 if (!idConnect) 140 return (kIOReturnNotReady); 141 142 uint64_t inData[] = { options, identifier }; 143 err = IOConnectCallScalarMethod(idConnect, kFree, 144 inData, arrayCnt(inData), NULL, NULL); 145 146 return (err); 147} 148 149IOReturn IOAccelCreateSurface( io_service_t accelerator, UInt32 wID, eIOAccelSurfaceModeBits modebits, 150 IOAccelConnect *connect ) 151{ 152 IOReturn kr; 153 io_connect_t window = MACH_PORT_NULL; 154 155 *connect = NULL; 156 157 /* Create a context */ 158 kr = IOServiceOpen( accelerator, 159 mach_task_self(), 160 kIOAccelSurfaceClientType, 161 &window ); 162 163 if( kr != kIOReturnSuccess) 164 { 165 return kr; 166 } 167 168 /* Set the window id */ 169 uint64_t data[] = { wID, modebits }; 170 kr = IOConnectCallScalarMethod(window, kIOAccelSurfaceSetIDMode, 171 data, arrayCnt(data), NULL, NULL); 172 if(kr != kIOReturnSuccess) 173 { 174 IOServiceClose(window); 175 return kr; 176 } 177 178 *connect = (IOAccelConnect) (uintptr_t) window; 179 180 return kIOReturnSuccess; 181} 182 183IOReturn IOAccelDestroySurface( IOAccelConnect connect ) 184{ 185 IOReturn kr; 186 187 if(!connect) 188 return kIOReturnError; 189 190 kr = IOServiceClose((io_connect_t) (uintptr_t) connect); 191 192 return kr; 193} 194 195IOReturn IOAccelSetSurfaceScale( IOAccelConnect connect, IOOptionBits options, 196 IOAccelSurfaceScaling * scaling, UInt32 scalingSize ) 197{ 198 uint64_t inData = options; 199 IOReturn result; 200 201 result = IOConnectCallMethod((io_connect_t) (uintptr_t) connect, 202 kIOAccelSurfaceSetScale, 203 &inData, 1, 204 scaling, (size_t) scalingSize, 205 NULL, NULL, NULL, NULL); // no output 206 207 return result; 208} 209 210 211IOReturn IOAccelSetSurfaceFramebufferShape( IOAccelConnect connect, IOAccelDeviceRegion *rgn, 212 eIOAccelSurfaceShapeBits options, UInt32 framebufferIndex ) 213{ 214 uint64_t inData[] = { options, framebufferIndex }; 215 IOReturn result; 216 size_t rgnSize = regionSize(rgn); 217 218 result = IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceSetShape, 219 inData, arrayCnt(inData), rgn, rgnSize, 220 NULL, NULL, NULL, NULL); // no output 221 return result; 222} 223 224IOReturn IOAccelSetSurfaceFramebufferShapeWithBacking( IOAccelConnect connect, IOAccelDeviceRegion *rgn, 225 eIOAccelSurfaceShapeBits options, UInt32 framebufferIndex, 226 IOVirtualAddress backing, UInt32 rowbytes ) 227{ 228 IOReturn err; 229 230 err = IOAccelSetSurfaceFramebufferShapeWithBackingAndLength(connect, rgn, options, 231 framebufferIndex, backing, rowbytes, rgn->bounds.h * rowbytes); 232 233 return (err); 234} 235 236IOReturn IOAccelSetSurfaceFramebufferShapeWithBackingAndLength( IOAccelConnect connect, IOAccelDeviceRegion *rgn, 237 eIOAccelSurfaceShapeBits options, UInt32 framebufferIndex, 238 IOVirtualAddress backing, UInt32 rowbytes, UInt32 backingLength ) 239{ 240 IOReturn err; 241 uint64_t inData[] = 242 { options, framebufferIndex, backing, rowbytes, backingLength }; 243 size_t rgnSize = regionSize(rgn); 244 245 err = IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceSetShapeBackingAndLength, 246 inData, arrayCnt(inData), rgn, rgnSize, 247 NULL, NULL, NULL, NULL); // no output 248 249 return (err); 250} 251 252IOReturn IOAccelSurfaceControl( IOAccelConnect connect, 253 UInt32 selector, UInt32 arg, UInt32 * result) 254{ 255 uint64_t inData[] = { selector, arg }; 256 uint64_t outData; 257 uint32_t outSize = 1; 258 259 IOReturn err = IOConnectCallScalarMethod((io_connect_t) (uintptr_t)connect, kIOAccelSurfaceControl, 260 inData, arrayCnt(inData), &outData, &outSize); 261 *result = (UInt32) outData; 262 263 return( err ); 264} 265 266IOReturn IOAccelReadLockSurface( IOAccelConnect connect, IOAccelSurfaceInformation * info, UInt32 infoSize ) 267{ 268 size_t size = (size_t) infoSize; 269 IOReturn ret = IOConnectCallStructMethod((io_connect_t) (uintptr_t)connect, kIOAccelSurfaceReadLock, 270 NULL, 0, info, &size); 271 272 return ret; 273} 274 275IOReturn IOAccelReadLockSurfaceWithOptions( IOAccelConnect connect, IOOptionBits options, 276 IOAccelSurfaceInformation * info, UInt32 infoSize ) 277{ 278 uint64_t inData = options; 279 size_t size = (size_t) infoSize; 280 IOReturn ret = IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceReadLockOptions, 281 &inData, 1, // in scalar 282 NULL, 0, // in struct 283 NULL, NULL, // out scalar 284 info, &size); // out struct 285 286 return ret; 287} 288 289IOReturn IOAccelWriteLockSurface( IOAccelConnect connect, IOAccelSurfaceInformation * info, UInt32 infoSize ) 290{ 291 size_t size = (size_t) infoSize; 292 IOReturn ret = IOConnectCallStructMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceWriteLock, 293 NULL, 0, info, &size); 294 return ret; 295} 296 297IOReturn IOAccelWriteLockSurfaceWithOptions( IOAccelConnect connect, IOOptionBits options, 298 IOAccelSurfaceInformation * info, UInt32 infoSize ) 299{ 300 uint64_t inData = options; 301 size_t size = (size_t) infoSize; 302 IOReturn ret = IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceWriteLockOptions, 303 &inData, 1, // in scalar 304 NULL, 0, // in struct 305 NULL, NULL, // out scalar 306 info, &size); // out struct 307 return ret; 308} 309 310IOReturn IOAccelReadUnlockSurface( IOAccelConnect connect ) 311{ 312 return IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceReadUnlock, 313 NULL, 0, NULL, 0, // input 314 NULL, NULL, NULL, NULL); // output 315} 316 317IOReturn IOAccelReadUnlockSurfaceWithOptions( IOAccelConnect connect, IOOptionBits options ) 318{ 319 uint64_t inData = options; 320 return IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceReadUnlockOptions, 321 &inData, 1, NULL, 0, // input 322 NULL, NULL, NULL, NULL); // output 323} 324 325IOReturn IOAccelWriteUnlockSurface( IOAccelConnect connect ) 326{ 327 return IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceWriteUnlock, 328 NULL, 0, NULL, 0, // input 329 NULL, NULL, NULL, NULL); // output 330} 331 332IOReturn IOAccelWriteUnlockSurfaceWithOptions( IOAccelConnect connect, IOOptionBits options ) 333{ 334 uint64_t inData = options; 335 return IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceWriteUnlockOptions, 336 &inData, 1, NULL, 0, // input 337 NULL, NULL, NULL, NULL); // output 338} 339 340IOReturn IOAccelWaitForSurface( IOAccelConnect connect __unused ) 341{ 342 return kIOReturnSuccess; 343} 344 345IOReturn IOAccelQueryLockSurface( IOAccelConnect connect ) 346{ 347 return IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceQueryLock, 348 NULL, 0, NULL, 0, // input 349 NULL, NULL, NULL, NULL); // output 350} 351 352/* Flush surface to visible region */ 353IOReturn IOAccelFlushSurfaceOnFramebuffers( IOAccelConnect connect, IOOptionBits options, UInt32 framebufferMask ) 354{ 355 uint64_t inData[] = { framebufferMask, options }; 356 return IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceFlush, 357 inData, arrayCnt(inData), NULL, 0,// input 358 NULL, NULL, NULL, NULL); // output 359} 360 361IOReturn IOAccelReadSurface( IOAccelConnect connect, IOAccelSurfaceReadData * parameters ) 362{ 363 IOReturn result; 364 365 result = IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceRead, 366 NULL, 0, parameters, sizeof( IOAccelSurfaceReadData), // input 367 NULL, NULL, NULL, NULL); // no output 368 369 return result; 370} 371 372