/* * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #include #include #include #include #include #define arrayCnt(var) (sizeof(var)/sizeof(var[0])) #define regionSize(rgn) ((size_t) IOACCEL_SIZEOF_DEVICE_REGION(rgn)) IOReturn IOAccelFindAccelerator( io_service_t framebuffer, io_service_t * pAccelerator, UInt32 * pFramebufferIndex ) { IOReturn kr; io_service_t accelerator = MACH_PORT_NULL; mach_port_t masterPort; CFMutableDictionaryRef props = 0; CFStringRef cfStr; CFNumberRef cfNum; const char * cStr; char * buffer = NULL; *pAccelerator = MACH_PORT_NULL; *pFramebufferIndex = 0; do { IOMasterPort(MACH_PORT_NULL, &masterPort); kr = IORegistryEntryCreateCFProperties( framebuffer, &props, kCFAllocatorDefault, kNilOptions); if( kr != kIOReturnSuccess) continue; kr = kIOReturnError; cfStr = CFDictionaryGetValue( props, CFSTR(kIOAccelTypesKey) ); if( !cfStr) continue; cStr = CFStringGetCStringPtr( cfStr, kCFStringEncodingMacRoman); if( !cStr) { CFIndex bufferSize = CFStringGetMaximumSizeForEncoding( CFStringGetLength(cfStr), kCFStringEncodingMacRoman) + sizeof('\0'); buffer = malloc( bufferSize); if( buffer && CFStringGetCString( cfStr, buffer, bufferSize, kCFStringEncodingMacRoman)) cStr = buffer; } if( !cStr) continue; accelerator = IORegistryEntryFromPath( masterPort, cStr ); if( !accelerator) continue; if( !IOObjectConformsTo( accelerator, kIOAcceleratorClassName )) { IOObjectRelease( accelerator ); accelerator = MACH_PORT_NULL; continue; } cfNum = CFDictionaryGetValue( props, CFSTR(kIOAccelIndexKey) ); if( cfNum) CFNumberGetValue( cfNum, kCFNumberSInt32Type, pFramebufferIndex ); kr = kIOReturnSuccess; } while( false ); if( buffer) free( buffer); if( props) CFRelease( props); *pAccelerator = accelerator; return( kr ); } static io_connect_t idConnect; enum { kAlloc, kFree }; IOReturn IOAccelCreateAccelID(IOOptionBits options, IOAccelID * identifier) { IOReturn err; if (!idConnect) { io_service_t service = IORegistryEntryFromPath(kIOMasterPortDefault, kIOServicePlane ":/IOResources/IODisplayWrangler"); if (service) { err = IOServiceOpen(service, mach_task_self(), 0, &idConnect); IOObjectRelease(service); } } if (!idConnect) return (kIOReturnNotReady); uint64_t inData[] = { options, *identifier }; uint64_t outData; uint32_t outLen = 1; err = IOConnectCallScalarMethod(idConnect, kAlloc, inData, arrayCnt(inData), &outData, &outLen); *identifier = (IOAccelID) outData; return (err); } IOReturn IOAccelDestroyAccelID(IOOptionBits options, IOAccelID identifier) { IOReturn err; if (!idConnect) return (kIOReturnNotReady); uint64_t inData[] = { options, identifier }; err = IOConnectCallScalarMethod(idConnect, kFree, inData, arrayCnt(inData), NULL, NULL); return (err); } IOReturn IOAccelCreateSurface( io_service_t accelerator, UInt32 wID, eIOAccelSurfaceModeBits modebits, IOAccelConnect *connect ) { IOReturn kr; io_connect_t window = MACH_PORT_NULL; *connect = NULL; /* Create a context */ kr = IOServiceOpen( accelerator, mach_task_self(), kIOAccelSurfaceClientType, &window ); if( kr != kIOReturnSuccess) { return kr; } /* Set the window id */ uint64_t data[] = { wID, modebits }; kr = IOConnectCallScalarMethod(window, kIOAccelSurfaceSetIDMode, data, arrayCnt(data), NULL, NULL); if(kr != kIOReturnSuccess) { IOServiceClose(window); return kr; } *connect = (IOAccelConnect) (uintptr_t) window; return kIOReturnSuccess; } IOReturn IOAccelDestroySurface( IOAccelConnect connect ) { IOReturn kr; if(!connect) return kIOReturnError; kr = IOServiceClose((io_connect_t) (uintptr_t) connect); return kr; } IOReturn IOAccelSetSurfaceScale( IOAccelConnect connect, IOOptionBits options, IOAccelSurfaceScaling * scaling, UInt32 scalingSize ) { uint64_t inData = options; IOReturn result; result = IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceSetScale, &inData, 1, scaling, (size_t) scalingSize, NULL, NULL, NULL, NULL); // no output return result; } IOReturn IOAccelSetSurfaceFramebufferShape( IOAccelConnect connect, IOAccelDeviceRegion *rgn, eIOAccelSurfaceShapeBits options, UInt32 framebufferIndex ) { uint64_t inData[] = { options, framebufferIndex }; IOReturn result; size_t rgnSize = regionSize(rgn); result = IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceSetShape, inData, arrayCnt(inData), rgn, rgnSize, NULL, NULL, NULL, NULL); // no output return result; } IOReturn IOAccelSetSurfaceFramebufferShapeWithBacking( IOAccelConnect connect, IOAccelDeviceRegion *rgn, eIOAccelSurfaceShapeBits options, UInt32 framebufferIndex, IOVirtualAddress backing, UInt32 rowbytes ) { IOReturn err; err = IOAccelSetSurfaceFramebufferShapeWithBackingAndLength(connect, rgn, options, framebufferIndex, backing, rowbytes, rgn->bounds.h * rowbytes); return (err); } IOReturn IOAccelSetSurfaceFramebufferShapeWithBackingAndLength( IOAccelConnect connect, IOAccelDeviceRegion *rgn, eIOAccelSurfaceShapeBits options, UInt32 framebufferIndex, IOVirtualAddress backing, UInt32 rowbytes, UInt32 backingLength ) { IOReturn err; uint64_t inData[] = { options, framebufferIndex, backing, rowbytes, backingLength }; size_t rgnSize = regionSize(rgn); err = IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceSetShapeBackingAndLength, inData, arrayCnt(inData), rgn, rgnSize, NULL, NULL, NULL, NULL); // no output return (err); } IOReturn IOAccelSurfaceControl( IOAccelConnect connect, UInt32 selector, UInt32 arg, UInt32 * result) { uint64_t inData[] = { selector, arg }; uint64_t outData; uint32_t outSize = 1; IOReturn err = IOConnectCallScalarMethod((io_connect_t) (uintptr_t)connect, kIOAccelSurfaceControl, inData, arrayCnt(inData), &outData, &outSize); *result = (UInt32) outData; return( err ); } IOReturn IOAccelReadLockSurface( IOAccelConnect connect, IOAccelSurfaceInformation * info, UInt32 infoSize ) { size_t size = (size_t) infoSize; IOReturn ret = IOConnectCallStructMethod((io_connect_t) (uintptr_t)connect, kIOAccelSurfaceReadLock, NULL, 0, info, &size); return ret; } IOReturn IOAccelReadLockSurfaceWithOptions( IOAccelConnect connect, IOOptionBits options, IOAccelSurfaceInformation * info, UInt32 infoSize ) { uint64_t inData = options; size_t size = (size_t) infoSize; IOReturn ret = IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceReadLockOptions, &inData, 1, // in scalar NULL, 0, // in struct NULL, NULL, // out scalar info, &size); // out struct return ret; } IOReturn IOAccelWriteLockSurface( IOAccelConnect connect, IOAccelSurfaceInformation * info, UInt32 infoSize ) { size_t size = (size_t) infoSize; IOReturn ret = IOConnectCallStructMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceWriteLock, NULL, 0, info, &size); return ret; } IOReturn IOAccelWriteLockSurfaceWithOptions( IOAccelConnect connect, IOOptionBits options, IOAccelSurfaceInformation * info, UInt32 infoSize ) { uint64_t inData = options; size_t size = (size_t) infoSize; IOReturn ret = IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceWriteLockOptions, &inData, 1, // in scalar NULL, 0, // in struct NULL, NULL, // out scalar info, &size); // out struct return ret; } IOReturn IOAccelReadUnlockSurface( IOAccelConnect connect ) { return IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceReadUnlock, NULL, 0, NULL, 0, // input NULL, NULL, NULL, NULL); // output } IOReturn IOAccelReadUnlockSurfaceWithOptions( IOAccelConnect connect, IOOptionBits options ) { uint64_t inData = options; return IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceReadUnlockOptions, &inData, 1, NULL, 0, // input NULL, NULL, NULL, NULL); // output } IOReturn IOAccelWriteUnlockSurface( IOAccelConnect connect ) { return IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceWriteUnlock, NULL, 0, NULL, 0, // input NULL, NULL, NULL, NULL); // output } IOReturn IOAccelWriteUnlockSurfaceWithOptions( IOAccelConnect connect, IOOptionBits options ) { uint64_t inData = options; return IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceWriteUnlockOptions, &inData, 1, NULL, 0, // input NULL, NULL, NULL, NULL); // output } IOReturn IOAccelWaitForSurface( IOAccelConnect connect __unused ) { return kIOReturnSuccess; } IOReturn IOAccelQueryLockSurface( IOAccelConnect connect ) { return IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceQueryLock, NULL, 0, NULL, 0, // input NULL, NULL, NULL, NULL); // output } /* Flush surface to visible region */ IOReturn IOAccelFlushSurfaceOnFramebuffers( IOAccelConnect connect, IOOptionBits options, UInt32 framebufferMask ) { uint64_t inData[] = { framebufferMask, options }; return IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceFlush, inData, arrayCnt(inData), NULL, 0,// input NULL, NULL, NULL, NULL); // output } IOReturn IOAccelReadSurface( IOAccelConnect connect, IOAccelSurfaceReadData * parameters ) { IOReturn result; result = IOConnectCallMethod((io_connect_t) (uintptr_t) connect, kIOAccelSurfaceRead, NULL, 0, parameters, sizeof( IOAccelSurfaceReadData), // input NULL, NULL, NULL, NULL); // no output return result; }