bool
initBackgroundLayer(
    BACKGROUND_LAYER_T *bg,
    uint16_t colour,
    int32_t layer)
{
    int result = 0;
    VC_IMAGE_TYPE_T type = VC_IMAGE_RGBA16;
    uint32_t vc_image_ptr;

    bg->resource = vc_dispmanx_resource_create(type, 1, 1, &vc_image_ptr);
    if(!bg->resource)
      return false;

    //---------------------------------------------------------------------

    VC_RECT_T dst_rect;
    vc_dispmanx_rect_set(&dst_rect, 0, 0, 1, 1);

    bg->layer = layer;

    result = vc_dispmanx_resource_write_data(bg->resource,
                                             type,
                                             sizeof(colour),
                                             &colour,
                                             &dst_rect);
    if(result != DISPMANX_SUCCESS){
      result = vc_dispmanx_resource_delete(bg->resource);
      return false;
    }
      
    return true;
}
Exemplo n.º 2
0
void vsync(DISPMANX_UPDATE_HANDLE_T u, void* arg)
{

    int ret;
    DISPMANX_UPDATE_HANDLE_T    update;

    update = vc_dispmanx_update_start( 10 );
    assert( update );
    ret = vc_dispmanx_element_change_source( update, element, resource[next_resource]);
    assert( ret == 0 );
    ret = vc_dispmanx_update_submit_sync( update );
    assert( ret == 0 );

    if(next_resource != 2) {

        int real_next_resource = next_resource ^ 1;
        next_resource = 2; // use filler if next callback called before this one ends

        // fill image
        int n;
        for (n=0; n<HEIGHT; n+=2) {
            get_packet(ROW(n)+24); // +24 because clock never changes
            memcpy(ROW(n+1)+24, ROW(n)+24, 336); // double it up because the hardware scaler
                                                 // will introduce blurring between lines
        }

        // write to resource
        ret = vc_dispmanx_resource_write_data(  resource[real_next_resource], TYPE, PITCH, image, &image_rect );
        assert( ret == 0 );

        next_resource = real_next_resource; // queue up next real resource

    }
}
Exemplo n.º 3
0
void
iterateLife(
    LIFE_T *life)
{
    memcpy(life->field, life->fieldNext, life->fieldLength);

    if (life->numberOfThreads == 0)
    {
        iterateLifeKernel(life, 0);
    }
    else
    {
        pthread_barrier_wait(&(life->startIterationBarrier));
        pthread_barrier_wait(&(life->finishedIterationBarrier));
    }

    int result = 0;
    VC_IMAGE_TYPE_T type = VC_IMAGE_RGBA16;

    result = vc_dispmanx_resource_write_data(life->backResource,
                                             type,
                                             life->pitch,
                                             life->buffer,
                                             &(life->bmpRect));
    assert(result == 0);
}
Exemplo n.º 4
0
static int DISPMANX_FlipHWSurface(_THIS, SDL_Surface *surface)
{
	/*if ( switched_away ) {
		return -2; // no hardware access
	}*/
	
	//Volcamos desde el ram bitmap buffer al dispmanx resource buffer
	//que toque. cada vez a uno.	
	vc_dispmanx_resource_write_data( dispvars->resources[flip_page], 
	   dispvars->pix_format, dispvars->pitch, dispvars->pixmem, 
	   &(dispvars->bmp_rect) );

	//**Empieza actualización***
	dispvars->update = vc_dispmanx_update_start( 0 );

	vc_dispmanx_element_change_source(dispvars->update, 
	   dispvars->element, dispvars->resources[flip_page]);

	vc_dispmanx_update_submit_sync( dispvars->update );		
	//vc_dispmanx_update_submit(dispvars->update, NULL, NULL); 
	//**Acaba actualización***
	flip_page = !flip_page;
	
	//MAC Esto no hace falta porque SDL siempre escribe en dispvars->pixmem, 
	//que es el buffer en RAM y que copiamos cada vez a un resource.
	//surface->pixels = flip_address[flip_page];
	
	return (0);
}
Exemplo n.º 5
0
static void dispmanx_surface_update(void *data, const void *frame, struct dispmanx_surface *surface)
{
   struct dispmanx_video *_dispvars = data;
   struct dispmanx_page *page = NULL;
   
   /* Wait until last issued flip completes to get a free page. Also, 
      dispmanx doesn't support issuing more than one pageflip.*/
   slock_lock(_dispvars->pending_mutex);
   if (_dispvars->pageflip_pending > 0)
   {
      scond_wait(_dispvars->vsync_condition, _dispvars->pending_mutex);
   }
   slock_unlock(_dispvars->pending_mutex);
  
   page = dispmanx_get_free_page(_dispvars, surface);
 
   /* Frame blitting */
   vc_dispmanx_resource_write_data(page->resource, surface->pixformat,
      surface->pitch, (void*)frame, &(surface->bmp_rect));
   
   /* Issue a page flip that will be done at the next vsync. */
   _dispvars->update = vc_dispmanx_update_start(0);

   vc_dispmanx_element_change_source(_dispvars->update, surface->element,
         page->resource);

   vc_dispmanx_update_submit(_dispvars->update, dispmanx_vsync_callback, (void*)page);

   slock_lock(_dispvars->pending_mutex);
   _dispvars->pageflip_pending++;	
   slock_unlock(_dispvars->pending_mutex);
}
static void DISPMANX_BlankBackground(void)
{
  //MAC: Funcion que simplemente pone un element nuevo cuyo resource es de un solo pixel de color negro,
  //se escala a pantalla completa y listo.
  
  // we create a 1x1 black pixel image that is added to display just behind video

  VC_IMAGE_TYPE_T type = VC_IMAGE_RGB565;
  uint32_t vc_image_ptr;
  uint16_t image = 0x0000; // black

  VC_RECT_T dst_rect, src_rect;

  dispvars->b_resource = vc_dispmanx_resource_create( type, 1 /*width*/, 1 /*height*/, &vc_image_ptr );

  vc_dispmanx_rect_set( &dst_rect, 0, 0, 1, 1);

  vc_dispmanx_resource_write_data( dispvars->b_resource, type, sizeof(image), &image, &dst_rect );

  vc_dispmanx_rect_set( &src_rect, 0, 0, 1<<16, 1<<16);
  vc_dispmanx_rect_set( &dst_rect, 0, 0, 0, 0);

  dispvars->b_update = vc_dispmanx_update_start(0);

  dispvars->b_element = vc_dispmanx_element_add(dispvars->b_update, dispvars->display, -1 /*layer*/, &dst_rect, 
	dispvars->b_resource, &src_rect, DISPMANX_PROTECTION_NONE, NULL, NULL, (DISPMANX_TRANSFORM_T)0 );
  
  vc_dispmanx_update_submit_sync( dispvars->b_update );
}
Exemplo n.º 7
0
ViewBackend::Cursor::Cursor(WPE::LibinputServer::Client& targetClient, DISPMANX_DISPLAY_HANDLE_T displayHandle, uint32_t displayWidth, uint32_t displayHeight)
    : targetClient(targetClient)
    , position({ 0, 0 })
    , displaySize({ displayWidth, displayHeight })
{
    static VC_DISPMANX_ALPHA_T alpha = {
        static_cast<DISPMANX_FLAGS_ALPHA_T>(DISPMANX_FLAGS_ALPHA_FROM_SOURCE),
        255, 0
    };

    DISPMANX_UPDATE_HANDLE_T updateHandle = vc_dispmanx_update_start(0);

    uint32_t imagePtr;
    VC_RECT_T rect;
    vc_dispmanx_rect_set(&rect, 0, 0, CursorData::width, CursorData::height);
    DISPMANX_RESOURCE_HANDLE_T pointerResource = vc_dispmanx_resource_create(VC_IMAGE_RGBA32, CursorData::width, CursorData::height, &imagePtr);
    vc_dispmanx_resource_write_data(pointerResource, VC_IMAGE_RGBA32, CursorData::width * 4, CursorData::data, &rect);

    VC_RECT_T srcRect, destRect;
    vc_dispmanx_rect_set(&srcRect, 0, 0, CursorData::width << 16, CursorData::height << 16);
    vc_dispmanx_rect_set(&destRect, position.first, position.second, cursorWidth, cursorHeight);

    cursorHandle = vc_dispmanx_element_add(updateHandle, displayHandle, 10,
        &destRect, pointerResource, &srcRect, DISPMANX_PROTECTION_NONE, &alpha,
        nullptr, DISPMANX_NO_ROTATE);

    vc_dispmanx_resource_delete(pointerResource);

    vc_dispmanx_update_submit_sync(updateHandle);
}
static void DISPMANX_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
{	
	//En OpenGL también va así­. No deberíamos esperar para cambiar el buffer, de hecho la aplicación
	//piensa que no hay doble buffer (hasta hemos desactivado el double buffer), sino que en lugar
	//de esperar, simplemente deberíamos actualizar la superficie visible directamente... Pero no
	//puedo hacer eso porque no tengo acceso a la superficie visible: tengo la superficie de vídeo en RAM
	//y cada vez que se hace un cambio (o sea, cada vez que llego aquí­) copio esa superficie a la VRAM
	//y espero a cambiar los buffers para no tener tearing, a pesar de que esta función se supone que no
	//hace eso. Pero en OpenGL se hace lo mismo ya que la única manera de mostrar los cambios es hacer
	//un GL_SWAP_BUFFERS que también es bloqueante. 
	//Volcamos desde el ram bitmap buffer al dispmanx resource buffer que toque. cada vez a uno.	
	vc_dispmanx_resource_write_data( dispvars->resources[flip_page], 
	   dispvars->pix_format, dispvars->pitch, dispvars->pixmem, 
	   &(dispvars->bmp_rect) );
	//Empieza actualización
	dispvars->update = vc_dispmanx_update_start( 0 );

	vc_dispmanx_element_change_source(dispvars->update, 
	   dispvars->element, dispvars->resources[flip_page]);
	
	vc_dispmanx_update_submit_sync( dispvars->update );		
	//vc_dispmanx_update_submit(dispvars->update, NULL, NULL); 
	//Acaba actualización
	flip_page = !flip_page;
	
	return;
}
Exemplo n.º 9
0
void vo_display_frame (RECT_VARS_T* vars, int width, int height,
                      int chroma_width, int chroma_height,
                      uint8_t * const * buf, int num)
{
  int ret;
  static VC_RECT_T       src_rect;
  static VC_RECT_T       dst_rect;
  static VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 
                                255, /*alpha 0->255*/
			        0 };
  int pitch = VO_ALIGN_UP(width,32);

  assert((height % 16) == 0);
  assert((chroma_height % 16) == 0);

  if (num == 0) {
    vars->resource = vc_dispmanx_resource_create( VC_IMAGE_YUV420,
                                                  width,
                                                  height,
                                                  &vars->vc_image_ptr );
    assert( vars->resource );

    vars->update = vc_dispmanx_update_start( 10 );
    assert( vars->update );

    vc_dispmanx_rect_set( &src_rect, 0, 0, width << 16, height << 16 );

    vc_dispmanx_rect_set( &dst_rect, 0, 0, vars->info.width, vars->info.height);

    vars->element = vc_dispmanx_element_add(    vars->update,
                                                vars->display,
                                                2000,               // layer
                                                &dst_rect,
                                                vars->resource,
                                                &src_rect,
                                                DISPMANX_PROTECTION_NONE,
                                                &alpha,
                                                NULL,             // clamp
                                                VC_IMAGE_ROT0 );
    ret = vc_dispmanx_update_submit( vars->update, NULL, NULL);

    vc_dispmanx_rect_set( &dst_rect, 0, 0, width, (3*height)/2);

  }

  ret = vc_dispmanx_resource_write_data(  vars->resource,
                                          VC_IMAGE_YUV420,
                                          pitch,
                                          buf[0],
                                          &dst_rect );
  assert( ret == 0 );

  vars->update = vc_dispmanx_update_start( 10 );
  assert( vars->update );

  //ret = vc_dispmanx_update_submit_sync( vars->update );
    ret = vc_dispmanx_update_submit( vars->update, NULL, NULL);
    assert( ret == 0 );
}
Exemplo n.º 10
0
Arquivo: vout.c Projeto: Kubink/vlc
static void dmx_region_update(struct dmx_region_t *dmx_region,
                DISPMANX_UPDATE_HANDLE_T update, picture_t *picture)
{
    vc_dispmanx_resource_write_data(dmx_region->resource, VC_IMAGE_RGBA32,
                    picture->p[0].i_pitch, picture->p[0].p_pixels, &dmx_region->bmp_rect);
    vc_dispmanx_element_change_source(update, dmx_region->element, dmx_region->resource);
    dmx_region->picture = picture;
}
Exemplo n.º 11
0
static void show_cursor(ALLEGRO_DISPLAY_RASPBERRYPI *d)
{
    if (d->cursor_data == NULL || cursor_added) {
        return;
    }

    int width = d->cursor_width;
    int height = d->cursor_height;

    uint32_t unused;
    cursor_resource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888, width, height, &unused);

    VC_RECT_T r;
    r.x = 0;
    r.y = 0;
    r.width = width;
    r.height = height;

    int dpitch = pot(sizeof(uint32_t) * width);

    dispman_update = vc_dispmanx_update_start(0);
    vc_dispmanx_resource_write_data(cursor_resource, VC_IMAGE_ARGB8888, dpitch, d->cursor_data, &r);
    vc_dispmanx_update_submit_sync(dispman_update);

    ALLEGRO_MOUSE_STATE state;
    al_get_mouse_state(&state);

    dst_rect.x = state.x+d->cursor_offset_x;
    dst_rect.y = state.y+d->cursor_offset_y;
    dst_rect.width = width;
    dst_rect.height = height;
    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = width << 16;
    src_rect.height = height << 16;

    dispman_update = vc_dispmanx_update_start(0);

    cursor_element = vc_dispmanx_element_add(
                         dispman_update,
                         dispman_display,
                         0/*layer*/,
                         &dst_rect,
                         cursor_resource,
                         &src_rect,
                         DISPMANX_PROTECTION_NONE,
                         0 /*alpha*/,
                         0/*clamp*/,
                         0/*transform*/
                     );

    vc_dispmanx_update_submit_sync(dispman_update);

    cursor_added = true;
}
Exemplo n.º 12
0
static void DISPMANX_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
{	
	//Esto es una solución temporal! no puedo volcar el bitmap buffer 
	//entero cada vez que quiero actualizar un área de pantalla!
	//En resoluciones internas bajas no se nota, pero en altas... 	
	vc_dispmanx_resource_write_data( dispvars->resources[flip_page], 
	   dispvars->pix_format, dispvars->pitch, dispvars->pixmem, 
	   &(dispvars->bmp_rect) );
	
	return;
}
Exemplo n.º 13
0
int SliceMngr::loadSlice(const char *pFilename){
  if (loadPng(&(mImage.image), pFilename) == false){
    printf("failed to load\n");
    return -1;
  }else{
    vc_dispmanx_resource_write_data(mImage.resource,
                                    mImage.image.type,
                                    mImage.image.pitch,
                                    mImage.image.buffer,
                                    &(mImage.dstRect));
  }
  return 0;
}
Exemplo n.º 14
0
NativeResource::NativeResource(unsigned int x, unsigned int y, unsigned int w, unsigned int h, VC_IMAGE_TYPE_T type, void * _imageData, int _imagePitch)
	: resourceHandle(0), rgbType(type), nativeImageHandle(0), imageData(_imageData ), imagePitch(_imagePitch)
{
	int ret;

	setRegion(x,y,w,h);

    resourceHandle = vc_dispmanx_resource_create( rgbType, region.width, region.height, &nativeImageHandle );
    ret = vc_dispmanx_resource_write_data( resourceHandle, rgbType, imagePitch, imageData, &region );
    if ( ret != 0 )
    	throw runtime_error("runtime error : NativeResource::NativeResource ** resourceWriteData failed.");

}
Exemplo n.º 15
0
static void frontend_display(void)
{
  VC_RECT_T dst_rect;

  vc_dispmanx_rect_set( &dst_rect, 0, 0, 640, 480 );

  // begin display update
  fe_update = vc_dispmanx_update_start( 0 );

  // blit image to the current resource
  vc_dispmanx_resource_write_data( fe_resource, VC_IMAGE_RGB565, 640*2, fe_screen, &dst_rect );

  vc_dispmanx_update_submit_sync( fe_update );

}
Exemplo n.º 16
0
void FE_DisplayScreen(void)
{
	VC_RECT_T dst_rect;

	vc_dispmanx_rect_set( &dst_rect, 0, 0, surface_width, surface_height );

	vc_dispmanx_resource_write_data( cur_res, VC_IMAGE_RGB565, surface_width*2, gp2x_screen15, &dst_rect );
	dispman_update = vc_dispmanx_update_start( 0 );
	vc_dispmanx_element_change_source( dispman_update, dispman_element, cur_res );
	vc_dispmanx_update_submit( dispman_update, 0, 0 );

	// swap current resource
	tmp_res = cur_res;
	cur_res = prev_res;
	prev_res = tmp_res;
}
Exemplo n.º 17
0
/* Create a cursor from a surface */
static SDL_Cursor *
RPI_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
{
    RPI_CursorData *curdata;
    SDL_Cursor *cursor;
    int ret;
    VC_RECT_T dst_rect;
    Uint32 dummy;
        
    SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
    SDL_assert(surface->pitch == surface->w * 4);
    
    cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
    if (cursor == NULL) {
        SDL_OutOfMemory();
        return NULL;
    }
    curdata = (RPI_CursorData *) SDL_calloc(1, sizeof(*curdata));
    if (curdata == NULL) {
        SDL_OutOfMemory();
        SDL_free(cursor);
        return NULL;
    }

    curdata->hot_x = hot_x;
    curdata->hot_y = hot_y;
    curdata->w = surface->w;
    curdata->h = surface->h;
    
    /* This usage is inspired by Wayland/Weston RPI code, how they figured this out is anyone's guess */
    curdata->resource = vc_dispmanx_resource_create( VC_IMAGE_ARGB8888, surface->w | (surface->pitch << 16), surface->h | (surface->h << 16), &dummy );
    SDL_assert(curdata->resource);
    vc_dispmanx_rect_set( &dst_rect, 0, 0, curdata->w, curdata->h);
    /* A note from Weston: 
     * vc_dispmanx_resource_write_data() ignores ifmt,
     * rect.x, rect.width, and uses stride only for computing
     * the size of the transfer as rect.height * stride.
     * Therefore we can only write rows starting at x=0.
     */
    ret = vc_dispmanx_resource_write_data( curdata->resource, VC_IMAGE_ARGB8888, surface->pitch, surface->pixels, &dst_rect );
    SDL_assert ( ret == DISPMANX_SUCCESS );
    
    cursor->driverdata = curdata;
    
    return cursor;

}
Exemplo n.º 18
0
void
writeDataWorms(
    WORMS_T *worms)
{
    VC_RECT_T dst_rect;
    vc_dispmanx_rect_set(&dst_rect,
                         0,
                         0,
                         worms->image.width,
                         worms->image.height);

    int result = vc_dispmanx_resource_write_data(worms->backResource,
                                                 worms->image.type,
                                                 worms->image.pitch,
                                                 worms->image.buffer,
                                                 &dst_rect);
    assert(result == 0);
}
Exemplo n.º 19
0
static void dispmanx_update_main(void *data, const void *frame)
{
   struct dispmanx_page *page = NULL;
   struct dispmanx_video *_dispvars = data;

   if (!_dispvars)
      return;

   page = dispmanx_get_free_page(_dispvars);

   if (!page)
      return;

   /* Frame blitting */
   vc_dispmanx_resource_write_data(_dispvars->resources[page->numpage], _dispvars->pixFormat,
         _dispvars->pitch, (void *)frame, &(_dispvars->bmpRect));

   /* Issue flipping: we send the page 
    * to the dispmanx API internal flipping FIFO stack.  */
   dispmanx_flip (page, _dispvars);	
}
Exemplo n.º 20
0
Arquivo: vout.c Projeto: Kubink/vlc
static struct dmx_region_t *dmx_region_new(vout_display_t *vd,
                DISPMANX_UPDATE_HANDLE_T update, subpicture_region_t *region)
{
    vout_display_sys_t *sys = vd->sys;
    video_format_t *fmt = &region->fmt;
    struct dmx_region_t *dmx_region = malloc(sizeof(struct dmx_region_t));
    uint32_t image_handle;

    dmx_region->pos_x = region->i_x;
    dmx_region->pos_y = region->i_y;

    vc_dispmanx_rect_set(&dmx_region->bmp_rect, 0, 0, fmt->i_visible_width,
                    fmt->i_visible_height);
    vc_dispmanx_rect_set(&dmx_region->src_rect, 0, 0, fmt->i_visible_width << 16,
                    fmt->i_visible_height << 16);
    vc_dispmanx_rect_set(&dmx_region->dst_rect, region->i_x, region->i_y,
                    fmt->i_visible_width, fmt->i_visible_height);

    dmx_region->resource = vc_dispmanx_resource_create(VC_IMAGE_RGBA32,
                    dmx_region->bmp_rect.width | (region->p_picture->p[0].i_pitch << 16),
                    dmx_region->bmp_rect.height | (dmx_region->bmp_rect.height << 16),
                    &image_handle);
    vc_dispmanx_resource_write_data(dmx_region->resource, VC_IMAGE_RGBA32,
                    region->p_picture->p[0].i_pitch,
                    region->p_picture->p[0].p_pixels, &dmx_region->bmp_rect);

    dmx_region->alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_MIX;
    dmx_region->alpha.opacity = region->i_alpha;
    dmx_region->alpha.mask = DISPMANX_NO_HANDLE;
    dmx_region->element = vc_dispmanx_element_add(update, sys->dmx_handle,
                    sys->layer + 1, &dmx_region->dst_rect, dmx_region->resource,
                    &dmx_region->src_rect, DISPMANX_PROTECTION_NONE,
                    &dmx_region->alpha, NULL, VC_IMAGE_ROT0);

    dmx_region->next = NULL;
    dmx_region->picture = region->p_picture;

    return dmx_region;
}
Exemplo n.º 21
0
static void dispmanx_set_texture_frame(void *data, const void *frame, bool rgb32,
      unsigned width, unsigned height, float alpha)
{
   struct dispmanx_video *_dispvars = data;

   if (!_dispvars)
      return;

   /* If we're entering the menu in this frame, 
    * we must setup rects, resources and menu element. */
   if (width != _dispvars->menu_width || height != _dispvars->menu_height)
   {
      int i, dst_width, dst_ypos;
      VC_DISPMANX_ALPHA_T layerAlpha;

      /* Sanity check */
      if (width == 0 || height == 0)
         return;

      _dispvars->menu_width = width;
      _dispvars->menu_height = height;

      _dispvars->menu_pitch = width * (rgb32 ? 4 : 2);

      _dispvars->menu_pixFormat = VC_IMAGE_RGBA16;	       
      _dispvars->menu_flip_page = 0;	

      /* Transparency disabled */
      layerAlpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
#if 0
      layerAlpha.opacity = (unsigned char)(255.0f * alpha);
#endif
      layerAlpha.opacity = 210;
      layerAlpha.mask = 0;
      _dispvars->menu_alpha = &layerAlpha;	

      dst_width = _dispvars->amode.height * _dispvars->aspect;	

      /* If we obtain a scaled image width that is 
       * bigger than the physical screen width,
       * then we keep the physical screen width as our maximun width. */
#if 0
      if (dst_width > _dispvars->amode.width) 
      dst_width = _dispvars->amode.width;
#endif
      dst_ypos  = (_dispvars->amode.width - dst_width) / 2; 
      vc_dispmanx_rect_set(&(_dispvars->menu_dstRect), dst_ypos, 0, 
            dst_width, _dispvars->amode.height);

      /* We configure the rects now. */
      vc_dispmanx_rect_set(&(_dispvars->menu_bmpRect), 0, 0, _dispvars->menu_width, _dispvars->menu_height);	
      vc_dispmanx_rect_set(&(_dispvars->menu_srcRect), 0, 0, _dispvars->menu_width << 16, _dispvars->menu_height << 16);	

      /* We create two resources for the menu element. */
      _dispvars->menu_resources[0] = vc_dispmanx_resource_create(_dispvars->menu_pixFormat, 
            _dispvars->menu_width, _dispvars->menu_height, &(_dispvars->vcImagePtr));
      _dispvars->menu_resources[1] = vc_dispmanx_resource_create(_dispvars->menu_pixFormat, 
            _dispvars->menu_width, _dispvars->menu_height, &(_dispvars->vcImagePtr));

      /* Add the menu element. */
      _dispvars->update = vc_dispmanx_update_start(0);

      _dispvars->menu_element = vc_dispmanx_element_add(_dispvars->update, _dispvars->display, 0,
            &(_dispvars->menu_dstRect), _dispvars->menu_resources[0], &(_dispvars->menu_srcRect), 
            DISPMANX_PROTECTION_NONE, _dispvars->menu_alpha, 0, (DISPMANX_TRANSFORM_T)0);

      vc_dispmanx_update_submit_sync(_dispvars->update);		
   }

   /* Flipping is done in every frame, 
    * in the gfx_frame function. 
    * That's why why change flip page here instead. */
   _dispvars->menu_flip_page = !_dispvars->menu_flip_page;

   /* Frame blitting. */
   vc_dispmanx_resource_write_data(_dispvars->menu_resources[_dispvars->menu_flip_page],
         _dispvars->menu_pixFormat, _dispvars->menu_pitch, (void *)frame, &(_dispvars->menu_bmpRect));

   /* We don't flip the menu buffers here: 
    * that's done in the gfx_frame function when menu is active. */
}
Exemplo n.º 22
0
void
initWorms(
    uint16_t number,
    uint16_t length,
    WORMS_T *worms,
    VC_IMAGE_TYPE_T imageType,
    DISPMANX_MODEINFO_T *info)
{
    initImage(&(worms->image), imageType, info->width, info->height, false);
    srand(time(NULL));

    worms->size = number;
    worms->worms = malloc(worms->size * sizeof(WORM_T));

    if (worms->worms == NULL)
    {
        fprintf(stderr, "worms: memory exhausted\n");
        exit(EXIT_FAILURE);
    }

    uint16_t i = 0;
    for (i = 0 ; i < worms->size ; i++)
    {
        WORM_T *worm = &(worms->worms[i]);
        initWorm(i, number, length, worm, &(worms->image));
    }

    //---------------------------------------------------------------------

    uint32_t vc_image_ptr;

    worms->frontResource =
        vc_dispmanx_resource_create(
            worms->image.type,
            worms->image.width  |(worms->image.pitch << 16),
            worms->image.height | (worms->image.alignedHeight << 16),
            &vc_image_ptr);
    assert(worms->frontResource != 0);

    worms->backResource =
        vc_dispmanx_resource_create(worms->image.type,
            worms->image.width | (worms->image.pitch << 16),
            worms->image.height | (worms->image.alignedHeight << 16),
            &vc_image_ptr);
    assert(worms->backResource != 0);

    //---------------------------------------------------------------------

    int result = 0;

    VC_RECT_T dst_rect;
    vc_dispmanx_rect_set(&dst_rect,
                         0,
                         0,
                         worms->image.width,
                         worms->image.height);

    result = vc_dispmanx_resource_write_data(worms->frontResource,
                                             worms->image.type,
                                             worms->image.pitch,
                                             worms->image.buffer,
                                             &dst_rect);
    assert(result == 0);
}
Exemplo n.º 23
0
/**
 * Process a single frame.
 *
 * Currently this converts the RGB image from the camera
 * to the BGR format expected by OpenCV, then displays
 * the image using OpenCV. In the future, image processing
 * will happen here.
 *
 * This does not have to be a global function; it could also
 * be put inline as a lambda function.
 *
 * @param frame the frame to be processed.
 */
void process_frame(cv::Mat frame) {
    ++n;
    cv::Mat_<cv::Vec3b> hsv(frame.size());
    cv::Mat_<unsigned char> binary(frame.size());
    cv::Mat_<unsigned char> back(frame.size());
    cv::Mat_<cv::Vec3b> disp(frame.size());
    cv::cvtColor(frame, hsv, CV_RGB2HSV_FULL);
    frame.copyTo(disp);
    //cv::cvtColor(frame, disp, CV_RGB2BGR);
    //int min[] = {hue-range, 0, 0};
    //int max[] = {hue+range, 255, 255};
    /*
    cv::inRange(hsv, cv::Scalar(hue-range, s_min, v_min), cv::Scalar(hue+range, s_max, v_max), binary);
    */
    int numP = 0;
    if(done_hist) {
        cv::calcBackProject(&hsv, 1, channels, hist, binary, ranges, 1);
        cv::calcBackProject(&hsv, 1, channels, back_hist, back, ranges, 1);
        //cv::inRange(binary, 150, 255, binary);
        //cv::morphologyEx(binary, binary, cv::MORPH_CLOSE, getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(20, 20)));
        //cv::close(binary, binary, getStructuringElement(MORPH_ELLIPSE, cv::Size(2*10+1, 2*10+1), cv::Point(10, 10)));

        float centroid_x = 0.0f;
        float centroid_y = 0.0f;
        for(int j = 0; j < frame.rows; ++j) {
            for(int i = 0; i < frame.cols; ++i) {
                float weight = binary(j, i);
                float back_weight = back(j, i);
                if(weight > back_weight * (threshold / 500.0f)) {
                    binary(j, i) = 255;
                    //if(weight > 200) {
                    numP += weight;
                    centroid_x += i * weight;
                    centroid_y += j * weight;
                } else {
                    binary(j, i) = 0;
                }
            }
        }
        centroid_x /= numP;
        centroid_y /= numP;

        cv::circle(disp, cv::Point((int)centroid_x, (int)centroid_y), 5, cv::Scalar(255, 0, 0), -1);

        float r = sqrt(centroid_x*centroid_x + centroid_y*centroid_y);
    }
    /*
    cv::Mat hue(frame.size(), CV_8U);
    const int fromto[] = {0, 0};
    cv::mixChannels(&frame, 1, &hue, 1, fromto, 1);
    cv::Mat binary(frame.size(), CV_8U);
    cv::inRange(frame, 0, 50, binary);
    */



    //cv::Mat_<unsigned char> binary = cv::Mat_<unsigned char>::zeros(frame.rows, frame.cols);
    /*
    for(int j = 0; j < frame.rows; ++j) {
        for(int i = 0; i < frame.cols; ++i) {
            int r = frame.at<cv::Vec3b>(j, i)[0];
            int b = frame.at<cv::Vec3b>(j, i)[1];
            int g = frame.at<cv::Vec3b>(j, i)[2];
            binary(j, i) = r - r*(b + g)/(2*255);
            float r = frame.at<cv::Vec3b>(j, i)[0]/255.0f;
            float b = frame.at<cv::Vec3b>(j, i)[1]/255.0f;
            float g = frame.at<cv::Vec3b>(j, i)[2]/255.0f;
            float h = 0;

            if(r>=g) {
                if(g>=b) {
                    h = 60*(2-(g-b)/(r-b));
                } else {
                    60*(4-(g-r)/(b-r));
                }
            } else {

            }

            if(r>=g && g>=b)        h = 60*(2-(g-b)/(r-b));
            else if(g>r && r>=b)    h = 60*(2-(r-b)/(g-b));
            else if(g>=b && b>r)    h = 60*(2+(b-r)/(g-r));
            else if(b>g && g>r)     h = 60*(4-(g-r)/(b-r));
            else if(b>r && r>=g)    h = 60*(4+(r-g)/(b-g));
            else if(r>=b && b>g)    h = 60*(6-(b-g)/(r-g));

            h *= 255.0f/360.0f;

            //binary(j, i) = target - (unsigned char)h;
            if( (target -(unsigned char)h) < 10 ||  ((unsigned char)h - target) < 10) {
                binary(j, i) = 255;
            } else {
                binary(j, i) = 0;
            }
        }
    }
    */

    /*
    cv::Mat blurred(binary.size(), CV_8U);
    cv::GaussianBlur(binary, blurred, cv::Size(9, 9), 2, 2);
    std::vector<cv::Vec3f> circles;
    cv::HoughCircles(blurred, circles, CV_HOUGH_GRADIENT, 2, frame.rows, 30, 100, 5, 100);

    for(size_t i = 0; i < circles.size(); ++i) {
        cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
        cv::circle(disp, center, 5, cv::Scalar(0, 255, 0), -1, 8, 0);
        //cv::circle(frame, center, radius, cv::Scalar(0), 3, 8, 0);
    }


    */
    cv::circle(disp, cv::Point(frame.size().width/2,frame.size().height/2), 25, cv::Scalar(0, 255, 0));


    VC_RECT_T dst_rect;
    vc_dispmanx_rect_set( &dst_rect, 0, 0, 160, 120);
    int ret = vc_dispmanx_resource_write_data(  display_resource,
              VC_IMAGE_RGB888,
              160*3,
              disp.data,
              &dst_rect);
    assert(ret==0);
    DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start( 10 );
    vc_dispmanx_element_modified(update, element, &dst_rect);
    vc_dispmanx_update_submit_sync(update);


    //cv::imshow("RPi Cam Raw", disp);
    //cv::imshow("RPi Cam Proc", binary);
}
Exemplo n.º 24
0
void flush_screen ()
{
    //SDL_UnlockSurface (prSDLScreen);

    if (show_inputmode)
    {
        inputmode_redraw();	
    }


    if (savestate_state == STATE_DOSAVE)
    {
    if(delay_savestate_frame > 0)
      --delay_savestate_frame;
    else
    {
        CreateScreenshot();
        save_thumb(screenshot_filename);
        savestate_state = 0;
    }
  }

  unsigned long start = read_processor_time();
  //if(start < next_synctime && next_synctime - start > time_per_frame - 1000)
  //  usleep((next_synctime - start) - 1000);
  //SDL_Flip(prSDLScreen);


	if (current_resource_amigafb == 1)
	{
		current_resource_amigafb = 0;
		vc_dispmanx_resource_write_data(  dispmanxresource_amigafb_1,
	                                    VC_IMAGE_RGB565,
	                                    gfxvidinfo.width * 2,
	                                    gfxvidinfo.bufmem,
	                                    &blit_rect );
		dispmanxupdate = vc_dispmanx_update_start( 10 );
		vc_dispmanx_element_change_source(dispmanxupdate,dispmanxelement,dispmanxresource_amigafb_1);

		vc_dispmanx_update_submit(dispmanxupdate,vsync_callback,NULL);
		//vc_dispmanx_update_submit_sync(dispmanxupdate);

	}
	else
	{
		current_resource_amigafb = 1;
		vc_dispmanx_resource_write_data(  dispmanxresource_amigafb_2,
	                                    VC_IMAGE_RGB565,
	                                    gfxvidinfo.width * 2,
	                                    gfxvidinfo.bufmem,
	                                    &blit_rect );
		dispmanxupdate = vc_dispmanx_update_start( 10 );
		vc_dispmanx_element_change_source(dispmanxupdate,dispmanxelement,dispmanxresource_amigafb_2);

		vc_dispmanx_update_submit(dispmanxupdate,vsync_callback,NULL);
	}

  last_synctime = read_processor_time();
  
  if(last_synctime - next_synctime > time_per_frame - 1000)
    adjust_idletime(0);
  else
    adjust_idletime(next_synctime - start);
  
  if(last_synctime - next_synctime > time_per_frame - 5000)
    next_synctime = last_synctime + time_per_frame * (1 + currprefs.gfx_framerate);
  else
    next_synctime = next_synctime + time_per_frame * (1 + currprefs.gfx_framerate);

	init_row_map();

}
Exemplo n.º 25
0
static void open_screen(struct uae_prefs *p)
{

  VC_DISPMANX_ALPHA_T alpha = { (DISPMANX_FLAGS_ALPHA_T ) (DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS), 
                            255, /*alpha 0->255*/
                            0 };


  uint32_t     vc_image_ptr;
  int          width;
  int          height;

#ifdef PICASSO96
  if (screen_is_picasso)
  {
    width  = picasso_vidinfo.width;
    height = picasso_vidinfo.height;
  } else
#endif
  {
    p->gfx_resolution = p->gfx_size.width > 600 ? 1 : 0;
    width  = p->gfx_size.width;
    height = p->gfx_size.height;
  }


  //if(prSDLScreen != NULL)
  //{
  //  SDL_FreeSurface(prSDLScreen);
  //  prSDLScreen = NULL;
  //} 

  if(Dummy_prSDLScreen == NULL )
  {
    const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo ();
    printf("DispmanX: Current resolution: %d x %d %d bpp\n",videoInfo->current_w, videoInfo->current_h, videoInfo->vfmt->BitsPerPixel);
    Dummy_prSDLScreen = SDL_SetVideoMode(videoInfo->current_w,videoInfo->current_h,16,SDL_SWSURFACE |SDL_FULLSCREEN);
    //Dummy_prSDLScreen = SDL_SetVideoMode(800,480,16,SDL_SWSURFACE );
  }

  SDL_ShowCursor(SDL_DISABLE);

  // check if resolution hasn't change in menu. otherwise free the resources so that they will be re-generated with new resolution.
  if ((dispmanxresource_amigafb_1 != 0) && 
     ((blit_rect.width != width) || (blit_rect.height != height) || (currprefs.gfx_correct_aspect != changed_prefs.gfx_correct_aspect)))
  {
	printf("Emulation resolution change detected.\n");
	if(prSDLScreen != NULL )
	{
		SDL_FreeSurface(prSDLScreen);
		prSDLScreen = 0;
	}
	graphics_dispmanshutdown();
	vc_dispmanx_resource_delete( dispmanxresource_amigafb_1 );
	vc_dispmanx_resource_delete( dispmanxresource_amigafb_2 );
	dispmanxresource_amigafb_1 = 0;
	dispmanxresource_amigafb_2 = 0;
  }

  if (dispmanxresource_amigafb_1 == 0)
  {
	printf("Emulation resolution: Width %i Height: %i\n",width,height);
	currprefs.gfx_correct_aspect = changed_prefs.gfx_correct_aspect;
	prSDLScreen = SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,16,
		Dummy_prSDLScreen->format->Rmask,
		Dummy_prSDLScreen->format->Gmask,
		Dummy_prSDLScreen->format->Bmask,
		Dummy_prSDLScreen->format->Amask);

	dispmanxdisplay = vc_dispmanx_display_open( 0 );
	vc_dispmanx_display_get_info( dispmanxdisplay, &dispmanxdinfo);

	dispmanxresource_amigafb_1 = vc_dispmanx_resource_create( VC_IMAGE_RGB565,  width,   height,  &vc_image_ptr);
	dispmanxresource_amigafb_2 = vc_dispmanx_resource_create( VC_IMAGE_RGB565,  width,   height,  &vc_image_ptr);
	vc_dispmanx_rect_set( &blit_rect, 0, 0, width,height);
	vc_dispmanx_resource_write_data(  dispmanxresource_amigafb_1,
                                    VC_IMAGE_RGB565,
                                    width *2,
                                    prSDLScreen->pixels,
                                    &blit_rect );
	vc_dispmanx_rect_set( &src_rect, 0, 0, width << 16, height << 16 );

  }
  // 16/9 to 4/3 ratio adaptation.
  if (currprefs.gfx_correct_aspect == 0)
  {
	// Fullscreen.
	vc_dispmanx_rect_set( &dst_rect, (dispmanxdinfo.width * 1)/100,
							(dispmanxdinfo.height * 2)/100 ,
							dispmanxdinfo.width - (dispmanxdinfo.width * 2)/100 ,
							dispmanxdinfo.height - (dispmanxdinfo.height * 4)/100 );
  }
  else
  {
	// 4/3 shrink.
	vc_dispmanx_rect_set( &dst_rect, ((dispmanxdinfo.width * 13)/100) ,
							(dispmanxdinfo.height * 2)/100 ,
							(dispmanxdinfo.width - ((dispmanxdinfo.width * 26)/100)) ,
							dispmanxdinfo.height - (dispmanxdinfo.height * 4)/100 );
  }

  // For debug, in order to avoid full screen.
  //vc_dispmanx_rect_set( &dst_rect, (dispmanxdinfo.width /2),
  //                     (dispmanxdinfo.height /2) ,
  //                     (dispmanxdinfo.width - (dispmanxdinfo.width * 6)/100 )/2,
  //                     (dispmanxdinfo.height - (dispmanxdinfo.height * 7)/100 )/2);


  if (DispManXElementpresent == 0)
  {
     DispManXElementpresent = 1;
     dispmanxupdate = vc_dispmanx_update_start( 10 );
     dispmanxelement = vc_dispmanx_element_add( dispmanxupdate,
                                        dispmanxdisplay,
                                        2000,               // layer
                                        &dst_rect,
                                        dispmanxresource_amigafb_1,
                                        &src_rect,
                                        DISPMANX_PROTECTION_NONE,
                                        &alpha,
                                        NULL,             // clamp
                                        DISPMANX_NO_ROTATE );

    vc_dispmanx_update_submit(dispmanxupdate,NULL,NULL);
    //dispmanxupdate = vc_dispmanx_update_start( 10 );
  }

  if(prSDLScreen != NULL)
  {
    InitAmigaVidMode(p);
    init_row_map();
  }    
  //framecnt = 1; // Don't draw frame before reset done
}
Exemplo n.º 26
0
int main(int argc, char *argv[])
{
    int ret;
    VC_RECT_T       src_rect;
    VC_RECT_T       dst_rect;

    DISPMANX_UPDATE_HANDLE_T    update;
    uint32_t                    vc_image_ptr;

    bcm_host_init();

    display = vc_dispmanx_display_open( 0 );

    image = calloc( 1, PITCH * HEIGHT ); // buffer 0
    assert(image);

    // initialize image buffer with clock run in
    int n, m, clock = 0x275555;
    for (m=0; m<24; m++) {
        for (n=0; n<HEIGHT; n++) {
            ROW(n)[m] = clock&1;
        }
        clock = clock >> 1;
    }

    // fill up image with filler packets
    // get_packet will return filler because we haven't loaded the fifo yet.
    get_packet(ROW(0)+24);
    for (n=1; n<HEIGHT; n++) {
        memcpy(ROW(n)+24, ROW(0)+24, 336);
    }

    // set up some resources
    vc_dispmanx_rect_set( &image_rect, 0, 0, WIDTH, HEIGHT);
    for (n=0;n<3;n++) {
        resource[n] = vc_dispmanx_resource_create( TYPE, WIDTH, HEIGHT, &vc_image_ptr );
        assert( resource[n] );
        ret = vc_dispmanx_resource_set_palette(  resource[n], palette, 0, sizeof palette );
        assert( ret == 0 );
        ret = vc_dispmanx_resource_write_data(  resource[n], TYPE, PITCH, image, &image_rect );
        assert( ret == 0 );
    }
    vc_dispmanx_rect_set( &image_rect, OFFSET+24, 0, 336, HEIGHT); // from now on, only copy the parts that change

    update = vc_dispmanx_update_start( 10 );
    assert( update );

    vc_dispmanx_rect_set( &src_rect, 0, 0, WIDTH << 16, HEIGHT << 16 );
    vc_dispmanx_rect_set( &dst_rect, 0, 0, 720, HEIGHT );
    element = vc_dispmanx_element_add( update, display, 2000,
                                       &dst_rect, resource[2], &src_rect,
                                       DISPMANX_PROTECTION_NONE,
                                       NULL, NULL, VC_IMAGE_ROT0 );

    ret = vc_dispmanx_update_submit_sync( update );
    assert( ret == 0 );

    // BUG: clear any existing callbacks, even to other apps.
    // https://github.com/raspberrypi/userland/issues/218
    vc_dispmanx_vsync_callback(display, NULL, NULL);

    vc_dispmanx_vsync_callback(display, vsync, NULL);

    if (argc == 2 && argv[1][0] == '-') {
        while(read_packets()) {
            ;
        }
    } else {
        demo();
    }

    vc_dispmanx_vsync_callback(display, NULL, NULL); // disable callback

    update = vc_dispmanx_update_start( 10 );
    assert( update );
    ret = vc_dispmanx_element_remove( update, element );
    assert( ret == 0 );
    ret = vc_dispmanx_update_submit_sync( update );
    assert( ret == 0 );
    for (n=0; n<3; n++) {
        ret = vc_dispmanx_resource_delete( resource[0] );
        assert( ret == 0 );
    }
    ret = vc_dispmanx_display_close( display );
    assert( ret == 0 );

    return 0;
}
Exemplo n.º 27
0
void
newLife(
    LIFE_T *life,
    int32_t size)
{
    life->width = size;
    life->height = size;
    life->alignedWidth = ALIGN_TO_16(life->width);
    life->alignedHeight = ALIGN_TO_16(life->height);
    life->pitch = ALIGN_TO_16(life->width);

    life->buffer = calloc(1, life->pitch * life->alignedHeight);

    if (life->buffer == NULL)
    {
        fprintf(stderr, "life: memory exhausted\n");
        exit(EXIT_FAILURE);
    }

    life->fieldLength = life->width * life->height;

    life->field = calloc(1, life->fieldLength);

    if (life->field == NULL)
    {
        fprintf(stderr, "life: memory exhausted\n");
        exit(EXIT_FAILURE);
    }

    life->fieldNext = calloc(1, life->fieldLength);

    if (life->fieldNext == NULL)
    {
        fprintf(stderr, "life: memory exhausted\n");
        exit(EXIT_FAILURE);
    }

    struct timeval tv;
    gettimeofday(&tv, NULL);
    srand(tv.tv_usec);

    int32_t row = 0;
    for (row = 0 ; row < life->height ; row++)
    {
        int32_t col = 0;
        for (col = 0 ; col < life->width ; col++)
        {
            if (rand() > (RAND_MAX / 2))
            {
                setCell(life, col, row);
            }
            else
            {
                life->buffer[col + (row * life->alignedWidth)] = DEAD;
            }
        }
    }

    //---------------------------------------------------------------------

    VC_IMAGE_TYPE_T type = VC_IMAGE_8BPP;
    uint32_t vc_image_ptr;
    int result = 0;

    life->frontResource = 
        vc_dispmanx_resource_create(
            type,
            life->width | (life->pitch << 16),
            life->height | (life->alignedHeight << 16),
            &vc_image_ptr);
    assert(life->frontResource != 0);

    life->backResource = 
        vc_dispmanx_resource_create(
            type,
            life->width | (life->pitch << 16),
            life->height | (life->alignedHeight << 16),
            &vc_image_ptr);
    assert(life->backResource != 0);

    //---------------------------------------------------------------------

    vc_dispmanx_rect_set(&(life->bmpRect), 0, 0, life->width, life->height);

    result = vc_dispmanx_resource_write_data(life->frontResource,
                                             type,
                                             life->pitch,
                                             life->buffer,
                                             &(life->bmpRect));
    assert(result == 0);

    //---------------------------------------------------------------------

    long cores = sysconf(_SC_NPROCESSORS_ONLN);

    if (cores == -1)
    {
        cores = 1;
    }

    if (cores > LIFE_MAX_THREADS)
    {
        life->numberOfThreads = LIFE_MAX_THREADS;
    }
    else
    {
        life->numberOfThreads = cores;
    }

    pthread_barrier_init(&(life->startIterationBarrier),
                         NULL,
                         life->numberOfThreads + 1);

    pthread_barrier_init(&(life->finishedIterationBarrier),
                         NULL,
                         life->numberOfThreads + 1);

    //---------------------------------------------------------------------

    int32_t heightStep = life->height / life->numberOfThreads;
    int32_t heightStart = 0;

    int32_t thread;
    for (thread = 0 ; thread < life->numberOfThreads ; thread++)
    {
        life->heightRange[thread].startHeight = heightStart;
        life->heightRange[thread].endHeight = heightStart + heightStep;

        heightStart += heightStep;

        pthread_create(&(life->threads[thread]),
                       NULL,
                       workerLife,
                       life);
    }

    thread = life->numberOfThreads - 1;
    life->heightRange[thread].endHeight = life->height;

    //---------------------------------------------------------------------

    memcpy(life->field, life->fieldNext, life->fieldLength);
    pthread_barrier_wait(&(life->startIterationBarrier));
}
Exemplo n.º 28
0
static void *display_thread (void *unused)
{
	VC_DISPMANX_ALPHA_T alpha = {
		(DISPMANX_FLAGS_ALPHA_T)(DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS), 
		255 /*alpha 0->255*/ , 	0
	};
	uint32_t vc_image_ptr;
	SDL_Surface *Dummy_prSDLScreen;
	int width, height;
	bool callback_registered = false;
	
  for(;;) {
    display_thread_busy = false;
    uae_u32 signal = read_comm_pipe_u32_blocking(display_pipe);
    display_thread_busy = true;
    switch(signal) {
      case DISPLAY_SIGNAL_SETUP:
        if(!callback_registered) {
  				bcm_host_init();
  				dispmanxdisplay = vc_dispmanx_display_open(0);
  			  vc_dispmanx_vsync_callback(dispmanxdisplay, vsync_callback, NULL);
  			  callback_registered = true;
  			}
			  break;

			case DISPLAY_SIGNAL_SUBSHUTDOWN:
				if (DispManXElementpresent == 1) {
					DispManXElementpresent = 0;
					dispmanxupdate = vc_dispmanx_update_start(0);
					vc_dispmanx_element_remove(dispmanxupdate, dispmanxelement);
					vc_dispmanx_update_submit_sync(dispmanxupdate);
				}
			
				if (dispmanxresource_amigafb_1 != 0) {
					vc_dispmanx_resource_delete(dispmanxresource_amigafb_1);
					dispmanxresource_amigafb_1 = 0;
			  }
				if (dispmanxresource_amigafb_2 != 0) {
					vc_dispmanx_resource_delete(dispmanxresource_amigafb_2);
					dispmanxresource_amigafb_2 = 0;
			  }
			  
			  if(prSDLScreen != NULL) {
			    SDL_FreeSurface(prSDLScreen);
			    prSDLScreen = NULL;
			  }
        uae_sem_post (&display_sem);
        break;
				
			case DISPLAY_SIGNAL_OPEN:
				width = display_width;
				height = display_height;
				
				Dummy_prSDLScreen = SDL_SetVideoMode(width, height, 16, SDL_SWSURFACE | SDL_FULLSCREEN);
				prSDLScreen = SDL_CreateRGBSurface(SDL_HWSURFACE, width, height, 16,
					Dummy_prSDLScreen->format->Rmask,	Dummy_prSDLScreen->format->Gmask, Dummy_prSDLScreen->format->Bmask, Dummy_prSDLScreen->format->Amask);
				SDL_FreeSurface(Dummy_prSDLScreen);
			
				vc_dispmanx_display_get_info(dispmanxdisplay, &dispmanxdinfo);
			
				dispmanxresource_amigafb_1 = vc_dispmanx_resource_create(VC_IMAGE_RGB565, width, height, &vc_image_ptr);
				dispmanxresource_amigafb_2 = vc_dispmanx_resource_create(VC_IMAGE_RGB565, width, height, &vc_image_ptr);
			
				vc_dispmanx_rect_set(&blit_rect, 0, 0, width, height);
				vc_dispmanx_resource_write_data(dispmanxresource_amigafb_1, VC_IMAGE_RGB565, prSDLScreen->pitch, prSDLScreen->pixels, &blit_rect);
				vc_dispmanx_rect_set(&src_rect, 0, 0, width << 16, height << 16);
			
				// 16/9 to 4/3 ratio adaptation.
				if (currprefs.gfx_correct_aspect == 0 || screen_is_picasso) {
				  // Fullscreen.
					int scaled_width = dispmanxdinfo.width * currprefs.gfx_fullscreen_ratio / 100;
					int scaled_height = dispmanxdinfo.height * currprefs.gfx_fullscreen_ratio / 100;
					vc_dispmanx_rect_set( &dst_rect, (dispmanxdinfo.width - scaled_width)/2, (dispmanxdinfo.height - scaled_height)/2,
						scaled_width,	scaled_height);
				}	else {
				  // 4/3 shrink.
					int scaled_width = dispmanxdinfo.width * currprefs.gfx_fullscreen_ratio / 100;
					int scaled_height = dispmanxdinfo.height * currprefs.gfx_fullscreen_ratio / 100;
					vc_dispmanx_rect_set( &dst_rect, (dispmanxdinfo.width - scaled_width / 16 * 12)/2, (dispmanxdinfo.height - scaled_height)/2,
						scaled_width/16*12,	scaled_height);
				}
			
				if (DispManXElementpresent == 0) {
					DispManXElementpresent = 1;
					dispmanxupdate = vc_dispmanx_update_start(0);
					dispmanxelement = vc_dispmanx_element_add(dispmanxupdate, dispmanxdisplay,	2,               // layer
						&dst_rect, dispmanxresource_amigafb_1, &src_rect,	DISPMANX_PROTECTION_NONE,	&alpha,	NULL, DISPMANX_NO_ROTATE);
			
					vc_dispmanx_update_submit(dispmanxupdate, NULL, NULL);
				}
        uae_sem_post (&display_sem);
        break;

			case DISPLAY_SIGNAL_SHOW:
				if (current_resource_amigafb == 1) {
					current_resource_amigafb = 0;
				  vc_dispmanx_resource_write_data(dispmanxresource_amigafb_1, VC_IMAGE_RGB565,
					  adisplays.gfxvidinfo.drawbuffer.rowbytes, adisplays.gfxvidinfo.drawbuffer.bufmem, &blit_rect);
				  dispmanxupdate = vc_dispmanx_update_start(0);
				  vc_dispmanx_element_change_source(dispmanxupdate, dispmanxelement, dispmanxresource_amigafb_1);
				} else {
					current_resource_amigafb = 1;
					vc_dispmanx_resource_write_data(dispmanxresource_amigafb_2,	VC_IMAGE_RGB565,
						adisplays.gfxvidinfo.drawbuffer.rowbytes,	adisplays.gfxvidinfo.drawbuffer.bufmem,	&blit_rect);
					dispmanxupdate = vc_dispmanx_update_start(0);
					vc_dispmanx_element_change_source(dispmanxupdate, dispmanxelement, dispmanxresource_amigafb_2);
				}
			  vc_dispmanx_update_submit(dispmanxupdate, NULL, NULL);
				break;
								
      case DISPLAY_SIGNAL_QUIT:
        callback_registered = false;
			  vc_dispmanx_vsync_callback(dispmanxdisplay, NULL, NULL);
				vc_dispmanx_display_close(dispmanxdisplay);
				bcm_host_deinit();
				SDL_VideoQuit();
        display_tid = 0;
        return 0;
    }
  }
}
static jlong fbDispmanCreateNativeCursor(JNIEnv *env, jint x, jint y,  jbyte *srcArray, jint width, jint height) {

    VC_RECT_T pixelRect;
    int rc;
    uint32_t imagePtr;
    jbyte *allocatedBuffer = NULL;
    DispmanCursorImage *cursorImage = (DispmanCursorImage *)malloc(sizeof(DispmanCursorImage));

    //Width should be aligned to 16 pixels
    if (width % 16 != 0) {
        int newWidth = width + 16 - (width % 16);
        allocatedBuffer = (jbyte *)malloc(newWidth * height * 4);
        int i;
        int offset = 0;
        for (i = 0; i < height; ++i) {
            memcpy(allocatedBuffer + offset, srcArray, width * 4);
            memset(allocatedBuffer + offset + (width * 4), 0, (newWidth - width) * 4);
            offset += newWidth * 4;
            srcArray += width * 4;
        }

        width = newWidth;
        srcArray = allocatedBuffer;
    }

    pixelRect.x = 0;
    pixelRect.y = 0;
    pixelRect.width = width;
    pixelRect.height = height;

    cursorImage->x = x;
    cursorImage->y = y;
    cursorImage->width = width;
    cursorImage->height = height;
    cursorImage->resource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888,
                            width,
                            height,
                            &imagePtr);
    if (cursorImage->resource == 0) {
        GLASS_LOG_SEVERE("Cannot create resource");
        if (allocatedBuffer != NULL) {
            free(allocatedBuffer);
            allocatedBuffer = NULL;
        }
        free(cursorImage);
        return 0;
    }

    rc = vc_dispmanx_resource_write_data(cursorImage->resource,
                                         VC_IMAGE_ARGB8888,
                                         width * 4,
                                         srcArray,
                                         &pixelRect);

    if (allocatedBuffer != NULL) {
        free(allocatedBuffer);
        allocatedBuffer = NULL;
    }

    if (rc != 0) {
        GLASS_LOG_SEVERE("Cannot write pixels");
        free(cursorImage);
        return 0;
    }

    return ptr_to_jlong(cursorImage);
}