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));
}
Пример #3
0
/*-----------------------------------------------------------*/
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;
}
Пример #7
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;
}
Пример #8
0
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;
}
Пример #9
0
/* 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;
}