예제 #1
0
파일: mem.c 프로젝트: sunkaizhu/zephyr
uint32_t mem_ut(void)
{
#define BLOCK_SIZE  MROUND(10)
#define BLOCK_COUNT 10
	uint8_t MALIGN(4) pool[BLOCK_COUNT][BLOCK_SIZE];
	void *mem_free;
	void *mem_used;
	uint16_t mem_free_count;
	void *mem;

	mem_init(pool, BLOCK_SIZE, BLOCK_COUNT, &mem_free);

	mem_free_count = mem_free_count_get(mem_free);
	if (mem_free_count != BLOCK_COUNT) {
		return 1;
	}

	mem_used = 0;
	while (mem_free_count--) {
		uint16_t mem_free_count_current;

		mem = mem_acquire(&mem_free);
		mem_free_count_current = mem_free_count_get(mem_free);
		if (mem_free_count != mem_free_count_current) {
			return 2;
		}

		memcpy(mem, &mem_used, sizeof(mem));
		mem_used = mem;
	}

	mem = mem_acquire(&mem_free);
	if (mem) {
		return 3;
	}

	while (++mem_free_count < BLOCK_COUNT) {
		uint16_t mem_free_count_current;

		mem = mem_used;
		memcpy(&mem_used, mem, sizeof(void *));
		mem_release(mem, &mem_free);

		mem_free_count_current = mem_free_count_get(mem_free);
		if ((mem_free_count + 1) != mem_free_count_current) {
			return 4;
		}
	}

	if (mem != mem_free) {
		return 5;
	}

	if (mem_free_count_get(mem_free) != BLOCK_COUNT) {
		return 6;
	}

	return 0;
}
MEM_HANDLE_T egl_server_platform_create_pixmap_info(uint32_t pixmap)
{
   VC_IMAGE_T *vcimage = (VC_IMAGE_T *)pixmap;
   KHRN_IMAGE_FORMAT_T format = 0;
   MEM_HANDLE_T data_handle;

   vcos_assert(pixmap);

   switch (vcimage->type) {
   case VC_IMAGE_TF_RGBA32:
      format = ABGR_8888_TF;
      break;
   case VC_IMAGE_TF_RGBX32:
      format = XBGR_8888_TF;
      break;
   case VC_IMAGE_TF_RGB565:
      format = RGB_565_TF;
      break;
   case VC_IMAGE_TF_RGBA5551:
      format = RGBA_5551_TF;
      break;
   case VC_IMAGE_TF_RGBA16:
      format = RGBA_4444_TF;
      break;
#ifdef __VIDEOCORE4__
   case VC_IMAGE_RGBA32:
      format = ABGR_8888_RSO;
      break;
   case VC_IMAGE_RGB565:
      format = RGB_565_RSO;
      break;
#endif
   default:
      UNREACHABLE();
   }

   if (vcimage->mem_handle != MEM_INVALID_HANDLE)
   {
      data_handle = vcimage->mem_handle;
      mem_acquire(data_handle);
   }
   else
      data_handle = mem_wrap(vcimage->image_data, vcimage->size, 64, MEM_FLAG_NONE, "egl_server_platform_create_pixmap_info");
   if (data_handle == MEM_INVALID_HANDLE) {
      return MEM_INVALID_HANDLE;
   }
   MEM_HANDLE_T handle = khrn_image_create_from_storage(format,
      vcimage->width, vcimage->height, vcimage->pitch,
      MEM_INVALID_HANDLE, data_handle, 0,
      (KHRN_IMAGE_CREATE_FLAG_T)(IMAGE_CREATE_FLAG_TEXTURE | IMAGE_CREATE_FLAG_RENDER_TARGET)); /* todo: are these flags right? */
   mem_release(data_handle);
   return handle;
}
bool khrn_fmem_interlock(KHRN_FMEM_T *fmem, MEM_HANDLE_T handle, uint32_t offset)
{
   KHRN_FMEM_TWEAK_T *tw;

   tw = tweak_next(fmem, &fmem->interlock);
   if (!tw) return false;

   tw->interlock.mh_handle = handle;
   tw->interlock.offset = offset;

   mem_acquire(handle);

   return true;
}
EGL_DISP_HANDLE_T egl_disp_alloc(
   uint64_t pid, uint32_t sem,
   uint32_t n, const MEM_HANDLE_T *images)
{
#ifdef BRCM_V3D_OPT
	return EGL_DISP_HANDLE_INVALID;
#endif
   EGL_DISP_HANDLE_T disp_handle;
   DISP_T *disp;
   uint32_t i;

   vcos_assert(n <= IMAGES_N_MAX);

   disp_handle = alloc_disp_handle();
   if (disp_handle == EGL_DISP_HANDLE_INVALID) {
      return EGL_DISP_HANDLE_INVALID;
   }

   disp = disp_from_handle(disp_handle);
   disp->in_use.pid = pid;
   disp->in_use.sem = sem;
   disp->in_use.n = n;
   for (i = 0; i != n; ++i) {
      KHRN_IMAGE_T *image = (KHRN_IMAGE_T *)mem_lock(images[i]);
      vcos_assert(image->flags & IMAGE_FLAG_DISPLAY);
      if (n != 1) {
         image->interlock.disp_image_handle = egl_disp_image_handle(disp_handle, i);
      }
      mem_unlock(images[i]);
      mem_acquire(images[i]);
      disp->in_use.images[i] = images[i];
   }
   disp->in_use.last_win = EGL_PLATFORM_WIN_NONE;
   /* we need to make it look like there's something on the display (and it's
    * been there long enough -- swap interval 0), but there's nothing queued up
    * (next_pos(on) == post). we also want to make sure the next image to be
    * displayed is 0 */
   disp->in_use.post = next_power_of_2(n);
   disp->in_use.on = n - 1;
   disp->in_use.asyncs = -1; /* we don't want an async when the fake image "comes off the display" */
   disp->in_use.want = true;
   disp->in_use.want_us = 0; /* todo: will probably get spurious khrn_hw_kick() on first display. care? */
   disp->in_use.finish = false;
   disp->in_use.slots[n - 1].swap_interval = 0;

   return disp_handle;
}