bool VsyncControl::wait(int disp, int64_t& timestamp) { ATRACE("disp = %d", disp); struct drm_psb_vsync_set_arg arg; memset(&arg, 0, sizeof(struct drm_psb_vsync_set_arg)); arg.vsync_operation_mask = VSYNC_WAIT; // pipe equals to disp arg.vsync.pipe = disp; Drm *drm = Hwcomposer::getInstance().getDrm(); bool ret = drm->writeReadIoctl(DRM_PSB_VSYNC_SET, &arg, sizeof(arg)); timestamp = (int64_t)arg.vsync.timestamp; return ret; }
bool VsyncControl::control(int disp, bool enabled) { ATRACE("disp = %d, enabled = %d", disp, enabled); struct drm_psb_vsync_set_arg arg; memset(&arg, 0, sizeof(struct drm_psb_vsync_set_arg)); // pipe equals to disp arg.vsync.pipe = disp; if (enabled) { arg.vsync_operation_mask = VSYNC_ENABLE; } else { arg.vsync_operation_mask = VSYNC_DISABLE; } Drm *drm = Hwcomposer::getInstance().getDrm(); return drm->writeReadIoctl(DRM_PSB_VSYNC_SET, &arg, sizeof(arg)); }
/*-----------------------------------------------------------*/ void vPortFree( void *pv ) { pre_free_hook(pv); unsigned char *puc = ( unsigned char * ) pv; xBlockLink *pxLink; ASSERT( ( pv >= (void*)WMSDK_HEAP_START_ADDR ) || ( pv == NULL ) ); ASSERT( ( pv <= (void*)lastHeapAddress ) || ( pv == NULL ) ); if( pv ) { /* The memory being freed will have an xBlockLink structure immediately before it. */ puc -= heapSTRUCT_SIZE; /* This casting is to keep the compiler from issuing warnings. */ pxLink = ( void * ) puc; ATRACE("MDC F %10x %6d %10d R: %x\r\n", puc + heapSTRUCT_SIZE, BLOCK_SIZE( pxLink ), xFreeBytesRemaining + BLOCK_SIZE(pxLink), __builtin_return_address(0)); post_free_hook(((unsigned)puc + heapSTRUCT_SIZE), GET_ACTUAL_SIZE( pxLink )); randomizeAreaData((unsigned char*)((unsigned)puc + heapSTRUCT_SIZE), BLOCK_SIZE( pxLink ) - heapSTRUCT_SIZE); vTaskSuspendAll(); { /* Add this block to the list of free blocks. */ SET_FREE( pxLink ); xFreeBytesRemaining += BLOCK_SIZE(pxLink); prvInsertBlockIntoFreeList( ( ( xBlockLink * ) pxLink ) ); #ifdef FREERTOS_ENABLE_MALLOC_STATS hI.totalAllocations--; #endif // FREERTOS_ENABLE_MALLOC_STATS } xTaskResumeAll(); } }
void DisplayPlaneManager::reclaimPlane(int dsp, DisplayPlane& plane) { RETURN_VOID_IF_NOT_INIT(); int index = plane.getIndex(); int type = plane.getType(); ATRACE("reclaimPlane = %d, type = %d", index, plane.getType()); if (type < 0 || type >= DisplayPlane::PLANE_MAX) { ETRACE("Invalid plane type %d", type); return; } putPlane(index, mReclaimedPlanes[type]); // NOTE: don't invalidate plane's data cache here because the reclaimed // plane might be re-assigned to the same layer later }
int psbWsbmAllocateFromUB(uint32_t size, uint32_t align, void ** buf, void *user_pt) { struct _WsbmBufferObject * wsbmBuf = NULL; int ret = 0; int offset = 0; ATRACE("size %d", align_to(size, 4096)); if(!buf || !user_pt) { ETRACE("invalid parameter"); return -EINVAL; } VTRACE("mainPool %p", mainPool); ret = wsbmGenBuffers(mainPool, 1, &wsbmBuf, align, DRM_PSB_FLAG_MEM_MMU | WSBM_PL_FLAG_CACHED | WSBM_PL_FLAG_NO_EVICT | WSBM_PL_FLAG_SHARED); if(ret) { ETRACE("wsbmGenBuffers failed with error code %d", ret); return ret; } ret = wsbmBODataUB(wsbmBuf, align_to(size, 4096), NULL, NULL, 0, user_pt, -1); if(ret) { ETRACE("wsbmBOData failed with error code %d", ret); /*FIXME: should I unreference this buffer here?*/ return ret; } *buf = wsbmBuf; VTRACE("ttm UB buffer allocated. %p", *buf); return 0; }
int psbWsbmAllocateTTMBuffer(uint32_t size, uint32_t align, void ** buf) { struct _WsbmBufferObject * wsbmBuf = NULL; int ret = 0; int offset = 0; ATRACE("size %d", align_to(size, 4096)); if(!buf) { ETRACE("invalid parameter"); return -EINVAL; } VTRACE("mainPool %p", mainPool); ret = wsbmGenBuffers(mainPool, 1, &wsbmBuf, align, (WSBM_PL_FLAG_VRAM | WSBM_PL_FLAG_TT | WSBM_PL_FLAG_SHARED | WSBM_PL_FLAG_NO_EVICT)); if(ret) { ETRACE("wsbmGenBuffers failed with error code %d", ret); return ret; } ret = wsbmBOData(wsbmBuf, align_to(size, 4096), NULL, NULL, 0); if(ret) { ETRACE("wsbmBOData failed with error code %d", ret); /*FIXME: should I unreference this buffer here?*/ return ret; } /* wsbmBOReference(wsbmBuf); */ /* no need to add reference */ *buf = wsbmBuf; VTRACE("ttm buffer allocated. %p", *buf); return 0; }
/*-----------------------------------------------------------*/ void* pvPortReAlloc( void *pv, size_t xWantedSize ) { ASSERT( ( pv >= (void*)WMSDK_HEAP_START_ADDR ) || ( pv == NULL ) ); ASSERT( ( pv <= (void*)lastHeapAddress ) || ( pv == NULL ) ); pre_free_hook(pv); unsigned char *puc = ( unsigned char * ) pv; #ifdef ALLOC_TRACE unsigned char *old_ptr= puc; #endif /* ALLOC_TRACE */ xBlockLink *pxLink; if( pv ) { if( !xWantedSize ) { vPortFree( pv ); return NULL; } void *newArea = pvPortMalloc( xWantedSize ); if( newArea ) { /* The memory being freed will have an xBlockLink structure immediately before it. */ puc -= heapSTRUCT_SIZE; /* This casting is to keep the compiler from issuing warnings. */ pxLink = ( void * ) puc; ATRACE("MDC F %10x %10d %10d\r\n", puc + heapSTRUCT_SIZE, BLOCK_SIZE( pxLink ), xFreeBytesRemaining + BLOCK_SIZE(pxLink)); post_free_hook( ( ( unsigned )puc + heapSTRUCT_SIZE ), GET_ACTUAL_SIZE( pxLink ) ); int oldSize = BLOCK_SIZE( pxLink ) - heapSTRUCT_SIZE; int copySize = ( oldSize < xWantedSize ) ? oldSize : xWantedSize; memcpy( newArea, pv, copySize ); randomizeAreaData((unsigned char*) ((unsigned)pxLink + heapSTRUCT_SIZE), BLOCK_SIZE( pxLink ) - heapSTRUCT_SIZE); vTaskSuspendAll(); { /* Add this block to the list of free blocks. */ SET_FREE( pxLink ); xFreeBytesRemaining += BLOCK_SIZE(pxLink); prvInsertBlockIntoFreeList( ( ( xBlockLink * ) pxLink ) ); #ifdef FREERTOS_ENABLE_MALLOC_STATS hI.totalAllocations--; #endif // FREERTOS_ENABLE_MALLOC_STATS } xTaskResumeAll(); return newArea; } } else if( xWantedSize ) return pvPortMalloc( xWantedSize ); else return NULL; return NULL; }
void *pvPortMalloc( size_t xWantedSize ) { xBlockLink *pxBlock = NULL, *pxPreviousBlock, *pxNewBlockLink; void *pvReturn = NULL; if(!xWantedSize) return NULL; pre_alloc_hook( xWantedSize ); vTaskSuspendAll(); { /* If this is the first call to malloc then the heap will require initialisation to setup the list of free blocks. */ if( xHeapHasBeenInitialised == pdFALSE ) { prvHeapInit(); xHeapHasBeenInitialised = pdTRUE; } /* The wanted size is increased so it can contain a xBlockLink structure in addition to the requested amount of bytes. */ if( xWantedSize > 0 ) { xWantedSize += heapSTRUCT_SIZE; /* Ensure that blocks are always aligned to the required number of bytes. */ if( xWantedSize & portBYTE_ALIGNMENT_MASK ) { /* Byte alignment required. */ xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); } } if( ( xWantedSize > 0 ) && ( xWantedSize < configTOTAL_HEAP_SIZE ) ) { /* Blocks are stored in byte order - traverse the list from the start (smallest) block until one of adequate size is found. */ pxPreviousBlock = &xStart; pxBlock = xStart.pxNextFreeBlock; while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock ) ) { pxPreviousBlock = pxBlock; pxBlock = pxBlock->pxNextFreeBlock; } /* If we found the end marker then a block of adequate size was not found. */ if( pxBlock != &xEnd ) { /* Return the memory space - jumping over the xBlockLink structure at its start. */ pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); #ifdef FREERTOS_ENABLE_MALLOC_STATS hI.totalAllocations++; #endif // FREERTOS_ENABLE_MALLOC_STATS /* This block is being returned for use so must be taken off the list of free blocks. */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; pxBlock->pxNextFreeBlock = NULL; /* If the block is larger than required it can be split into two. */ if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) { /* This block is to be split into two. Create a new block following the number of bytes requested. The void cast is used to prevent byte alignment warnings from the compiler. */ pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize ); /* Calculate the sizes of two blocks split from the single block. */ pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; /* Assume bit 0 is 0 i.e. BLOCK_ALLOCATED flag is clear */ pxBlock->xBlockSize = xWantedSize; /* Add the new block to the serial list */ pxNewBlockLink->pxPrev = pxBlock; if( ! IS_LAST_BLOCK(pxNewBlockLink) ) NEXT_BLOCK( pxNewBlockLink )->pxPrev = pxNewBlockLink; SET_ALLOCATED(pxBlock); /* insert the new block into the list of free blocks. */ prvInsertBlockIntoFreeList( pxNewBlockLink ); } else { SET_ALLOCATED(pxBlock); } xFreeBytesRemaining -= BLOCK_SIZE(pxBlock); } } } xTaskResumeAll(); #if( configUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { DTRACE("Heap allocation failed.\n\r" "Requested: %d\n\r" "Available : %d\n\r", xWantedSize, xFreeBytesRemaining); extern void vApplicationMallocFailedHook( void ); vApplicationMallocFailedHook(); } } #else if( pvReturn == NULL ) { DTRACE("Heap allocation failed.\n\r" "Requested: %d\n\r" "Available : %d\n\r", xWantedSize, xFreeBytesRemaining); #ifdef FREERTOS_ENABLE_MALLOC_STATS hI.failedAllocations++; #endif /* FREERTOS_ENABLE_MALLOC_STATS */ } #endif if(pvReturn) { SET_ACTUAL_SIZE( pxBlock ); SET_CALLER_ADDR( pxBlock ); ATRACE("MDC A %10x %6d %10d R: %x\r\n", pvReturn , BLOCK_SIZE( pxBlock ), xFreeBytesRemaining, __builtin_return_address(0)); randomizeAreaData((unsigned char*)pvReturn, BLOCK_SIZE( pxBlock ) - heapSTRUCT_SIZE); post_alloc_hook( pvReturn ); #ifdef FREERTOS_ENABLE_MALLOC_STATS if ((configTOTAL_HEAP_SIZE - xFreeBytesRemaining) > hI.peakHeapUsage) { hI.peakHeapUsage = (configTOTAL_HEAP_SIZE - xFreeBytesRemaining); } #endif } return pvReturn; }
/* TBD: Make this function force inline */ static inline void prvInsertBlockIntoFreeList( xBlockLink * pxBlockToInsert ) { xBlockLink *pxIterator; xBlockLink *xBlockToMerge; size_t xBlockSize; ASSERT(IS_FREE_BLOCK(pxBlockToInsert)); /* We have a block which we are about to declare as a free block. * Lets find out if there is a free block in front of us and back * of us */ /* TRACE("pxBlockToInsert->pxNextFreeBlock: %x ->pxPrev = %x\n\r", pxBlockToInsert->pxNextFreeBlock, pxBlockToInsert->pxPrev); */ /* Check for front merge */ if ( !IS_LAST_BLOCK( pxBlockToInsert ) ) { if ( IS_FREE_BLOCK(NEXT_BLOCK( pxBlockToInsert ) ) ) { xBlockToMerge = NEXT_BLOCK( pxBlockToInsert ); /* Find out xBlockToMerge's location on the free list.*/ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock != xBlockToMerge && pxIterator->pxNextFreeBlock != NULL; pxIterator = pxIterator->pxNextFreeBlock ) {} #ifdef DEBUG_HEAP if(! ( pxIterator->pxNextFreeBlock == xBlockToMerge ) ) { /* * This is not a good situation. The * problem is that data structures here are * showing that the next block is free. But * ths free block could not be found in the * free list. */ ATRACE("Target block dump :\n\r"); ATRACE("pxNextFreeBlock : 0x%x\n\r", xBlockToMerge->pxNextFreeBlock); ATRACE("pxPrev : 0x%x\n\r", xBlockToMerge->pxPrev); ATRACE("xBlockSize : %d (0x%x)\n\r", xBlockToMerge->xBlockSize, xBlockToMerge->xBlockSize); #ifdef DEBUG_HEAP_EXTRA ATRACE("xActualBlockSize: %d\n\r", xBlockToMerge->xActualBlockSize); #endif /* DEBUG_HEAP_EXTRA */ ATRACE("Panic\n\r"); while(1) {} } #endif /* DEBUG_HEAP */ ASSERT( pxIterator->pxNextFreeBlock == xBlockToMerge ); //TRACE("Merge: F\n\r"); /* Delete node from Free list */ pxIterator->pxNextFreeBlock = xBlockToMerge->pxNextFreeBlock; /* Delete xBlockToMerge node from Serial List */ if( ! IS_LAST_BLOCK( xBlockToMerge ) ) NEXT_BLOCK( xBlockToMerge )->pxPrev = pxBlockToInsert; /* Update node size */ pxBlockToInsert->xBlockSize += BLOCK_SIZE( xBlockToMerge ); /* Now forget about xBlockToMerge */ } } /* Check for back merge */ if ( ! IS_FIRST_BLOCK(pxBlockToInsert) ) { if ( IS_FREE_BLOCK( PREV_BLOCK(pxBlockToInsert ))) { xBlockToMerge = PREV_BLOCK(pxBlockToInsert); /* Find out xBlockToMerge's location on the free list */ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock != xBlockToMerge && pxIterator->pxNextFreeBlock != NULL; pxIterator = pxIterator->pxNextFreeBlock ) {} ASSERT( pxIterator->pxNextFreeBlock == xBlockToMerge ); //TRACE("Merge: R\n\r"); /* Delete xBlockToMerge node from Free list */ pxIterator->pxNextFreeBlock = xBlockToMerge->pxNextFreeBlock; /* Delete _ pxBlockToInsert _ node from Serial List */ if( ! IS_LAST_BLOCK( pxBlockToInsert ) ) NEXT_BLOCK( pxBlockToInsert )->pxPrev = xBlockToMerge; /* Update node size */ xBlockToMerge->xBlockSize += BLOCK_SIZE( pxBlockToInsert ); /* Now forget about pxBlockToInsert */ pxBlockToInsert = xBlockToMerge; } } xBlockSize = pxBlockToInsert->xBlockSize; /* Iterate through the list until a block is found that has a larger size */ /* than the block we are inserting. */ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) { /* There is nothing to do here - just iterate to the correct position. */ } /* Update the list to include the block being inserted in the correct */ /* position. */ pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; pxIterator->pxNextFreeBlock = pxBlockToInsert; }